From 4847f3fe15e8cfb3e222bdc0f582ca1f4aa07e5c Mon Sep 17 00:00:00 2001 From: Thai Cong Nguyen <21520169@gm.uit.edu.vn> Date: Wed, 31 Dec 2025 14:24:50 +0700 Subject: [PATCH 01/25] feat: init track 1-xcm-hyperbridge --- .../.github/workflows/test.yml | 40 + .../hyperbridge-token-bridge/.gitignore | 14 + .../hyperbridge-token-bridge/README.md | 66 + .../hyperbridge-token-bridge/foundry.lock | 8 + .../hyperbridge-token-bridge/foundry.toml | 13 + .../lib/forge-std/.gitattributes | 1 + .../lib/forge-std/.github/CODEOWNERS | 1 + .../lib/forge-std/.github/dependabot.yml | 6 + .../lib/forge-std/.github/workflows/ci.yml | 137 + .../lib/forge-std/.github/workflows/sync.yml | 36 + .../lib/forge-std/.gitignore | 4 + .../lib/forge-std/CONTRIBUTING.md | 193 + .../lib/forge-std/LICENSE-APACHE | 203 + .../lib/forge-std/LICENSE-MIT | 25 + .../lib/forge-std/README.md | 266 + .../lib/forge-std/RELEASE_CHECKLIST.md | 12 + .../lib/forge-std/foundry.toml | 30 + .../lib/forge-std/package.json | 16 + .../lib/forge-std/scripts/vm.py | 646 + .../lib/forge-std/src/Base.sol | 48 + .../lib/forge-std/src/Config.sol | 60 + .../lib/forge-std/src/LibVariable.sol | 477 + .../lib/forge-std/src/Script.sol | 28 + .../lib/forge-std/src/StdAssertions.sol | 780 + .../lib/forge-std/src/StdChains.sol | 292 + .../lib/forge-std/src/StdCheats.sol | 830 + .../lib/forge-std/src/StdConfig.sol | 613 + .../lib/forge-std/src/StdConstants.sol | 30 + .../lib/forge-std/src/StdError.sol | 15 + .../lib/forge-std/src/StdInvariant.sol | 122 + .../lib/forge-std/src/StdJson.sol | 277 + .../lib/forge-std/src/StdMath.sol | 47 + .../lib/forge-std/src/StdStorage.sol | 473 + .../lib/forge-std/src/StdStyle.sol | 333 + .../lib/forge-std/src/StdToml.sol | 277 + .../lib/forge-std/src/StdUtils.sol | 208 + .../lib/forge-std/src/Test.sol | 34 + .../lib/forge-std/src/Vm.sol | 2501 +++ .../lib/forge-std/src/console.sol | 1560 ++ .../lib/forge-std/src/console2.sol | 4 + .../lib/forge-std/src/interfaces/IERC1155.sol | 105 + .../lib/forge-std/src/interfaces/IERC165.sol | 12 + .../lib/forge-std/src/interfaces/IERC20.sol | 43 + .../lib/forge-std/src/interfaces/IERC4626.sol | 190 + .../lib/forge-std/src/interfaces/IERC6909.sol | 72 + .../lib/forge-std/src/interfaces/IERC721.sol | 164 + .../lib/forge-std/src/interfaces/IERC7540.sol | 144 + .../lib/forge-std/src/interfaces/IERC7575.sol | 241 + .../forge-std/src/interfaces/IMulticall3.sol | 70 + .../lib/forge-std/src/safeconsole.sol | 13937 ++++++++++++++++ .../lib/forge-std/test/CommonBase.t.sol | 44 + .../lib/forge-std/test/Config.t.sol | 352 + .../lib/forge-std/test/LibVariable.t.sol | 434 + .../lib/forge-std/test/StdAssertions.t.sol | 141 + .../lib/forge-std/test/StdChains.t.sol | 227 + .../lib/forge-std/test/StdCheats.t.sol | 639 + .../lib/forge-std/test/StdConstants.t.sol | 38 + .../lib/forge-std/test/StdError.t.sol | 120 + .../lib/forge-std/test/StdJson.t.sol | 49 + .../lib/forge-std/test/StdMath.t.sol | 202 + .../lib/forge-std/test/StdStorage.t.sol | 486 + .../lib/forge-std/test/StdStyle.t.sol | 110 + .../lib/forge-std/test/StdToml.t.sol | 49 + .../lib/forge-std/test/StdUtils.t.sol | 342 + .../lib/forge-std/test/Vm.t.sol | 18 + .../test/compilation/CompilationScript.sol | 10 + .../compilation/CompilationScriptBase.sol | 10 + .../test/compilation/CompilationTest.sol | 10 + .../test/compilation/CompilationTestBase.sol | 10 + .../test/fixtures/broadcast.log.json | 187 + .../lib/forge-std/test/fixtures/config.toml | 81 + .../lib/forge-std/test/fixtures/test.json | 8 + .../lib/forge-std/test/fixtures/test.toml | 6 + .../lib/hyperbridge-sdk/.changeset/README.md | 8 + .../hyperbridge-sdk/.changeset/config.json | 13 + .../lib/hyperbridge-sdk/.dockerignore | 51 + .../lib/hyperbridge-sdk/.eslintrc.js | 23 + .../.github/workflows/filler-docker.yml | 63 + .../.github/workflows/publish-core.yml | 124 + .../.github/workflows/publish-sdk.yml | 121 + .../.github/workflows/test-core.yml | 69 + .../.github/workflows/test-nexus-ci.yml | 108 + .../.github/workflows/test-sdk.yml | 128 + .../lib/hyperbridge-sdk/.gitignore | 95 + .../lib/hyperbridge-sdk/.npmrc | 2 + .../lib/hyperbridge-sdk/LICENSE | 21 + .../lib/hyperbridge-sdk/README.md | 71 + .../lib/hyperbridge-sdk/package.json | 77 + .../hyperbridge-sdk/packages/core/.gitignore | 17 + .../hyperbridge-sdk/packages/core/.prettierrc | 5 + .../lib/hyperbridge-sdk/packages/core/LICENSE | 51 + .../hyperbridge-sdk/packages/core/README.md | 30 + .../packages/core/contracts/apps/HyperApp.sol | 179 + .../contracts/apps/HyperFungibleToken.sol | 72 + .../core/contracts/apps/IntentGateway.sol | 228 + .../core/contracts/apps/TokenGateway.sol | 142 + .../core/contracts/interfaces/IApp.sol | 98 + .../core/contracts/interfaces/IConsensus.sol | 86 + .../core/contracts/interfaces/IDispatcher.sol | 228 + .../core/contracts/interfaces/IHandler.sol | 97 + .../core/contracts/interfaces/IHost.sol | 209 + .../core/contracts/libraries/Message.sol | 335 + .../core/contracts/libraries/StateMachine.sol | 75 + .../packages/core/foundry.toml | 11 + .../packages/core/package.json | 43 + .../packages/core/pnpm-lock.yaml | 72 + .../packages/core/remappings.txt | 2 + .../packages/filler/.dockerignore | 66 + .../packages/filler/.eslintrc.js | 3 + .../packages/filler/CHANGELOG.md | 16 + .../hyperbridge-sdk/packages/filler/README.md | 196 + .../filler/filler-config-example.toml | 119 + .../packages/filler/package.json | 102 + .../packages/filler/pnpm-lock.yaml | 3750 +++++ .../packages/filler/scripts/Dockerfile | 57 + .../packages/filler/scripts/README.md | 43 + .../filler/scripts/docker-compose.yml | 31 + .../packages/filler/scripts/docker.sh | 136 + .../packages/filler/src/bin/filler.ts | 245 + .../packages/filler/src/config/abis/ERC20.ts | 222 + .../filler/src/config/abis/EvmHost.ts | 2272 +++ .../filler/src/config/abis/HandlerV1.ts | 748 + .../filler/src/config/abis/IntentGateway.ts | 1440 ++ .../filler/src/config/abis/UniswapRouterV2.ts | 953 ++ .../filler/src/config/confirmation-policy.ts | 58 + .../packages/filler/src/core/event-monitor.ts | 191 + .../packages/filler/src/core/filler.ts | 170 + .../packages/filler/src/index.ts | 14 + .../filler/src/services/CacheService.ts | 226 + .../filler/src/services/ChainClientManager.ts | 93 + .../services/ContractInteractionService.ts | 936 ++ .../src/services/FillerConfigService.ts | 166 + .../packages/filler/src/services/Logger.ts | 49 + .../packages/filler/src/services/index.ts | 4 + .../packages/filler/src/strategies/base.ts | 10 + .../packages/filler/src/strategies/basic.ts | 255 + .../packages/filler/src/tests/filler.test.ts | 1156 ++ .../filler/src/tests/sdk-imports.test.ts | 5 + .../packages/filler/src/tests/setup.ts | 5 + .../filler/src/tests/test-config.toml | 167 + .../packages/filler/src/utils.ts | 27 + .../packages/filler/tsconfig.json | 20 + .../packages/filler/tsup.config.ts | 33 + .../packages/filler/vitest.config.ts | 9 + .../packages/indexer/.eslintrc.js | 9 + .../packages/indexer/README.md | 26 + .../indexer/docker/docker-compose.local.yml | 198 + .../docker/docker-compose.nexus-ci.yml | 89 + .../packages/indexer/jest.config.ts | 19 + .../packages/indexer/package.json | 102 + .../packages/indexer/pnpm-lock.yaml | 13920 +++++++++++++++ .../packages/indexer/scripts/down.sh | 78 + .../indexer/scripts/generate-chain-yamls.ts | 318 + .../indexer/scripts/generate-compose.ts | 63 + .../indexer/scripts/generate-l2-chains.ts | 49 + .../templates/docker-compose-service.yaml.hbs | 2 + .../scripts/templates/evm-chain.yaml.hbs | 116 + .../scripts/templates/multichain.yaml.hbs | 8 + .../templates/partials/docker-command.hbs | 17 + .../templates/partials/docker-service.hbs | 19 + .../scripts/templates/partials/handlers.hbs | 14 + .../scripts/templates/partials/metadata.hbs | 14 + .../templates/partials/network-config.hbs | 6 + .../templates/substrate-chain.yaml.hbs | 52 + .../packages/indexer/scripts/up.sh | 30 + .../chainlink-price-feeds.addresses.ts | 19 + .../src/addresses/token-registry.addresses.ts | 108 + .../src/addresses/uniswap.addresses.ts | 115 + .../abis/ChainLinkAggregatorV3.abi.json | 49 + .../src/configs/abis/ERC6160Ext20.abi.json | 255 + .../src/configs/abis/EthereumHost.abi.json | 1746 ++ .../src/configs/abis/HandlerV1.abi.json | 748 + .../src/configs/abis/IntentGateway.abi.json | 1250 ++ .../src/configs/abis/TokenGateway.abi.json | 415 + .../src/configs/abis/UniswapV2.abi.json | 79 + .../configs/abis/UniswapV3Factory.abi.json | 198 + .../src/configs/abis/UniswapV3Pool.abi.json | 983 ++ .../configs/abis/UniswapV3QuoterV2.abi.json | 202 + .../src/configs/abis/UniswapV4Quoter.abi.json | 294 + .../indexer/src/configs/config-local.json | 40 + .../indexer/src/configs/config-mainnet.json | 153 + .../indexer/src/configs/config-nexus-ci.json | 21 + .../indexer/src/configs/config-testnet.json | 113 + .../packages/indexer/src/configs/index.ts | 114 + .../indexer/src/configs/opstack-chains.json | 1331 ++ .../indexer/src/configs/schema.graphql | 1478 ++ .../packages/indexer/src/constants.ts | 96 + .../graphql/incentives.graphql.test.ts | 83 + .../graphql/treasury.graphql.test.ts | 67 + .../erc6160ext20/transfer.event.handlers.ts | 60 + .../evmHost/getRequest.event.handler.ts | 139 + .../getRequestHandled.event.handler.ts | 111 + .../getRequestTimeoutHandled.event.handler.ts | 109 + .../evmHost/postRequest.event.handler.ts | 137 + .../postRequestHandled.event.handler.ts | 117 + ...postRequestTimeoutHandled.event.handler.ts | 109 + .../evmHost/postResponse.event.handler.ts | 146 + .../postResponseHandled.event.handler.ts | 110 + ...ostResponseTimeoutHandled.event.handler.ts | 116 + .../stateMachineUpdated.event.handler.ts | 48 + .../fees/accumulatedFees.event.handler.ts | 75 + .../incentives/feeRewarded.event.handler.ts | 40 + .../relayerRewarded.event.handler.ts | 44 + .../escrowRefunded.event.handler.ts | 31 + .../escrowReleased.event.handler.ts | 31 + .../orderFilled.event.handler.ts | 36 + .../orderPlaced.event.handler.ts | 92 + .../handlePriceIndexing.event.handler.ts | 32 + .../handleAssetTeleportedEvent.handler.ts | 60 + .../handleGetRequestHandledEvent.handler.ts | 63 + ...leGetRequestTimeoutHandledEvent.handler.ts | 60 + ...dleIsmpStateMachineUpdatedEvent.handler.ts | 158 + .../handlePostRequestHandledEvent.handler.ts | 75 + ...ePostRequestTimeoutHandledEvent.handler.ts | 59 + .../handlePostResponseHandledEvent.handler.ts | 77 + ...PostResponseTimeoutHandledEvent.handler.ts | 45 + .../handleRequestEvent.handler.ts | 141 + .../handleResponseEvent.handler.ts | 76 + ...BridgeTokenSupplyIndexing.event.handler.ts | 32 + .../assetReceived.event.handler.ts | 34 + .../assetRefunded.event.handler.ts | 32 + .../assetTeleported.event.handler.ts | 54 + .../treasuryTransfer.event.handler.ts | 53 + ...lePostRequestTransactionHandler.handler.ts | 45 + ...ePostResponseTransactionHandler.handler.ts | 48 + .../packages/indexer/src/index.ts | 15 + .../indexer/src/mappings/mappingHandlers.ts | 52 + .../bridgeTokenSupply.service.test.ts | 108 + .../services/__tests__/volume.service.test.ts | 309 + .../src/services/assetTeleported.service.ts | 49 + .../src/services/bridgeTokenSupply.service.ts | 548 + .../services/dailyTreasuryReward.service.ts | 243 + .../src/services/getRequest.service.ts | 208 + .../src/services/getResponse.service.ts | 99 + .../src/services/hyperbridge.service.ts | 218 + .../services/hyperbridgeChainStats.service.ts | 86 + .../src/services/intentGateway.service.ts | 422 + .../indexer/src/services/points.service.ts | 128 + .../indexer/src/services/relayer.service.ts | 172 + .../src/services/relayerChainStats.service.ts | 41 + .../indexer/src/services/request.service.ts | 227 + .../indexer/src/services/response.service.ts | 222 + .../src/services/stateMachine.service.ts | 165 + .../src/services/token-price.service.ts | 209 + .../src/services/token-registry.service.ts | 137 + .../src/services/tokenGateway.service.ts | 180 + .../indexer/src/services/transfer.service.ts | 69 + .../src/services/userActivity.services.ts | 28 + .../indexer/src/services/volume.service.ts | 101 + .../src/substrate-chaintypes/hyperbridge.ts | 12 + .../transfer.event.handler.test.ts | 24 + .../src/test/units/state-commitment.test.ts | 65 + .../test/utils/helpers/date.helpers.test.ts | 45 + .../test/utils/helpers/rpc.helpers.test.ts | 75 + .../packages/indexer/src/types/errors.ts | 11 + .../packages/indexer/src/types/global.d.ts | 15 + .../packages/indexer/src/types/ismp.ts | 166 + .../indexer/src/types/network.types.ts | 2 + .../src/utils/__tests__/data.helper.test.ts | 30 + .../src/utils/__tests__/date.helpers.test.ts | 32 + .../src/utils/__tests__/price.helpers.test.ts | 54 + .../packages/indexer/src/utils/data.helper.ts | 28 + .../indexer/src/utils/date.helpers.ts | 72 + .../indexer/src/utils/enum.helpers.ts | 24 + .../packages/indexer/src/utils/event.utils.ts | 46 + .../indexer/src/utils/price.helpers.ts | 402 + .../packages/indexer/src/utils/retry.utils.ts | 22 + .../packages/indexer/src/utils/rpc.helpers.ts | 109 + .../indexer/src/utils/state-machine.helper.ts | 247 + .../indexer/src/utils/substrate.helpers.ts | 209 + .../indexer/src/utils/transfer.helpers.ts | 58 + .../packages/indexer/tsconfig.json | 25 + .../hyperbridge-sdk/packages/sdk/.eslintrc.js | 9 + .../hyperbridge-sdk/packages/sdk/.gitignore | 3 + .../hyperbridge-sdk/packages/sdk/CHANGELOG.md | 91 + .../hyperbridge-sdk/packages/sdk/README.md | 184 + .../hyperbridge-sdk/packages/sdk/biome.json | 29 + .../hyperbridge-sdk/packages/sdk/package.json | 136 + .../packages/sdk/plugins/monorepo-helper.js | 83 + .../packages/sdk/plugins/vite.d.ts | 13 + .../packages/sdk/plugins/vite.js | 134 + .../packages/sdk/pnpm-lock.yaml | 3380 ++++ .../packages/sdk/src/abis/IntentGateway.ts | 1442 ++ .../packages/sdk/src/abis/erc6160.ts | 238 + .../packages/sdk/src/abis/evmHost.ts | 2274 +++ .../packages/sdk/src/abis/handler.ts | 750 + .../packages/sdk/src/abis/permit2.ts | 29 + .../packages/sdk/src/abis/pingModule.ts | 765 + .../packages/sdk/src/abis/tokenGateway.ts | 471 + .../packages/sdk/src/abis/uniswapRouterV2.ts | 955 ++ .../packages/sdk/src/abis/uniswapV2Factory.ts | 256 + .../packages/sdk/src/abis/uniswapV3Quoter.ts | 204 + .../packages/sdk/src/abis/uniswapV4Quoter.ts | 294 + .../packages/sdk/src/abis/universalRouter.ts | 445 + .../packages/sdk/src/abis/weth.ts | 18 + .../hyperbridge-sdk/packages/sdk/src/chain.ts | 218 + .../packages/sdk/src/chains/evm.ts | 795 + .../packages/sdk/src/chains/substrate.ts | 692 + .../packages/sdk/src/client.ts | 1946 +++ .../sdk/src/configs/ChainConfigService.ts | 111 + .../packages/sdk/src/configs/chain.ts | 309 + .../packages/sdk/src/helpers/data.helpers.ts | 3 + .../hyperbridge-sdk/packages/sdk/src/index.ts | 34 + .../packages/sdk/src/protocols/intents.ts | 780 + .../packages/sdk/src/queries.ts | 279 + .../packages/sdk/src/query-client.ts | 417 + .../sdk/src/storage/drivers/browser.ts | 23 + .../packages/sdk/src/storage/drivers/node.ts | 7 + .../packages/sdk/src/storage/index.ts | 114 + .../packages/sdk/src/storage/load-driver.ts | 3 + .../packages/sdk/src/storage/types.ts | 10 + .../tests/sequential/evm-substrate.test.ts | 357 + .../src/tests/sequential/hyperbridge.test.ts | 680 + .../tests/sequential/intentGateway.test.ts | 2329 +++ .../sdk/src/tests/sequential/requests.test.ts | 607 + .../src/tests/sequential/tokenPrices.test.ts | 96 + .../packages/sdk/src/tests/setup.ts | 7 + .../packages/sdk/src/tests/stateCalls.test.ts | 131 + .../sdk/src/tests/tokenGateway.test.ts | 414 + .../packages/sdk/src/types/index.ts | 1198 ++ .../hyperbridge-sdk/packages/sdk/src/utils.ts | 842 + .../sdk/src/utils/ckb-mmr-wasm/.gitignore | 1 + .../sdk/src/utils/ckb-mmr-wasm/Cargo.lock | 229 + .../sdk/src/utils/ckb-mmr-wasm/Cargo.toml | 21 + .../sdk/src/utils/ckb-mmr-wasm/README.md | 3 + .../sdk/src/utils/ckb-mmr-wasm/build.sh | 16 + .../utils/ckb-mmr-wasm/dist/node/node.d.ts | 8 + .../src/utils/ckb-mmr-wasm/dist/node/node.js | 255 + .../utils/ckb-mmr-wasm/dist/node/node_bg.wasm | Bin 0 -> 77679 bytes .../ckb-mmr-wasm/dist/node/node_bg.wasm.d.ts | 13 + .../src/utils/ckb-mmr-wasm/dist/web/web.d.ts | 45 + .../src/utils/ckb-mmr-wasm/dist/web/web.js | 316 + .../utils/ckb-mmr-wasm/dist/web/web_bg.wasm | Bin 0 -> 77594 bytes .../ckb-mmr-wasm/dist/web/web_bg.wasm.d.ts | 13 + .../utils/ckb-mmr-wasm/overwrites/node-esm.js | 255 + .../sdk/src/utils/ckb-mmr-wasm/src/lib.rs | 184 + .../sdk/src/utils/ckb-mmr-wasm/src/main.rs | 26 + .../packages/sdk/src/utils/exceptions.ts | 25 + .../packages/sdk/src/utils/mmr.ts | 249 + .../packages/sdk/src/utils/substrate.ts | 435 + .../packages/sdk/src/utils/swap.ts | 1756 ++ .../packages/sdk/src/utils/tokenGateway.ts | 261 + .../packages/sdk/src/utils/txEvents.ts | 52 + .../packages/sdk/src/utils/xcmGateway.ts | 282 + .../packages/sdk/tsconfig.json | 22 + .../packages/sdk/tsup-browser.config.ts | 47 + .../packages/sdk/tsup-node.config.ts | 47 + .../packages/sdk/vitest.config.ts | 18 + .../lib/hyperbridge-sdk/pnpm-lock.yaml | 4095 +++++ .../lib/hyperbridge-sdk/pnpm-workspace.yaml | 2 + .../lib/hyperbridge-sdk/tsconfig.base.json | 12 + .../script/Counter.s.sol | 19 + .../src/BridgeableToken.sol | 22 + .../hyperbridge-token-bridge/src/Counter.sol | 14 + .../src/TokenBridge.sol | 34 + .../test/Counter.t.sol | 24 + 356 files changed, 113240 insertions(+) create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/.github/workflows/test.yml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/.gitignore create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/README.md create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/foundry.lock create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/foundry.toml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.gitattributes create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/CODEOWNERS create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/dependabot.yml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/workflows/ci.yml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/workflows/sync.yml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.gitignore create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/CONTRIBUTING.md create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/LICENSE-APACHE create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/LICENSE-MIT create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/README.md create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/RELEASE_CHECKLIST.md create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/foundry.toml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/package.json create mode 100755 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/scripts/vm.py create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Base.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Config.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/LibVariable.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Script.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdAssertions.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdChains.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdCheats.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdConfig.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdConstants.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdError.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdInvariant.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdJson.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdMath.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdStorage.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdStyle.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdToml.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdUtils.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Test.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Vm.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/console.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/console2.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC1155.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC165.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC20.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC4626.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC6909.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC721.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC7540.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC7575.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IMulticall3.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/safeconsole.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/CommonBase.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/Config.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/LibVariable.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdAssertions.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdChains.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdCheats.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdConstants.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdError.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdJson.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdMath.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdStorage.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdStyle.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdToml.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdUtils.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/Vm.t.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationScript.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationScriptBase.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationTest.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationTestBase.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/broadcast.log.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/config.toml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/test.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/test.toml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.changeset/README.md create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.changeset/config.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.dockerignore create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.eslintrc.js create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/filler-docker.yml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/publish-core.yml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/publish-sdk.yml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/test-core.yml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/test-nexus-ci.yml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/test-sdk.yml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.gitignore create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.npmrc create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/LICENSE create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/README.md create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/package.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/.gitignore create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/.prettierrc create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/LICENSE create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/README.md create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/HyperApp.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/HyperFungibleToken.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/IntentGateway.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/TokenGateway.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IApp.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IConsensus.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IDispatcher.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IHandler.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IHost.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/libraries/Message.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/libraries/StateMachine.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/foundry.toml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/package.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/pnpm-lock.yaml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/remappings.txt create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/.dockerignore create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/.eslintrc.js create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/CHANGELOG.md create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/README.md create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/filler-config-example.toml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/package.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/pnpm-lock.yaml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/Dockerfile create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/README.md create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/docker-compose.yml create mode 100755 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/docker.sh create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/bin/filler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/ERC20.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/EvmHost.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/HandlerV1.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/IntentGateway.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/UniswapRouterV2.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/confirmation-policy.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/core/event-monitor.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/core/filler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/index.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/CacheService.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/ChainClientManager.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/ContractInteractionService.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/FillerConfigService.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/Logger.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/index.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/strategies/base.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/strategies/basic.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/filler.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/sdk-imports.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/setup.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/test-config.toml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/utils.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/tsconfig.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/tsup.config.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/vitest.config.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/.eslintrc.js create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/README.md create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/docker/docker-compose.local.yml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/docker/docker-compose.nexus-ci.yml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/jest.config.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/package.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/pnpm-lock.yaml create mode 100755 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/down.sh create mode 100755 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/generate-chain-yamls.ts create mode 100755 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/generate-compose.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/generate-l2-chains.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/docker-compose-service.yaml.hbs create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/evm-chain.yaml.hbs create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/multichain.yaml.hbs create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/docker-command.hbs create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/docker-service.hbs create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/handlers.hbs create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/metadata.hbs create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/network-config.hbs create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/substrate-chain.yaml.hbs create mode 100755 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/up.sh create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/addresses/chainlink-price-feeds.addresses.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/addresses/token-registry.addresses.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/addresses/uniswap.addresses.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/ChainLinkAggregatorV3.abi.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/ERC6160Ext20.abi.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/EthereumHost.abi.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/HandlerV1.abi.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/IntentGateway.abi.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/TokenGateway.abi.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV2.abi.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV3Factory.abi.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV3Pool.abi.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV3QuoterV2.abi.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV4Quoter.abi.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-local.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-mainnet.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-nexus-ci.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-testnet.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/index.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/opstack-chains.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/schema.graphql create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/constants.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/__tests__/graphql/incentives.graphql.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/__tests__/graphql/treasury.graphql.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/erc6160ext20/transfer.event.handlers.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/getRequest.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/getRequestHandled.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/getRequestTimeoutHandled.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postRequest.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postRequestHandled.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postRequestTimeoutHandled.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postResponse.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postResponseHandled.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postResponseTimeoutHandled.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/stateMachineUpdated.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/fees/accumulatedFees.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/incentives/feeRewarded.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/incentives/relayerRewarded.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/escrowRefunded.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/escrowReleased.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/orderFilled.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/orderPlaced.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/price/handlePriceIndexing.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleAssetTeleportedEvent.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleGetRequestHandledEvent.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleGetRequestTimeoutHandledEvent.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleIsmpStateMachineUpdatedEvent.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostRequestHandledEvent.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostRequestTimeoutHandledEvent.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostResponseHandledEvent.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostResponseTimeoutHandledEvent.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleRequestEvent.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleResponseEvent.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/supply/handleBridgeTokenSupplyIndexing.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/tokenGateway/assetReceived.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/tokenGateway/assetRefunded.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/tokenGateway/assetTeleported.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/treasury/treasuryTransfer.event.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/transactions/handlerV1/handlePostRequestTransactionHandler.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/transactions/handlerV1/handlePostResponseTransactionHandler.handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/index.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/mappings/mappingHandlers.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/__tests__/bridgeTokenSupply.service.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/__tests__/volume.service.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/assetTeleported.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/bridgeTokenSupply.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/dailyTreasuryReward.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/getRequest.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/getResponse.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/hyperbridge.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/hyperbridgeChainStats.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/intentGateway.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/points.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/relayer.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/relayerChainStats.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/request.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/response.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/stateMachine.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/token-price.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/token-registry.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/tokenGateway.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/transfer.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/userActivity.services.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/volume.service.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/substrate-chaintypes/hyperbridge.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/events/erc6160ext20/transfer.event.handler.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/units/state-commitment.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/utils/helpers/date.helpers.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/utils/helpers/rpc.helpers.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/errors.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/global.d.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/ismp.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/network.types.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/__tests__/data.helper.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/__tests__/date.helpers.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/__tests__/price.helpers.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/data.helper.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/date.helpers.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/enum.helpers.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/event.utils.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/price.helpers.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/retry.utils.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/rpc.helpers.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/state-machine.helper.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/substrate.helpers.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/transfer.helpers.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/tsconfig.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/.eslintrc.js create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/.gitignore create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/CHANGELOG.md create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/README.md create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/biome.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/package.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/plugins/monorepo-helper.js create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/plugins/vite.d.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/plugins/vite.js create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/pnpm-lock.yaml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/IntentGateway.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/erc6160.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/evmHost.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/handler.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/permit2.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/pingModule.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/tokenGateway.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapRouterV2.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapV2Factory.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapV3Quoter.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapV4Quoter.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/universalRouter.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/weth.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/chain.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/chains/evm.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/chains/substrate.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/client.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/configs/ChainConfigService.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/configs/chain.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/helpers/data.helpers.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/index.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/protocols/intents.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/queries.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/query-client.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/drivers/browser.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/drivers/node.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/index.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/load-driver.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/types.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/evm-substrate.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/hyperbridge.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/intentGateway.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/requests.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/tokenPrices.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/setup.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/stateCalls.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/tokenGateway.test.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/types/index.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/.gitignore create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/Cargo.lock create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/Cargo.toml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/README.md create mode 100755 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/build.sh create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/node/node.d.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/node/node.js create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/node/node_bg.wasm create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/node/node_bg.wasm.d.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/web/web.d.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/web/web.js create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/web/web_bg.wasm create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/web/web_bg.wasm.d.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/overwrites/node-esm.js create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/src/lib.rs create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/src/main.rs create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/exceptions.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/mmr.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/substrate.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/swap.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/tokenGateway.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/txEvents.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/xcmGateway.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/tsconfig.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/tsup-browser.config.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/tsup-node.config.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/vitest.config.ts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/pnpm-lock.yaml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/pnpm-workspace.yaml create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/tsconfig.base.json create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/script/Counter.s.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/src/BridgeableToken.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/src/Counter.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/src/TokenBridge.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/test/Counter.t.sol diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/.github/workflows/test.yml b/1-xcm-hyperbridge/hyperbridge-token-bridge/.github/workflows/test.yml new file mode 100644 index 00000000..4481ec6a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/.github/workflows/test.yml @@ -0,0 +1,40 @@ +name: CI + +on: + push: + pull_request: + workflow_dispatch: + +env: + FOUNDRY_PROFILE: ci + +jobs: + check: + name: Foundry project + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: recursive + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + + - name: Show Forge version + run: | + forge --version + + - name: Run Forge fmt + run: | + forge fmt --check + id: fmt + + - name: Run Forge build + run: | + forge build --sizes + id: build + + - name: Run Forge tests + run: | + forge test -vvv + id: test diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/.gitignore b/1-xcm-hyperbridge/hyperbridge-token-bridge/.gitignore new file mode 100644 index 00000000..85198aaa --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/.gitignore @@ -0,0 +1,14 @@ +# Compiler files +cache/ +out/ + +# Ignores development broadcast logs +!/broadcast +/broadcast/*/31337/ +/broadcast/**/dry-run/ + +# Docs +docs/ + +# Dotenv file +.env diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/README.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/README.md new file mode 100644 index 00000000..8817d6ab --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/README.md @@ -0,0 +1,66 @@ +## Foundry + +**Foundry is a blazing fast, portable and modular toolkit for Ethereum application development written in Rust.** + +Foundry consists of: + +- **Forge**: Ethereum testing framework (like Truffle, Hardhat and DappTools). +- **Cast**: Swiss army knife for interacting with EVM smart contracts, sending transactions and getting chain data. +- **Anvil**: Local Ethereum node, akin to Ganache, Hardhat Network. +- **Chisel**: Fast, utilitarian, and verbose solidity REPL. + +## Documentation + +https://book.getfoundry.sh/ + +## Usage + +### Build + +```shell +$ forge build +``` + +### Test + +```shell +$ forge test +``` + +### Format + +```shell +$ forge fmt +``` + +### Gas Snapshots + +```shell +$ forge snapshot +``` + +### Anvil + +```shell +$ anvil +``` + +### Deploy + +```shell +$ forge script script/Counter.s.sol:CounterScript --rpc-url --private-key +``` + +### Cast + +```shell +$ cast +``` + +### Help + +```shell +$ forge --help +$ anvil --help +$ cast --help +``` diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/foundry.lock b/1-xcm-hyperbridge/hyperbridge-token-bridge/foundry.lock new file mode 100644 index 00000000..3fb0b96f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/foundry.lock @@ -0,0 +1,8 @@ +{ + "lib/forge-std": { + "tag": { + "name": "v1.12.0", + "rev": "7117c90c8cf6c68e5acce4f09a6b24715cea4de6" + } + } +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/foundry.toml b/1-xcm-hyperbridge/hyperbridge-token-bridge/foundry.toml new file mode 100644 index 00000000..ee1b5571 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/foundry.toml @@ -0,0 +1,13 @@ +[profile.default] +src = "src" +out = "out" +libs = ["lib"] + +remappings = [ + "openzeppelin/=lib/openzeppelin-contracts/", + "ds-test/=lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "@hyperbridge/core/=lib/hyperbridge-sdk/packages/core/", +] + +# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.gitattributes b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.gitattributes new file mode 100644 index 00000000..27042d45 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.gitattributes @@ -0,0 +1 @@ +src/Vm.sol linguist-generated diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/CODEOWNERS b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/CODEOWNERS new file mode 100644 index 00000000..beae7aa8 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/CODEOWNERS @@ -0,0 +1 @@ +* @danipopes @klkvr @mattsse @grandizzy @yash-atreya @zerosnacks @onbjerg @0xrusowsky \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/dependabot.yml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/dependabot.yml new file mode 100644 index 00000000..5ace4600 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/workflows/ci.yml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/workflows/ci.yml new file mode 100644 index 00000000..0c4fe4f8 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/workflows/ci.yml @@ -0,0 +1,137 @@ +name: CI + +permissions: {} + +on: + workflow_dispatch: + pull_request: + push: + branches: + - master + +jobs: + build: + name: build +${{ matrix.toolchain }} ${{ matrix.flags }} + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + strategy: + fail-fast: false + matrix: + toolchain: [stable, nightly] + flags: + - "" + - --via-ir + - --use solc:0.8.17 --via-ir + - --use solc:0.8.17 + - --use solc:0.8.0 + - --use solc:0.7.6 + - --use solc:0.7.0 + - --use solc:0.6.2 + - --use solc:0.6.12 + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: foundry-rs/foundry-toolchain@v1 + - run: forge --version + - run: | + case "${{ matrix.flags }}" in + *"solc:0.8.0"* | *"solc:0.7"* | *"solc:0.6"*) + forge build --skip test --skip Config --skip StdConfig --skip LibVariable --deny-warnings ${{ matrix.flags }} + ;; + *) + forge build --skip test --deny-warnings ${{ matrix.flags }} + ;; + esac + # via-ir compilation time checks. + - if: contains(matrix.flags, '--via-ir') + run: forge build --skip test --deny-warnings ${{ matrix.flags }} --contracts 'test/compilation/*' + + test: + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + strategy: + fail-fast: false + matrix: + toolchain: [stable, nightly] + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: foundry-rs/foundry-toolchain@v1 + with: + version: ${{ matrix.toolchain }} + - run: forge --version + - run: forge test -vvv + + fmt: + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: foundry-rs/foundry-toolchain@v1 + - run: forge --version + - run: forge fmt --check + + typos: + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + steps: + - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: crate-ci/typos@626c4bedb751ce0b7f03262ca97ddda9a076ae1c # v1 + + codeql: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-latest + permissions: + security-events: write + actions: read + contents: read + strategy: + fail-fast: false + matrix: + include: + - language: actions + build-mode: none + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + persist-credentials: false + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 + with: + category: "/language:${{matrix.language}}" + + ci-success: + runs-on: ubuntu-latest + if: always() + needs: + - build + - test + - fmt + - typos + - codeql + timeout-minutes: 10 + steps: + - name: Decide whether the needed jobs succeeded or failed + uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # release/v1 + with: + jobs: ${{ toJSON(needs) }} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/workflows/sync.yml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/workflows/sync.yml new file mode 100644 index 00000000..ad4b173c --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.github/workflows/sync.yml @@ -0,0 +1,36 @@ +name: Sync Release Branch + +permissions: {} + +on: + release: + types: + - created + +jobs: + sync-release-branch: + runs-on: ubuntu-latest + permissions: + contents: write + if: startsWith(github.event.release.tag_name, 'v1') + steps: + - name: Check out the repo + uses: actions/checkout@v6 + with: + persist-credentials: true + fetch-depth: 0 + ref: v1 + + # The email is derived from the bots user id, + # found here: https://api.github.com/users/github-actions%5Bbot%5D + - name: Configure Git + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + + - name: Sync Release Branch + run: | + git fetch --tags + git checkout v1 + git reset --hard ${GITHUB_REF} + git push --force diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.gitignore b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.gitignore new file mode 100644 index 00000000..756106d3 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/.gitignore @@ -0,0 +1,4 @@ +cache/ +out/ +.vscode +.idea diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/CONTRIBUTING.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/CONTRIBUTING.md new file mode 100644 index 00000000..89b75f3f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/CONTRIBUTING.md @@ -0,0 +1,193 @@ +## Contributing to Foundry + +Thanks for your interest in improving Foundry! + +There are multiple opportunities to contribute at any level. It doesn't matter if you are just getting started with Rust or are the most weathered expert, we can use your help. + +This document will help you get started. **Do not let the document intimidate you**. +It should be considered as a guide to help you navigate the process. + +The [dev Telegram][dev-tg] is available for any concerns you may have that are not covered in this guide. + +### Code of Conduct + +The Foundry project adheres to the [Rust Code of Conduct][rust-coc]. This code of conduct describes the _minimum_ behavior expected from all contributors. + +Instances of violations of the Code of Conduct can be reported by contacting the team at [me@gakonst.com](mailto:me@gakonst.com). + +### Ways to contribute + +There are fundamentally four ways an individual can contribute: + +1. **By opening an issue:** For example, if you believe that you have uncovered a bug + in Foundry, creating a new issue in the issue tracker is the way to report it. +2. **By adding context:** Providing additional context to existing issues, + such as screenshots and code snippets, which help resolve issues. +3. **By resolving issues:** Typically this is done in the form of either + demonstrating that the issue reported is not a problem after all, or more often, + by opening a pull request that fixes the underlying problem, in a concrete and + reviewable manner. + +**Anybody can participate in any stage of contribution**. We urge you to participate in the discussion +around bugs and participate in reviewing PRs. + +### Contributions Related to Spelling and Grammar + +At this time, we will not be accepting contributions that only fix spelling or grammatical errors in documentation, code or +elsewhere. + +### Asking for help + +If you have reviewed existing documentation and still have questions, or you are having problems, you can get help in the following ways: + +- **Asking in the support Telegram:** The [Foundry Support Telegram][support-tg] is a fast and easy way to ask questions. +- **Opening a discussion:** This repository comes with a discussions board where you can also ask for help. Click the "Discussions" tab at the top. + +As Foundry is still in heavy development, the documentation can be a bit scattered. +The [Foundry Book][foundry-book] is our current best-effort attempt at keeping up-to-date information. + +### Submitting a bug report + +When filing a new bug report in the issue tracker, you will be presented with a basic form to fill out. + +If you believe that you have uncovered a bug, please fill out the form to the best of your ability. Do not worry if you cannot answer every detail; just fill in what you can. Contributors will ask follow-up questions if something is unclear. + +The most important pieces of information we need in a bug report are: + +- The Foundry version you are on (and that it is up to date) +- The platform you are on (Windows, macOS, an M1 Mac or Linux) +- Code snippets if this is happening in relation to testing or building code +- Concrete steps to reproduce the bug + +In order to rule out the possibility of the bug being in your project, the code snippets should be as minimal +as possible. It is better if you can reproduce the bug with a small snippet as opposed to an entire project! + +See [this guide][mcve] on how to create a minimal, complete, and verifiable example. + +### Submitting a feature request + +When adding a feature request in the issue tracker, you will be presented with a basic form to fill out. + +Please include as detailed of an explanation as possible of the feature you would like, adding additional context if necessary. + +If you have examples of other tools that have the feature you are requesting, please include them as well. + +### Resolving an issue + +Pull requests are the way concrete changes are made to the code, documentation, and dependencies of Foundry. + +Even minor pull requests, such as those fixing wording, are greatly appreciated. Before making a large change, it is usually +a good idea to first open an issue describing the change to solicit feedback and guidance. This will increase +the likelihood of the PR getting merged. + +Please make sure that the following commands pass if you have changed the code: + +```sh +forge fmt --check +forge test -vvv +``` + +To make sure your changes are compatible with all compiler version targets, run the following commands: + +```sh +forge build --skip test --use solc:0.6.2 +forge build --skip test --use solc:0.6.12 +forge build --skip test --use solc:0.7.0 +forge build --skip test --use solc:0.7.6 +forge build --skip test --use solc:0.8.0 +``` + +The CI will also ensure that the code is formatted correctly and that the tests are passing across all compiler version targets. + +#### Adding cheatcodes + +Please follow the guide outlined in the [cheatcodes](https://github.com/foundry-rs/foundry/blob/master/docs/dev/cheatcodes.md#adding-a-new-cheatcode) documentation of Foundry. + +When making modifications to the native cheatcodes or adding new ones, please make sure to run [`./scripts/vm.py`](./scripts/vm.py) to update the cheatcodes in the [`src/Vm.sol`](./src/Vm.sol) file. + +By default the script will automatically generate the cheatcodes from the [`cheatcodes.json`](https://raw.githubusercontent.com/foundry-rs/foundry/master/crates/cheatcodes/assets/cheatcodes.json) file but alternatively you can provide a path to a JSON file containing the Vm interface, as generated by Foundry, with the `--from` flag. + +```sh +./scripts/vm.py --from path/to/cheatcodes.json +``` + +It is possible that the resulting [`src/Vm.sol`](./src/Vm.sol) file will have some changes that are not directly related to your changes, this is not a problem. + +#### Commits + +It is a recommended best practice to keep your changes as logically grouped as possible within individual commits. There is no limit to the number of commits any single pull request may have, and many contributors find it easier to review changes that are split across multiple commits. + +That said, if you have a number of commits that are "checkpoints" and don't represent a single logical change, please squash those together. + +#### Opening the pull request + +From within GitHub, opening a new pull request will present you with a template that should be filled out. Please try your best at filling out the details, but feel free to skip parts if you're not sure what to put. + +#### Discuss and update + +You will probably get feedback or requests for changes to your pull request. +This is a big part of the submission process, so don't be discouraged! Some contributors may sign off on the pull request right away, others may have more detailed comments or feedback. +This is a necessary part of the process in order to evaluate whether the changes are correct and necessary. + +**Any community member can review a PR, so you might get conflicting feedback**. +Keep an eye out for comments from code owners to provide guidance on conflicting feedback. + +#### Reviewing pull requests + +**Any Foundry community member is welcome to review any pull request**. + +All contributors who choose to review and provide feedback on pull requests have a responsibility to both the project and individual making the contribution. Reviews and feedback must be helpful, insightful, and geared towards improving the contribution as opposed to simply blocking it. If there are reasons why you feel the PR should not be merged, explain what those are. Do not expect to be able to block a PR from advancing simply because you say "no" without giving an explanation. Be open to having your mind changed. Be open to working _with_ the contributor to make the pull request better. + +Reviews that are dismissive or disrespectful of the contributor or any other reviewers are strictly counter to the Code of Conduct. + +When reviewing a pull request, the primary goals are for the codebase to improve and for the person submitting the request to succeed. **Even if a pull request is not merged, the submitter should come away from the experience feeling like their effort was not unappreciated**. Every PR from a new contributor is an opportunity to grow the community. + +##### Review a bit at a time + +Do not overwhelm new contributors. + +It is tempting to micro-optimize and make everything about relative performance, perfect grammar, or exact style matches. Do not succumb to that temptation.. + +Focus first on the most significant aspects of the change: + +1. Does this change make sense for Foundry? +2. Does this change make Foundry better, even if only incrementally? +3. Are there clear bugs or larger scale issues that need attending? +4. Are the commit messages readable and correct? If it contains a breaking change, is it clear enough? + +Note that only **incremental** improvement is needed to land a PR. This means that the PR does not need to be perfect, only better than the status quo. Follow-up PRs may be opened to continue iterating. + +When changes are necessary, _request_ them, do not _demand_ them, and **do not assume that the submitter already knows how to add a test or run a benchmark**. + +Specific performance optimization techniques, coding styles and conventions change over time. The first impression you give to a new contributor never does. + +Nits (requests for small changes that are not essential) are fine, but try to avoid stalling the pull request. Most nits can typically be fixed by the Foundry maintainers merging the pull request, but they can also be an opportunity for the contributor to learn a bit more about the project. + +It is always good to clearly indicate nits when you comment, e.g.: `Nit: change foo() to bar(). But this is not blocking`. + +If your comments were addressed but were not folded after new commits, or if they proved to be mistaken, please, [hide them][hiding-a-comment] with the appropriate reason to keep the conversation flow concise and relevant. + +##### Be aware of the person behind the code + +Be aware that _how_ you communicate requests and reviews in your feedback can have a significant impact on the success of the pull request. Yes, we may merge a particular change that makes Foundry better, but the individual might just not want to have anything to do with Foundry ever again. The goal is not just having good code. + +##### Abandoned or stale pull requests + +If a pull request appears to be abandoned or stalled, it is polite to first check with the contributor to see if they intend to continue the work before checking if they would mind if you took it over (especially if it just has nits left). When doing so, it is courteous to give the original contributor credit for the work they started, either by preserving their name and e-mail address in the commit log, or by using the `Author: ` or `Co-authored-by: ` metadata tag in the commits. + +_Adapted from the [ethers-rs contributing guide](https://github.com/gakonst/ethers-rs/blob/master/CONTRIBUTING.md)_. + +### Releasing + +Releases are automatically done by the release workflow when a tag is pushed, however, these steps still need to be taken: + +1. Ensure that the versions in the relevant `Cargo.toml` files are up-to-date. +2. Update documentation links +3. Perform a final audit for breaking changes. + +[rust-coc]: https://github.com/rust-lang/rust/blob/master/CODE_OF_CONDUCT.md +[dev-tg]: https://t.me/foundry_rs +[foundry-book]: https://github.com/foundry-rs/foundry-book +[support-tg]: https://t.me/foundry_support +[mcve]: https://stackoverflow.com/help/mcve +[hiding-a-comment]: https://help.github.com/articles/managing-disruptive-comments/#hiding-a-comment \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/LICENSE-APACHE b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/LICENSE-APACHE new file mode 100644 index 00000000..cf01a499 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/LICENSE-APACHE @@ -0,0 +1,203 @@ +Copyright Contributors to Forge Standard Library + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/LICENSE-MIT b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/LICENSE-MIT new file mode 100644 index 00000000..28f98304 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright Contributors to Forge Standard Library + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE O THE USE OR OTHER +DEALINGS IN THE SOFTWARE.R diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/README.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/README.md new file mode 100644 index 00000000..51673e5e --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/README.md @@ -0,0 +1,266 @@ +# Forge Standard Library • [![CI status](https://github.com/foundry-rs/forge-std/actions/workflows/ci.yml/badge.svg)](https://github.com/foundry-rs/forge-std/actions/workflows/ci.yml) + +Forge Standard Library is a collection of helpful contracts and libraries for use with [Forge and Foundry](https://github.com/foundry-rs/foundry). It leverages Forge's cheatcodes to make writing tests easier and faster, while improving the UX of cheatcodes. + +**Learn how to use Forge-Std with the [📖 Foundry Book (Forge-Std Guide)](https://getfoundry.sh/reference/forge-std/overview/).** + +## Install + +```bash +forge install foundry-rs/forge-std +``` + +## Contracts +### stdError + +This is a helper contract for errors and reverts. In Forge, this contract is particularly helpful for the `expectRevert` cheatcode, as it provides all compiler built-in errors. + +See the contract itself for all error codes. + +#### Example usage + +```solidity + +import "forge-std/Test.sol"; + +contract TestContract is Test { + ErrorsTest test; + + function setUp() public { + test = new ErrorsTest(); + } + + function testExpectArithmetic() public { + vm.expectRevert(stdError.arithmeticError); + test.arithmeticError(10); + } +} + +contract ErrorsTest { + function arithmeticError(uint256 a) public { + a = a - 100; + } +} +``` + +### stdStorage + +This is a rather large contract due to all of the overloading to make the UX decent. Primarily, it is a wrapper around the `record` and `accesses` cheatcodes. It can *always* find and write the storage slot(s) associated with a particular variable without knowing the storage layout. The one _major_ caveat to this is while a slot can be found for packed storage variables, we can't write to that variable safely. If a user tries to write to a packed slot, the execution throws an error, unless it is uninitialized (`bytes32(0)`). + +This works by recording all `SLOAD`s and `SSTORE`s during a function call. If there is a single slot read or written to, it immediately returns the slot. Otherwise, behind the scenes, we iterate through and check each one (assuming the user passed in a `depth` parameter). If the variable is a struct, you can pass in a `depth` parameter which is basically the field depth. + +I.e.: +```solidity +struct T { + // depth 0 + uint256 a; + // depth 1 + uint256 b; +} +``` + +#### Example usage + +```solidity +import "forge-std/Test.sol"; + +contract TestContract is Test { + using stdStorage for StdStorage; + + Storage test; + + function setUp() public { + test = new Storage(); + } + + function testFindExists() public { + // Lets say we want to find the slot for the public + // variable `exists`. We just pass in the function selector + // to the `find` command + uint256 slot = stdstore.target(address(test)).sig("exists()").find(); + assertEq(slot, 0); + } + + function testWriteExists() public { + // Lets say we want to write to the slot for the public + // variable `exists`. We just pass in the function selector + // to the `checked_write` command + stdstore.target(address(test)).sig("exists()").checked_write(100); + assertEq(test.exists(), 100); + } + + // It supports arbitrary storage layouts, like assembly based storage locations + function testFindHidden() public { + // `hidden` is a random hash of a bytes, iteration through slots would + // not find it. Our mechanism does + // Also, you can use the selector instead of a string + uint256 slot = stdstore.target(address(test)).sig(test.hidden.selector).find(); + assertEq(slot, uint256(keccak256("my.random.var"))); + } + + // If targeting a mapping, you have to pass in the keys necessary to perform the find + // i.e.: + function testFindMapping() public { + uint256 slot = stdstore + .target(address(test)) + .sig(test.map_addr.selector) + .with_key(address(this)) + .find(); + // in the `Storage` constructor, we wrote that this address' value was 1 in the map + // so when we load the slot, we expect it to be 1 + assertEq(uint(vm.load(address(test), bytes32(slot))), 1); + } + + // If the target is a struct, you can specify the field depth: + function testFindStruct() public { + // NOTE: see the depth parameter - 0 means 0th field, 1 means 1st field, etc. + uint256 slot_for_a_field = stdstore + .target(address(test)) + .sig(test.basicStruct.selector) + .depth(0) + .find(); + + uint256 slot_for_b_field = stdstore + .target(address(test)) + .sig(test.basicStruct.selector) + .depth(1) + .find(); + + assertEq(uint(vm.load(address(test), bytes32(slot_for_a_field))), 1); + assertEq(uint(vm.load(address(test), bytes32(slot_for_b_field))), 2); + } +} + +// A complex storage contract +contract Storage { + struct UnpackedStruct { + uint256 a; + uint256 b; + } + + constructor() { + map_addr[msg.sender] = 1; + } + + uint256 public exists = 1; + mapping(address => uint256) public map_addr; + // mapping(address => Packed) public map_packed; + mapping(address => UnpackedStruct) public map_struct; + mapping(address => mapping(address => uint256)) public deep_map; + mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; + UnpackedStruct public basicStruct = UnpackedStruct({ + a: 1, + b: 2 + }); + + function hidden() public view returns (bytes32 t) { + // an extremely hidden storage slot + bytes32 slot = keccak256("my.random.var"); + assembly { + t := sload(slot) + } + } +} +``` + +### stdCheats + +This is a wrapper over miscellaneous cheatcodes that need wrappers to be more dev friendly. Currently there are only functions related to `prank`. In general, users may expect ETH to be put into an address on `prank`, but this is not the case for safety reasons. Explicitly this `hoax` function should only be used for addresses that have expected balances as it will get overwritten. If an address already has ETH, you should just use `prank`. If you want to change that balance explicitly, just use `deal`. If you want to do both, `hoax` is also right for you. + + +#### Example usage: +```solidity + +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import "forge-std/Test.sol"; + +// Inherit the stdCheats +contract StdCheatsTest is Test { + Bar test; + function setUp() public { + test = new Bar(); + } + + function testHoax() public { + // we call `hoax`, which gives the target address + // eth and then calls `prank` + hoax(address(1337)); + test.bar{value: 100}(address(1337)); + + // overloaded to allow you to specify how much eth to + // initialize the address with + hoax(address(1337), 1); + test.bar{value: 1}(address(1337)); + } + + function testStartHoax() public { + // we call `startHoax`, which gives the target address + // eth and then calls `startPrank` + // + // it is also overloaded so that you can specify an eth amount + startHoax(address(1337)); + test.bar{value: 100}(address(1337)); + test.bar{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } +} + +contract Bar { + function bar(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + } +} +``` + +### Std Assertions + +Contains various assertions. + +### `console.log` + +Usage follows the same format as [Hardhat](https://hardhat.org/hardhat-network/reference/#console-log). +It's recommended to use `console2.sol` as shown below, as this will show the decoded logs in Forge traces. + +```solidity +// import it indirectly via Test.sol +import "forge-std/Test.sol"; +// or directly import it +import "forge-std/console2.sol"; +... +console2.log(someValue); +``` + +If you need compatibility with Hardhat, you must use the standard `console.sol` instead. +Due to a bug in `console.sol`, logs that use `uint256` or `int256` types will not be properly decoded in Forge traces. + +```solidity +// import it indirectly via Test.sol +import "forge-std/Test.sol"; +// or directly import it +import "forge-std/console.sol"; +... +console.log(someValue); +``` + +## Contributing + +See our [contributing guidelines](./CONTRIBUTING.md). + +## Getting Help + +First, see if the answer to your question can be found in [book](https://book.getfoundry.sh). + +If the answer is not there: + +- Join the [support Telegram](https://t.me/foundry_support) to get help, or +- Open a [discussion](https://github.com/foundry-rs/foundry/discussions/new/choose) with your question, or +- Open an issue with [the bug](https://github.com/foundry-rs/foundry/issues/new/choose) + +If you want to contribute, or follow along with contributor discussion, you can use our [main telegram](https://t.me/foundry_rs) to chat with us about the development of Foundry! + +## License + +Forge Standard Library is offered under either [MIT](LICENSE-MIT) or [Apache 2.0](LICENSE-APACHE) license. diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/RELEASE_CHECKLIST.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/RELEASE_CHECKLIST.md new file mode 100644 index 00000000..4611de4d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/RELEASE_CHECKLIST.md @@ -0,0 +1,12 @@ +# Release checklist + +This checklist is meant to be used as a guide for the `forge-std` release process. + +## Steps + +- [ ] Update the version number in `package.json` +- [ ] Open and merge a PR with the version bump +- [ ] Tag the merged commit with the version number: `git tag v` +- [ ] Push the tag to the repository: `git push --tags` +- [ ] Create a new GitHub release with the automatically generated changelog and with the name set to `v` +- [ ] Add `## Featured Changes` section to the top of the release notes diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/foundry.toml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/foundry.toml new file mode 100644 index 00000000..376654da --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/foundry.toml @@ -0,0 +1,30 @@ +[profile.default] +fs_permissions = [{ access = "read-write", path = "./" }] +optimizer = true +optimizer_runs = 200 + +# A list of solidity error codes to ignore. +# 3860 = init-code-size +ignored_error_codes = [3860] + +[rpc_endpoints] +# The RPC URLs are modified versions of the default for testing initialization. +mainnet = "https://reth-ethereum.ithaca.xyz/rpc" +optimism_sepolia = "https://sepolia.optimism.io/" # Adds a trailing slash. +arbitrum_one_sepolia = "https://sepolia-rollup.arbitrum.io/rpc/" # Adds a trailing slash. +needs_undefined_env_var = "${UNDEFINED_RPC_URL_PLACEHOLDER}" + +[lint] +lint_on_build = false + +[fmt] +# These are all the `forge fmt` defaults. +line_length = 120 +tab_width = 4 +bracket_spacing = false +int_types = 'long' +multiline_func_header = 'attributes_first' +quote_style = 'double' +number_underscore = 'preserve' +single_line_statement_blocks = 'preserve' +ignore = ["src/console.sol", "src/console2.sol"] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/package.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/package.json new file mode 100644 index 00000000..3bfa8f93 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/package.json @@ -0,0 +1,16 @@ +{ + "name": "forge-std", + "version": "1.12.0", + "description": "Forge Standard Library is a collection of helpful contracts and libraries for use with Forge and Foundry.", + "homepage": "https://book.getfoundry.sh/forge/forge-std", + "bugs": "https://github.com/foundry-rs/forge-std/issues", + "license": "(Apache-2.0 OR MIT)", + "author": "Contributors to Forge Standard Library", + "files": [ + "src/**/*" + ], + "repository": { + "type": "git", + "url": "https://github.com/foundry-rs/forge-std.git" + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/scripts/vm.py b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/scripts/vm.py new file mode 100755 index 00000000..3cd047d3 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/scripts/vm.py @@ -0,0 +1,646 @@ +#!/usr/bin/env python3 + +import argparse +import copy +import json +import re +import subprocess +from enum import Enum as PyEnum +from pathlib import Path +from typing import Callable +from urllib import request + +VoidFn = Callable[[], None] + +CHEATCODES_JSON_URL = "https://raw.githubusercontent.com/foundry-rs/foundry/master/crates/cheatcodes/assets/cheatcodes.json" +OUT_PATH = "src/Vm.sol" + +VM_SAFE_DOC = """\ +/// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may +/// result in Script simulations differing from on-chain execution. It is recommended to only use +/// these cheats in scripts. +""" + +VM_DOC = """\ +/// The `Vm` interface does allow manipulation of the EVM state. These are all intended to be used +/// in tests, but it is not recommended to use these cheats in scripts. +""" + + +def main(): + parser = argparse.ArgumentParser( + description="Generate Vm.sol based on the cheatcodes json created by Foundry") + parser.add_argument( + "--from", + metavar="PATH", + dest="path", + required=False, + help="path to a json file containing the Vm interface, as generated by Foundry") + args = parser.parse_args() + json_str = request.urlopen(CHEATCODES_JSON_URL).read().decode("utf-8") if args.path is None else Path(args.path).read_text() + contract = Cheatcodes.from_json(json_str) + + ccs = contract.cheatcodes + ccs = list(filter(lambda cc: cc.status not in ["experimental", "internal"], ccs)) + ccs.sort(key=lambda cc: cc.func.id) + + safe = list(filter(lambda cc: cc.safety == "safe", ccs)) + safe.sort(key=CmpCheatcode) + unsafe = list(filter(lambda cc: cc.safety == "unsafe", ccs)) + unsafe.sort(key=CmpCheatcode) + assert len(safe) + len(unsafe) == len(ccs) + + prefix_with_group_headers(safe) + prefix_with_group_headers(unsafe) + + out = "" + + out += "// Automatically @generated by scripts/vm.py. Do not modify manually.\n\n" + + pp = CheatcodesPrinter( + spdx_identifier="MIT OR Apache-2.0", + solidity_requirement=">=0.6.2 <0.9.0", + abicoder_pragma=True, + ) + pp.p_prelude() + pp.prelude = False + out += pp.finish() + + out += "\n\n" + out += VM_SAFE_DOC + vm_safe = Cheatcodes( + # TODO: Custom errors were introduced in 0.8.4 + errors=[], # contract.errors + events=contract.events, + enums=contract.enums, + structs=contract.structs, + cheatcodes=safe, + ) + pp.p_contract(vm_safe, "VmSafe") + out += pp.finish() + + out += "\n\n" + out += VM_DOC + vm_unsafe = Cheatcodes( + errors=[], + events=[], + enums=[], + structs=[], + cheatcodes=unsafe, + ) + pp.p_contract(vm_unsafe, "Vm", "VmSafe") + out += pp.finish() + + # Compatibility with <0.8.0 + def memory_to_calldata(m: re.Match) -> str: + return " calldata " + m.group(1) + + out = re.sub(r" memory (.*returns)", memory_to_calldata, out) + + with open(OUT_PATH, "w") as f: + f.write(out) + + forge_fmt = ["forge", "fmt", OUT_PATH] + res = subprocess.run(forge_fmt) + assert res.returncode == 0, f"command failed: {forge_fmt}" + + print(f"Wrote to {OUT_PATH}") + + +class CmpCheatcode: + cheatcode: "Cheatcode" + + def __init__(self, cheatcode: "Cheatcode"): + self.cheatcode = cheatcode + + def __lt__(self, other: "CmpCheatcode") -> bool: + return cmp_cheatcode(self.cheatcode, other.cheatcode) < 0 + + def __eq__(self, other: "CmpCheatcode") -> bool: + return cmp_cheatcode(self.cheatcode, other.cheatcode) == 0 + + def __gt__(self, other: "CmpCheatcode") -> bool: + return cmp_cheatcode(self.cheatcode, other.cheatcode) > 0 + + +def cmp_cheatcode(a: "Cheatcode", b: "Cheatcode") -> int: + if a.group != b.group: + return -1 if a.group < b.group else 1 + if a.status != b.status: + return -1 if a.status < b.status else 1 + if a.safety != b.safety: + return -1 if a.safety < b.safety else 1 + if a.func.id != b.func.id: + return -1 if a.func.id < b.func.id else 1 + return 0 + + +# HACK: A way to add group header comments without having to modify printer code +def prefix_with_group_headers(cheats: list["Cheatcode"]): + s = set() + for i, cheat in enumerate(cheats): + if cheat.group in s: + continue + + s.add(cheat.group) + + c = copy.deepcopy(cheat) + c.func.description = "" + c.func.declaration = f"// ======== {group(c.group)} ========" + cheats.insert(i, c) + return cheats + + +def group(s: str) -> str: + if s == "evm": + return "EVM" + if s == "json": + return "JSON" + return s[0].upper() + s[1:] + + +class Visibility(PyEnum): + EXTERNAL: str = "external" + PUBLIC: str = "public" + INTERNAL: str = "internal" + PRIVATE: str = "private" + + def __str__(self): + return self.value + + +class Mutability(PyEnum): + PURE: str = "pure" + VIEW: str = "view" + NONE: str = "" + + def __str__(self): + return self.value + + +class Function: + id: str + description: str + declaration: str + visibility: Visibility + mutability: Mutability + signature: str + selector: str + selector_bytes: bytes + + def __init__( + self, + id: str, + description: str, + declaration: str, + visibility: Visibility, + mutability: Mutability, + signature: str, + selector: str, + selector_bytes: bytes, + ): + self.id = id + self.description = description + self.declaration = declaration + self.visibility = visibility + self.mutability = mutability + self.signature = signature + self.selector = selector + self.selector_bytes = selector_bytes + + @staticmethod + def from_dict(d: dict) -> "Function": + return Function( + d["id"], + d["description"], + d["declaration"], + Visibility(d["visibility"]), + Mutability(d["mutability"]), + d["signature"], + d["selector"], + bytes(d["selectorBytes"]), + ) + + +class Cheatcode: + func: Function + group: str + status: str + safety: str + + def __init__(self, func: Function, group: str, status: str, safety: str): + self.func = func + self.group = group + self.status = status + self.safety = safety + + @staticmethod + def from_dict(d: dict) -> "Cheatcode": + return Cheatcode( + Function.from_dict(d["func"]), + str(d["group"]), + str(d["status"]), + str(d["safety"]), + ) + + +class Error: + name: str + description: str + declaration: str + + def __init__(self, name: str, description: str, declaration: str): + self.name = name + self.description = description + self.declaration = declaration + + @staticmethod + def from_dict(d: dict) -> "Error": + return Error(**d) + + +class Event: + name: str + description: str + declaration: str + + def __init__(self, name: str, description: str, declaration: str): + self.name = name + self.description = description + self.declaration = declaration + + @staticmethod + def from_dict(d: dict) -> "Event": + return Event(**d) + + +class EnumVariant: + name: str + description: str + + def __init__(self, name: str, description: str): + self.name = name + self.description = description + + +class Enum: + name: str + description: str + variants: list[EnumVariant] + + def __init__(self, name: str, description: str, variants: list[EnumVariant]): + self.name = name + self.description = description + self.variants = variants + + @staticmethod + def from_dict(d: dict) -> "Enum": + return Enum( + d["name"], + d["description"], + list(map(lambda v: EnumVariant(**v), d["variants"])), + ) + + +class StructField: + name: str + ty: str + description: str + + def __init__(self, name: str, ty: str, description: str): + self.name = name + self.ty = ty + self.description = description + + +class Struct: + name: str + description: str + fields: list[StructField] + + def __init__(self, name: str, description: str, fields: list[StructField]): + self.name = name + self.description = description + self.fields = fields + + @staticmethod + def from_dict(d: dict) -> "Struct": + return Struct( + d["name"], + d["description"], + list(map(lambda f: StructField(**f), d["fields"])), + ) + + +class Cheatcodes: + errors: list[Error] + events: list[Event] + enums: list[Enum] + structs: list[Struct] + cheatcodes: list[Cheatcode] + + def __init__( + self, + errors: list[Error], + events: list[Event], + enums: list[Enum], + structs: list[Struct], + cheatcodes: list[Cheatcode], + ): + self.errors = errors + self.events = events + self.enums = enums + self.structs = structs + self.cheatcodes = cheatcodes + + @staticmethod + def from_dict(d: dict) -> "Cheatcodes": + return Cheatcodes( + errors=[Error.from_dict(e) for e in d["errors"]], + events=[Event.from_dict(e) for e in d["events"]], + enums=[Enum.from_dict(e) for e in d["enums"]], + structs=[Struct.from_dict(e) for e in d["structs"]], + cheatcodes=[Cheatcode.from_dict(e) for e in d["cheatcodes"]], + ) + + @staticmethod + def from_json(s) -> "Cheatcodes": + return Cheatcodes.from_dict(json.loads(s)) + + @staticmethod + def from_json_file(file_path: str) -> "Cheatcodes": + with open(file_path, "r") as f: + return Cheatcodes.from_dict(json.load(f)) + + +class Item(PyEnum): + ERROR: str = "error" + EVENT: str = "event" + ENUM: str = "enum" + STRUCT: str = "struct" + FUNCTION: str = "function" + + +class ItemOrder: + _list: list[Item] + + def __init__(self, list: list[Item]) -> None: + assert len(list) <= len(Item), "list must not contain more items than Item" + assert len(list) == len(set(list)), "list must not contain duplicates" + self._list = list + pass + + def get_list(self) -> list[Item]: + return self._list + + @staticmethod + def default() -> "ItemOrder": + return ItemOrder( + [ + Item.ERROR, + Item.EVENT, + Item.ENUM, + Item.STRUCT, + Item.FUNCTION, + ] + ) + + +class CheatcodesPrinter: + buffer: str + + prelude: bool + spdx_identifier: str + solidity_requirement: str + abicoder_v2: bool + + block_doc_style: bool + + indent_level: int + _indent_str: str + + nl_str: str + + items_order: ItemOrder + + def __init__( + self, + buffer: str = "", + prelude: bool = True, + spdx_identifier: str = "UNLICENSED", + solidity_requirement: str = "", + abicoder_pragma: bool = False, + block_doc_style: bool = False, + indent_level: int = 0, + indent_with: int | str = 4, + nl_str: str = "\n", + items_order: ItemOrder = ItemOrder.default(), + ): + self.prelude = prelude + self.spdx_identifier = spdx_identifier + self.solidity_requirement = solidity_requirement + self.abicoder_v2 = abicoder_pragma + self.block_doc_style = block_doc_style + self.buffer = buffer + self.indent_level = indent_level + self.nl_str = nl_str + + if isinstance(indent_with, int): + assert indent_with >= 0 + self._indent_str = " " * indent_with + elif isinstance(indent_with, str): + self._indent_str = indent_with + else: + assert False, "indent_with must be int or str" + + self.items_order = items_order + + def finish(self) -> str: + ret = self.buffer.rstrip() + self.buffer = "" + return ret + + def p_contract(self, contract: Cheatcodes, name: str, inherits: str = ""): + if self.prelude: + self.p_prelude(contract) + + self._p_str("interface ") + name = name.strip() + if name != "": + self._p_str(name) + self._p_str(" ") + if inherits != "": + self._p_str("is ") + self._p_str(inherits) + self._p_str(" ") + self._p_str("{") + self._p_nl() + self._with_indent(lambda: self._p_items(contract)) + self._p_str("}") + self._p_nl() + + def _p_items(self, contract: Cheatcodes): + for item in self.items_order.get_list(): + if item == Item.ERROR: + self.p_errors(contract.errors) + elif item == Item.EVENT: + self.p_events(contract.events) + elif item == Item.ENUM: + self.p_enums(contract.enums) + elif item == Item.STRUCT: + self.p_structs(contract.structs) + elif item == Item.FUNCTION: + self.p_functions(contract.cheatcodes) + else: + assert False, f"unknown item {item}" + + def p_prelude(self, contract: Cheatcodes | None = None): + self._p_str(f"// SPDX-License-Identifier: {self.spdx_identifier}") + self._p_nl() + + if self.solidity_requirement != "": + req = self.solidity_requirement + elif contract and len(contract.errors) > 0: + req = ">=0.8.4 <0.9.0" + else: + req = ">=0.6.0 <0.9.0" + self._p_str(f"pragma solidity {req};") + self._p_nl() + + if self.abicoder_v2: + self._p_str("pragma experimental ABIEncoderV2;") + self._p_nl() + + self._p_nl() + + def p_errors(self, errors: list[Error]): + for error in errors: + self._p_line(lambda: self.p_error(error)) + + def p_error(self, error: Error): + self._p_comment(error.description, doc=True) + self._p_line(lambda: self._p_str(error.declaration)) + + def p_events(self, events: list[Event]): + for event in events: + self._p_line(lambda: self.p_event(event)) + + def p_event(self, event: Event): + self._p_comment(event.description, doc=True) + self._p_line(lambda: self._p_str(event.declaration)) + + def p_enums(self, enums: list[Enum]): + for enum in enums: + self._p_line(lambda: self.p_enum(enum)) + + def p_enum(self, enum: Enum): + self._p_comment(enum.description, doc=True) + self._p_line(lambda: self._p_str(f"enum {enum.name} {{")) + self._with_indent(lambda: self.p_enum_variants(enum.variants)) + self._p_line(lambda: self._p_str("}")) + + def p_enum_variants(self, variants: list[EnumVariant]): + for i, variant in enumerate(variants): + self._p_indent() + self._p_comment(variant.description) + + self._p_indent() + self._p_str(variant.name) + if i < len(variants) - 1: + self._p_str(",") + self._p_nl() + + def p_structs(self, structs: list[Struct]): + for struct in structs: + self._p_line(lambda: self.p_struct(struct)) + + def p_struct(self, struct: Struct): + self._p_comment(struct.description, doc=True) + self._p_line(lambda: self._p_str(f"struct {struct.name} {{")) + self._with_indent(lambda: self.p_struct_fields(struct.fields)) + self._p_line(lambda: self._p_str("}")) + + def p_struct_fields(self, fields: list[StructField]): + for field in fields: + self._p_line(lambda: self.p_struct_field(field)) + + def p_struct_field(self, field: StructField): + self._p_comment(field.description) + self._p_indented(lambda: self._p_str(f"{field.ty} {field.name};")) + + def p_functions(self, cheatcodes: list[Cheatcode]): + for cheatcode in cheatcodes: + self._p_line(lambda: self.p_function(cheatcode.func)) + + def p_function(self, func: Function): + self._p_comment(func.description, doc=True) + self._p_line(lambda: self._p_str(func.declaration)) + + def _p_comment(self, s: str, doc: bool = False): + s = s.strip() + if s == "": + return + + s = map(lambda line: line.lstrip(), s.split("\n")) + if self.block_doc_style: + self._p_str("/*") + if doc: + self._p_str("*") + self._p_nl() + for line in s: + self._p_indent() + self._p_str(" ") + if doc: + self._p_str("* ") + self._p_str(line) + self._p_nl() + self._p_indent() + self._p_str(" */") + self._p_nl() + else: + first_line = True + for line in s: + if not first_line: + self._p_indent() + first_line = False + + if doc: + self._p_str("/// ") + else: + self._p_str("// ") + self._p_str(line) + self._p_nl() + + def _with_indent(self, f: VoidFn): + self._inc_indent() + f() + self._dec_indent() + + def _p_line(self, f: VoidFn): + self._p_indent() + f() + self._p_nl() + + def _p_indented(self, f: VoidFn): + self._p_indent() + f() + + def _p_indent(self): + for _ in range(self.indent_level): + self._p_str(self._indent_str) + + def _p_nl(self): + self._p_str(self.nl_str) + + def _p_str(self, txt: str): + self.buffer += txt + + def _inc_indent(self): + self.indent_level += 1 + + def _dec_indent(self): + self.indent_level -= 1 + + +if __name__ == "__main__": + main() diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Base.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Base.sol new file mode 100644 index 00000000..52a50821 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Base.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {StdStorage} from "./StdStorage.sol"; +import {Vm, VmSafe} from "./Vm.sol"; + +abstract contract CommonBase { + /// @dev Cheat code address. + /// Calculated as `address(uint160(uint256(keccak256("hevm cheat code"))))`. + address internal constant VM_ADDRESS = 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D; + + /// @dev console.sol and console2.sol work by executing a staticcall to this address. + /// Calculated as `address(uint160(uint88(bytes11("console.log"))))`. + address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67; + + /// @dev Used when deploying with create2. + /// Taken from https://github.com/Arachnid/deterministic-deployment-proxy. + address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + + /// @dev The default address for tx.origin and msg.sender. + /// Calculated as `address(uint160(uint256(keccak256("foundry default caller"))))`. + address internal constant DEFAULT_SENDER = 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38; + + /// @dev The address of the first contract `CREATE`d by a running test contract. + /// When running tests, each test contract is `CREATE`d by `DEFAULT_SENDER` with nonce 1. + /// Calculated as `VM.computeCreateAddress(VM.computeCreateAddress(DEFAULT_SENDER, 1), 1)`. + address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; + + /// @dev Deterministic deployment address of the Multicall3 contract. + /// Taken from https://www.multicall3.com. + address internal constant MULTICALL3_ADDRESS = 0xcA11bde05977b3631167028862bE2a173976CA11; + + /// @dev The order of the secp256k1 curve. + uint256 internal constant SECP256K1_ORDER = + 115792089237316195423570985008687907852837564279074904382605163141518161494337; + + uint256 internal constant UINT256_MAX = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + Vm internal constant vm = Vm(VM_ADDRESS); + StdStorage internal stdstore; +} + +abstract contract TestBase is CommonBase {} + +abstract contract ScriptBase is CommonBase { + VmSafe internal constant vmSafe = VmSafe(VM_ADDRESS); +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Config.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Config.sol new file mode 100644 index 00000000..1c63c872 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Config.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import {console} from "./console.sol"; +import {StdConfig} from "./StdConfig.sol"; +import {CommonBase} from "./Base.sol"; + +/// @notice Boilerplate to streamline the setup of multi-chain environments. +abstract contract Config is CommonBase { + // -- STORAGE (CONFIG + CHAINS + FORKS) ------------------------------------ + + /// @dev Contract instance holding the data from the TOML config file. + StdConfig internal config; + + /// @dev Array of chain IDs for which forks have been created. + uint256[] internal chainIds; + + /// @dev A mapping from a chain ID to its initialized fork ID. + mapping(uint256 => uint256) internal forkOf; + + // -- HELPER FUNCTIONS ----------------------------------------------------- + + /// @notice Loads configuration from a file. + /// + /// @dev This function instantiates a `Config` contract, caching all its config variables. + /// + /// @param filePath: the path to the TOML configuration file. + /// @param writeToFile: whether updates are written back to the TOML file. + function _loadConfig(string memory filePath, bool writeToFile) internal { + console.log("----------"); + console.log(string.concat("Loading config from '", filePath, "'")); + config = new StdConfig(filePath, writeToFile); + vm.makePersistent(address(config)); + console.log("Config successfully loaded"); + console.log("----------"); + } + + /// @notice Loads configuration from a file and creates forks for each specified chain. + /// + /// @dev This function instantiates a `Config` contract, caching all its config variables, + /// reads the configured chain ids, and iterates through them to create a fork for each one. + /// It also creates a map `forkOf[chainId] -> forkId` to easily switch between forks. + /// + /// @param filePath: the path to the TOML configuration file. + /// @param writeToFile: whether updates are written back to the TOML file. + function _loadConfigAndForks(string memory filePath, bool writeToFile) internal { + _loadConfig(filePath, writeToFile); + + console.log("Setting up forks for the configured chains..."); + uint256[] memory chains = config.getChainIds(); + for (uint256 i = 0; i < chains.length; i++) { + uint256 chainId = chains[i]; + uint256 forkId = vm.createFork(config.getRpcUrl(chainId)); + forkOf[chainId] = forkId; + chainIds.push(chainId); + } + console.log("Forks successfully created"); + console.log("----------"); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/LibVariable.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/LibVariable.sol new file mode 100644 index 00000000..c46b1532 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/LibVariable.sol @@ -0,0 +1,477 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +// Enable globally. +using LibVariable for Variable global; + +struct Variable { + Type ty; + bytes data; +} + +struct Type { + TypeKind kind; + bool isArray; +} + +enum TypeKind { + None, + Bool, + Address, + Bytes32, + Uint256, + Int256, + String, + Bytes +} + +/// @notice Library for type-safe coercion of the `Variable` struct to concrete types. +/// +/// @dev Ensures that when a `Variable` is cast to a concrete Solidity type, the operation is safe and the +/// underlying type matches what is expected. +/// Provides functions to check types, convert them to strings, and coerce `Variable` instances into +/// both single values and arrays of various types. +/// +/// Usage example: +/// ```solidity +/// import {LibVariable} from "./LibVariable.sol"; +/// +/// contract MyContract { +/// using LibVariable for Variable; +/// StdConfig config; // Assume 'config' is an instance of `StdConfig` and has already been loaded. +/// +/// function readValues() public { +/// // Retrieve a 'uint256' value from the config. +/// uint256 myNumber = config.get("important_number").toUint256(); +/// +/// // Would revert with `TypeMismatch` as 'important_number' isn't a `uint256` in the config file. +/// // string memory notANumber = config.get("important_number").toString(); +/// +/// // Retrieve a address array from the config. +/// string[] memory admins = config.get("whitelisted_admins").toAddressArray(); +/// } +/// } +/// ``` +library LibVariable { + error NotInitialized(); + error TypeMismatch(string expected, string actual); + error UnsafeCast(string message); + + // -- TYPE HELPERS ---------------------------------------------------- + + /// @notice Compares two Type instances for equality. + function isEqual(Type memory self, Type memory other) internal pure returns (bool) { + return self.kind == other.kind && self.isArray == other.isArray; + } + + /// @notice Compares two Type instances for equality. Reverts if they are not equal. + function assertEq(Type memory self, Type memory other) internal pure { + if (!isEqual(self, other)) { + revert TypeMismatch(toString(other), toString(self)); + } + } + + /// @notice Converts a Type struct to its full string representation (i.e. "uint256[]"). + function toString(Type memory self) internal pure returns (string memory) { + string memory tyStr = toString(self.kind); + if (!self.isArray || self.kind == TypeKind.None) { + return tyStr; + } else { + return string.concat(tyStr, "[]"); + } + } + + /// @dev Converts a `TypeKind` enum to its base string representation. + function toString(TypeKind self) internal pure returns (string memory) { + if (self == TypeKind.Bool) return "bool"; + if (self == TypeKind.Address) return "address"; + if (self == TypeKind.Bytes32) return "bytes32"; + if (self == TypeKind.Uint256) return "uint256"; + if (self == TypeKind.Int256) return "int256"; + if (self == TypeKind.String) return "string"; + if (self == TypeKind.Bytes) return "bytes"; + return "none"; + } + + /// @dev Converts a `TypeKind` enum to its base string representation. + function toTomlKey(TypeKind self) internal pure returns (string memory) { + if (self == TypeKind.Bool) return "bool"; + if (self == TypeKind.Address) return "address"; + if (self == TypeKind.Bytes32) return "bytes32"; + if (self == TypeKind.Uint256) return "uint"; + if (self == TypeKind.Int256) return "int"; + if (self == TypeKind.String) return "string"; + if (self == TypeKind.Bytes) return "bytes"; + return "none"; + } + + // -- VARIABLE HELPERS ---------------------------------------------------- + + /// @dev Checks if a `Variable` has been initialized and matches the expected type reverting if not. + modifier check(Variable memory self, Type memory expected) { + assertExists(self); + assertEq(self.ty, expected); + _; + } + + /// @dev Checks if a `Variable` has been initialized, reverting if not. + function assertExists(Variable memory self) public pure { + if (self.ty.kind == TypeKind.None) { + revert NotInitialized(); + } + } + + // -- VARIABLE COERCION FUNCTIONS (SINGLE VALUES) -------------------------- + + /// @notice Coerces a `Variable` to a `bool` value. + function toBool(Variable memory self) internal pure check(self, Type(TypeKind.Bool, false)) returns (bool) { + return abi.decode(self.data, (bool)); + } + + /// @notice Coerces a `Variable` to an `address` value. + function toAddress(Variable memory self) + internal + pure + check(self, Type(TypeKind.Address, false)) + returns (address) + { + return abi.decode(self.data, (address)); + } + + /// @notice Coerces a `Variable` to a `bytes32` value. + function toBytes32(Variable memory self) + internal + pure + check(self, Type(TypeKind.Bytes32, false)) + returns (bytes32) + { + return abi.decode(self.data, (bytes32)); + } + + /// @notice Coerces a `Variable` to a `uint256` value. + function toUint256(Variable memory self) + internal + pure + check(self, Type(TypeKind.Uint256, false)) + returns (uint256) + { + return abi.decode(self.data, (uint256)); + } + + /// @notice Coerces a `Variable` to a `uint128` value, checking for overflow. + function toUint128(Variable memory self) internal pure returns (uint128) { + uint256 value = self.toUint256(); + if (value > type(uint128).max) { + revert UnsafeCast("value does not fit in 'uint128'"); + } + return uint128(value); + } + + /// @notice Coerces a `Variable` to a `uint64` value, checking for overflow. + function toUint64(Variable memory self) internal pure returns (uint64) { + uint256 value = self.toUint256(); + if (value > type(uint64).max) { + revert UnsafeCast("value does not fit in 'uint64'"); + } + return uint64(value); + } + + /// @notice Coerces a `Variable` to a `uint32` value, checking for overflow. + function toUint32(Variable memory self) internal pure returns (uint32) { + uint256 value = self.toUint256(); + if (value > type(uint32).max) { + revert UnsafeCast("value does not fit in 'uint32'"); + } + return uint32(value); + } + + /// @notice Coerces a `Variable` to a `uint16` value, checking for overflow. + function toUint16(Variable memory self) internal pure returns (uint16) { + uint256 value = self.toUint256(); + if (value > type(uint16).max) { + revert UnsafeCast("value does not fit in 'uint16'"); + } + return uint16(value); + } + + /// @notice Coerces a `Variable` to a `uint8` value, checking for overflow. + function toUint8(Variable memory self) internal pure returns (uint8) { + uint256 value = self.toUint256(); + if (value > type(uint8).max) { + revert UnsafeCast("value does not fit in 'uint8'"); + } + return uint8(value); + } + + /// @notice Coerces a `Variable` to an `int256` value. + function toInt256(Variable memory self) internal pure check(self, Type(TypeKind.Int256, false)) returns (int256) { + return abi.decode(self.data, (int256)); + } + + /// @notice Coerces a `Variable` to an `int128` value, checking for overflow/underflow. + function toInt128(Variable memory self) internal pure returns (int128) { + int256 value = self.toInt256(); + if (value > type(int128).max || value < type(int128).min) { + revert UnsafeCast("value does not fit in 'int128'"); + } + return int128(value); + } + + /// @notice Coerces a `Variable` to an `int64` value, checking for overflow/underflow. + function toInt64(Variable memory self) internal pure returns (int64) { + int256 value = self.toInt256(); + if (value > type(int64).max || value < type(int64).min) { + revert UnsafeCast("value does not fit in 'int64'"); + } + return int64(value); + } + + /// @notice Coerces a `Variable` to an `int32` value, checking for overflow/underflow. + function toInt32(Variable memory self) internal pure returns (int32) { + int256 value = self.toInt256(); + if (value > type(int32).max || value < type(int32).min) { + revert UnsafeCast("value does not fit in 'int32'"); + } + return int32(value); + } + + /// @notice Coerces a `Variable` to an `int16` value, checking for overflow/underflow. + function toInt16(Variable memory self) internal pure returns (int16) { + int256 value = self.toInt256(); + if (value > type(int16).max || value < type(int16).min) { + revert UnsafeCast("value does not fit in 'int16'"); + } + return int16(value); + } + + /// @notice Coerces a `Variable` to an `int8` value, checking for overflow/underflow. + function toInt8(Variable memory self) internal pure returns (int8) { + int256 value = self.toInt256(); + if (value > type(int8).max || value < type(int8).min) { + revert UnsafeCast("value does not fit in 'int8'"); + } + return int8(value); + } + + /// @notice Coerces a `Variable` to a `string` value. + function toString(Variable memory self) + internal + pure + check(self, Type(TypeKind.String, false)) + returns (string memory) + { + return abi.decode(self.data, (string)); + } + + /// @notice Coerces a `Variable` to a `bytes` value. + function toBytes(Variable memory self) + internal + pure + check(self, Type(TypeKind.Bytes, false)) + returns (bytes memory) + { + return abi.decode(self.data, (bytes)); + } + + // -- VARIABLE COERCION FUNCTIONS (ARRAYS) --------------------------------- + + /// @notice Coerces a `Variable` to a `bool` array. + function toBoolArray(Variable memory self) + internal + pure + check(self, Type(TypeKind.Bool, true)) + returns (bool[] memory) + { + return abi.decode(self.data, (bool[])); + } + + /// @notice Coerces a `Variable` to an `address` array. + function toAddressArray(Variable memory self) + internal + pure + check(self, Type(TypeKind.Address, true)) + returns (address[] memory) + { + return abi.decode(self.data, (address[])); + } + + /// @notice Coerces a `Variable` to a `bytes32` array. + function toBytes32Array(Variable memory self) + internal + pure + check(self, Type(TypeKind.Bytes32, true)) + returns (bytes32[] memory) + { + return abi.decode(self.data, (bytes32[])); + } + + /// @notice Coerces a `Variable` to a `uint256` array. + function toUint256Array(Variable memory self) + internal + pure + check(self, Type(TypeKind.Uint256, true)) + returns (uint256[] memory) + { + return abi.decode(self.data, (uint256[])); + } + + /// @notice Coerces a `Variable` to a `uint128` array, checking for overflow. + function toUint128Array(Variable memory self) internal pure returns (uint128[] memory) { + uint256[] memory values = self.toUint256Array(); + uint128[] memory result = new uint128[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(uint128).max) { + revert UnsafeCast("value in array does not fit in 'uint128'"); + } + result[i] = uint128(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `uint64` array, checking for overflow. + function toUint64Array(Variable memory self) internal pure returns (uint64[] memory) { + uint256[] memory values = self.toUint256Array(); + uint64[] memory result = new uint64[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(uint64).max) { + revert UnsafeCast("value in array does not fit in 'uint64'"); + } + result[i] = uint64(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `uint32` array, checking for overflow. + function toUint32Array(Variable memory self) internal pure returns (uint32[] memory) { + uint256[] memory values = self.toUint256Array(); + uint32[] memory result = new uint32[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(uint32).max) { + revert UnsafeCast("value in array does not fit in 'uint32'"); + } + result[i] = uint32(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `uint16` array, checking for overflow. + function toUint16Array(Variable memory self) internal pure returns (uint16[] memory) { + uint256[] memory values = self.toUint256Array(); + uint16[] memory result = new uint16[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(uint16).max) { + revert UnsafeCast("value in array does not fit in 'uint16'"); + } + result[i] = uint16(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `uint8` array, checking for overflow. + function toUint8Array(Variable memory self) internal pure returns (uint8[] memory) { + uint256[] memory values = self.toUint256Array(); + uint8[] memory result = new uint8[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(uint8).max) { + revert UnsafeCast("value in array does not fit in 'uint8'"); + } + result[i] = uint8(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to an `int256` array. + function toInt256Array(Variable memory self) + internal + pure + check(self, Type(TypeKind.Int256, true)) + returns (int256[] memory) + { + return abi.decode(self.data, (int256[])); + } + + /// @notice Coerces a `Variable` to a `int128` array, checking for overflow/underflow. + function toInt128Array(Variable memory self) internal pure returns (int128[] memory) { + int256[] memory values = self.toInt256Array(); + int128[] memory result = new int128[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(int128).max || values[i] < type(int128).min) { + revert UnsafeCast("value in array does not fit in 'int128'"); + } + result[i] = int128(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `int64` array, checking for overflow/underflow. + function toInt64Array(Variable memory self) internal pure returns (int64[] memory) { + int256[] memory values = self.toInt256Array(); + int64[] memory result = new int64[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(int64).max || values[i] < type(int64).min) { + revert UnsafeCast("value in array does not fit in 'int64'"); + } + result[i] = int64(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `int32` array, checking for overflow/underflow. + function toInt32Array(Variable memory self) internal pure returns (int32[] memory) { + int256[] memory values = self.toInt256Array(); + int32[] memory result = new int32[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(int32).max || values[i] < type(int32).min) { + revert UnsafeCast("value in array does not fit in 'int32'"); + } + result[i] = int32(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `int16` array, checking for overflow/underflow. + function toInt16Array(Variable memory self) internal pure returns (int16[] memory) { + int256[] memory values = self.toInt256Array(); + int16[] memory result = new int16[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(int16).max || values[i] < type(int16).min) { + revert UnsafeCast("value in array does not fit in 'int16'"); + } + result[i] = int16(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `int8` array, checking for overflow/underflow. + function toInt8Array(Variable memory self) internal pure returns (int8[] memory) { + int256[] memory values = self.toInt256Array(); + int8[] memory result = new int8[](values.length); + for (uint256 i = 0; i < values.length; i++) { + if (values[i] > type(int8).max || values[i] < type(int8).min) { + revert UnsafeCast("value in array does not fit in 'int8'"); + } + result[i] = int8(values[i]); + } + return result; + } + + /// @notice Coerces a `Variable` to a `string` array. + function toStringArray(Variable memory self) + internal + pure + check(self, Type(TypeKind.String, true)) + returns (string[] memory) + { + return abi.decode(self.data, (string[])); + } + + /// @notice Coerces a `Variable` to a `bytes` array. + function toBytesArray(Variable memory self) + internal + pure + check(self, Type(TypeKind.Bytes, true)) + returns (bytes[] memory) + { + return abi.decode(self.data, (bytes[])); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Script.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Script.sol new file mode 100644 index 00000000..a2e2aa1c --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Script.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +// 💬 ABOUT +// Forge Std's default Script. + +// 🧩 MODULES +import {console} from "./console.sol"; +import {console2} from "./console2.sol"; +import {safeconsole} from "./safeconsole.sol"; +import {StdChains} from "./StdChains.sol"; +import {StdCheatsSafe} from "./StdCheats.sol"; +import {StdConstants} from "./StdConstants.sol"; +import {stdJson} from "./StdJson.sol"; +import {stdMath} from "./StdMath.sol"; +import {StdStorage, stdStorageSafe} from "./StdStorage.sol"; +import {StdStyle} from "./StdStyle.sol"; +import {StdUtils} from "./StdUtils.sol"; +import {VmSafe} from "./Vm.sol"; + +// 📦 BOILERPLATE +import {ScriptBase} from "./Base.sol"; + +// ⭐️ SCRIPT +abstract contract Script is ScriptBase, StdChains, StdCheatsSafe, StdUtils { + // Note: IS_SCRIPT() must return true. + bool public IS_SCRIPT = true; +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdAssertions.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdAssertions.sol new file mode 100644 index 00000000..45418f2c --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdAssertions.sol @@ -0,0 +1,780 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; +pragma experimental ABIEncoderV2; + +import {Vm} from "./Vm.sol"; + +abstract contract StdAssertions { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + event log(string); + event logs(bytes); + + event log_address(address); + event log_bytes32(bytes32); + event log_int(int256); + event log_uint(uint256); + event log_bytes(bytes); + event log_string(string); + + event log_named_address(string key, address val); + event log_named_bytes32(string key, bytes32 val); + event log_named_decimal_int(string key, int256 val, uint256 decimals); + event log_named_decimal_uint(string key, uint256 val, uint256 decimals); + event log_named_int(string key, int256 val); + event log_named_uint(string key, uint256 val); + event log_named_bytes(string key, bytes val); + event log_named_string(string key, string val); + + event log_array(uint256[] val); + event log_array(int256[] val); + event log_array(address[] val); + event log_named_array(string key, uint256[] val); + event log_named_array(string key, int256[] val); + event log_named_array(string key, address[] val); + + bytes32 private constant FAILED_SLOT = bytes32("failed"); + + bool private _failed; + + function failed() public view returns (bool) { + if (_failed) { + return true; + } else { + return vm.load(address(vm), FAILED_SLOT) != bytes32(0); + } + } + + function fail() internal virtual { + vm.store(address(vm), FAILED_SLOT, bytes32(uint256(1))); + _failed = true; + } + + function fail(string memory message) internal virtual { + fail(); + vm.assertTrue(false, message); + } + + function assertTrue(bool data) internal pure virtual { + if (!data) { + vm.assertTrue(data); + } + } + + function assertTrue(bool data, string memory err) internal pure virtual { + if (!data) { + vm.assertTrue(data, err); + } + } + + function assertFalse(bool data) internal pure virtual { + if (data) { + vm.assertFalse(data); + } + } + + function assertFalse(bool data, string memory err) internal pure virtual { + if (data) { + vm.assertFalse(data, err); + } + } + + function assertEq(bool left, bool right) internal pure virtual { + if (left != right) { + vm.assertEq(left, right); + } + } + + function assertEq(bool left, bool right, string memory err) internal pure virtual { + if (left != right) { + vm.assertEq(left, right, err); + } + } + + function assertEq(uint256 left, uint256 right) internal pure virtual { + if (left != right) { + vm.assertEq(left, right); + } + } + + function assertEq(uint256 left, uint256 right, string memory err) internal pure virtual { + if (left != right) { + vm.assertEq(left, right, err); + } + } + + function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { + vm.assertEqDecimal(left, right, decimals); + } + + function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertEqDecimal(left, right, decimals, err); + } + + function assertEq(int256 left, int256 right) internal pure virtual { + if (left != right) { + vm.assertEq(left, right); + } + } + + function assertEq(int256 left, int256 right, string memory err) internal pure virtual { + if (left != right) { + vm.assertEq(left, right, err); + } + } + + function assertEqDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { + vm.assertEqDecimal(left, right, decimals); + } + + function assertEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertEqDecimal(left, right, decimals, err); + } + + function assertEq(address left, address right) internal pure virtual { + if (left != right) { + vm.assertEq(left, right); + } + } + + function assertEq(address left, address right, string memory err) internal pure virtual { + if (left != right) { + vm.assertEq(left, right, err); + } + } + + function assertEq(bytes32 left, bytes32 right) internal pure virtual { + if (left != right) { + vm.assertEq(left, right); + } + } + + function assertEq(bytes32 left, bytes32 right, string memory err) internal pure virtual { + if (left != right) { + vm.assertEq(left, right, err); + } + } + + function assertEq32(bytes32 left, bytes32 right) internal pure virtual { + if (left != right) { + vm.assertEq(left, right); + } + } + + function assertEq32(bytes32 left, bytes32 right, string memory err) internal pure virtual { + if (left != right) { + vm.assertEq(left, right, err); + } + } + + function assertEq(string memory left, string memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(string memory left, string memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(bytes memory left, bytes memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(bytes memory left, bytes memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(bool[] memory left, bool[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(bool[] memory left, bool[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(uint256[] memory left, uint256[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(uint256[] memory left, uint256[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(int256[] memory left, int256[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(int256[] memory left, int256[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(address[] memory left, address[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(address[] memory left, address[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(bytes32[] memory left, bytes32[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(bytes32[] memory left, bytes32[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(string[] memory left, string[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(string[] memory left, string[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + function assertEq(bytes[] memory left, bytes[] memory right) internal pure virtual { + vm.assertEq(left, right); + } + + function assertEq(bytes[] memory left, bytes[] memory right, string memory err) internal pure virtual { + vm.assertEq(left, right, err); + } + + // Legacy helper + function assertEqUint(uint256 left, uint256 right) internal pure virtual { + assertEq(left, right); + } + + function assertNotEq(bool left, bool right) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right); + } + } + + function assertNotEq(bool left, bool right, string memory err) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right, err); + } + } + + function assertNotEq(uint256 left, uint256 right) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right); + } + } + + function assertNotEq(uint256 left, uint256 right, string memory err) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right, err); + } + } + + function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { + vm.assertNotEqDecimal(left, right, decimals); + } + + function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) + internal + pure + virtual + { + vm.assertNotEqDecimal(left, right, decimals, err); + } + + function assertNotEq(int256 left, int256 right) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right); + } + } + + function assertNotEq(int256 left, int256 right, string memory err) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right, err); + } + } + + function assertNotEqDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { + vm.assertNotEqDecimal(left, right, decimals); + } + + function assertNotEqDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertNotEqDecimal(left, right, decimals, err); + } + + function assertNotEq(address left, address right) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right); + } + } + + function assertNotEq(address left, address right, string memory err) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right, err); + } + } + + function assertNotEq(bytes32 left, bytes32 right) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right); + } + } + + function assertNotEq(bytes32 left, bytes32 right, string memory err) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right, err); + } + } + + function assertNotEq32(bytes32 left, bytes32 right) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right); + } + } + + function assertNotEq32(bytes32 left, bytes32 right, string memory err) internal pure virtual { + if (left == right) { + vm.assertNotEq(left, right, err); + } + } + + function assertNotEq(string memory left, string memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(string memory left, string memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(bytes memory left, bytes memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(bytes memory left, bytes memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(bool[] memory left, bool[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(bool[] memory left, bool[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(uint256[] memory left, uint256[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(uint256[] memory left, uint256[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(int256[] memory left, int256[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(int256[] memory left, int256[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(address[] memory left, address[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(address[] memory left, address[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(bytes32[] memory left, bytes32[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(bytes32[] memory left, bytes32[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(string[] memory left, string[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(string[] memory left, string[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertNotEq(bytes[] memory left, bytes[] memory right) internal pure virtual { + vm.assertNotEq(left, right); + } + + function assertNotEq(bytes[] memory left, bytes[] memory right, string memory err) internal pure virtual { + vm.assertNotEq(left, right, err); + } + + function assertLt(uint256 left, uint256 right) internal pure virtual { + if (left >= right) { + vm.assertLt(left, right); + } + } + + function assertLt(uint256 left, uint256 right, string memory err) internal pure virtual { + if (left >= right) { + vm.assertLt(left, right, err); + } + } + + function assertLtDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { + vm.assertLtDecimal(left, right, decimals); + } + + function assertLtDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertLtDecimal(left, right, decimals, err); + } + + function assertLt(int256 left, int256 right) internal pure virtual { + if (left >= right) { + vm.assertLt(left, right); + } + } + + function assertLt(int256 left, int256 right, string memory err) internal pure virtual { + if (left >= right) { + vm.assertLt(left, right, err); + } + } + + function assertLtDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { + vm.assertLtDecimal(left, right, decimals); + } + + function assertLtDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertLtDecimal(left, right, decimals, err); + } + + function assertGt(uint256 left, uint256 right) internal pure virtual { + if (left <= right) { + vm.assertGt(left, right); + } + } + + function assertGt(uint256 left, uint256 right, string memory err) internal pure virtual { + if (left <= right) { + vm.assertGt(left, right, err); + } + } + + function assertGtDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { + vm.assertGtDecimal(left, right, decimals); + } + + function assertGtDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertGtDecimal(left, right, decimals, err); + } + + function assertGt(int256 left, int256 right) internal pure virtual { + if (left <= right) { + vm.assertGt(left, right); + } + } + + function assertGt(int256 left, int256 right, string memory err) internal pure virtual { + if (left <= right) { + vm.assertGt(left, right, err); + } + } + + function assertGtDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { + vm.assertGtDecimal(left, right, decimals); + } + + function assertGtDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertGtDecimal(left, right, decimals, err); + } + + function assertLe(uint256 left, uint256 right) internal pure virtual { + if (left > right) { + vm.assertLe(left, right); + } + } + + function assertLe(uint256 left, uint256 right, string memory err) internal pure virtual { + if (left > right) { + vm.assertLe(left, right, err); + } + } + + function assertLeDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { + vm.assertLeDecimal(left, right, decimals); + } + + function assertLeDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertLeDecimal(left, right, decimals, err); + } + + function assertLe(int256 left, int256 right) internal pure virtual { + if (left > right) { + vm.assertLe(left, right); + } + } + + function assertLe(int256 left, int256 right, string memory err) internal pure virtual { + if (left > right) { + vm.assertLe(left, right, err); + } + } + + function assertLeDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { + vm.assertLeDecimal(left, right, decimals); + } + + function assertLeDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertLeDecimal(left, right, decimals, err); + } + + function assertGe(uint256 left, uint256 right) internal pure virtual { + if (left < right) { + vm.assertGe(left, right); + } + } + + function assertGe(uint256 left, uint256 right, string memory err) internal pure virtual { + if (left < right) { + vm.assertGe(left, right, err); + } + } + + function assertGeDecimal(uint256 left, uint256 right, uint256 decimals) internal pure virtual { + vm.assertGeDecimal(left, right, decimals); + } + + function assertGeDecimal(uint256 left, uint256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertGeDecimal(left, right, decimals, err); + } + + function assertGe(int256 left, int256 right) internal pure virtual { + if (left < right) { + vm.assertGe(left, right); + } + } + + function assertGe(int256 left, int256 right, string memory err) internal pure virtual { + if (left < right) { + vm.assertGe(left, right, err); + } + } + + function assertGeDecimal(int256 left, int256 right, uint256 decimals) internal pure virtual { + vm.assertGeDecimal(left, right, decimals); + } + + function assertGeDecimal(int256 left, int256 right, uint256 decimals, string memory err) internal pure virtual { + vm.assertGeDecimal(left, right, decimals, err); + } + + function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta) internal pure virtual { + vm.assertApproxEqAbs(left, right, maxDelta); + } + + function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta, string memory err) internal pure virtual { + vm.assertApproxEqAbs(left, right, maxDelta, err); + } + + function assertApproxEqAbsDecimal(uint256 left, uint256 right, uint256 maxDelta, uint256 decimals) + internal + pure + virtual + { + vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals); + } + + function assertApproxEqAbsDecimal( + uint256 left, + uint256 right, + uint256 maxDelta, + uint256 decimals, + string memory err + ) internal pure virtual { + vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals, err); + } + + function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta) internal pure virtual { + vm.assertApproxEqAbs(left, right, maxDelta); + } + + function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta, string memory err) internal pure virtual { + vm.assertApproxEqAbs(left, right, maxDelta, err); + } + + function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals) + internal + pure + virtual + { + vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals); + } + + function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals, string memory err) + internal + pure + virtual + { + vm.assertApproxEqAbsDecimal(left, right, maxDelta, decimals, err); + } + + function assertApproxEqRel( + uint256 left, + uint256 right, + uint256 maxPercentDelta // An 18 decimal fixed point number, where 1e18 == 100% + ) + internal + pure + virtual + { + vm.assertApproxEqRel(left, right, maxPercentDelta); + } + + function assertApproxEqRel( + uint256 left, + uint256 right, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + string memory err + ) + internal + pure + virtual + { + vm.assertApproxEqRel(left, right, maxPercentDelta, err); + } + + function assertApproxEqRelDecimal( + uint256 left, + uint256 right, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals + ) + internal + pure + virtual + { + vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals); + } + + function assertApproxEqRelDecimal( + uint256 left, + uint256 right, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals, + string memory err + ) internal pure virtual { + vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals, err); + } + + function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta) internal pure virtual { + vm.assertApproxEqRel(left, right, maxPercentDelta); + } + + function assertApproxEqRel( + int256 left, + int256 right, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + string memory err + ) + internal + pure + virtual + { + vm.assertApproxEqRel(left, right, maxPercentDelta, err); + } + + function assertApproxEqRelDecimal( + int256 left, + int256 right, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals + ) + internal + pure + virtual + { + vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals); + } + + function assertApproxEqRelDecimal( + int256 left, + int256 right, + uint256 maxPercentDelta, // An 18 decimal fixed point number, where 1e18 == 100% + uint256 decimals, + string memory err + ) internal pure virtual { + vm.assertApproxEqRelDecimal(left, right, maxPercentDelta, decimals, err); + } + + // Inherited from DSTest, not used but kept for backwards-compatibility + function checkEq0(bytes memory left, bytes memory right) internal pure returns (bool) { + return keccak256(left) == keccak256(right); + } + + function assertEq0(bytes memory left, bytes memory right) internal pure virtual { + assertEq(left, right); + } + + function assertEq0(bytes memory left, bytes memory right, string memory err) internal pure virtual { + assertEq(left, right, err); + } + + function assertNotEq0(bytes memory left, bytes memory right) internal pure virtual { + assertNotEq(left, right); + } + + function assertNotEq0(bytes memory left, bytes memory right, string memory err) internal pure virtual { + assertNotEq(left, right, err); + } + + function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB) internal virtual { + assertEqCall(target, callDataA, target, callDataB, true); + } + + function assertEqCall(address targetA, bytes memory callDataA, address targetB, bytes memory callDataB) + internal + virtual + { + assertEqCall(targetA, callDataA, targetB, callDataB, true); + } + + function assertEqCall(address target, bytes memory callDataA, bytes memory callDataB, bool strictRevertData) + internal + virtual + { + assertEqCall(target, callDataA, target, callDataB, strictRevertData); + } + + function assertEqCall( + address targetA, + bytes memory callDataA, + address targetB, + bytes memory callDataB, + bool strictRevertData + ) internal virtual { + (bool successA, bytes memory returnDataA) = address(targetA).call(callDataA); + (bool successB, bytes memory returnDataB) = address(targetB).call(callDataB); + + if (successA && successB) { + assertEq(returnDataA, returnDataB, "Call return data does not match"); + } + + if (!successA && !successB && strictRevertData) { + assertEq(returnDataA, returnDataB, "Call revert data does not match"); + } + + if (!successA && successB) { + emit log("Error: Calls were not equal"); + emit log_named_bytes(" Left call revert data", returnDataA); + emit log_named_bytes(" Right call return data", returnDataB); + revert("assertion failed"); + } + + if (successA && !successB) { + emit log("Error: Calls were not equal"); + emit log_named_bytes(" Left call return data", returnDataA); + emit log_named_bytes(" Right call revert data", returnDataB); + revert("assertion failed"); + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdChains.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdChains.sol new file mode 100644 index 00000000..502e51ca --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdChains.sol @@ -0,0 +1,292 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; +pragma experimental ABIEncoderV2; + +import {VmSafe} from "./Vm.sol"; + +/** + * StdChains provides information about EVM compatible chains that can be used in scripts/tests. + * For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are + * identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of + * the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the + * alias used in this contract, which can be found as the first argument to the + * `setChainWithDefaultRpcUrl` call in the `initializeStdChains` function. + * + * There are two main ways to use this contract: + * 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or + * `setChain(string memory chainAlias, Chain memory chain)` + * 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`. + * + * The first time either of those are used, chains are initialized with the default set of RPC URLs. + * This is done in `initializeStdChains`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in + * `defaultRpcUrls`. + * + * The `setChain` function is straightforward, and it simply saves off the given chain data. + * + * The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say + * we want to retrieve the RPC URL for `mainnet`: + * - If you have specified data with `setChain`, it will return that. + * - If you have configured a mainnet RPC URL in `foundry.toml`, it will return the URL, provided it + * is valid (e.g. a URL is specified, or an environment variable is given and exists). + * - If neither of the above conditions is met, the default data is returned. + * + * Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults. + */ +abstract contract StdChains { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + bool private stdChainsInitialized; + + struct ChainData { + string name; + uint256 chainId; + string rpcUrl; + } + + struct Chain { + // The chain name. + string name; + // The chain's Chain ID. + uint256 chainId; + // The chain's alias. (i.e. what gets specified in `foundry.toml`). + string chainAlias; + // A default RPC endpoint for this chain. + // NOTE: This default RPC URL is included for convenience to facilitate quick tests and + // experimentation. Do not use this RPC URL for production test suites, CI, or other heavy + // usage as you will be throttled and this is a disservice to others who need this endpoint. + string rpcUrl; + } + + // Maps from the chain's alias (matching the alias in the `foundry.toml` file) to chain data. + mapping(string => Chain) private chains; + // Maps from the chain's alias to it's default RPC URL. + mapping(string => string) private defaultRpcUrls; + // Maps from a chain ID to it's alias. + mapping(uint256 => string) private idToAlias; + + bool private fallbackToDefaultRpcUrls = true; + + // The RPC URL will be fetched from config or defaultRpcUrls if possible. + function getChain(string memory chainAlias) internal virtual returns (Chain memory chain) { + require(bytes(chainAlias).length != 0, "StdChains getChain(string): Chain alias cannot be the empty string."); + + initializeStdChains(); + chain = chains[chainAlias]; + require( + chain.chainId != 0, + string(abi.encodePacked("StdChains getChain(string): Chain with alias \"", chainAlias, "\" not found.")) + ); + + chain = getChainWithUpdatedRpcUrl(chainAlias, chain); + } + + function getChain(uint256 chainId) internal virtual returns (Chain memory chain) { + require(chainId != 0, "StdChains getChain(uint256): Chain ID cannot be 0."); + initializeStdChains(); + string memory chainAlias = idToAlias[chainId]; + + chain = chains[chainAlias]; + + require( + chain.chainId != 0, + string(abi.encodePacked("StdChains getChain(uint256): Chain with ID ", vm.toString(chainId), " not found.")) + ); + + chain = getChainWithUpdatedRpcUrl(chainAlias, chain); + } + + // set chain info, with priority to argument's rpcUrl field. + function setChain(string memory chainAlias, ChainData memory chain) internal virtual { + require( + bytes(chainAlias).length != 0, + "StdChains setChain(string,ChainData): Chain alias cannot be the empty string." + ); + + require(chain.chainId != 0, "StdChains setChain(string,ChainData): Chain ID cannot be 0."); + + initializeStdChains(); + string memory foundAlias = idToAlias[chain.chainId]; + + require( + bytes(foundAlias).length == 0 || keccak256(bytes(foundAlias)) == keccak256(bytes(chainAlias)), + string( + abi.encodePacked( + "StdChains setChain(string,ChainData): Chain ID ", + vm.toString(chain.chainId), + " already used by \"", + foundAlias, + "\"." + ) + ) + ); + + uint256 oldChainId = chains[chainAlias].chainId; + delete idToAlias[oldChainId]; + + chains[chainAlias] = + Chain({name: chain.name, chainId: chain.chainId, chainAlias: chainAlias, rpcUrl: chain.rpcUrl}); + idToAlias[chain.chainId] = chainAlias; + } + + // set chain info, with priority to argument's rpcUrl field. + function setChain(string memory chainAlias, Chain memory chain) internal virtual { + setChain(chainAlias, ChainData({name: chain.name, chainId: chain.chainId, rpcUrl: chain.rpcUrl})); + } + + function _toUpper(string memory str) private pure returns (string memory) { + bytes memory strb = bytes(str); + bytes memory copy = new bytes(strb.length); + for (uint256 i = 0; i < strb.length; i++) { + bytes1 b = strb[i]; + if (b >= 0x61 && b <= 0x7A) { + copy[i] = bytes1(uint8(b) - 32); + } else { + copy[i] = b; + } + } + return string(copy); + } + + // lookup rpcUrl, in descending order of priority: + // current -> config (foundry.toml) -> environment variable -> default + function getChainWithUpdatedRpcUrl(string memory chainAlias, Chain memory chain) + private + view + returns (Chain memory) + { + if (bytes(chain.rpcUrl).length == 0) { + try vm.rpcUrl(chainAlias) returns (string memory configRpcUrl) { + chain.rpcUrl = configRpcUrl; + } catch (bytes memory err) { + string memory envName = string(abi.encodePacked(_toUpper(chainAlias), "_RPC_URL")); + if (fallbackToDefaultRpcUrls) { + chain.rpcUrl = vm.envOr(envName, defaultRpcUrls[chainAlias]); + } else { + chain.rpcUrl = vm.envString(envName); + } + // Distinguish 'not found' from 'cannot read' + // The upstream error thrown by forge for failing cheats changed so we check both the old and new versions + bytes memory oldNotFoundError = + abi.encodeWithSignature("CheatCodeError", string(abi.encodePacked("invalid rpc url ", chainAlias))); + bytes memory newNotFoundError = abi.encodeWithSignature( + "CheatcodeError(string)", string(abi.encodePacked("invalid rpc url: ", chainAlias)) + ); + bytes32 errHash = keccak256(err); + if ( + (errHash != keccak256(oldNotFoundError) && errHash != keccak256(newNotFoundError)) + || bytes(chain.rpcUrl).length == 0 + ) { + /// @solidity memory-safe-assembly + assembly { + revert(add(32, err), mload(err)) + } + } + } + } + return chain; + } + + function setFallbackToDefaultRpcUrls(bool useDefault) internal { + fallbackToDefaultRpcUrls = useDefault; + } + + function initializeStdChains() private { + if (stdChainsInitialized) return; + + stdChainsInitialized = true; + + // If adding an RPC here, make sure to test the default RPC URL in `test_Rpcs` in `StdChains.t.sol` + setChainWithDefaultRpcUrl("anvil", ChainData("Anvil", 31337, "http://127.0.0.1:8545")); + setChainWithDefaultRpcUrl("mainnet", ChainData("Mainnet", 1, "https://eth.llamarpc.com")); + setChainWithDefaultRpcUrl( + "sepolia", ChainData("Sepolia", 11155111, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001") + ); + setChainWithDefaultRpcUrl("holesky", ChainData("Holesky", 17000, "https://rpc.holesky.ethpandaops.io")); + setChainWithDefaultRpcUrl("hoodi", ChainData("Hoodi", 560048, "https://rpc.hoodi.ethpandaops.io")); + setChainWithDefaultRpcUrl("optimism", ChainData("Optimism", 10, "https://mainnet.optimism.io")); + setChainWithDefaultRpcUrl( + "optimism_sepolia", ChainData("Optimism Sepolia", 11155420, "https://sepolia.optimism.io") + ); + setChainWithDefaultRpcUrl("arbitrum_one", ChainData("Arbitrum One", 42161, "https://arb1.arbitrum.io/rpc")); + setChainWithDefaultRpcUrl( + "arbitrum_one_sepolia", ChainData("Arbitrum One Sepolia", 421614, "https://sepolia-rollup.arbitrum.io/rpc") + ); + setChainWithDefaultRpcUrl("arbitrum_nova", ChainData("Arbitrum Nova", 42170, "https://nova.arbitrum.io/rpc")); + setChainWithDefaultRpcUrl("polygon", ChainData("Polygon", 137, "https://polygon-rpc.com")); + setChainWithDefaultRpcUrl( + "polygon_amoy", ChainData("Polygon Amoy", 80002, "https://rpc-amoy.polygon.technology") + ); + setChainWithDefaultRpcUrl("avalanche", ChainData("Avalanche", 43114, "https://api.avax.network/ext/bc/C/rpc")); + setChainWithDefaultRpcUrl( + "avalanche_fuji", ChainData("Avalanche Fuji", 43113, "https://api.avax-test.network/ext/bc/C/rpc") + ); + setChainWithDefaultRpcUrl( + "bnb_smart_chain", ChainData("BNB Smart Chain", 56, "https://bsc-dataseed1.binance.org") + ); + setChainWithDefaultRpcUrl( + "bnb_smart_chain_testnet", + ChainData("BNB Smart Chain Testnet", 97, "https://rpc.ankr.com/bsc_testnet_chapel") + ); + setChainWithDefaultRpcUrl("gnosis_chain", ChainData("Gnosis Chain", 100, "https://rpc.gnosischain.com")); + setChainWithDefaultRpcUrl("moonbeam", ChainData("Moonbeam", 1284, "https://rpc.api.moonbeam.network")); + setChainWithDefaultRpcUrl( + "moonriver", ChainData("Moonriver", 1285, "https://rpc.api.moonriver.moonbeam.network") + ); + setChainWithDefaultRpcUrl("moonbase", ChainData("Moonbase", 1287, "https://rpc.testnet.moonbeam.network")); + setChainWithDefaultRpcUrl("base_sepolia", ChainData("Base Sepolia", 84532, "https://sepolia.base.org")); + setChainWithDefaultRpcUrl("base", ChainData("Base", 8453, "https://mainnet.base.org")); + setChainWithDefaultRpcUrl("blast_sepolia", ChainData("Blast Sepolia", 168587773, "https://sepolia.blast.io")); + setChainWithDefaultRpcUrl("blast", ChainData("Blast", 81457, "https://rpc.blast.io")); + setChainWithDefaultRpcUrl("fantom_opera", ChainData("Fantom Opera", 250, "https://rpc.ankr.com/fantom/")); + setChainWithDefaultRpcUrl( + "fantom_opera_testnet", ChainData("Fantom Opera Testnet", 4002, "https://rpc.ankr.com/fantom_testnet/") + ); + setChainWithDefaultRpcUrl("fraxtal", ChainData("Fraxtal", 252, "https://rpc.frax.com")); + setChainWithDefaultRpcUrl("fraxtal_testnet", ChainData("Fraxtal Testnet", 2522, "https://rpc.testnet.frax.com")); + setChainWithDefaultRpcUrl( + "berachain_bartio_testnet", ChainData("Berachain bArtio Testnet", 80084, "https://bartio.rpc.berachain.com") + ); + setChainWithDefaultRpcUrl("flare", ChainData("Flare", 14, "https://flare-api.flare.network/ext/C/rpc")); + setChainWithDefaultRpcUrl( + "flare_coston2", ChainData("Flare Coston2", 114, "https://coston2-api.flare.network/ext/C/rpc") + ); + + setChainWithDefaultRpcUrl("mode", ChainData("Mode", 34443, "https://mode.drpc.org")); + setChainWithDefaultRpcUrl("mode_sepolia", ChainData("Mode Sepolia", 919, "https://sepolia.mode.network")); + + setChainWithDefaultRpcUrl("zora", ChainData("Zora", 7777777, "https://zora.drpc.org")); + setChainWithDefaultRpcUrl( + "zora_sepolia", ChainData("Zora Sepolia", 999999999, "https://sepolia.rpc.zora.energy") + ); + + setChainWithDefaultRpcUrl("race", ChainData("Race", 6805, "https://racemainnet.io")); + setChainWithDefaultRpcUrl("race_sepolia", ChainData("Race Sepolia", 6806, "https://racemainnet.io")); + + setChainWithDefaultRpcUrl("metal", ChainData("Metal", 1750, "https://metall2.drpc.org")); + setChainWithDefaultRpcUrl("metal_sepolia", ChainData("Metal Sepolia", 1740, "https://testnet.rpc.metall2.com")); + + setChainWithDefaultRpcUrl("binary", ChainData("Binary", 624, "https://rpc.zero.thebinaryholdings.com")); + setChainWithDefaultRpcUrl( + "binary_sepolia", ChainData("Binary Sepolia", 625, "https://rpc.zero.thebinaryholdings.com") + ); + + setChainWithDefaultRpcUrl("orderly", ChainData("Orderly", 291, "https://rpc.orderly.network")); + setChainWithDefaultRpcUrl( + "orderly_sepolia", ChainData("Orderly Sepolia", 4460, "https://testnet-rpc.orderly.org") + ); + + setChainWithDefaultRpcUrl("unichain", ChainData("Unichain", 130, "https://mainnet.unichain.org")); + setChainWithDefaultRpcUrl( + "unichain_sepolia", ChainData("Unichain Sepolia", 1301, "https://sepolia.unichain.org") + ); + } + + // set chain info, with priority to chainAlias' rpc url in foundry.toml + function setChainWithDefaultRpcUrl(string memory chainAlias, ChainData memory chain) private { + string memory rpcUrl = chain.rpcUrl; + defaultRpcUrls[chainAlias] = rpcUrl; + chain.rpcUrl = ""; + setChain(chainAlias, chain); + chain.rpcUrl = rpcUrl; // restore argument + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdCheats.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdCheats.sol new file mode 100644 index 00000000..59bfea8b --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdCheats.sol @@ -0,0 +1,830 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {StdStorage, stdStorage} from "./StdStorage.sol"; +import {console2} from "./console2.sol"; +import {Vm} from "./Vm.sol"; + +abstract contract StdCheatsSafe { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + uint256 private constant UINT256_MAX = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + bool private gasMeteringOff; + + // Data structures to parse Transaction objects from the broadcast artifact + // that conform to EIP1559. The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct RawTx1559 { + string[] arguments; + address contractAddress; + string contractName; + // json value name = function + string functionSig; + bytes32 hash; + // json value name = tx + RawTx1559Detail txDetail; + // json value name = type + string opcode; + } + + struct RawTx1559Detail { + AccessList[] accessList; + bytes data; + address from; + bytes gas; + bytes nonce; + address to; + bytes txType; + bytes value; + } + + struct Tx1559 { + string[] arguments; + address contractAddress; + string contractName; + string functionSig; + bytes32 hash; + Tx1559Detail txDetail; + string opcode; + } + + struct Tx1559Detail { + AccessList[] accessList; + bytes data; + address from; + uint256 gas; + uint256 nonce; + address to; + uint256 txType; + uint256 value; + } + + // Data structures to parse Transaction objects from the broadcast artifact + // that DO NOT conform to EIP1559. The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct TxLegacy { + string[] arguments; + address contractAddress; + string contractName; + string functionSig; + string hash; + string opcode; + TxDetailLegacy transaction; + } + + struct TxDetailLegacy { + AccessList[] accessList; + uint256 chainId; + bytes data; + address from; + uint256 gas; + uint256 gasPrice; + bytes32 hash; + uint256 nonce; + bytes1 opcode; + bytes32 r; + bytes32 s; + uint256 txType; + address to; + uint8 v; + uint256 value; + } + + struct AccessList { + address accessAddress; + bytes32[] storageKeys; + } + + // Data structures to parse Receipt objects from the broadcast artifact. + // The Raw structs is what is parsed from the JSON + // and then converted to the one that is used by the user for better UX. + + struct RawReceipt { + bytes32 blockHash; + bytes blockNumber; + address contractAddress; + bytes cumulativeGasUsed; + bytes effectiveGasPrice; + address from; + bytes gasUsed; + RawReceiptLog[] logs; + bytes logsBloom; + bytes status; + address to; + bytes32 transactionHash; + bytes transactionIndex; + } + + struct Receipt { + bytes32 blockHash; + uint256 blockNumber; + address contractAddress; + uint256 cumulativeGasUsed; + uint256 effectiveGasPrice; + address from; + uint256 gasUsed; + ReceiptLog[] logs; + bytes logsBloom; + uint256 status; + address to; + bytes32 transactionHash; + uint256 transactionIndex; + } + + // Data structures to parse the entire broadcast artifact, assuming the + // transactions conform to EIP1559. + + struct EIP1559ScriptArtifact { + string[] libraries; + string path; + string[] pending; + Receipt[] receipts; + uint256 timestamp; + Tx1559[] transactions; + TxReturn[] txReturns; + } + + struct RawEIP1559ScriptArtifact { + string[] libraries; + string path; + string[] pending; + RawReceipt[] receipts; + TxReturn[] txReturns; + uint256 timestamp; + RawTx1559[] transactions; + } + + struct RawReceiptLog { + // json value = address + address logAddress; + bytes32 blockHash; + bytes blockNumber; + bytes data; + bytes logIndex; + bool removed; + bytes32[] topics; + bytes32 transactionHash; + bytes transactionIndex; + bytes transactionLogIndex; + } + + struct ReceiptLog { + // json value = address + address logAddress; + bytes32 blockHash; + uint256 blockNumber; + bytes data; + uint256 logIndex; + bytes32[] topics; + uint256 transactionIndex; + uint256 transactionLogIndex; + bool removed; + } + + struct TxReturn { + string internalType; + string value; + } + + struct Account { + address addr; + uint256 key; + } + + enum AddressType { + Payable, + NonPayable, + ZeroAddress, + Precompile, + ForgeAddress + } + + // Checks that `addr` is not blacklisted by token contracts that have a blacklist. + function assumeNotBlacklisted(address token, address addr) internal view virtual { + // Nothing to check if `token` is not a contract. + uint256 tokenCodeSize; + assembly { + tokenCodeSize := extcodesize(token) + } + require(tokenCodeSize > 0, "StdCheats assumeNotBlacklisted(address,address): Token address is not a contract."); + + bool success; + bytes memory returnData; + + // 4-byte selector for `isBlacklisted(address)`, used by USDC. + (success, returnData) = token.staticcall(abi.encodeWithSelector(0xfe575a87, addr)); + vm.assume(!success || abi.decode(returnData, (bool)) == false); + + // 4-byte selector for `isBlackListed(address)`, used by USDT. + (success, returnData) = token.staticcall(abi.encodeWithSelector(0xe47d6060, addr)); + vm.assume(!success || abi.decode(returnData, (bool)) == false); + } + + // Checks that `addr` is not blacklisted by token contracts that have a blacklist. + // This is identical to `assumeNotBlacklisted(address,address)` but with a different name, for + // backwards compatibility, since this name was used in the original PR which already has + // a release. This function can be removed in a future release once we want a breaking change. + function assumeNoBlacklisted(address token, address addr) internal view virtual { + assumeNotBlacklisted(token, addr); + } + + function assumeAddressIsNot(address addr, AddressType addressType) internal virtual { + if (addressType == AddressType.Payable) { + assumeNotPayable(addr); + } else if (addressType == AddressType.NonPayable) { + assumePayable(addr); + } else if (addressType == AddressType.ZeroAddress) { + assumeNotZeroAddress(addr); + } else if (addressType == AddressType.Precompile) { + assumeNotPrecompile(addr); + } else if (addressType == AddressType.ForgeAddress) { + assumeNotForgeAddress(addr); + } + } + + function assumeAddressIsNot(address addr, AddressType addressType1, AddressType addressType2) internal virtual { + assumeAddressIsNot(addr, addressType1); + assumeAddressIsNot(addr, addressType2); + } + + function assumeAddressIsNot( + address addr, + AddressType addressType1, + AddressType addressType2, + AddressType addressType3 + ) internal virtual { + assumeAddressIsNot(addr, addressType1); + assumeAddressIsNot(addr, addressType2); + assumeAddressIsNot(addr, addressType3); + } + + function assumeAddressIsNot( + address addr, + AddressType addressType1, + AddressType addressType2, + AddressType addressType3, + AddressType addressType4 + ) internal virtual { + assumeAddressIsNot(addr, addressType1); + assumeAddressIsNot(addr, addressType2); + assumeAddressIsNot(addr, addressType3); + assumeAddressIsNot(addr, addressType4); + } + + // This function checks whether an address, `addr`, is payable. It works by sending 1 wei to + // `addr` and checking the `success` return value. + // NOTE: This function may result in state changes depending on the fallback/receive logic + // implemented by `addr`, which should be taken into account when this function is used. + function _isPayable(address addr) private returns (bool) { + require( + addr.balance < UINT256_MAX, + "StdCheats _isPayable(address): Balance equals max uint256, so it cannot receive any more funds" + ); + uint256 origBalanceTest = address(this).balance; + uint256 origBalanceAddr = address(addr).balance; + + vm.deal(address(this), 1); + (bool success,) = payable(addr).call{value: 1}(""); + + // reset balances + vm.deal(address(this), origBalanceTest); + vm.deal(addr, origBalanceAddr); + + return success; + } + + // NOTE: This function may result in state changes depending on the fallback/receive logic + // implemented by `addr`, which should be taken into account when this function is used. See the + // `_isPayable` method for more information. + function assumePayable(address addr) internal virtual { + vm.assume(_isPayable(addr)); + } + + function assumeNotPayable(address addr) internal virtual { + vm.assume(!_isPayable(addr)); + } + + function assumeNotZeroAddress(address addr) internal pure virtual { + vm.assume(addr != address(0)); + } + + function assumeNotPrecompile(address addr) internal pure virtual { + assumeNotPrecompile(addr, _pureChainId()); + } + + function assumeNotPrecompile(address addr, uint256 chainId) internal pure virtual { + // Note: For some chains like Optimism these are technically predeploys (i.e. bytecode placed at a specific + // address), but the same rationale for excluding them applies so we include those too. + + // These are reserved by Ethereum and may be on all EVM-compatible chains. + vm.assume(addr < address(0x1) || addr > address(0xff)); + + // forgefmt: disable-start + if (chainId == 10 || chainId == 420 || chainId == 11155420) { + // https://github.com/ethereum-optimism/optimism/blob/eaa371a0184b56b7ca6d9eb9cb0a2b78b2ccd864/op-bindings/predeploys/addresses.go#L6-L21 + vm.assume(addr < address(0x4200000000000000000000000000000000000000) || addr > address(0x4200000000000000000000000000000000000800)); + } else if (chainId == 42161 || chainId == 421613) { + // https://developer.arbitrum.io/useful-addresses#arbitrum-precompiles-l2-same-on-all-arb-chains + vm.assume(addr < address(0x0000000000000000000000000000000000000064) || addr > address(0x0000000000000000000000000000000000000068)); + } else if (chainId == 43114 || chainId == 43113) { + // https://github.com/ava-labs/subnet-evm/blob/47c03fd007ecaa6de2c52ea081596e0a88401f58/precompile/params.go#L18-L59 + vm.assume(addr < address(0x0100000000000000000000000000000000000000) || addr > address(0x01000000000000000000000000000000000000ff)); + vm.assume(addr < address(0x0200000000000000000000000000000000000000) || addr > address(0x02000000000000000000000000000000000000FF)); + vm.assume(addr < address(0x0300000000000000000000000000000000000000) || addr > address(0x03000000000000000000000000000000000000Ff)); + } + // forgefmt: disable-end + } + + function assumeNotForgeAddress(address addr) internal pure virtual { + // vm, console, and Create2Deployer addresses + vm.assume( + addr != address(vm) && addr != 0x000000000000000000636F6e736F6c652e6c6f67 + && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C + ); + } + + function assumeUnusedAddress(address addr) internal view virtual { + uint256 size; + assembly { + size := extcodesize(addr) + } + vm.assume(size == 0); + + assumeNotPrecompile(addr); + assumeNotZeroAddress(addr); + assumeNotForgeAddress(addr); + } + + function readEIP1559ScriptArtifact(string memory path) + internal + view + virtual + returns (EIP1559ScriptArtifact memory) + { + string memory data = vm.readFile(path); + bytes memory parsedData = vm.parseJson(data); + RawEIP1559ScriptArtifact memory rawArtifact = abi.decode(parsedData, (RawEIP1559ScriptArtifact)); + EIP1559ScriptArtifact memory artifact; + artifact.libraries = rawArtifact.libraries; + artifact.path = rawArtifact.path; + artifact.timestamp = rawArtifact.timestamp; + artifact.pending = rawArtifact.pending; + artifact.txReturns = rawArtifact.txReturns; + artifact.receipts = rawToConvertedReceipts(rawArtifact.receipts); + artifact.transactions = rawToConvertedEIPTx1559s(rawArtifact.transactions); + return artifact; + } + + function rawToConvertedEIPTx1559s(RawTx1559[] memory rawTxs) internal pure virtual returns (Tx1559[] memory) { + Tx1559[] memory txs = new Tx1559[](rawTxs.length); + for (uint256 i; i < rawTxs.length; i++) { + txs[i] = rawToConvertedEIPTx1559(rawTxs[i]); + } + return txs; + } + + function rawToConvertedEIPTx1559(RawTx1559 memory rawTx) internal pure virtual returns (Tx1559 memory) { + Tx1559 memory transaction; + transaction.arguments = rawTx.arguments; + transaction.contractName = rawTx.contractName; + transaction.functionSig = rawTx.functionSig; + transaction.hash = rawTx.hash; + transaction.txDetail = rawToConvertedEIP1559Detail(rawTx.txDetail); + transaction.opcode = rawTx.opcode; + return transaction; + } + + function rawToConvertedEIP1559Detail(RawTx1559Detail memory rawDetail) + internal + pure + virtual + returns (Tx1559Detail memory) + { + Tx1559Detail memory txDetail; + txDetail.data = rawDetail.data; + txDetail.from = rawDetail.from; + txDetail.to = rawDetail.to; + txDetail.nonce = _bytesToUint(rawDetail.nonce); + txDetail.txType = _bytesToUint(rawDetail.txType); + txDetail.value = _bytesToUint(rawDetail.value); + txDetail.gas = _bytesToUint(rawDetail.gas); + txDetail.accessList = rawDetail.accessList; + return txDetail; + } + + function readTx1559s(string memory path) internal view virtual returns (Tx1559[] memory) { + string memory deployData = vm.readFile(path); + bytes memory parsedDeployData = vm.parseJson(deployData, ".transactions"); + RawTx1559[] memory rawTxs = abi.decode(parsedDeployData, (RawTx1559[])); + return rawToConvertedEIPTx1559s(rawTxs); + } + + function readTx1559(string memory path, uint256 index) internal view virtual returns (Tx1559 memory) { + string memory deployData = vm.readFile(path); + string memory key = string(abi.encodePacked(".transactions[", vm.toString(index), "]")); + bytes memory parsedDeployData = vm.parseJson(deployData, key); + RawTx1559 memory rawTx = abi.decode(parsedDeployData, (RawTx1559)); + return rawToConvertedEIPTx1559(rawTx); + } + + // Analogous to readTransactions, but for receipts. + function readReceipts(string memory path) internal view virtual returns (Receipt[] memory) { + string memory deployData = vm.readFile(path); + bytes memory parsedDeployData = vm.parseJson(deployData, ".receipts"); + RawReceipt[] memory rawReceipts = abi.decode(parsedDeployData, (RawReceipt[])); + return rawToConvertedReceipts(rawReceipts); + } + + function readReceipt(string memory path, uint256 index) internal view virtual returns (Receipt memory) { + string memory deployData = vm.readFile(path); + string memory key = string(abi.encodePacked(".receipts[", vm.toString(index), "]")); + bytes memory parsedDeployData = vm.parseJson(deployData, key); + RawReceipt memory rawReceipt = abi.decode(parsedDeployData, (RawReceipt)); + return rawToConvertedReceipt(rawReceipt); + } + + function rawToConvertedReceipts(RawReceipt[] memory rawReceipts) internal pure virtual returns (Receipt[] memory) { + Receipt[] memory receipts = new Receipt[](rawReceipts.length); + for (uint256 i; i < rawReceipts.length; i++) { + receipts[i] = rawToConvertedReceipt(rawReceipts[i]); + } + return receipts; + } + + function rawToConvertedReceipt(RawReceipt memory rawReceipt) internal pure virtual returns (Receipt memory) { + Receipt memory receipt; + receipt.blockHash = rawReceipt.blockHash; + receipt.to = rawReceipt.to; + receipt.from = rawReceipt.from; + receipt.contractAddress = rawReceipt.contractAddress; + receipt.effectiveGasPrice = _bytesToUint(rawReceipt.effectiveGasPrice); + receipt.cumulativeGasUsed = _bytesToUint(rawReceipt.cumulativeGasUsed); + receipt.gasUsed = _bytesToUint(rawReceipt.gasUsed); + receipt.status = _bytesToUint(rawReceipt.status); + receipt.transactionIndex = _bytesToUint(rawReceipt.transactionIndex); + receipt.blockNumber = _bytesToUint(rawReceipt.blockNumber); + receipt.logs = rawToConvertedReceiptLogs(rawReceipt.logs); + receipt.logsBloom = rawReceipt.logsBloom; + receipt.transactionHash = rawReceipt.transactionHash; + return receipt; + } + + function rawToConvertedReceiptLogs(RawReceiptLog[] memory rawLogs) + internal + pure + virtual + returns (ReceiptLog[] memory) + { + ReceiptLog[] memory logs = new ReceiptLog[](rawLogs.length); + for (uint256 i; i < rawLogs.length; i++) { + logs[i].logAddress = rawLogs[i].logAddress; + logs[i].blockHash = rawLogs[i].blockHash; + logs[i].blockNumber = _bytesToUint(rawLogs[i].blockNumber); + logs[i].data = rawLogs[i].data; + logs[i].logIndex = _bytesToUint(rawLogs[i].logIndex); + logs[i].topics = rawLogs[i].topics; + logs[i].transactionIndex = _bytesToUint(rawLogs[i].transactionIndex); + logs[i].transactionLogIndex = _bytesToUint(rawLogs[i].transactionLogIndex); + logs[i].removed = rawLogs[i].removed; + } + return logs; + } + + // Deploy a contract by fetching the contract bytecode from + // the artifacts directory + // e.g. `deployCode(code, abi.encode(arg1,arg2,arg3))` + function deployCode(string memory what, bytes memory args) internal virtual returns (address addr) { + bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); + /// @solidity memory-safe-assembly + assembly { + addr := create(0, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,bytes): Deployment failed."); + } + + function deployCode(string memory what) internal virtual returns (address addr) { + bytes memory bytecode = vm.getCode(what); + /// @solidity memory-safe-assembly + assembly { + addr := create(0, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string): Deployment failed."); + } + + /// @dev deploy contract with value on construction + function deployCode(string memory what, bytes memory args, uint256 val) internal virtual returns (address addr) { + bytes memory bytecode = abi.encodePacked(vm.getCode(what), args); + /// @solidity memory-safe-assembly + assembly { + addr := create(val, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,bytes,uint256): Deployment failed."); + } + + function deployCode(string memory what, uint256 val) internal virtual returns (address addr) { + bytes memory bytecode = vm.getCode(what); + /// @solidity memory-safe-assembly + assembly { + addr := create(val, add(bytecode, 0x20), mload(bytecode)) + } + + require(addr != address(0), "StdCheats deployCode(string,uint256): Deployment failed."); + } + + // creates a labeled address and the corresponding private key + function makeAddrAndKey(string memory name) internal virtual returns (address addr, uint256 privateKey) { + privateKey = uint256(keccak256(abi.encodePacked(name))); + addr = vm.addr(privateKey); + vm.label(addr, name); + } + + // creates a labeled address + function makeAddr(string memory name) internal virtual returns (address addr) { + (addr,) = makeAddrAndKey(name); + } + + // Destroys an account immediately, sending the balance to beneficiary. + // Destroying means: balance will be zero, code will be empty, and nonce will be 0 + // This is similar to selfdestruct but not identical: selfdestruct destroys code and nonce + // only after tx ends, this will run immediately. + function destroyAccount(address who, address beneficiary) internal virtual { + uint256 currBalance = who.balance; + vm.etch(who, abi.encode()); + vm.deal(who, 0); + vm.resetNonce(who); + + uint256 beneficiaryBalance = beneficiary.balance; + vm.deal(beneficiary, currBalance + beneficiaryBalance); + } + + // creates a struct containing both a labeled address and the corresponding private key + function makeAccount(string memory name) internal virtual returns (Account memory account) { + (account.addr, account.key) = makeAddrAndKey(name); + } + + function deriveRememberKey(string memory mnemonic, uint32 index) + internal + virtual + returns (address who, uint256 privateKey) + { + privateKey = vm.deriveKey(mnemonic, index); + who = vm.rememberKey(privateKey); + } + + function _bytesToUint(bytes memory b) private pure returns (uint256) { + require(b.length <= 32, "StdCheats _bytesToUint(bytes): Bytes length exceeds 32."); + return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); + } + + function isFork() internal view virtual returns (bool status) { + try vm.activeFork() { + status = true; + } catch (bytes memory) {} + } + + modifier skipWhenForking() { + if (!isFork()) { + _; + } + } + + modifier skipWhenNotForking() { + if (isFork()) { + _; + } + } + + modifier noGasMetering() { + vm.pauseGasMetering(); + // To prevent turning gas monitoring back on with nested functions that use this modifier, + // we check if gasMetering started in the off position. If it did, we don't want to turn + // it back on until we exit the top level function that used the modifier + // + // i.e. funcA() noGasMetering { funcB() }, where funcB has noGasMetering as well. + // funcA will have `gasStartedOff` as false, funcB will have it as true, + // so we only turn metering back on at the end of the funcA + bool gasStartedOff = gasMeteringOff; + gasMeteringOff = true; + + _; + + // if gas metering was on when this modifier was called, turn it back on at the end + if (!gasStartedOff) { + gasMeteringOff = false; + vm.resumeGasMetering(); + } + } + + // We use this complex approach of `_viewChainId` and `_pureChainId` to ensure there are no + // compiler warnings when accessing chain ID in any solidity version supported by forge-std. We + // can't simply access the chain ID in a normal view or pure function because the solc View Pure + // Checker changed `chainid` from pure to view in 0.8.0. + function _viewChainId() private view returns (uint256 chainId) { + // Assembly required since `block.chainid` was introduced in 0.8.0. + assembly { + chainId := chainid() + } + + address(this); // Silence warnings in older Solc versions. + } + + function _pureChainId() private pure returns (uint256 chainId) { + function() internal view returns (uint256) fnIn = _viewChainId; + function() internal pure returns (uint256) pureChainId; + assembly { + pureChainId := fnIn + } + chainId = pureChainId(); + } +} + +// Wrappers around cheatcodes to avoid footguns +abstract contract StdCheats is StdCheatsSafe { + using stdStorage for StdStorage; + + StdStorage private stdstore; + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; + + // Skip forward or rewind time by the specified number of seconds + function skip(uint256 time) internal virtual { + vm.warp(vm.getBlockTimestamp() + time); + } + + function rewind(uint256 time) internal virtual { + vm.warp(vm.getBlockTimestamp() - time); + } + + // Setup a prank from an address that has some ether + function hoax(address msgSender) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.prank(msgSender); + } + + function hoax(address msgSender, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.prank(msgSender); + } + + function hoax(address msgSender, address origin) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.prank(msgSender, origin); + } + + function hoax(address msgSender, address origin, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.prank(msgSender, origin); + } + + // Start perpetual prank from an address that has some ether + function startHoax(address msgSender) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.startPrank(msgSender); + } + + function startHoax(address msgSender, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.startPrank(msgSender); + } + + // Start perpetual prank from an address that has some ether + // tx.origin is set to the origin parameter + function startHoax(address msgSender, address origin) internal virtual { + vm.deal(msgSender, 1 << 128); + vm.startPrank(msgSender, origin); + } + + function startHoax(address msgSender, address origin, uint256 give) internal virtual { + vm.deal(msgSender, give); + vm.startPrank(msgSender, origin); + } + + function changePrank(address msgSender) internal virtual { + console2_log_StdCheats("changePrank is deprecated. Please use vm.startPrank instead."); + vm.stopPrank(); + vm.startPrank(msgSender); + } + + function changePrank(address msgSender, address txOrigin) internal virtual { + console2_log_StdCheats("changePrank is deprecated. Please use vm.startPrank instead."); + vm.stopPrank(); + vm.startPrank(msgSender, txOrigin); + } + + // The same as Vm's `deal` + // Use the alternative signature for ERC20 tokens + function deal(address to, uint256 give) internal virtual { + vm.deal(to, give); + } + + // Set the balance of an account for any ERC20 token + // Use the alternative signature to update `totalSupply` + function deal(address token, address to, uint256 give) internal virtual { + deal(token, to, give, false); + } + + // Set the balance of an account for any ERC1155 token + // Use the alternative signature to update `totalSupply` + function dealERC1155(address token, address to, uint256 id, uint256 give) internal virtual { + dealERC1155(token, to, id, give, false); + } + + function deal(address token, address to, uint256 give, bool adjust) internal virtual { + // get current balance + (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); + uint256 prevBal = abi.decode(balData, (uint256)); + + // update balance + stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(give); + + // update total supply + if (adjust) { + (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0x18160ddd)); + uint256 totSup = abi.decode(totSupData, (uint256)); + if (give < prevBal) { + totSup -= (prevBal - give); + } else { + totSup += (give - prevBal); + } + stdstore.target(token).sig(0x18160ddd).checked_write(totSup); + } + } + + function dealERC1155(address token, address to, uint256 id, uint256 give, bool adjust) internal virtual { + // get current balance + (, bytes memory balData) = token.staticcall(abi.encodeWithSelector(0x00fdd58e, to, id)); + uint256 prevBal = abi.decode(balData, (uint256)); + + // update balance + stdstore.target(token).sig(0x00fdd58e).with_key(to).with_key(id).checked_write(give); + + // update total supply + if (adjust) { + (, bytes memory totSupData) = token.staticcall(abi.encodeWithSelector(0xbd85b039, id)); + require( + totSupData.length != 0, + "StdCheats deal(address,address,uint,uint,bool): target contract is not ERC1155Supply." + ); + uint256 totSup = abi.decode(totSupData, (uint256)); + if (give < prevBal) { + totSup -= (prevBal - give); + } else { + totSup += (give - prevBal); + } + stdstore.target(token).sig(0xbd85b039).with_key(id).checked_write(totSup); + } + } + + function dealERC721(address token, address to, uint256 id) internal virtual { + // check if token id is already minted and the actual owner. + (bool successMinted, bytes memory ownerData) = token.staticcall(abi.encodeWithSelector(0x6352211e, id)); + require(successMinted, "StdCheats deal(address,address,uint,bool): id not minted."); + + // get owner current balance + (, bytes memory fromBalData) = + token.staticcall(abi.encodeWithSelector(0x70a08231, abi.decode(ownerData, (address)))); + uint256 fromPrevBal = abi.decode(fromBalData, (uint256)); + + // get new user current balance + (, bytes memory toBalData) = token.staticcall(abi.encodeWithSelector(0x70a08231, to)); + uint256 toPrevBal = abi.decode(toBalData, (uint256)); + + // update balances + stdstore.target(token).sig(0x70a08231).with_key(abi.decode(ownerData, (address))).checked_write(--fromPrevBal); + stdstore.target(token).sig(0x70a08231).with_key(to).checked_write(++toPrevBal); + + // update owner + stdstore.target(token).sig(0x6352211e).with_key(id).checked_write(to); + } + + function deployCodeTo(string memory what, address where) internal virtual { + deployCodeTo(what, "", 0, where); + } + + function deployCodeTo(string memory what, bytes memory args, address where) internal virtual { + deployCodeTo(what, args, 0, where); + } + + function deployCodeTo(string memory what, bytes memory args, uint256 value, address where) internal virtual { + bytes memory creationCode = vm.getCode(what); + vm.etch(where, abi.encodePacked(creationCode, args)); + (bool success, bytes memory runtimeBytecode) = where.call{value: value}(""); + require(success, "StdCheats deployCodeTo(string,bytes,uint256,address): Failed to create runtime bytecode."); + vm.etch(where, runtimeBytecode); + } + + // Used to prevent the compilation of console, which shortens the compilation time when console is not used elsewhere. + function console2_log_StdCheats(string memory p0) private view { + (bool status,) = address(CONSOLE2_ADDRESS).staticcall(abi.encodeWithSignature("log(string)", p0)); + status; + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdConfig.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdConfig.sol new file mode 100644 index 00000000..161e3171 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdConfig.sol @@ -0,0 +1,613 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import {VmSafe} from "./Vm.sol"; +import {Variable, Type, TypeKind, LibVariable} from "./LibVariable.sol"; + +/// @notice A contract that parses a toml configuration file and load its +/// variables into storage, automatically casting them, on deployment. +/// +/// @dev This contract assumes a toml structure where top-level keys +/// represent chain ids or aliases. Under each chain key, variables are +/// organized by type in separate sub-tables like `[.]`, where +/// type must be: `bool`, `address`, `bytes32`, `uint`, `ìnt`, `string`, or `bytes`. +/// +/// Supported format: +/// ``` +/// [mainnet] +/// endpoint_url = "${MAINNET_RPC}" +/// +/// [mainnet.bool] +/// is_live = true +/// +/// [mainnet.address] +/// weth = "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2" +/// whitelisted_admins = [ +/// "${MAINNET_ADMIN}", +/// "0x00000000000000000000000000000000deadbeef", +/// "0x000000000000000000000000000000c0ffeebabe" +/// ] +/// +/// [mainnet.uint] +/// important_number = 123 +/// ``` +contract StdConfig { + using LibVariable for Type; + using LibVariable for TypeKind; + + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + /// @dev Types: `bool`, `address`, `bytes32`, `uint`, `ìnt`, `string`, `bytes`. + uint8 private constant NUM_TYPES = 7; + + // -- ERRORS --------------------------------------------------------------- + + error AlreadyInitialized(string key); + error InvalidChainKey(string aliasOrId); + error ChainNotInitialized(uint256 chainId); + error UnableToParseVariable(string key); + error WriteToFileInForbiddenCtxt(); + + // -- STORAGE (CACHE FROM CONFIG FILE) ------------------------------------ + + /// @dev Path to the loaded TOML configuration file. + string private _filePath; + + /// @dev List of top-level keys found in the TOML file, assumed to be chain names/aliases. + string[] private _chainKeys; + + /// @dev Storage for the configured RPC URL for each chain. + mapping(uint256 => string) private _rpcOf; + + /// @dev Storage for values, organized by chain ID and variable key. + mapping(uint256 => mapping(string => bytes)) private _dataOf; + + /// @dev Type cache for runtime checking when casting. + mapping(uint256 => mapping(string => Type)) private _typeOf; + + /// @dev When enabled, `set` will always write updates back to the configuration file. + /// Can only be enabled in a scripting context to prevent file corruption from + /// concurrent I/O access, as tests run in parallel. + bool private _writeToFile; + + // -- CONSTRUCTOR ---------------------------------------------------------- + + /// @notice Reads the TOML file and iterates through each top-level key, which is + /// assumed to be a chain name or ID. For each chain, it caches its RPC + /// endpoint and all variables defined in typed sub-tables like `[.]`, + /// where type must be: `bool`, `address`, `uint`, `bytes32`, `string`, or `bytes`. + /// + /// The constructor attempts to parse each variable first as a single value, + /// and if that fails, as an array of that type. If a variable cannot be + /// parsed as either, the constructor will revert with an error. + /// + /// @param configFilePath: The local path to the TOML configuration file. + /// @param writeToFile: Whether to write updates back to the TOML file. Only for scripts. + constructor(string memory configFilePath, bool writeToFile) { + if (writeToFile && !vm.isContext(VmSafe.ForgeContext.ScriptGroup)) { + revert WriteToFileInForbiddenCtxt(); + } + + _filePath = configFilePath; + _writeToFile = writeToFile; + string memory content = vm.resolveEnv(vm.readFile(configFilePath)); + string[] memory chain_keys = vm.parseTomlKeys(content, "$"); + + // Cache the entire configuration to storage + for (uint256 i = 0; i < chain_keys.length; i++) { + string memory chain_key = chain_keys[i]; + // Ignore top-level keys that are not tables + if (vm.parseTomlKeys(content, string.concat("$.", chain_key)).length == 0) { + continue; + } + uint256 chainId = resolveChainId(chain_key); + _chainKeys.push(chain_key); + + // Cache the configure rpc endpoint for that chain. + // Falls back to `[rpc_endpoints]`. Panics if no rpc endpoint is configured. + try vm.parseTomlString(content, string.concat("$.", chain_key, ".endpoint_url")) returns ( + string memory url + ) { + _rpcOf[chainId] = vm.resolveEnv(url); + } catch { + _rpcOf[chainId] = vm.resolveEnv(vm.rpcUrl(chain_key)); + } + + // Iterate through all the available `TypeKind`s (except `None`) to create the sub-section paths + for (uint8 t = 1; t <= NUM_TYPES; t++) { + TypeKind ty = TypeKind(t); + string memory typePath = string.concat("$.", chain_key, ".", ty.toTomlKey()); + + try vm.parseTomlKeys(content, typePath) returns (string[] memory keys) { + for (uint256 j = 0; j < keys.length; j++) { + string memory key = keys[j]; + if (_typeOf[chainId][key].kind == TypeKind.None) { + _loadAndCacheValue(content, string.concat(typePath, ".", key), chainId, key, ty); + } else { + revert AlreadyInitialized(key); + } + } + } catch {} + } + } + } + + function _loadAndCacheValue( + string memory content, + string memory path, + uint256 chainId, + string memory key, + TypeKind ty + ) private { + bool success = false; + if (ty == TypeKind.Bool) { + try vm.parseTomlBool(content, path) returns (bool val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Bool, false); + success = true; + } catch { + try vm.parseTomlBoolArray(content, path) returns (bool[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Bool, true); + success = true; + } catch {} + } + } else if (ty == TypeKind.Address) { + try vm.parseTomlAddress(content, path) returns (address val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Address, false); + success = true; + } catch { + try vm.parseTomlAddressArray(content, path) returns (address[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Address, true); + success = true; + } catch {} + } + } else if (ty == TypeKind.Bytes32) { + try vm.parseTomlBytes32(content, path) returns (bytes32 val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Bytes32, false); + success = true; + } catch { + try vm.parseTomlBytes32Array(content, path) returns (bytes32[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Bytes32, true); + success = true; + } catch {} + } + } else if (ty == TypeKind.Uint256) { + try vm.parseTomlUint(content, path) returns (uint256 val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Uint256, false); + success = true; + } catch { + try vm.parseTomlUintArray(content, path) returns (uint256[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Uint256, true); + success = true; + } catch {} + } + } else if (ty == TypeKind.Int256) { + try vm.parseTomlInt(content, path) returns (int256 val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Int256, false); + success = true; + } catch { + try vm.parseTomlIntArray(content, path) returns (int256[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Int256, true); + success = true; + } catch {} + } + } else if (ty == TypeKind.Bytes) { + try vm.parseTomlBytes(content, path) returns (bytes memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Bytes, false); + success = true; + } catch { + try vm.parseTomlBytesArray(content, path) returns (bytes[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.Bytes, true); + success = true; + } catch {} + } + } else if (ty == TypeKind.String) { + try vm.parseTomlString(content, path) returns (string memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.String, false); + success = true; + } catch { + try vm.parseTomlStringArray(content, path) returns (string[] memory val) { + _dataOf[chainId][key] = abi.encode(val); + _typeOf[chainId][key] = Type(TypeKind.String, true); + success = true; + } catch {} + } + } + + if (!success) { + revert UnableToParseVariable(key); + } + } + + // -- HELPER FUNCTIONS ----------------------------------------------------- + + /// @notice Enable or disable automatic writing to the TOML file on `set`. + /// Can only be enabled when scripting. + function writeUpdatesBackToFile(bool enabled) public { + if (enabled && !vm.isContext(VmSafe.ForgeContext.ScriptGroup)) { + revert WriteToFileInForbiddenCtxt(); + } + + _writeToFile = enabled; + } + + /// @notice Resolves a chain alias or a chain id string to its numerical chain id. + /// @param aliasOrId The string representing the chain alias (i.e. "mainnet") or a numerical ID (i.e. "1"). + /// @return The numerical chain ID. + /// @dev It first attempts to parse the input as a number. If that fails, it uses `vm.getChain` to resolve a named alias. + /// Reverts if the alias is not valid or not a number. + function resolveChainId(string memory aliasOrId) public view returns (uint256) { + try vm.parseUint(aliasOrId) returns (uint256 chainId) { + return chainId; + } catch { + try vm.getChain(aliasOrId) returns (VmSafe.Chain memory chainInfo) { + return chainInfo.chainId; + } catch { + revert InvalidChainKey(aliasOrId); + } + } + } + + /// @dev Retrieves the chain key/alias from the configuration based on the chain ID. + function _getChainKeyFromId(uint256 chainId) private view returns (string memory) { + for (uint256 i = 0; i < _chainKeys.length; i++) { + if (resolveChainId(_chainKeys[i]) == chainId) { + return _chainKeys[i]; + } + } + revert ChainNotInitialized(chainId); + } + + /// @dev Ensures type consistency when setting a value - prevents changing types unless uninitialized. + /// Updates type only when the previous type was `None`. + function _ensureTypeConsistency(uint256 chainId, string memory key, Type memory ty) private { + Type memory current = _typeOf[chainId][key]; + + if (current.kind == TypeKind.None) { + _typeOf[chainId][key] = ty; + } else { + current.assertEq(ty); + } + } + + /// @dev Wraps a string in double quotes for JSON compatibility. + function _quote(string memory s) private pure returns (string memory) { + return string.concat('"', s, '"'); + } + + /// @dev Writes a JSON-formatted value to a specific key in the TOML file. + /// @param chainId The chain id to write under. + /// @param ty The type category ('bool', 'address', 'uint', 'bytes32', 'string', or 'bytes'). + /// @param key The variable key name. + /// @param jsonValue The JSON-formatted value to write. + function _writeToToml(uint256 chainId, string memory ty, string memory key, string memory jsonValue) private { + string memory chainKey = _getChainKeyFromId(chainId); + string memory valueKey = string.concat("$.", chainKey, ".", ty, ".", key); + vm.writeToml(jsonValue, _filePath, valueKey); + } + + // -- GETTER FUNCTIONS ----------------------------------------------------- + + /// @dev Reads a variable for a given chain id and key, and returns it in a generic container. + /// The caller should use `LibVariable` to safely coerce the type. + /// Example: `uint256 myVar = config.get("my_key").toUint256();` + /// + /// @param chain_id The chain ID to read from. + /// @param key The key of the variable to retrieve. + /// @return `Variable` struct containing the type and the ABI-encoded value. + function get(uint256 chain_id, string memory key) public view returns (Variable memory) { + return Variable(_typeOf[chain_id][key], _dataOf[chain_id][key]); + } + + /// @dev Reads a variable for the current chain and a given key, and returns it in a generic container. + /// The caller should use `LibVariable` to safely coerce the type. + /// Example: `uint256 myVar = config.get("my_key").toUint256();` + /// + /// @param key The key of the variable to retrieve. + /// @return `Variable` struct containing the type and the ABI-encoded value. + function get(string memory key) public view returns (Variable memory) { + return get(vm.getChainId(), key); + } + + /// @notice Returns the numerical chain ids for all configured chains. + function getChainIds() public view returns (uint256[] memory) { + string[] memory keys = _chainKeys; + + uint256[] memory ids = new uint256[](keys.length); + for (uint256 i = 0; i < keys.length; i++) { + ids[i] = resolveChainId(keys[i]); + } + + return ids; + } + + /// @notice Reads the RPC URL for a specific chain id. + function getRpcUrl(uint256 chainId) public view returns (string memory) { + return _rpcOf[chainId]; + } + + /// @notice Reads the RPC URL for the current chain. + function getRpcUrl() public view returns (string memory) { + return _rpcOf[vm.getChainId()]; + } + + // -- SETTER FUNCTIONS (SINGLE VALUES) ------------------------------------- + + /// @notice Sets a boolean value for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, bool value) public { + Type memory ty = Type(TypeKind.Bool, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, vm.toString(value)); + } + + /// @notice Sets a boolean value for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, bool value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets an address value for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, address value) public { + Type memory ty = Type(TypeKind.Address, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, _quote(vm.toString(value))); + } + + /// @notice Sets an address value for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, address value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a bytes32 value for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, bytes32 value) public { + Type memory ty = Type(TypeKind.Bytes32, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, _quote(vm.toString(value))); + } + + /// @notice Sets a bytes32 value for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, bytes32 value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a uint256 value for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, uint256 value) public { + Type memory ty = Type(TypeKind.Uint256, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, vm.toString(value)); + } + + /// @notice Sets a uint256 value for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, uint256 value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets an int256 value for a given key and chain ID. + function set(uint256 chainId, string memory key, int256 value) public { + Type memory ty = Type(TypeKind.Int256, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, vm.toString(value)); + } + + /// @notice Sets an int256 value for a given key on the current chain. + function set(string memory key, int256 value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a string value for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, string memory value) public { + Type memory ty = Type(TypeKind.String, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, _quote(value)); + } + + /// @notice Sets a string value for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, string memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a bytes value for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, bytes memory value) public { + Type memory ty = Type(TypeKind.Bytes, false); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) _writeToToml(chainId, ty.kind.toTomlKey(), key, _quote(vm.toString(value))); + } + + /// @notice Sets a bytes value for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, bytes memory value) public { + set(vm.getChainId(), key, value); + } + + // -- SETTER FUNCTIONS (ARRAYS) -------------------------------------------- + + /// @notice Sets a boolean array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, bool[] memory value) public { + Type memory ty = Type(TypeKind.Bool, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, vm.toString(value[i])); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets a boolean array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, bool[] memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets an address array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, address[] memory value) public { + Type memory ty = Type(TypeKind.Address, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, _quote(vm.toString(value[i]))); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets an address array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, address[] memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a bytes32 array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, bytes32[] memory value) public { + Type memory ty = Type(TypeKind.Bytes32, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, _quote(vm.toString(value[i]))); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets a bytes32 array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, bytes32[] memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a uint256 array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, uint256[] memory value) public { + Type memory ty = Type(TypeKind.Uint256, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, vm.toString(value[i])); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets a uint256 array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, uint256[] memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a int256 array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, int256[] memory value) public { + Type memory ty = Type(TypeKind.Int256, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, vm.toString(value[i])); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets a int256 array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, int256[] memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a string array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, string[] memory value) public { + Type memory ty = Type(TypeKind.String, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, _quote(value[i])); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets a string array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, string[] memory value) public { + set(vm.getChainId(), key, value); + } + + /// @notice Sets a bytes array for a given key and chain ID. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(uint256 chainId, string memory key, bytes[] memory value) public { + Type memory ty = Type(TypeKind.Bytes, true); + _ensureTypeConsistency(chainId, key, ty); + _dataOf[chainId][key] = abi.encode(value); + if (_writeToFile) { + string memory json = "["; + for (uint256 i = 0; i < value.length; i++) { + json = string.concat(json, _quote(vm.toString(value[i]))); + if (i < value.length - 1) json = string.concat(json, ","); + } + json = string.concat(json, "]"); + _writeToToml(chainId, ty.kind.toTomlKey(), key, json); + } + } + + /// @notice Sets a bytes array for a given key on the current chain. + /// @dev Sets the cached value in storage and writes the change back to the TOML file if `autoWrite` is enabled. + function set(string memory key, bytes[] memory value) public { + set(vm.getChainId(), key, value); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdConstants.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdConstants.sol new file mode 100644 index 00000000..2047d2b3 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdConstants.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {IMulticall3} from "./interfaces/IMulticall3.sol"; +import {Vm} from "./Vm.sol"; + +library StdConstants { + /// @dev Cheat code address. + /// Calculated as `address(uint160(uint256(keccak256("hevm cheat code"))))`. + Vm internal constant VM = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + /// @dev console.sol and console2.sol work by executing a staticcall to this address. + /// Calculated as `address(uint160(uint88(bytes11("console.log"))))`. + address internal constant CONSOLE = 0x000000000000000000636F6e736F6c652e6c6f67; + /// @dev Used when deploying with create2. + /// Taken from https://github.com/Arachnid/deterministic-deployment-proxy. + address internal constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + /// @dev The default address for tx.origin and msg.sender. + /// Calculated as `address(uint160(uint256(keccak256("foundry default caller"))))`. + address internal constant DEFAULT_SENDER = 0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38; + /// @dev The address of the first contract `CREATE`d by a running test contract. + /// When running tests, each test contract is `CREATE`d by `DEFAULT_SENDER` with nonce 1. + /// Calculated as `VM.computeCreateAddress(VM.computeCreateAddress(DEFAULT_SENDER, 1), 1)`. + address internal constant DEFAULT_TEST_CONTRACT = 0x5615dEB798BB3E4dFa0139dFa1b3D433Cc23b72f; + /// @dev Deterministic deployment address of the Multicall3 contract. + /// Taken from https://www.multicall3.com. + IMulticall3 internal constant MULTICALL3_ADDRESS = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11); + /// @dev The order of the secp256k1 curve. + uint256 internal constant SECP256K1_ORDER = + 115792089237316195423570985008687907852837564279074904382605163141518161494337; +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdError.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdError.sol new file mode 100644 index 00000000..a302191f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdError.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +// Panics work for versions >=0.8.0, but we lowered the pragma to make this compatible with Test +pragma solidity >=0.6.2 <0.9.0; + +library stdError { + bytes public constant assertionError = abi.encodeWithSignature("Panic(uint256)", 0x01); + bytes public constant arithmeticError = abi.encodeWithSignature("Panic(uint256)", 0x11); + bytes public constant divisionError = abi.encodeWithSignature("Panic(uint256)", 0x12); + bytes public constant enumConversionError = abi.encodeWithSignature("Panic(uint256)", 0x21); + bytes public constant encodeStorageError = abi.encodeWithSignature("Panic(uint256)", 0x22); + bytes public constant popError = abi.encodeWithSignature("Panic(uint256)", 0x31); + bytes public constant indexOOBError = abi.encodeWithSignature("Panic(uint256)", 0x32); + bytes public constant memOverflowError = abi.encodeWithSignature("Panic(uint256)", 0x41); + bytes public constant zeroVarError = abi.encodeWithSignature("Panic(uint256)", 0x51); +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdInvariant.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdInvariant.sol new file mode 100644 index 00000000..056db98f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdInvariant.sol @@ -0,0 +1,122 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +abstract contract StdInvariant { + struct FuzzSelector { + address addr; + bytes4[] selectors; + } + + struct FuzzArtifactSelector { + string artifact; + bytes4[] selectors; + } + + struct FuzzInterface { + address addr; + string[] artifacts; + } + + address[] private _excludedContracts; + address[] private _excludedSenders; + address[] private _targetedContracts; + address[] private _targetedSenders; + + string[] private _excludedArtifacts; + string[] private _targetedArtifacts; + + FuzzArtifactSelector[] private _targetedArtifactSelectors; + + FuzzSelector[] private _excludedSelectors; + FuzzSelector[] private _targetedSelectors; + + FuzzInterface[] private _targetedInterfaces; + + // Functions for users: + // These are intended to be called in tests. + + function excludeContract(address newExcludedContract_) internal { + _excludedContracts.push(newExcludedContract_); + } + + function excludeSelector(FuzzSelector memory newExcludedSelector_) internal { + _excludedSelectors.push(newExcludedSelector_); + } + + function excludeSender(address newExcludedSender_) internal { + _excludedSenders.push(newExcludedSender_); + } + + function excludeArtifact(string memory newExcludedArtifact_) internal { + _excludedArtifacts.push(newExcludedArtifact_); + } + + function targetArtifact(string memory newTargetedArtifact_) internal { + _targetedArtifacts.push(newTargetedArtifact_); + } + + function targetArtifactSelector(FuzzArtifactSelector memory newTargetedArtifactSelector_) internal { + _targetedArtifactSelectors.push(newTargetedArtifactSelector_); + } + + function targetContract(address newTargetedContract_) internal { + _targetedContracts.push(newTargetedContract_); + } + + function targetSelector(FuzzSelector memory newTargetedSelector_) internal { + _targetedSelectors.push(newTargetedSelector_); + } + + function targetSender(address newTargetedSender_) internal { + _targetedSenders.push(newTargetedSender_); + } + + function targetInterface(FuzzInterface memory newTargetedInterface_) internal { + _targetedInterfaces.push(newTargetedInterface_); + } + + // Functions for forge: + // These are called by forge to run invariant tests and don't need to be called in tests. + + function excludeArtifacts() public view returns (string[] memory excludedArtifacts_) { + excludedArtifacts_ = _excludedArtifacts; + } + + function excludeContracts() public view returns (address[] memory excludedContracts_) { + excludedContracts_ = _excludedContracts; + } + + function excludeSelectors() public view returns (FuzzSelector[] memory excludedSelectors_) { + excludedSelectors_ = _excludedSelectors; + } + + function excludeSenders() public view returns (address[] memory excludedSenders_) { + excludedSenders_ = _excludedSenders; + } + + function targetArtifacts() public view returns (string[] memory targetedArtifacts_) { + targetedArtifacts_ = _targetedArtifacts; + } + + function targetArtifactSelectors() public view returns (FuzzArtifactSelector[] memory targetedArtifactSelectors_) { + targetedArtifactSelectors_ = _targetedArtifactSelectors; + } + + function targetContracts() public view returns (address[] memory targetedContracts_) { + targetedContracts_ = _targetedContracts; + } + + function targetSelectors() public view returns (FuzzSelector[] memory targetedSelectors_) { + targetedSelectors_ = _targetedSelectors; + } + + function targetSenders() public view returns (address[] memory targetedSenders_) { + targetedSenders_ = _targetedSenders; + } + + function targetInterfaces() public view returns (FuzzInterface[] memory targetedInterfaces_) { + targetedInterfaces_ = _targetedInterfaces; + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdJson.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdJson.sol new file mode 100644 index 00000000..193f89a6 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdJson.sol @@ -0,0 +1,277 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.0 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {VmSafe} from "./Vm.sol"; + +// Helpers for parsing and writing JSON files +// To parse: +// ``` +// using stdJson for string; +// string memory json = vm.readFile(""); +// json.readUint(""); +// ``` +// To write: +// ``` +// using stdJson for string; +// string memory json = "json"; +// json.serialize("a", uint256(123)); +// string memory semiFinal = json.serialize("b", string("test")); +// string memory finalJson = json.serialize("c", semiFinal); +// finalJson.write(""); +// ``` + +library stdJson { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function keyExists(string memory json, string memory key) internal view returns (bool) { + return vm.keyExistsJson(json, key); + } + + function parseRaw(string memory json, string memory key) internal pure returns (bytes memory) { + return vm.parseJson(json, key); + } + + function readUint(string memory json, string memory key) internal pure returns (uint256) { + return vm.parseJsonUint(json, key); + } + + function readUintArray(string memory json, string memory key) internal pure returns (uint256[] memory) { + return vm.parseJsonUintArray(json, key); + } + + function readInt(string memory json, string memory key) internal pure returns (int256) { + return vm.parseJsonInt(json, key); + } + + function readIntArray(string memory json, string memory key) internal pure returns (int256[] memory) { + return vm.parseJsonIntArray(json, key); + } + + function readBytes32(string memory json, string memory key) internal pure returns (bytes32) { + return vm.parseJsonBytes32(json, key); + } + + function readBytes32Array(string memory json, string memory key) internal pure returns (bytes32[] memory) { + return vm.parseJsonBytes32Array(json, key); + } + + function readString(string memory json, string memory key) internal pure returns (string memory) { + return vm.parseJsonString(json, key); + } + + function readStringArray(string memory json, string memory key) internal pure returns (string[] memory) { + return vm.parseJsonStringArray(json, key); + } + + function readAddress(string memory json, string memory key) internal pure returns (address) { + return vm.parseJsonAddress(json, key); + } + + function readAddressArray(string memory json, string memory key) internal pure returns (address[] memory) { + return vm.parseJsonAddressArray(json, key); + } + + function readBool(string memory json, string memory key) internal pure returns (bool) { + return vm.parseJsonBool(json, key); + } + + function readBoolArray(string memory json, string memory key) internal pure returns (bool[] memory) { + return vm.parseJsonBoolArray(json, key); + } + + function readBytes(string memory json, string memory key) internal pure returns (bytes memory) { + return vm.parseJsonBytes(json, key); + } + + function readBytesArray(string memory json, string memory key) internal pure returns (bytes[] memory) { + return vm.parseJsonBytesArray(json, key); + } + + function readUintOr(string memory json, string memory key, uint256 defaultValue) internal view returns (uint256) { + return keyExists(json, key) ? readUint(json, key) : defaultValue; + } + + function readUintArrayOr(string memory json, string memory key, uint256[] memory defaultValue) + internal + view + returns (uint256[] memory) + { + return keyExists(json, key) ? readUintArray(json, key) : defaultValue; + } + + function readIntOr(string memory json, string memory key, int256 defaultValue) internal view returns (int256) { + return keyExists(json, key) ? readInt(json, key) : defaultValue; + } + + function readIntArrayOr(string memory json, string memory key, int256[] memory defaultValue) + internal + view + returns (int256[] memory) + { + return keyExists(json, key) ? readIntArray(json, key) : defaultValue; + } + + function readBytes32Or(string memory json, string memory key, bytes32 defaultValue) + internal + view + returns (bytes32) + { + return keyExists(json, key) ? readBytes32(json, key) : defaultValue; + } + + function readBytes32ArrayOr(string memory json, string memory key, bytes32[] memory defaultValue) + internal + view + returns (bytes32[] memory) + { + return keyExists(json, key) ? readBytes32Array(json, key) : defaultValue; + } + + function readStringOr(string memory json, string memory key, string memory defaultValue) + internal + view + returns (string memory) + { + return keyExists(json, key) ? readString(json, key) : defaultValue; + } + + function readStringArrayOr(string memory json, string memory key, string[] memory defaultValue) + internal + view + returns (string[] memory) + { + return keyExists(json, key) ? readStringArray(json, key) : defaultValue; + } + + function readAddressOr(string memory json, string memory key, address defaultValue) + internal + view + returns (address) + { + return keyExists(json, key) ? readAddress(json, key) : defaultValue; + } + + function readAddressArrayOr(string memory json, string memory key, address[] memory defaultValue) + internal + view + returns (address[] memory) + { + return keyExists(json, key) ? readAddressArray(json, key) : defaultValue; + } + + function readBoolOr(string memory json, string memory key, bool defaultValue) internal view returns (bool) { + return keyExists(json, key) ? readBool(json, key) : defaultValue; + } + + function readBoolArrayOr(string memory json, string memory key, bool[] memory defaultValue) + internal + view + returns (bool[] memory) + { + return keyExists(json, key) ? readBoolArray(json, key) : defaultValue; + } + + function readBytesOr(string memory json, string memory key, bytes memory defaultValue) + internal + view + returns (bytes memory) + { + return keyExists(json, key) ? readBytes(json, key) : defaultValue; + } + + function readBytesArrayOr(string memory json, string memory key, bytes[] memory defaultValue) + internal + view + returns (bytes[] memory) + { + return keyExists(json, key) ? readBytesArray(json, key) : defaultValue; + } + + function serialize(string memory jsonKey, string memory rootObject) internal returns (string memory) { + return vm.serializeJson(jsonKey, rootObject); + } + + function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bool[] memory value) internal returns (string memory) { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256[] memory value) + internal + returns (string memory) + { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256[] memory value) + internal + returns (string memory) + { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address[] memory value) + internal + returns (string memory) + { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string memory value) internal returns (string memory) { + return vm.serializeString(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string[] memory value) + internal + returns (string memory) + { + return vm.serializeString(jsonKey, key, value); + } + + function write(string memory jsonKey, string memory path) internal { + vm.writeJson(jsonKey, path); + } + + function write(string memory jsonKey, string memory path, string memory valueKey) internal { + vm.writeJson(jsonKey, path, valueKey); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdMath.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdMath.sol new file mode 100644 index 00000000..0fe61066 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdMath.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +library stdMath { + int256 private constant INT256_MIN = -57896044618658097711785492504343953926634992332820282019728792003956564819968; + + function abs(int256 a) internal pure returns (uint256) { + // Required or it will fail when `a = type(int256).min` + if (a == INT256_MIN) { + return 57896044618658097711785492504343953926634992332820282019728792003956564819968; + } + + return uint256(a > 0 ? a : -a); + } + + function delta(uint256 a, uint256 b) internal pure returns (uint256) { + return a > b ? a - b : b - a; + } + + function delta(int256 a, int256 b) internal pure returns (uint256) { + // a and b are of the same sign + // this works thanks to two's complement, the left-most bit is the sign bit + if ((a ^ b) > -1) { + return delta(abs(a), abs(b)); + } + + // a and b are of opposite signs + return abs(a) + abs(b); + } + + function percentDelta(uint256 a, uint256 b) internal pure returns (uint256) { + // Prevent division by zero + require(b != 0, "stdMath percentDelta(uint256,uint256): Divisor is zero"); + uint256 absDelta = delta(a, b); + + return absDelta * 1e18 / b; + } + + function percentDelta(int256 a, int256 b) internal pure returns (uint256) { + uint256 absDelta = delta(a, b); + uint256 absB = abs(b); + // Prevent division by zero + require(absB != 0, "stdMath percentDelta(int256,int256): Divisor is zero"); + + return absDelta * 1e18 / absB; + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdStorage.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdStorage.sol new file mode 100644 index 00000000..1627af75 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdStorage.sol @@ -0,0 +1,473 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +import {Vm} from "./Vm.sol"; + +struct FindData { + uint256 slot; + uint256 offsetLeft; + uint256 offsetRight; + bool found; +} + +struct StdStorage { + mapping(address => mapping(bytes4 => mapping(bytes32 => FindData))) finds; + bytes32[] _keys; + bytes4 _sig; + uint256 _depth; + address _target; + bytes32 _set; + bool _enable_packed_slots; + bytes _calldata; +} + +library stdStorageSafe { + event SlotFound(address who, bytes4 fsig, bytes32 keysHash, uint256 slot); + event WARNING_UninitedSlot(address who, uint256 slot); + + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + uint256 constant UINT256_MAX = 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + function sigs(string memory sigStr) internal pure returns (bytes4) { + return bytes4(keccak256(bytes(sigStr))); + } + + function getCallParams(StdStorage storage self) internal view returns (bytes memory) { + if (self._calldata.length == 0) { + return flatten(self._keys); + } else { + return self._calldata; + } + } + + // Calls target contract with configured parameters + function callTarget(StdStorage storage self) internal view returns (bool, bytes32) { + bytes memory cd = abi.encodePacked(self._sig, getCallParams(self)); + (bool success, bytes memory rdat) = self._target.staticcall(cd); + bytes32 result = bytesToBytes32(rdat, 32 * self._depth); + + return (success, result); + } + + // Tries mutating slot value to determine if the targeted value is stored in it. + // If current value is 0, then we are setting slot value to type(uint256).max + // Otherwise, we set it to 0. That way, return value should always be affected. + function checkSlotMutatesCall(StdStorage storage self, bytes32 slot) internal returns (bool) { + bytes32 prevSlotValue = vm.load(self._target, slot); + (bool success, bytes32 prevReturnValue) = callTarget(self); + + bytes32 testVal = prevReturnValue == bytes32(0) ? bytes32(UINT256_MAX) : bytes32(0); + vm.store(self._target, slot, testVal); + + (, bytes32 newReturnValue) = callTarget(self); + + vm.store(self._target, slot, prevSlotValue); + + return (success && (prevReturnValue != newReturnValue)); + } + + // Tries setting one of the bits in slot to 1 until return value changes. + // Index of resulted bit is an offset packed slot has from left/right side + function findOffset(StdStorage storage self, bytes32 slot, bool left) internal returns (bool, uint256) { + for (uint256 offset = 0; offset < 256; offset++) { + uint256 valueToPut = left ? (1 << (255 - offset)) : (1 << offset); + vm.store(self._target, slot, bytes32(valueToPut)); + + (bool success, bytes32 data) = callTarget(self); + + if (success && (uint256(data) > 0)) { + return (true, offset); + } + } + return (false, 0); + } + + function findOffsets(StdStorage storage self, bytes32 slot) internal returns (bool, uint256, uint256) { + bytes32 prevSlotValue = vm.load(self._target, slot); + + (bool foundLeft, uint256 offsetLeft) = findOffset(self, slot, true); + (bool foundRight, uint256 offsetRight) = findOffset(self, slot, false); + + // `findOffset` may mutate slot value, so we are setting it to initial value + vm.store(self._target, slot, prevSlotValue); + return (foundLeft && foundRight, offsetLeft, offsetRight); + } + + function find(StdStorage storage self) internal returns (FindData storage) { + return find(self, true); + } + + /// @notice find an arbitrary storage slot given a function sig, input data, address of the contract and a value to check against + // slot complexity: + // if flat, will be bytes32(uint256(uint)); + // if map, will be keccak256(abi.encode(key, uint(slot))); + // if deep map, will be keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot))))); + // if map struct, will be bytes32(uint256(keccak256(abi.encode(key1, keccak256(abi.encode(key0, uint(slot)))))) + structFieldDepth); + function find(StdStorage storage self, bool _clear) internal returns (FindData storage) { + address who = self._target; + bytes4 fsig = self._sig; + uint256 field_depth = self._depth; + bytes memory params = getCallParams(self); + + // calldata to test against + if (self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found) { + if (_clear) { + clear(self); + } + return self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))]; + } + vm.record(); + (, bytes32 callResult) = callTarget(self); + (bytes32[] memory reads,) = vm.accesses(address(who)); + + if (reads.length == 0) { + revert("stdStorage find(StdStorage): No storage use detected for target."); + } else { + for (uint256 i = reads.length; --i >= 0;) { + bytes32 prev = vm.load(who, reads[i]); + if (prev == bytes32(0)) { + emit WARNING_UninitedSlot(who, uint256(reads[i])); + } + + if (!checkSlotMutatesCall(self, reads[i])) { + continue; + } + + (uint256 offsetLeft, uint256 offsetRight) = (0, 0); + + if (self._enable_packed_slots) { + bool found; + (found, offsetLeft, offsetRight) = findOffsets(self, reads[i]); + if (!found) { + continue; + } + } + + // Check that value between found offsets is equal to the current call result + uint256 curVal = (uint256(prev) & getMaskByOffsets(offsetLeft, offsetRight)) >> offsetRight; + + if (uint256(callResult) != curVal) { + continue; + } + + emit SlotFound(who, fsig, keccak256(abi.encodePacked(params, field_depth)), uint256(reads[i])); + self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))] = + FindData(uint256(reads[i]), offsetLeft, offsetRight, true); + break; + } + } + + require( + self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found, + "stdStorage find(StdStorage): Slot(s) not found." + ); + + if (_clear) { + clear(self); + } + return self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))]; + } + + function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { + self._target = _target; + return self; + } + + function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { + self._sig = _sig; + return self; + } + + function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { + self._sig = sigs(_sig); + return self; + } + + function with_calldata(StdStorage storage self, bytes memory _calldata) internal returns (StdStorage storage) { + self._calldata = _calldata; + return self; + } + + function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { + self._keys.push(bytes32(uint256(uint160(who)))); + return self; + } + + function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { + self._keys.push(bytes32(amt)); + return self; + } + + function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { + self._keys.push(key); + return self; + } + + function enable_packed_slots(StdStorage storage self) internal returns (StdStorage storage) { + self._enable_packed_slots = true; + return self; + } + + function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { + self._depth = _depth; + return self; + } + + function read(StdStorage storage self) private returns (bytes memory) { + FindData storage data = find(self, false); + uint256 mask = getMaskByOffsets(data.offsetLeft, data.offsetRight); + uint256 value = (uint256(vm.load(self._target, bytes32(data.slot))) & mask) >> data.offsetRight; + clear(self); + return abi.encode(value); + } + + function read_bytes32(StdStorage storage self) internal returns (bytes32) { + return abi.decode(read(self), (bytes32)); + } + + function read_bool(StdStorage storage self) internal returns (bool) { + int256 v = read_int(self); + if (v == 0) return false; + if (v == 1) return true; + revert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); + } + + function read_address(StdStorage storage self) internal returns (address) { + return abi.decode(read(self), (address)); + } + + function read_uint(StdStorage storage self) internal returns (uint256) { + return abi.decode(read(self), (uint256)); + } + + function read_int(StdStorage storage self) internal returns (int256) { + return abi.decode(read(self), (int256)); + } + + function parent(StdStorage storage self) internal returns (uint256, bytes32) { + address who = self._target; + uint256 field_depth = self._depth; + vm.startMappingRecording(); + uint256 child = find(self, true).slot - field_depth; + (bool found, bytes32 key, bytes32 parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(child)); + if (!found) { + revert( + "stdStorage read_bool(StdStorage): Cannot find parent. Make sure you give a slot and startMappingRecording() has been called." + ); + } + return (uint256(parent_slot), key); + } + + function root(StdStorage storage self) internal returns (uint256) { + address who = self._target; + uint256 field_depth = self._depth; + vm.startMappingRecording(); + uint256 child = find(self, true).slot - field_depth; + bool found; + bytes32 root_slot; + bytes32 parent_slot; + (found,, parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(child)); + if (!found) { + revert( + "stdStorage read_bool(StdStorage): Cannot find parent. Make sure you give a slot and startMappingRecording() has been called." + ); + } + while (found) { + root_slot = parent_slot; + (found,, parent_slot) = vm.getMappingKeyAndParentOf(who, bytes32(root_slot)); + } + return uint256(root_slot); + } + + function bytesToBytes32(bytes memory b, uint256 offset) private pure returns (bytes32) { + bytes32 out; + + uint256 max = b.length > 32 ? 32 : b.length; + for (uint256 i = 0; i < max; i++) { + out |= bytes32(b[offset + i] & 0xFF) >> (i * 8); + } + return out; + } + + function flatten(bytes32[] memory b) private pure returns (bytes memory) { + bytes memory result = new bytes(b.length * 32); + for (uint256 i = 0; i < b.length; i++) { + bytes32 k = b[i]; + /// @solidity memory-safe-assembly + assembly { + mstore(add(result, add(32, mul(32, i))), k) + } + } + + return result; + } + + function clear(StdStorage storage self) internal { + delete self._target; + delete self._sig; + delete self._keys; + delete self._depth; + delete self._enable_packed_slots; + delete self._calldata; + } + + // Returns mask which contains non-zero bits for values between `offsetLeft` and `offsetRight` + // (slotValue & mask) >> offsetRight will be the value of the given packed variable + function getMaskByOffsets(uint256 offsetLeft, uint256 offsetRight) internal pure returns (uint256 mask) { + // mask = ((1 << (256 - (offsetRight + offsetLeft))) - 1) << offsetRight; + // using assembly because (1 << 256) causes overflow + assembly { + mask := shl(offsetRight, sub(shl(sub(256, add(offsetRight, offsetLeft)), 1), 1)) + } + } + + // Returns slot value with updated packed variable. + function getUpdatedSlotValue(bytes32 curValue, uint256 varValue, uint256 offsetLeft, uint256 offsetRight) + internal + pure + returns (bytes32 newValue) + { + return bytes32((uint256(curValue) & ~getMaskByOffsets(offsetLeft, offsetRight)) | (varValue << offsetRight)); + } +} + +library stdStorage { + Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function sigs(string memory sigStr) internal pure returns (bytes4) { + return stdStorageSafe.sigs(sigStr); + } + + function find(StdStorage storage self) internal returns (uint256) { + return find(self, true); + } + + function find(StdStorage storage self, bool _clear) internal returns (uint256) { + return stdStorageSafe.find(self, _clear).slot; + } + + function target(StdStorage storage self, address _target) internal returns (StdStorage storage) { + return stdStorageSafe.target(self, _target); + } + + function sig(StdStorage storage self, bytes4 _sig) internal returns (StdStorage storage) { + return stdStorageSafe.sig(self, _sig); + } + + function sig(StdStorage storage self, string memory _sig) internal returns (StdStorage storage) { + return stdStorageSafe.sig(self, _sig); + } + + function with_key(StdStorage storage self, address who) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, who); + } + + function with_key(StdStorage storage self, uint256 amt) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, amt); + } + + function with_key(StdStorage storage self, bytes32 key) internal returns (StdStorage storage) { + return stdStorageSafe.with_key(self, key); + } + + function with_calldata(StdStorage storage self, bytes memory _calldata) internal returns (StdStorage storage) { + return stdStorageSafe.with_calldata(self, _calldata); + } + + function enable_packed_slots(StdStorage storage self) internal returns (StdStorage storage) { + return stdStorageSafe.enable_packed_slots(self); + } + + function depth(StdStorage storage self, uint256 _depth) internal returns (StdStorage storage) { + return stdStorageSafe.depth(self, _depth); + } + + function clear(StdStorage storage self) internal { + stdStorageSafe.clear(self); + } + + function checked_write(StdStorage storage self, address who) internal { + checked_write(self, bytes32(uint256(uint160(who)))); + } + + function checked_write(StdStorage storage self, uint256 amt) internal { + checked_write(self, bytes32(amt)); + } + + function checked_write_int(StdStorage storage self, int256 val) internal { + checked_write(self, bytes32(uint256(val))); + } + + function checked_write(StdStorage storage self, bool write) internal { + bytes32 t; + /// @solidity memory-safe-assembly + assembly { + t := write + } + checked_write(self, t); + } + + function checked_write(StdStorage storage self, bytes32 set) internal { + address who = self._target; + bytes4 fsig = self._sig; + uint256 field_depth = self._depth; + bytes memory params = stdStorageSafe.getCallParams(self); + + if (!self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))].found) { + find(self, false); + } + FindData storage data = self.finds[who][fsig][keccak256(abi.encodePacked(params, field_depth))]; + if ((data.offsetLeft + data.offsetRight) > 0) { + uint256 maxVal = 2 ** (256 - (data.offsetLeft + data.offsetRight)); + require( + uint256(set) < maxVal, + string( + abi.encodePacked( + "stdStorage find(StdStorage): Packed slot. We can't fit value greater than ", + vm.toString(maxVal) + ) + ) + ); + } + bytes32 curVal = vm.load(who, bytes32(data.slot)); + bytes32 valToSet = stdStorageSafe.getUpdatedSlotValue(curVal, uint256(set), data.offsetLeft, data.offsetRight); + + vm.store(who, bytes32(data.slot), valToSet); + + (bool success, bytes32 callResult) = stdStorageSafe.callTarget(self); + + if (!success || callResult != set) { + vm.store(who, bytes32(data.slot), curVal); + revert("stdStorage find(StdStorage): Failed to write value."); + } + clear(self); + } + + function read_bytes32(StdStorage storage self) internal returns (bytes32) { + return stdStorageSafe.read_bytes32(self); + } + + function read_bool(StdStorage storage self) internal returns (bool) { + return stdStorageSafe.read_bool(self); + } + + function read_address(StdStorage storage self) internal returns (address) { + return stdStorageSafe.read_address(self); + } + + function read_uint(StdStorage storage self) internal returns (uint256) { + return stdStorageSafe.read_uint(self); + } + + function read_int(StdStorage storage self) internal returns (int256) { + return stdStorageSafe.read_int(self); + } + + function parent(StdStorage storage self) internal returns (uint256, bytes32) { + return stdStorageSafe.parent(self); + } + + function root(StdStorage storage self) internal returns (uint256) { + return stdStorageSafe.root(self); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdStyle.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdStyle.sol new file mode 100644 index 00000000..d371e0c6 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdStyle.sol @@ -0,0 +1,333 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +import {VmSafe} from "./Vm.sol"; + +library StdStyle { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + string constant RED = "\u001b[91m"; + string constant GREEN = "\u001b[92m"; + string constant YELLOW = "\u001b[93m"; + string constant BLUE = "\u001b[94m"; + string constant MAGENTA = "\u001b[95m"; + string constant CYAN = "\u001b[96m"; + string constant BOLD = "\u001b[1m"; + string constant DIM = "\u001b[2m"; + string constant ITALIC = "\u001b[3m"; + string constant UNDERLINE = "\u001b[4m"; + string constant INVERSE = "\u001b[7m"; + string constant RESET = "\u001b[0m"; + + function styleConcat(string memory style, string memory self) private pure returns (string memory) { + return string(abi.encodePacked(style, self, RESET)); + } + + function red(string memory self) internal pure returns (string memory) { + return styleConcat(RED, self); + } + + function red(uint256 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(int256 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(address self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function red(bool self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function redBytes(bytes memory self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function redBytes32(bytes32 self) internal pure returns (string memory) { + return red(vm.toString(self)); + } + + function green(string memory self) internal pure returns (string memory) { + return styleConcat(GREEN, self); + } + + function green(uint256 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(int256 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(address self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function green(bool self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function greenBytes(bytes memory self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function greenBytes32(bytes32 self) internal pure returns (string memory) { + return green(vm.toString(self)); + } + + function yellow(string memory self) internal pure returns (string memory) { + return styleConcat(YELLOW, self); + } + + function yellow(uint256 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(int256 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(address self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellow(bool self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellowBytes(bytes memory self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function yellowBytes32(bytes32 self) internal pure returns (string memory) { + return yellow(vm.toString(self)); + } + + function blue(string memory self) internal pure returns (string memory) { + return styleConcat(BLUE, self); + } + + function blue(uint256 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(int256 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(address self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blue(bool self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blueBytes(bytes memory self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function blueBytes32(bytes32 self) internal pure returns (string memory) { + return blue(vm.toString(self)); + } + + function magenta(string memory self) internal pure returns (string memory) { + return styleConcat(MAGENTA, self); + } + + function magenta(uint256 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(int256 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(address self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magenta(bool self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magentaBytes(bytes memory self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function magentaBytes32(bytes32 self) internal pure returns (string memory) { + return magenta(vm.toString(self)); + } + + function cyan(string memory self) internal pure returns (string memory) { + return styleConcat(CYAN, self); + } + + function cyan(uint256 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(int256 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(address self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyan(bool self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyanBytes(bytes memory self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function cyanBytes32(bytes32 self) internal pure returns (string memory) { + return cyan(vm.toString(self)); + } + + function bold(string memory self) internal pure returns (string memory) { + return styleConcat(BOLD, self); + } + + function bold(uint256 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(int256 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(address self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function bold(bool self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function boldBytes(bytes memory self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function boldBytes32(bytes32 self) internal pure returns (string memory) { + return bold(vm.toString(self)); + } + + function dim(string memory self) internal pure returns (string memory) { + return styleConcat(DIM, self); + } + + function dim(uint256 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(int256 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(address self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dim(bool self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dimBytes(bytes memory self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function dimBytes32(bytes32 self) internal pure returns (string memory) { + return dim(vm.toString(self)); + } + + function italic(string memory self) internal pure returns (string memory) { + return styleConcat(ITALIC, self); + } + + function italic(uint256 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(int256 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(address self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italic(bool self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italicBytes(bytes memory self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function italicBytes32(bytes32 self) internal pure returns (string memory) { + return italic(vm.toString(self)); + } + + function underline(string memory self) internal pure returns (string memory) { + return styleConcat(UNDERLINE, self); + } + + function underline(uint256 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(int256 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(address self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underline(bool self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underlineBytes(bytes memory self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function underlineBytes32(bytes32 self) internal pure returns (string memory) { + return underline(vm.toString(self)); + } + + function inverse(string memory self) internal pure returns (string memory) { + return styleConcat(INVERSE, self); + } + + function inverse(uint256 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(int256 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(address self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverse(bool self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverseBytes(bytes memory self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } + + function inverseBytes32(bytes32 self) internal pure returns (string memory) { + return inverse(vm.toString(self)); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdToml.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdToml.sol new file mode 100644 index 00000000..7ea92e26 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdToml.sol @@ -0,0 +1,277 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.0 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {VmSafe} from "./Vm.sol"; + +// Helpers for parsing and writing TOML files +// To parse: +// ``` +// using stdToml for string; +// string memory toml = vm.readFile(""); +// toml.readUint(""); +// ``` +// To write: +// ``` +// using stdToml for string; +// string memory json = "json"; +// json.serialize("a", uint256(123)); +// string memory semiFinal = json.serialize("b", string("test")); +// string memory finalJson = json.serialize("c", semiFinal); +// finalJson.write(""); +// ``` + +library stdToml { + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function keyExists(string memory toml, string memory key) internal view returns (bool) { + return vm.keyExistsToml(toml, key); + } + + function parseRaw(string memory toml, string memory key) internal pure returns (bytes memory) { + return vm.parseToml(toml, key); + } + + function readUint(string memory toml, string memory key) internal pure returns (uint256) { + return vm.parseTomlUint(toml, key); + } + + function readUintArray(string memory toml, string memory key) internal pure returns (uint256[] memory) { + return vm.parseTomlUintArray(toml, key); + } + + function readInt(string memory toml, string memory key) internal pure returns (int256) { + return vm.parseTomlInt(toml, key); + } + + function readIntArray(string memory toml, string memory key) internal pure returns (int256[] memory) { + return vm.parseTomlIntArray(toml, key); + } + + function readBytes32(string memory toml, string memory key) internal pure returns (bytes32) { + return vm.parseTomlBytes32(toml, key); + } + + function readBytes32Array(string memory toml, string memory key) internal pure returns (bytes32[] memory) { + return vm.parseTomlBytes32Array(toml, key); + } + + function readString(string memory toml, string memory key) internal pure returns (string memory) { + return vm.parseTomlString(toml, key); + } + + function readStringArray(string memory toml, string memory key) internal pure returns (string[] memory) { + return vm.parseTomlStringArray(toml, key); + } + + function readAddress(string memory toml, string memory key) internal pure returns (address) { + return vm.parseTomlAddress(toml, key); + } + + function readAddressArray(string memory toml, string memory key) internal pure returns (address[] memory) { + return vm.parseTomlAddressArray(toml, key); + } + + function readBool(string memory toml, string memory key) internal pure returns (bool) { + return vm.parseTomlBool(toml, key); + } + + function readBoolArray(string memory toml, string memory key) internal pure returns (bool[] memory) { + return vm.parseTomlBoolArray(toml, key); + } + + function readBytes(string memory toml, string memory key) internal pure returns (bytes memory) { + return vm.parseTomlBytes(toml, key); + } + + function readBytesArray(string memory toml, string memory key) internal pure returns (bytes[] memory) { + return vm.parseTomlBytesArray(toml, key); + } + + function readUintOr(string memory toml, string memory key, uint256 defaultValue) internal view returns (uint256) { + return keyExists(toml, key) ? readUint(toml, key) : defaultValue; + } + + function readUintArrayOr(string memory toml, string memory key, uint256[] memory defaultValue) + internal + view + returns (uint256[] memory) + { + return keyExists(toml, key) ? readUintArray(toml, key) : defaultValue; + } + + function readIntOr(string memory toml, string memory key, int256 defaultValue) internal view returns (int256) { + return keyExists(toml, key) ? readInt(toml, key) : defaultValue; + } + + function readIntArrayOr(string memory toml, string memory key, int256[] memory defaultValue) + internal + view + returns (int256[] memory) + { + return keyExists(toml, key) ? readIntArray(toml, key) : defaultValue; + } + + function readBytes32Or(string memory toml, string memory key, bytes32 defaultValue) + internal + view + returns (bytes32) + { + return keyExists(toml, key) ? readBytes32(toml, key) : defaultValue; + } + + function readBytes32ArrayOr(string memory toml, string memory key, bytes32[] memory defaultValue) + internal + view + returns (bytes32[] memory) + { + return keyExists(toml, key) ? readBytes32Array(toml, key) : defaultValue; + } + + function readStringOr(string memory toml, string memory key, string memory defaultValue) + internal + view + returns (string memory) + { + return keyExists(toml, key) ? readString(toml, key) : defaultValue; + } + + function readStringArrayOr(string memory toml, string memory key, string[] memory defaultValue) + internal + view + returns (string[] memory) + { + return keyExists(toml, key) ? readStringArray(toml, key) : defaultValue; + } + + function readAddressOr(string memory toml, string memory key, address defaultValue) + internal + view + returns (address) + { + return keyExists(toml, key) ? readAddress(toml, key) : defaultValue; + } + + function readAddressArrayOr(string memory toml, string memory key, address[] memory defaultValue) + internal + view + returns (address[] memory) + { + return keyExists(toml, key) ? readAddressArray(toml, key) : defaultValue; + } + + function readBoolOr(string memory toml, string memory key, bool defaultValue) internal view returns (bool) { + return keyExists(toml, key) ? readBool(toml, key) : defaultValue; + } + + function readBoolArrayOr(string memory toml, string memory key, bool[] memory defaultValue) + internal + view + returns (bool[] memory) + { + return keyExists(toml, key) ? readBoolArray(toml, key) : defaultValue; + } + + function readBytesOr(string memory toml, string memory key, bytes memory defaultValue) + internal + view + returns (bytes memory) + { + return keyExists(toml, key) ? readBytes(toml, key) : defaultValue; + } + + function readBytesArrayOr(string memory toml, string memory key, bytes[] memory defaultValue) + internal + view + returns (bytes[] memory) + { + return keyExists(toml, key) ? readBytesArray(toml, key) : defaultValue; + } + + function serialize(string memory jsonKey, string memory rootObject) internal returns (string memory) { + return vm.serializeJson(jsonKey, rootObject); + } + + function serialize(string memory jsonKey, string memory key, bool value) internal returns (string memory) { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bool[] memory value) internal returns (string memory) { + return vm.serializeBool(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256 value) internal returns (string memory) { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, uint256[] memory value) + internal + returns (string memory) + { + return vm.serializeUint(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256 value) internal returns (string memory) { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, int256[] memory value) + internal + returns (string memory) + { + return vm.serializeInt(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address value) internal returns (string memory) { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, address[] memory value) + internal + returns (string memory) + { + return vm.serializeAddress(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32 value) internal returns (string memory) { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes32[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes32(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes memory value) internal returns (string memory) { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, bytes[] memory value) + internal + returns (string memory) + { + return vm.serializeBytes(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string memory value) internal returns (string memory) { + return vm.serializeString(jsonKey, key, value); + } + + function serialize(string memory jsonKey, string memory key, string[] memory value) + internal + returns (string memory) + { + return vm.serializeString(jsonKey, key, value); + } + + function write(string memory jsonKey, string memory path) internal { + vm.writeToml(jsonKey, path); + } + + function write(string memory jsonKey, string memory path, string memory valueKey) internal { + vm.writeToml(jsonKey, path, valueKey); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdUtils.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdUtils.sol new file mode 100644 index 00000000..9321df14 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/StdUtils.sol @@ -0,0 +1,208 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {IMulticall3} from "./interfaces/IMulticall3.sol"; +import {VmSafe} from "./Vm.sol"; + +abstract contract StdUtils { + /*////////////////////////////////////////////////////////////////////////// + CONSTANTS + //////////////////////////////////////////////////////////////////////////*/ + + IMulticall3 private constant multicall = IMulticall3(0xcA11bde05977b3631167028862bE2a173976CA11); + VmSafe private constant vm = VmSafe(address(uint160(uint256(keccak256("hevm cheat code"))))); + address private constant CONSOLE2_ADDRESS = 0x000000000000000000636F6e736F6c652e6c6f67; + uint256 private constant INT256_MIN_ABS = + 57896044618658097711785492504343953926634992332820282019728792003956564819968; + uint256 private constant SECP256K1_ORDER = + 115792089237316195423570985008687907852837564279074904382605163141518161494337; + uint256 private constant UINT256_MAX = + 115792089237316195423570985008687907853269984665640564039457584007913129639935; + + // Used by default when deploying with create2, https://github.com/Arachnid/deterministic-deployment-proxy. + address private constant CREATE2_FACTORY = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + + /*////////////////////////////////////////////////////////////////////////// + INTERNAL FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + function _bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) { + require(min <= max, "StdUtils bound(uint256,uint256,uint256): Max is less than min."); + // If x is between min and max, return x directly. This is to ensure that dictionary values + // do not get shifted if the min is nonzero. More info: https://github.com/foundry-rs/forge-std/issues/188 + if (x >= min && x <= max) return x; + + uint256 size = max - min + 1; + + // If the value is 0, 1, 2, 3, wrap that to min, min+1, min+2, min+3. Similarly for the UINT256_MAX side. + // This helps ensure coverage of the min/max values. + if (x <= 3 && size > x) return min + x; + if (x >= UINT256_MAX - 3 && size > UINT256_MAX - x) return max - (UINT256_MAX - x); + + // Otherwise, wrap x into the range [min, max], i.e. the range is inclusive. + if (x > max) { + uint256 diff = x - max; + uint256 rem = diff % size; + if (rem == 0) return max; + result = min + rem - 1; + } else if (x < min) { + uint256 diff = min - x; + uint256 rem = diff % size; + if (rem == 0) return min; + result = max - rem + 1; + } + } + + function bound(uint256 x, uint256 min, uint256 max) internal pure virtual returns (uint256 result) { + result = _bound(x, min, max); + console2_log_StdUtils("Bound result", result); + } + + function _bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) { + require(min <= max, "StdUtils bound(int256,int256,int256): Max is less than min."); + + // Shifting all int256 values to uint256 to use _bound function. The range of two types are: + // int256 : -(2**255) ~ (2**255 - 1) + // uint256: 0 ~ (2**256 - 1) + // So, add 2**255, INT256_MIN_ABS to the integer values. + // + // If the given integer value is -2**255, we cannot use `-uint256(-x)` because of the overflow. + // So, use `~uint256(x) + 1` instead. + uint256 _x = x < 0 ? (INT256_MIN_ABS - ~uint256(x) - 1) : (uint256(x) + INT256_MIN_ABS); + uint256 _min = min < 0 ? (INT256_MIN_ABS - ~uint256(min) - 1) : (uint256(min) + INT256_MIN_ABS); + uint256 _max = max < 0 ? (INT256_MIN_ABS - ~uint256(max) - 1) : (uint256(max) + INT256_MIN_ABS); + + uint256 y = _bound(_x, _min, _max); + + // To move it back to int256 value, subtract INT256_MIN_ABS at here. + result = y < INT256_MIN_ABS ? int256(~(INT256_MIN_ABS - y) + 1) : int256(y - INT256_MIN_ABS); + } + + function bound(int256 x, int256 min, int256 max) internal pure virtual returns (int256 result) { + result = _bound(x, min, max); + console2_log_StdUtils("Bound result", vm.toString(result)); + } + + function boundPrivateKey(uint256 privateKey) internal pure virtual returns (uint256 result) { + result = _bound(privateKey, 1, SECP256K1_ORDER - 1); + } + + function bytesToUint(bytes memory b) internal pure virtual returns (uint256) { + require(b.length <= 32, "StdUtils bytesToUint(bytes): Bytes length exceeds 32."); + return abi.decode(abi.encodePacked(new bytes(32 - b.length), b), (uint256)); + } + + /// @dev Compute the address a contract will be deployed at for a given deployer address and nonce + function computeCreateAddress(address deployer, uint256 nonce) internal pure virtual returns (address) { + console2_log_StdUtils("computeCreateAddress is deprecated. Please use vm.computeCreateAddress instead."); + return vm.computeCreateAddress(deployer, nonce); + } + + function computeCreate2Address(bytes32 salt, bytes32 initcodeHash, address deployer) + internal + pure + virtual + returns (address) + { + console2_log_StdUtils("computeCreate2Address is deprecated. Please use vm.computeCreate2Address instead."); + return vm.computeCreate2Address(salt, initcodeHash, deployer); + } + + /// @dev returns the address of a contract created with CREATE2 using the default CREATE2 deployer + function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) internal pure returns (address) { + console2_log_StdUtils("computeCreate2Address is deprecated. Please use vm.computeCreate2Address instead."); + return vm.computeCreate2Address(salt, initCodeHash); + } + + /// @dev returns the hash of the init code (creation code + no args) used in CREATE2 with no constructor arguments + /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode + function hashInitCode(bytes memory creationCode) internal pure returns (bytes32) { + return hashInitCode(creationCode, ""); + } + + /// @dev returns the hash of the init code (creation code + ABI-encoded args) used in CREATE2 + /// @param creationCode the creation code of a contract C, as returned by type(C).creationCode + /// @param args the ABI-encoded arguments to the constructor of C + function hashInitCode(bytes memory creationCode, bytes memory args) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(creationCode, args)); + } + + // Performs a single call with Multicall3 to query the ERC-20 token balances of the given addresses. + function getTokenBalances(address token, address[] memory addresses) + internal + virtual + returns (uint256[] memory balances) + { + uint256 tokenCodeSize; + assembly { + tokenCodeSize := extcodesize(token) + } + require(tokenCodeSize > 0, "StdUtils getTokenBalances(address,address[]): Token address is not a contract."); + + // ABI encode the aggregate call to Multicall3. + uint256 length = addresses.length; + IMulticall3.Call[] memory calls = new IMulticall3.Call[](length); + for (uint256 i = 0; i < length; ++i) { + // 0x70a08231 = bytes4("balanceOf(address)")) + calls[i] = IMulticall3.Call({target: token, callData: abi.encodeWithSelector(0x70a08231, (addresses[i]))}); + } + + // Make the aggregate call. + (, bytes[] memory returnData) = multicall.aggregate(calls); + + // ABI decode the return data and return the balances. + balances = new uint256[](length); + for (uint256 i = 0; i < length; ++i) { + balances[i] = abi.decode(returnData[i], (uint256)); + } + } + + /*////////////////////////////////////////////////////////////////////////// + PRIVATE FUNCTIONS + //////////////////////////////////////////////////////////////////////////*/ + + function addressFromLast20Bytes(bytes32 bytesValue) private pure returns (address) { + return address(uint160(uint256(bytesValue))); + } + + // This section is used to prevent the compilation of console, which shortens the compilation time when console is + // not used elsewhere. We also trick the compiler into letting us make the console log methods as `pure` to avoid + // any breaking changes to function signatures. + function _castLogPayloadViewToPure(function(bytes memory) internal view fnIn) + internal + pure + returns (function(bytes memory) internal pure fnOut) + { + assembly { + fnOut := fnIn + } + } + + function _sendLogPayload(bytes memory payload) internal pure { + _castLogPayloadViewToPure(_sendLogPayloadView)(payload); + } + + function _sendLogPayloadView(bytes memory payload) private view { + uint256 payloadLength = payload.length; + address consoleAddress = CONSOLE2_ADDRESS; + /// @solidity memory-safe-assembly + assembly { + let payloadStart := add(payload, 32) + let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) + } + } + + function console2_log_StdUtils(string memory p0) private pure { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function console2_log_StdUtils(string memory p0, uint256 p1) private pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); + } + + function console2_log_StdUtils(string memory p0, string memory p1) private pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Test.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Test.sol new file mode 100644 index 00000000..11b18f29 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Test.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +// 💬 ABOUT +// Forge Std's default Test. + +// 🧩 MODULES +import {console} from "./console.sol"; +import {console2} from "./console2.sol"; +import {safeconsole} from "./safeconsole.sol"; +import {StdAssertions} from "./StdAssertions.sol"; +import {StdChains} from "./StdChains.sol"; +import {StdCheats} from "./StdCheats.sol"; +import {StdConstants} from "./StdConstants.sol"; +import {stdError} from "./StdError.sol"; +import {StdInvariant} from "./StdInvariant.sol"; +import {stdJson} from "./StdJson.sol"; +import {stdMath} from "./StdMath.sol"; +import {StdStorage, stdStorage} from "./StdStorage.sol"; +import {StdStyle} from "./StdStyle.sol"; +import {stdToml} from "./StdToml.sol"; +import {StdUtils} from "./StdUtils.sol"; +import {Vm} from "./Vm.sol"; + +// 📦 BOILERPLATE +import {TestBase} from "./Base.sol"; + +// ⭐️ TEST +abstract contract Test is TestBase, StdAssertions, StdChains, StdCheats, StdInvariant, StdUtils { + // Note: IS_TEST() must return true. + bool public IS_TEST = true; +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Vm.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Vm.sol new file mode 100644 index 00000000..d98d0812 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/Vm.sol @@ -0,0 +1,2501 @@ +// Automatically @generated by scripts/vm.py. Do not modify manually. + +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity >=0.6.2 <0.9.0; +pragma experimental ABIEncoderV2; + +/// The `VmSafe` interface does not allow manipulation of the EVM state or other actions that may +/// result in Script simulations differing from on-chain execution. It is recommended to only use +/// these cheats in scripts. +interface VmSafe { + /// A modification applied to either `msg.sender` or `tx.origin`. Returned by `readCallers`. + enum CallerMode { + // No caller modification is currently active. + None, + // A one time broadcast triggered by a `vm.broadcast()` call is currently active. + Broadcast, + // A recurrent broadcast triggered by a `vm.startBroadcast()` call is currently active. + RecurrentBroadcast, + // A one time prank triggered by a `vm.prank()` call is currently active. + Prank, + // A recurrent prank triggered by a `vm.startPrank()` call is currently active. + RecurrentPrank + } + + /// The kind of account access that occurred. + enum AccountAccessKind { + // The account was called. + Call, + // The account was called via delegatecall. + DelegateCall, + // The account was called via callcode. + CallCode, + // The account was called via staticcall. + StaticCall, + // The account was created. + Create, + // The account was selfdestructed. + SelfDestruct, + // Synthetic access indicating the current context has resumed after a previous sub-context (AccountAccess). + Resume, + // The account's balance was read. + Balance, + // The account's codesize was read. + Extcodesize, + // The account's codehash was read. + Extcodehash, + // The account's code was copied. + Extcodecopy + } + + /// Forge execution contexts. + enum ForgeContext { + // Test group execution context (test, coverage or snapshot). + TestGroup, + // `forge test` execution context. + Test, + // `forge coverage` execution context. + Coverage, + // `forge snapshot` execution context. + Snapshot, + // Script group execution context (dry run, broadcast or resume). + ScriptGroup, + // `forge script` execution context. + ScriptDryRun, + // `forge script --broadcast` execution context. + ScriptBroadcast, + // `forge script --resume` execution context. + ScriptResume, + // Unknown `forge` execution context. + Unknown + } + + /// The transaction type (`txType`) of the broadcast. + enum BroadcastTxType { + // Represents a CALL broadcast tx. + Call, + // Represents a CREATE broadcast tx. + Create, + // Represents a CREATE2 broadcast tx. + Create2 + } + + /// An Ethereum log. Returned by `getRecordedLogs`. + struct Log { + // The topics of the log, including the signature, if any. + bytes32[] topics; + // The raw data of the log. + bytes data; + // The address of the log's emitter. + address emitter; + } + + /// An RPC URL and its alias. Returned by `rpcUrlStructs`. + struct Rpc { + // The alias of the RPC URL. + string key; + // The RPC URL. + string url; + } + + /// An RPC log object. Returned by `eth_getLogs`. + struct EthGetLogs { + // The address of the log's emitter. + address emitter; + // The topics of the log, including the signature, if any. + bytes32[] topics; + // The raw data of the log. + bytes data; + // The block hash. + bytes32 blockHash; + // The block number. + uint64 blockNumber; + // The transaction hash. + bytes32 transactionHash; + // The transaction index in the block. + uint64 transactionIndex; + // The log index. + uint256 logIndex; + // Whether the log was removed. + bool removed; + } + + /// A single entry in a directory listing. Returned by `readDir`. + struct DirEntry { + // The error message, if any. + string errorMessage; + // The path of the entry. + string path; + // The depth of the entry. + uint64 depth; + // Whether the entry is a directory. + bool isDir; + // Whether the entry is a symlink. + bool isSymlink; + } + + /// Metadata information about a file. + /// This structure is returned from the `fsMetadata` function and represents known + /// metadata about a file such as its permissions, size, modification + /// times, etc. + struct FsMetadata { + // True if this metadata is for a directory. + bool isDir; + // True if this metadata is for a symlink. + bool isSymlink; + // The size of the file, in bytes, this metadata is for. + uint256 length; + // True if this metadata is for a readonly (unwritable) file. + bool readOnly; + // The last modification time listed in this metadata. + uint256 modified; + // The last access time of this metadata. + uint256 accessed; + // The creation time listed in this metadata. + uint256 created; + } + + /// A wallet with a public and private key. + struct Wallet { + // The wallet's address. + address addr; + // The wallet's public key `X`. + uint256 publicKeyX; + // The wallet's public key `Y`. + uint256 publicKeyY; + // The wallet's private key. + uint256 privateKey; + } + + /// The result of a `tryFfi` call. + struct FfiResult { + // The exit code of the call. + int32 exitCode; + // The optionally hex-decoded `stdout` data. + bytes stdout; + // The `stderr` data. + bytes stderr; + } + + /// Information on the chain and fork. + struct ChainInfo { + // The fork identifier. Set to zero if no fork is active. + uint256 forkId; + // The chain ID of the current fork. + uint256 chainId; + } + + /// Information about a blockchain. + struct Chain { + // The chain name. + string name; + // The chain's Chain ID. + uint256 chainId; + // The chain's alias. (i.e. what gets specified in `foundry.toml`). + string chainAlias; + // A default RPC endpoint for this chain. + string rpcUrl; + } + + /// The result of a `stopAndReturnStateDiff` call. + struct AccountAccess { + // The chain and fork the access occurred. + ChainInfo chainInfo; + // The kind of account access that determines what the account is. + // If kind is Call, DelegateCall, StaticCall or CallCode, then the account is the callee. + // If kind is Create, then the account is the newly created account. + // If kind is SelfDestruct, then the account is the selfdestruct recipient. + // If kind is a Resume, then account represents a account context that has resumed. + AccountAccessKind kind; + // The account that was accessed. + // It's either the account created, callee or a selfdestruct recipient for CREATE, CALL or SELFDESTRUCT. + address account; + // What accessed the account. + address accessor; + // If the account was initialized or empty prior to the access. + // An account is considered initialized if it has code, a + // non-zero nonce, or a non-zero balance. + bool initialized; + // The previous balance of the accessed account. + uint256 oldBalance; + // The potential new balance of the accessed account. + // That is, all balance changes are recorded here, even if reverts occurred. + uint256 newBalance; + // Code of the account deployed by CREATE. + bytes deployedCode; + // Value passed along with the account access + uint256 value; + // Input data provided to the CREATE or CALL + bytes data; + // If this access reverted in either the current or parent context. + bool reverted; + // An ordered list of storage accesses made during an account access operation. + StorageAccess[] storageAccesses; + // Call depth traversed during the recording of state differences + uint64 depth; + // The previous nonce of the accessed account. + uint64 oldNonce; + // The new nonce of the accessed account. + uint64 newNonce; + } + + /// The storage accessed during an `AccountAccess`. + struct StorageAccess { + // The account whose storage was accessed. + address account; + // The slot that was accessed. + bytes32 slot; + // If the access was a write. + bool isWrite; + // The previous value of the slot. + bytes32 previousValue; + // The new value of the slot. + bytes32 newValue; + // If the access was reverted. + bool reverted; + } + + /// Gas used. Returned by `lastCallGas`. + struct Gas { + // The gas limit of the call. + uint64 gasLimit; + // The total gas used. + uint64 gasTotalUsed; + // DEPRECATED: The amount of gas used for memory expansion. Ref: + uint64 gasMemoryUsed; + // The amount of gas refunded. + int64 gasRefunded; + // The amount of gas remaining. + uint64 gasRemaining; + } + + /// The result of the `stopDebugTraceRecording` call + struct DebugStep { + // The stack before executing the step of the run. + // stack\[0\] represents the top of the stack. + // and only stack data relevant to the opcode execution is contained. + uint256[] stack; + // The memory input data before executing the step of the run. + // only input data relevant to the opcode execution is contained. + // e.g. for MLOAD, it will have memory\[offset:offset+32\] copied here. + // the offset value can be get by the stack data. + bytes memoryInput; + // The opcode that was accessed. + uint8 opcode; + // The call depth of the step. + uint64 depth; + // Whether the call end up with out of gas error. + bool isOutOfGas; + // The contract address where the opcode is running + address contractAddr; + } + + /// Represents a transaction's broadcast details. + struct BroadcastTxSummary { + // The hash of the transaction that was broadcasted + bytes32 txHash; + // Represent the type of transaction among CALL, CREATE, CREATE2 + BroadcastTxType txType; + // The address of the contract that was called or created. + // This is address of the contract that is created if the txType is CREATE or CREATE2. + address contractAddress; + // The block number the transaction landed in. + uint64 blockNumber; + // Status of the transaction, retrieved from the transaction receipt. + bool success; + } + + /// Holds a signed EIP-7702 authorization for an authority account to delegate to an implementation. + struct SignedDelegation { + // The y-parity of the recovered secp256k1 signature (0 or 1). + uint8 v; + // First 32 bytes of the signature. + bytes32 r; + // Second 32 bytes of the signature. + bytes32 s; + // The current nonce of the authority account at signing time. + // Used to ensure signature can't be replayed after account nonce changes. + uint64 nonce; + // Address of the contract implementation that will be delegated to. + // Gets encoded into delegation code: 0xef0100 || implementation. + address implementation; + } + + /// Represents a "potential" revert reason from a single subsequent call when using `vm.assumeNoReverts`. + /// Reverts that match will result in a FOUNDRY::ASSUME rejection, whereas unmatched reverts will be surfaced + /// as normal. + struct PotentialRevert { + // The allowed origin of the revert opcode; address(0) allows reverts from any address + address reverter; + // When true, only matches on the beginning of the revert data, otherwise, matches on entire revert data + bool partialMatch; + // The data to use to match encountered reverts + bytes revertData; + } + + /// An EIP-2930 access list item. + struct AccessListItem { + // The address to be added in access list. + address target; + // The storage keys to be added in access list. + bytes32[] storageKeys; + } + + // ======== Crypto ======== + + /// Derives a private key from the name, labels the account with that name, and returns the wallet. + function createWallet(string calldata walletLabel) external returns (Wallet memory wallet); + + /// Generates a wallet from the private key and returns the wallet. + function createWallet(uint256 privateKey) external returns (Wallet memory wallet); + + /// Generates a wallet from the private key, labels the account with that name, and returns the wallet. + function createWallet(uint256 privateKey, string calldata walletLabel) external returns (Wallet memory wallet); + + /// Derive a private key from a provided mnemonic string (or mnemonic file path) + /// at the derivation path `m/44'/60'/0'/0/{index}`. + function deriveKey(string calldata mnemonic, uint32 index) external pure returns (uint256 privateKey); + + /// Derive a private key from a provided mnemonic string (or mnemonic file path) + /// at `{derivationPath}{index}`. + function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index) + external + pure + returns (uint256 privateKey); + + /// Derive a private key from a provided mnemonic string (or mnemonic file path) in the specified language + /// at the derivation path `m/44'/60'/0'/0/{index}`. + function deriveKey(string calldata mnemonic, uint32 index, string calldata language) + external + pure + returns (uint256 privateKey); + + /// Derive a private key from a provided mnemonic string (or mnemonic file path) in the specified language + /// at `{derivationPath}{index}`. + function deriveKey(string calldata mnemonic, string calldata derivationPath, uint32 index, string calldata language) + external + pure + returns (uint256 privateKey); + + /// Derives secp256r1 public key from the provided `privateKey`. + function publicKeyP256(uint256 privateKey) external pure returns (uint256 publicKeyX, uint256 publicKeyY); + + /// Adds a private key to the local forge wallet and returns the address. + function rememberKey(uint256 privateKey) external returns (address keyAddr); + + /// Derive a set number of wallets from a mnemonic at the derivation path `m/44'/60'/0'/0/{0..count}`. + /// The respective private keys are saved to the local forge wallet for later use and their addresses are returned. + function rememberKeys(string calldata mnemonic, string calldata derivationPath, uint32 count) + external + returns (address[] memory keyAddrs); + + /// Derive a set number of wallets from a mnemonic in the specified language at the derivation path `m/44'/60'/0'/0/{0..count}`. + /// The respective private keys are saved to the local forge wallet for later use and their addresses are returned. + function rememberKeys( + string calldata mnemonic, + string calldata derivationPath, + string calldata language, + uint32 count + ) external returns (address[] memory keyAddrs); + + /// Signs data with a `Wallet`. + /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the + /// signature's `s` value, and the recovery id `v` in a single bytes32. + /// This format reduces the signature size from 65 to 64 bytes. + function signCompact(Wallet calldata wallet, bytes32 digest) external returns (bytes32 r, bytes32 vs); + + /// Signs `digest` with `privateKey` using the secp256k1 curve. + /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the + /// signature's `s` value, and the recovery id `v` in a single bytes32. + /// This format reduces the signature size from 65 to 64 bytes. + function signCompact(uint256 privateKey, bytes32 digest) external pure returns (bytes32 r, bytes32 vs); + + /// Signs `digest` with signer provided to script using the secp256k1 curve. + /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the + /// signature's `s` value, and the recovery id `v` in a single bytes32. + /// This format reduces the signature size from 65 to 64 bytes. + /// If `--sender` is provided, the signer with provided address is used, otherwise, + /// if exactly one signer is provided to the script, that signer is used. + /// Raises error if signer passed through `--sender` does not match any unlocked signers or + /// if `--sender` is not provided and not exactly one signer is passed to the script. + function signCompact(bytes32 digest) external pure returns (bytes32 r, bytes32 vs); + + /// Signs `digest` with signer provided to script using the secp256k1 curve. + /// Returns a compact signature (`r`, `vs`) as per EIP-2098, where `vs` encodes both the + /// signature's `s` value, and the recovery id `v` in a single bytes32. + /// This format reduces the signature size from 65 to 64 bytes. + /// Raises error if none of the signers passed into the script have provided address. + function signCompact(address signer, bytes32 digest) external pure returns (bytes32 r, bytes32 vs); + + /// Signs `digest` with `privateKey` using the secp256r1 curve. + function signP256(uint256 privateKey, bytes32 digest) external pure returns (bytes32 r, bytes32 s); + + /// Signs `digest` with `privateKey` on the secp256k1 curve, using the given `nonce` + /// as the raw ephemeral k value in ECDSA (instead of deriving it deterministically). + function signWithNonceUnsafe(uint256 privateKey, bytes32 digest, uint256 nonce) + external + pure + returns (uint8 v, bytes32 r, bytes32 s); + + /// Signs data with a `Wallet`. + function sign(Wallet calldata wallet, bytes32 digest) external returns (uint8 v, bytes32 r, bytes32 s); + + /// Signs `digest` with `privateKey` using the secp256k1 curve. + function sign(uint256 privateKey, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); + + /// Signs `digest` with signer provided to script using the secp256k1 curve. + /// If `--sender` is provided, the signer with provided address is used, otherwise, + /// if exactly one signer is provided to the script, that signer is used. + /// Raises error if signer passed through `--sender` does not match any unlocked signers or + /// if `--sender` is not provided and not exactly one signer is passed to the script. + function sign(bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); + + /// Signs `digest` with signer provided to script using the secp256k1 curve. + /// Raises error if none of the signers passed into the script have provided address. + function sign(address signer, bytes32 digest) external pure returns (uint8 v, bytes32 r, bytes32 s); + + // ======== Environment ======== + + /// Gets the environment variable `name` and parses it as `address`. + /// Reverts if the variable was not found or could not be parsed. + function envAddress(string calldata name) external view returns (address value); + + /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envAddress(string calldata name, string calldata delim) external view returns (address[] memory value); + + /// Gets the environment variable `name` and parses it as `bool`. + /// Reverts if the variable was not found or could not be parsed. + function envBool(string calldata name) external view returns (bool value); + + /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envBool(string calldata name, string calldata delim) external view returns (bool[] memory value); + + /// Gets the environment variable `name` and parses it as `bytes32`. + /// Reverts if the variable was not found or could not be parsed. + function envBytes32(string calldata name) external view returns (bytes32 value); + + /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envBytes32(string calldata name, string calldata delim) external view returns (bytes32[] memory value); + + /// Gets the environment variable `name` and parses it as `bytes`. + /// Reverts if the variable was not found or could not be parsed. + function envBytes(string calldata name) external view returns (bytes memory value); + + /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envBytes(string calldata name, string calldata delim) external view returns (bytes[] memory value); + + /// Gets the environment variable `name` and returns true if it exists, else returns false. + function envExists(string calldata name) external view returns (bool result); + + /// Gets the environment variable `name` and parses it as `int256`. + /// Reverts if the variable was not found or could not be parsed. + function envInt(string calldata name) external view returns (int256 value); + + /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envInt(string calldata name, string calldata delim) external view returns (int256[] memory value); + + /// Gets the environment variable `name` and parses it as `bool`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, bool defaultValue) external view returns (bool value); + + /// Gets the environment variable `name` and parses it as `uint256`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, uint256 defaultValue) external view returns (uint256 value); + + /// Gets the environment variable `name` and parses it as an array of `address`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, address[] calldata defaultValue) + external + view + returns (address[] memory value); + + /// Gets the environment variable `name` and parses it as an array of `bytes32`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, bytes32[] calldata defaultValue) + external + view + returns (bytes32[] memory value); + + /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, string[] calldata defaultValue) + external + view + returns (string[] memory value); + + /// Gets the environment variable `name` and parses it as an array of `bytes`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, bytes[] calldata defaultValue) + external + view + returns (bytes[] memory value); + + /// Gets the environment variable `name` and parses it as `int256`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, int256 defaultValue) external view returns (int256 value); + + /// Gets the environment variable `name` and parses it as `address`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, address defaultValue) external view returns (address value); + + /// Gets the environment variable `name` and parses it as `bytes32`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, bytes32 defaultValue) external view returns (bytes32 value); + + /// Gets the environment variable `name` and parses it as `string`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata defaultValue) external view returns (string memory value); + + /// Gets the environment variable `name` and parses it as `bytes`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, bytes calldata defaultValue) external view returns (bytes memory value); + + /// Gets the environment variable `name` and parses it as an array of `bool`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, bool[] calldata defaultValue) + external + view + returns (bool[] memory value); + + /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, uint256[] calldata defaultValue) + external + view + returns (uint256[] memory value); + + /// Gets the environment variable `name` and parses it as an array of `int256`, delimited by `delim`. + /// Reverts if the variable could not be parsed. + /// Returns `defaultValue` if the variable was not found. + function envOr(string calldata name, string calldata delim, int256[] calldata defaultValue) + external + view + returns (int256[] memory value); + + /// Gets the environment variable `name` and parses it as `string`. + /// Reverts if the variable was not found or could not be parsed. + function envString(string calldata name) external view returns (string memory value); + + /// Gets the environment variable `name` and parses it as an array of `string`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envString(string calldata name, string calldata delim) external view returns (string[] memory value); + + /// Gets the environment variable `name` and parses it as `uint256`. + /// Reverts if the variable was not found or could not be parsed. + function envUint(string calldata name) external view returns (uint256 value); + + /// Gets the environment variable `name` and parses it as an array of `uint256`, delimited by `delim`. + /// Reverts if the variable was not found or could not be parsed. + function envUint(string calldata name, string calldata delim) external view returns (uint256[] memory value); + + /// Returns true if `forge` command was executed in given context. + function isContext(ForgeContext context) external view returns (bool result); + + /// Resolves the env variable placeholders of a given input string. + function resolveEnv(string calldata input) external returns (string memory); + + /// Sets environment variables. + function setEnv(string calldata name, string calldata value) external; + + // ======== EVM ======== + + /// Gets all accessed reads and write slot from a `vm.record` session, for a given address. + function accesses(address target) external view returns (bytes32[] memory readSlots, bytes32[] memory writeSlots); + + /// Gets the address for a given private key. + function addr(uint256 privateKey) external pure returns (address keyAddr); + + /// Gets all the logs according to specified filter. + function eth_getLogs(uint256 fromBlock, uint256 toBlock, address target, bytes32[] calldata topics) + external + view + returns (EthGetLogs[] memory logs); + + /// Gets the current `block.blobbasefee`. + /// You should use this instead of `block.blobbasefee` if you use `vm.blobBaseFee`, as `block.blobbasefee` is assumed to be constant across a transaction, + /// and as a result will get optimized out by the compiler. + /// See https://github.com/foundry-rs/foundry/issues/6180 + function getBlobBaseFee() external view returns (uint256 blobBaseFee); + + /// Gets the current `block.number`. + /// You should use this instead of `block.number` if you use `vm.roll`, as `block.number` is assumed to be constant across a transaction, + /// and as a result will get optimized out by the compiler. + /// See https://github.com/foundry-rs/foundry/issues/6180 + function getBlockNumber() external view returns (uint256 height); + + /// Gets the current `block.timestamp`. + /// You should use this instead of `block.timestamp` if you use `vm.warp`, as `block.timestamp` is assumed to be constant across a transaction, + /// and as a result will get optimized out by the compiler. + /// See https://github.com/foundry-rs/foundry/issues/6180 + function getBlockTimestamp() external view returns (uint256 timestamp); + + /// Gets the current `block.chainid` of the currently selected environment. + /// You should use this instead of `block.chainid` if you use `vm.selectFork` or `vm.createSelectFork`, as `block.chainid` could be assumed + /// to be constant across a transaction, and as a result will get optimized out by the compiler. + /// See https://github.com/foundry-rs/foundry/issues/6180 + function getChainId() external view returns (uint256 blockChainId); + + /// Returns the test or script execution evm version. + /// **Note:** The execution evm version is not the same as the compilation one. + function getEvmVersion() external pure returns (string memory evm); + + /// Gets the map key and parent of a mapping at a given slot, for a given address. + function getMappingKeyAndParentOf(address target, bytes32 elementSlot) + external + view + returns (bool found, bytes32 key, bytes32 parent); + + /// Gets the number of elements in the mapping at the given slot, for a given address. + function getMappingLength(address target, bytes32 mappingSlot) external view returns (uint256 length); + + /// Gets the elements at index idx of the mapping at the given slot, for a given address. The + /// index must be less than the length of the mapping (i.e. the number of keys in the mapping). + function getMappingSlotAt(address target, bytes32 mappingSlot, uint256 idx) external view returns (bytes32 value); + + /// Gets the nonce of an account. + function getNonce(address account) external view returns (uint64 nonce); + + /// Get the nonce of a `Wallet`. + function getNonce(Wallet calldata wallet) external view returns (uint64 nonce); + + /// Gets the RLP encoded block header for a given block number. + /// Returns the block header in the same format as `cast block --raw`. + function getRawBlockHeader(uint256 blockNumber) external view returns (bytes memory rlpHeader); + + /// Gets all the recorded logs. + function getRecordedLogs() external view returns (Log[] memory logs); + + /// Returns state diffs from current `vm.startStateDiffRecording` session. + function getStateDiff() external view returns (string memory diff); + + /// Returns state diffs from current `vm.startStateDiffRecording` session, in json format. + function getStateDiffJson() external view returns (string memory diff); + + /// Returns an array of `StorageAccess` from current `vm.stateStateDiffRecording` session + function getStorageAccesses() external view returns (StorageAccess[] memory storageAccesses); + + /// Returns an array of storage slots occupied by the specified variable. + function getStorageSlots(address target, string calldata variableName) + external + view + returns (uint256[] memory slots); + + /// Gets the gas used in the last call from the callee perspective. + function lastCallGas() external view returns (Gas memory gas); + + /// Loads a storage slot from an address. + function load(address target, bytes32 slot) external view returns (bytes32 data); + + /// Pauses gas metering (i.e. gas usage is not counted). Noop if already paused. + function pauseGasMetering() external; + + /// Records all storage reads and writes. Use `accesses` to get the recorded data. + /// Subsequent calls to `record` will clear the previous data. + function record() external; + + /// Record all the transaction logs. + function recordLogs() external; + + /// Reset gas metering (i.e. gas usage is set to gas limit). + function resetGasMetering() external; + + /// Resumes gas metering (i.e. gas usage is counted again). Noop if already on. + function resumeGasMetering() external; + + /// Performs an Ethereum JSON-RPC request to the current fork URL. + function rpc(string calldata method, string calldata params) external returns (bytes memory data); + + /// Performs an Ethereum JSON-RPC request to the given endpoint. + function rpc(string calldata urlOrAlias, string calldata method, string calldata params) + external + returns (bytes memory data); + + /// Set the exact test or script execution evm version, e.g. `berlin`, `cancun`. + /// **Note:** The execution evm version is not the same as the compilation one. + function setEvmVersion(string calldata evm) external; + + /// Records the debug trace during the run. + function startDebugTraceRecording() external; + + /// Starts recording all map SSTOREs for later retrieval. + function startMappingRecording() external; + + /// Record all account accesses as part of CREATE, CALL or SELFDESTRUCT opcodes in order, + /// along with the context of the calls + function startStateDiffRecording() external; + + /// Stop debug trace recording and returns the recorded debug trace. + function stopAndReturnDebugTraceRecording() external returns (DebugStep[] memory step); + + /// Returns an ordered array of all account accesses from a `vm.startStateDiffRecording` session. + function stopAndReturnStateDiff() external returns (AccountAccess[] memory accountAccesses); + + /// Stops recording all map SSTOREs for later retrieval and clears the recorded data. + function stopMappingRecording() external; + + /// Stops recording storage reads and writes. + function stopRecord() external; + + // ======== Filesystem ======== + + /// Closes file for reading, resetting the offset and allowing to read it from beginning with readLine. + /// `path` is relative to the project root. + function closeFile(string calldata path) external; + + /// Copies the contents of one file to another. This function will **overwrite** the contents of `to`. + /// On success, the total number of bytes copied is returned and it is equal to the length of the `to` file as reported by `metadata`. + /// Both `from` and `to` are relative to the project root. + function copyFile(string calldata from, string calldata to) external returns (uint64 copied); + + /// Creates a new, empty directory at the provided path. + /// This cheatcode will revert in the following situations, but is not limited to just these cases: + /// - User lacks permissions to modify `path`. + /// - A parent of the given path doesn't exist and `recursive` is false. + /// - `path` already exists and `recursive` is false. + /// `path` is relative to the project root. + function createDir(string calldata path, bool recursive) external; + + /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Reverts if the target artifact contains unlinked library placeholders. + function deployCode(string calldata artifactPath) external returns (address deployedAddress); + + /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Reverts if the target artifact contains unlinked library placeholders. + /// Additionally accepts abi-encoded constructor arguments. + function deployCode(string calldata artifactPath, bytes calldata constructorArgs) + external + returns (address deployedAddress); + + /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Reverts if the target artifact contains unlinked library placeholders. + /// Additionally accepts `msg.value`. + function deployCode(string calldata artifactPath, uint256 value) external returns (address deployedAddress); + + /// Deploys a contract from an artifact file. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Reverts if the target artifact contains unlinked library placeholders. + /// Additionally accepts abi-encoded constructor arguments and `msg.value`. + function deployCode(string calldata artifactPath, bytes calldata constructorArgs, uint256 value) + external + returns (address deployedAddress); + + /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Reverts if the target artifact contains unlinked library placeholders. + function deployCode(string calldata artifactPath, bytes32 salt) external returns (address deployedAddress); + + /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Reverts if the target artifact contains unlinked library placeholders. + /// Additionally accepts abi-encoded constructor arguments. + function deployCode(string calldata artifactPath, bytes calldata constructorArgs, bytes32 salt) + external + returns (address deployedAddress); + + /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Reverts if the target artifact contains unlinked library placeholders. + /// Additionally accepts `msg.value`. + function deployCode(string calldata artifactPath, uint256 value, bytes32 salt) + external + returns (address deployedAddress); + + /// Deploys a contract from an artifact file, using the CREATE2 salt. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + /// Reverts if the target artifact contains unlinked library placeholders. + /// Additionally accepts abi-encoded constructor arguments and `msg.value`. + function deployCode(string calldata artifactPath, bytes calldata constructorArgs, uint256 value, bytes32 salt) + external + returns (address deployedAddress); + + /// Returns true if the given path points to an existing entity, else returns false. + function exists(string calldata path) external view returns (bool result); + + /// Performs a foreign function call via the terminal. + function ffi(string[] calldata commandInput) external returns (bytes memory result); + + /// Given a path, query the file system to get information about a file, directory, etc. + function fsMetadata(string calldata path) external view returns (FsMetadata memory metadata); + + /// Gets the artifact path from code (aka. creation code). + function getArtifactPathByCode(bytes calldata code) external view returns (string memory path); + + /// Gets the artifact path from deployed code (aka. runtime code). + function getArtifactPathByDeployedCode(bytes calldata deployedCode) external view returns (string memory path); + + /// Returns the most recent broadcast for the given contract on `chainId` matching `txType`. + /// For example: + /// The most recent deployment can be fetched by passing `txType` as `CREATE` or `CREATE2`. + /// The most recent call can be fetched by passing `txType` as `CALL`. + function getBroadcast(string calldata contractName, uint64 chainId, BroadcastTxType txType) + external + view + returns (BroadcastTxSummary memory); + + /// Returns all broadcasts for the given contract on `chainId` with the specified `txType`. + /// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber. + function getBroadcasts(string calldata contractName, uint64 chainId, BroadcastTxType txType) + external + view + returns (BroadcastTxSummary[] memory); + + /// Returns all broadcasts for the given contract on `chainId`. + /// Sorted such that the most recent broadcast is the first element, and the oldest is the last. i.e descending order of BroadcastTxSummary.blockNumber. + function getBroadcasts(string calldata contractName, uint64 chainId) + external + view + returns (BroadcastTxSummary[] memory); + + /// Gets the creation bytecode from an artifact file. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + function getCode(string calldata artifactPath) external view returns (bytes memory creationBytecode); + + /// Gets the deployed bytecode from an artifact file. Takes in the relative path to the json file or the path to the + /// artifact in the form of :: where and parts are optional. + function getDeployedCode(string calldata artifactPath) external view returns (bytes memory runtimeBytecode); + + /// Returns the most recent deployment for the current `chainId`. + function getDeployment(string calldata contractName) external view returns (address deployedAddress); + + /// Returns the most recent deployment for the given contract on `chainId` + function getDeployment(string calldata contractName, uint64 chainId) external view returns (address deployedAddress); + + /// Returns all deployments for the given contract on `chainId` + /// Sorted in descending order of deployment time i.e descending order of BroadcastTxSummary.blockNumber. + /// The most recent deployment is the first element, and the oldest is the last. + function getDeployments(string calldata contractName, uint64 chainId) + external + view + returns (address[] memory deployedAddresses); + + /// Returns true if the path exists on disk and is pointing at a directory, else returns false. + function isDir(string calldata path) external view returns (bool result); + + /// Returns true if the path exists on disk and is pointing at a regular file, else returns false. + function isFile(string calldata path) external view returns (bool result); + + /// Get the path of the current project root. + function projectRoot() external view returns (string memory path); + + /// Prompts the user for a string value in the terminal. + function prompt(string calldata promptText) external returns (string memory input); + + /// Prompts the user for an address in the terminal. + function promptAddress(string calldata promptText) external returns (address); + + /// Prompts the user for a hidden string value in the terminal. + function promptSecret(string calldata promptText) external returns (string memory input); + + /// Prompts the user for hidden uint256 in the terminal (usually pk). + function promptSecretUint(string calldata promptText) external returns (uint256); + + /// Prompts the user for uint256 in the terminal. + function promptUint(string calldata promptText) external returns (uint256); + + /// Reads the directory at the given path recursively, up to `maxDepth`. + /// `maxDepth` defaults to 1, meaning only the direct children of the given directory will be returned. + /// Follows symbolic links if `followLinks` is true. + function readDir(string calldata path) external view returns (DirEntry[] memory entries); + + /// See `readDir(string)`. + function readDir(string calldata path, uint64 maxDepth) external view returns (DirEntry[] memory entries); + + /// See `readDir(string)`. + function readDir(string calldata path, uint64 maxDepth, bool followLinks) + external + view + returns (DirEntry[] memory entries); + + /// Reads the entire content of file to string. `path` is relative to the project root. + function readFile(string calldata path) external view returns (string memory data); + + /// Reads the entire content of file as binary. `path` is relative to the project root. + function readFileBinary(string calldata path) external view returns (bytes memory data); + + /// Reads next line of file to string. + function readLine(string calldata path) external view returns (string memory line); + + /// Reads a symbolic link, returning the path that the link points to. + /// This cheatcode will revert in the following situations, but is not limited to just these cases: + /// - `path` is not a symbolic link. + /// - `path` does not exist. + function readLink(string calldata linkPath) external view returns (string memory targetPath); + + /// Removes a directory at the provided path. + /// This cheatcode will revert in the following situations, but is not limited to just these cases: + /// - `path` doesn't exist. + /// - `path` isn't a directory. + /// - User lacks permissions to modify `path`. + /// - The directory is not empty and `recursive` is false. + /// `path` is relative to the project root. + function removeDir(string calldata path, bool recursive) external; + + /// Removes a file from the filesystem. + /// This cheatcode will revert in the following situations, but is not limited to just these cases: + /// - `path` points to a directory. + /// - The file doesn't exist. + /// - The user lacks permissions to remove the file. + /// `path` is relative to the project root. + function removeFile(string calldata path) external; + + /// Performs a foreign function call via terminal and returns the exit code, stdout, and stderr. + function tryFfi(string[] calldata commandInput) external returns (FfiResult memory result); + + /// Returns the time since unix epoch in milliseconds. + function unixTime() external view returns (uint256 milliseconds); + + /// Writes data to file, creating a file if it does not exist, and entirely replacing its contents if it does. + /// `path` is relative to the project root. + function writeFile(string calldata path, string calldata data) external; + + /// Writes binary data to a file, creating a file if it does not exist, and entirely replacing its contents if it does. + /// `path` is relative to the project root. + function writeFileBinary(string calldata path, bytes calldata data) external; + + /// Writes line to file, creating a file if it does not exist. + /// `path` is relative to the project root. + function writeLine(string calldata path, string calldata data) external; + + // ======== JSON ======== + + /// Checks if `key` exists in a JSON object. + function keyExistsJson(string calldata json, string calldata key) external view returns (bool); + + /// Parses a string of JSON data at `key` and coerces it to `address`. + function parseJsonAddress(string calldata json, string calldata key) external pure returns (address); + + /// Parses a string of JSON data at `key` and coerces it to `address[]`. + function parseJsonAddressArray(string calldata json, string calldata key) external pure returns (address[] memory); + + /// Parses a string of JSON data at `key` and coerces it to `bool`. + function parseJsonBool(string calldata json, string calldata key) external pure returns (bool); + + /// Parses a string of JSON data at `key` and coerces it to `bool[]`. + function parseJsonBoolArray(string calldata json, string calldata key) external pure returns (bool[] memory); + + /// Parses a string of JSON data at `key` and coerces it to `bytes`. + function parseJsonBytes(string calldata json, string calldata key) external pure returns (bytes memory); + + /// Parses a string of JSON data at `key` and coerces it to `bytes32`. + function parseJsonBytes32(string calldata json, string calldata key) external pure returns (bytes32); + + /// Parses a string of JSON data at `key` and coerces it to `bytes32[]`. + function parseJsonBytes32Array(string calldata json, string calldata key) external pure returns (bytes32[] memory); + + /// Parses a string of JSON data at `key` and coerces it to `bytes[]`. + function parseJsonBytesArray(string calldata json, string calldata key) external pure returns (bytes[] memory); + + /// Parses a string of JSON data at `key` and coerces it to `int256`. + function parseJsonInt(string calldata json, string calldata key) external pure returns (int256); + + /// Parses a string of JSON data at `key` and coerces it to `int256[]`. + function parseJsonIntArray(string calldata json, string calldata key) external pure returns (int256[] memory); + + /// Returns an array of all the keys in a JSON object. + function parseJsonKeys(string calldata json, string calldata key) external pure returns (string[] memory keys); + + /// Parses a string of JSON data at `key` and coerces it to `string`. + function parseJsonString(string calldata json, string calldata key) external pure returns (string memory); + + /// Parses a string of JSON data at `key` and coerces it to `string[]`. + function parseJsonStringArray(string calldata json, string calldata key) external pure returns (string[] memory); + + /// Parses a string of JSON data at `key` and coerces it to type array corresponding to `typeDescription`. + function parseJsonTypeArray(string calldata json, string calldata key, string calldata typeDescription) + external + pure + returns (bytes memory); + + /// Parses a string of JSON data and coerces it to type corresponding to `typeDescription`. + function parseJsonType(string calldata json, string calldata typeDescription) external pure returns (bytes memory); + + /// Parses a string of JSON data at `key` and coerces it to type corresponding to `typeDescription`. + function parseJsonType(string calldata json, string calldata key, string calldata typeDescription) + external + pure + returns (bytes memory); + + /// Parses a string of JSON data at `key` and coerces it to `uint256`. + function parseJsonUint(string calldata json, string calldata key) external pure returns (uint256); + + /// Parses a string of JSON data at `key` and coerces it to `uint256[]`. + function parseJsonUintArray(string calldata json, string calldata key) external pure returns (uint256[] memory); + + /// ABI-encodes a JSON object. + function parseJson(string calldata json) external pure returns (bytes memory abiEncodedData); + + /// ABI-encodes a JSON object at `key`. + function parseJson(string calldata json, string calldata key) external pure returns (bytes memory abiEncodedData); + + /// See `serializeJson`. + function serializeAddress(string calldata objectKey, string calldata valueKey, address value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeAddress(string calldata objectKey, string calldata valueKey, address[] calldata values) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeBool(string calldata objectKey, string calldata valueKey, bool value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeBool(string calldata objectKey, string calldata valueKey, bool[] calldata values) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32 value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeBytes32(string calldata objectKey, string calldata valueKey, bytes32[] calldata values) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeBytes(string calldata objectKey, string calldata valueKey, bytes calldata value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeBytes(string calldata objectKey, string calldata valueKey, bytes[] calldata values) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeInt(string calldata objectKey, string calldata valueKey, int256 value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeInt(string calldata objectKey, string calldata valueKey, int256[] calldata values) + external + returns (string memory json); + + /// Serializes a key and value to a JSON object stored in-memory that can be later written to a file. + /// Returns the stringified version of the specific JSON file up to that moment. + function serializeJson(string calldata objectKey, string calldata value) external returns (string memory json); + + /// See `serializeJson`. + function serializeJsonType(string calldata typeDescription, bytes calldata value) + external + pure + returns (string memory json); + + /// See `serializeJson`. + function serializeJsonType( + string calldata objectKey, + string calldata valueKey, + string calldata typeDescription, + bytes calldata value + ) external returns (string memory json); + + /// See `serializeJson`. + function serializeString(string calldata objectKey, string calldata valueKey, string calldata value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeString(string calldata objectKey, string calldata valueKey, string[] calldata values) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeUintToHex(string calldata objectKey, string calldata valueKey, uint256 value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeUint(string calldata objectKey, string calldata valueKey, uint256 value) + external + returns (string memory json); + + /// See `serializeJson`. + function serializeUint(string calldata objectKey, string calldata valueKey, uint256[] calldata values) + external + returns (string memory json); + + /// Write a serialized JSON object to a file. If the file exists, it will be overwritten. + function writeJson(string calldata json, string calldata path) external; + + /// Write a serialized JSON object to an **existing** JSON file, replacing a value with key = + /// This is useful to replace a specific value of a JSON file, without having to parse the entire thing. + /// This cheatcode will create new keys if they didn't previously exist. + function writeJson(string calldata json, string calldata path, string calldata valueKey) external; + + /// Checks if `key` exists in a JSON object + /// `keyExists` is being deprecated in favor of `keyExistsJson`. It will be removed in future versions. + function keyExists(string calldata json, string calldata key) external view returns (bool); + + // ======== Scripting ======== + + /// Attach an EIP-4844 blob to the next call + function attachBlob(bytes calldata blob) external; + + /// Designate the next call as an EIP-7702 transaction + function attachDelegation(SignedDelegation calldata signedDelegation) external; + + /// Designate the next call as an EIP-7702 transaction, with optional cross-chain validity. + function attachDelegation(SignedDelegation calldata signedDelegation, bool crossChain) external; + + /// Takes a signed transaction and broadcasts it to the network. + function broadcastRawTransaction(bytes calldata data) external; + + /// Has the next call (at this call depth only) create transactions that can later be signed and sent onchain. + /// Broadcasting address is determined by checking the following in order: + /// 1. If `--sender` argument was provided, that address is used. + /// 2. If exactly one signer (e.g. private key, hw wallet, keystore) is set when `forge broadcast` is invoked, that signer is used. + /// 3. Otherwise, default foundry sender (1804c8AB1F12E6bbf3894d4083f33e07309d1f38) is used. + function broadcast() external; + + /// Has the next call (at this call depth only) create a transaction with the address provided + /// as the sender that can later be signed and sent onchain. + function broadcast(address signer) external; + + /// Has the next call (at this call depth only) create a transaction with the private key + /// provided as the sender that can later be signed and sent onchain. + function broadcast(uint256 privateKey) external; + + /// Returns addresses of available unlocked wallets in the script environment. + function getWallets() external view returns (address[] memory wallets); + + /// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction + function signAndAttachDelegation(address implementation, uint256 privateKey) + external + returns (SignedDelegation memory signedDelegation); + + /// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction for specific nonce + function signAndAttachDelegation(address implementation, uint256 privateKey, uint64 nonce) + external + returns (SignedDelegation memory signedDelegation); + + /// Sign an EIP-7702 authorization and designate the next call as an EIP-7702 transaction, with optional cross-chain validity. + function signAndAttachDelegation(address implementation, uint256 privateKey, bool crossChain) + external + returns (SignedDelegation memory signedDelegation); + + /// Sign an EIP-7702 authorization for delegation + function signDelegation(address implementation, uint256 privateKey) + external + returns (SignedDelegation memory signedDelegation); + + /// Sign an EIP-7702 authorization for delegation for specific nonce + function signDelegation(address implementation, uint256 privateKey, uint64 nonce) + external + returns (SignedDelegation memory signedDelegation); + + /// Sign an EIP-7702 authorization for delegation, with optional cross-chain validity. + function signDelegation(address implementation, uint256 privateKey, bool crossChain) + external + returns (SignedDelegation memory signedDelegation); + + /// Has all subsequent calls (at this call depth only) create transactions that can later be signed and sent onchain. + /// Broadcasting address is determined by checking the following in order: + /// 1. If `--sender` argument was provided, that address is used. + /// 2. If exactly one signer (e.g. private key, hw wallet, keystore) is set when `forge broadcast` is invoked, that signer is used. + /// 3. Otherwise, default foundry sender (1804c8AB1F12E6bbf3894d4083f33e07309d1f38) is used. + function startBroadcast() external; + + /// Has all subsequent calls (at this call depth only) create transactions with the address + /// provided that can later be signed and sent onchain. + function startBroadcast(address signer) external; + + /// Has all subsequent calls (at this call depth only) create transactions with the private key + /// provided that can later be signed and sent onchain. + function startBroadcast(uint256 privateKey) external; + + /// Stops collecting onchain transactions. + function stopBroadcast() external; + + // ======== String ======== + + /// Returns true if `search` is found in `subject`, false otherwise. + function contains(string calldata subject, string calldata search) external pure returns (bool result); + + /// Returns the index of the first occurrence of a `key` in an `input` string. + /// Returns `NOT_FOUND` (i.e. `type(uint256).max`) if the `key` is not found. + /// Returns 0 in case of an empty `key`. + function indexOf(string calldata input, string calldata key) external pure returns (uint256); + + /// Parses the given `string` into an `address`. + function parseAddress(string calldata stringifiedValue) external pure returns (address parsedValue); + + /// Parses the given `string` into a `bool`. + function parseBool(string calldata stringifiedValue) external pure returns (bool parsedValue); + + /// Parses the given `string` into `bytes`. + function parseBytes(string calldata stringifiedValue) external pure returns (bytes memory parsedValue); + + /// Parses the given `string` into a `bytes32`. + function parseBytes32(string calldata stringifiedValue) external pure returns (bytes32 parsedValue); + + /// Parses the given `string` into a `int256`. + function parseInt(string calldata stringifiedValue) external pure returns (int256 parsedValue); + + /// Parses the given `string` into a `uint256`. + function parseUint(string calldata stringifiedValue) external pure returns (uint256 parsedValue); + + /// Replaces occurrences of `from` in the given `string` with `to`. + function replace(string calldata input, string calldata from, string calldata to) + external + pure + returns (string memory output); + + /// Splits the given `string` into an array of strings divided by the `delimiter`. + function split(string calldata input, string calldata delimiter) external pure returns (string[] memory outputs); + + /// Converts the given `string` value to Lowercase. + function toLowercase(string calldata input) external pure returns (string memory output); + + /// Converts the given value to a `string`. + function toString(address value) external pure returns (string memory stringifiedValue); + + /// Converts the given value to a `string`. + function toString(bytes calldata value) external pure returns (string memory stringifiedValue); + + /// Converts the given value to a `string`. + function toString(bytes32 value) external pure returns (string memory stringifiedValue); + + /// Converts the given value to a `string`. + function toString(bool value) external pure returns (string memory stringifiedValue); + + /// Converts the given value to a `string`. + function toString(uint256 value) external pure returns (string memory stringifiedValue); + + /// Converts the given value to a `string`. + function toString(int256 value) external pure returns (string memory stringifiedValue); + + /// Converts the given `string` value to Uppercase. + function toUppercase(string calldata input) external pure returns (string memory output); + + /// Trims leading and trailing whitespace from the given `string` value. + function trim(string calldata input) external pure returns (string memory output); + + // ======== Testing ======== + + /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. + /// Formats values with decimals in failure message. + function assertApproxEqAbsDecimal(uint256 left, uint256 right, uint256 maxDelta, uint256 decimals) external pure; + + /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertApproxEqAbsDecimal( + uint256 left, + uint256 right, + uint256 maxDelta, + uint256 decimals, + string calldata error + ) external pure; + + /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. + /// Formats values with decimals in failure message. + function assertApproxEqAbsDecimal(int256 left, int256 right, uint256 maxDelta, uint256 decimals) external pure; + + /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertApproxEqAbsDecimal( + int256 left, + int256 right, + uint256 maxDelta, + uint256 decimals, + string calldata error + ) external pure; + + /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. + function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta) external pure; + + /// Compares two `uint256` values. Expects difference to be less than or equal to `maxDelta`. + /// Includes error message into revert string on failure. + function assertApproxEqAbs(uint256 left, uint256 right, uint256 maxDelta, string calldata error) external pure; + + /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. + function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta) external pure; + + /// Compares two `int256` values. Expects difference to be less than or equal to `maxDelta`. + /// Includes error message into revert string on failure. + function assertApproxEqAbs(int256 left, int256 right, uint256 maxDelta, string calldata error) external pure; + + /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + /// Formats values with decimals in failure message. + function assertApproxEqRelDecimal(uint256 left, uint256 right, uint256 maxPercentDelta, uint256 decimals) + external + pure; + + /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertApproxEqRelDecimal( + uint256 left, + uint256 right, + uint256 maxPercentDelta, + uint256 decimals, + string calldata error + ) external pure; + + /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + /// Formats values with decimals in failure message. + function assertApproxEqRelDecimal(int256 left, int256 right, uint256 maxPercentDelta, uint256 decimals) + external + pure; + + /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertApproxEqRelDecimal( + int256 left, + int256 right, + uint256 maxPercentDelta, + uint256 decimals, + string calldata error + ) external pure; + + /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + function assertApproxEqRel(uint256 left, uint256 right, uint256 maxPercentDelta) external pure; + + /// Compares two `uint256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + /// Includes error message into revert string on failure. + function assertApproxEqRel(uint256 left, uint256 right, uint256 maxPercentDelta, string calldata error) + external + pure; + + /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta) external pure; + + /// Compares two `int256` values. Expects relative difference in percents to be less than or equal to `maxPercentDelta`. + /// `maxPercentDelta` is an 18 decimal fixed point number, where 1e18 == 100% + /// Includes error message into revert string on failure. + function assertApproxEqRel(int256 left, int256 right, uint256 maxPercentDelta, string calldata error) external pure; + + /// Asserts that two `uint256` values are equal, formatting them with decimals in failure message. + function assertEqDecimal(uint256 left, uint256 right, uint256 decimals) external pure; + + /// Asserts that two `uint256` values are equal, formatting them with decimals in failure message. + /// Includes error message into revert string on failure. + function assertEqDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; + + /// Asserts that two `int256` values are equal, formatting them with decimals in failure message. + function assertEqDecimal(int256 left, int256 right, uint256 decimals) external pure; + + /// Asserts that two `int256` values are equal, formatting them with decimals in failure message. + /// Includes error message into revert string on failure. + function assertEqDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; + + /// Asserts that two `bool` values are equal. + function assertEq(bool left, bool right) external pure; + + /// Asserts that two `bool` values are equal and includes error message into revert string on failure. + function assertEq(bool left, bool right, string calldata error) external pure; + + /// Asserts that two `string` values are equal. + function assertEq(string calldata left, string calldata right) external pure; + + /// Asserts that two `string` values are equal and includes error message into revert string on failure. + function assertEq(string calldata left, string calldata right, string calldata error) external pure; + + /// Asserts that two `bytes` values are equal. + function assertEq(bytes calldata left, bytes calldata right) external pure; + + /// Asserts that two `bytes` values are equal and includes error message into revert string on failure. + function assertEq(bytes calldata left, bytes calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `bool` values are equal. + function assertEq(bool[] calldata left, bool[] calldata right) external pure; + + /// Asserts that two arrays of `bool` values are equal and includes error message into revert string on failure. + function assertEq(bool[] calldata left, bool[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `uint256 values are equal. + function assertEq(uint256[] calldata left, uint256[] calldata right) external pure; + + /// Asserts that two arrays of `uint256` values are equal and includes error message into revert string on failure. + function assertEq(uint256[] calldata left, uint256[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `int256` values are equal. + function assertEq(int256[] calldata left, int256[] calldata right) external pure; + + /// Asserts that two arrays of `int256` values are equal and includes error message into revert string on failure. + function assertEq(int256[] calldata left, int256[] calldata right, string calldata error) external pure; + + /// Asserts that two `uint256` values are equal. + function assertEq(uint256 left, uint256 right) external pure; + + /// Asserts that two arrays of `address` values are equal. + function assertEq(address[] calldata left, address[] calldata right) external pure; + + /// Asserts that two arrays of `address` values are equal and includes error message into revert string on failure. + function assertEq(address[] calldata left, address[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `bytes32` values are equal. + function assertEq(bytes32[] calldata left, bytes32[] calldata right) external pure; + + /// Asserts that two arrays of `bytes32` values are equal and includes error message into revert string on failure. + function assertEq(bytes32[] calldata left, bytes32[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `string` values are equal. + function assertEq(string[] calldata left, string[] calldata right) external pure; + + /// Asserts that two arrays of `string` values are equal and includes error message into revert string on failure. + function assertEq(string[] calldata left, string[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `bytes` values are equal. + function assertEq(bytes[] calldata left, bytes[] calldata right) external pure; + + /// Asserts that two arrays of `bytes` values are equal and includes error message into revert string on failure. + function assertEq(bytes[] calldata left, bytes[] calldata right, string calldata error) external pure; + + /// Asserts that two `uint256` values are equal and includes error message into revert string on failure. + function assertEq(uint256 left, uint256 right, string calldata error) external pure; + + /// Asserts that two `int256` values are equal. + function assertEq(int256 left, int256 right) external pure; + + /// Asserts that two `int256` values are equal and includes error message into revert string on failure. + function assertEq(int256 left, int256 right, string calldata error) external pure; + + /// Asserts that two `address` values are equal. + function assertEq(address left, address right) external pure; + + /// Asserts that two `address` values are equal and includes error message into revert string on failure. + function assertEq(address left, address right, string calldata error) external pure; + + /// Asserts that two `bytes32` values are equal. + function assertEq(bytes32 left, bytes32 right) external pure; + + /// Asserts that two `bytes32` values are equal and includes error message into revert string on failure. + function assertEq(bytes32 left, bytes32 right, string calldata error) external pure; + + /// Asserts that the given condition is false. + function assertFalse(bool condition) external pure; + + /// Asserts that the given condition is false and includes error message into revert string on failure. + function assertFalse(bool condition, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than or equal to second. + /// Formats values with decimals in failure message. + function assertGeDecimal(uint256 left, uint256 right, uint256 decimals) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than or equal to second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertGeDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be greater than or equal to second. + /// Formats values with decimals in failure message. + function assertGeDecimal(int256 left, int256 right, uint256 decimals) external pure; + + /// Compares two `int256` values. Expects first value to be greater than or equal to second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertGeDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than or equal to second. + function assertGe(uint256 left, uint256 right) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than or equal to second. + /// Includes error message into revert string on failure. + function assertGe(uint256 left, uint256 right, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be greater than or equal to second. + function assertGe(int256 left, int256 right) external pure; + + /// Compares two `int256` values. Expects first value to be greater than or equal to second. + /// Includes error message into revert string on failure. + function assertGe(int256 left, int256 right, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than second. + /// Formats values with decimals in failure message. + function assertGtDecimal(uint256 left, uint256 right, uint256 decimals) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertGtDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be greater than second. + /// Formats values with decimals in failure message. + function assertGtDecimal(int256 left, int256 right, uint256 decimals) external pure; + + /// Compares two `int256` values. Expects first value to be greater than second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertGtDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than second. + function assertGt(uint256 left, uint256 right) external pure; + + /// Compares two `uint256` values. Expects first value to be greater than second. + /// Includes error message into revert string on failure. + function assertGt(uint256 left, uint256 right, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be greater than second. + function assertGt(int256 left, int256 right) external pure; + + /// Compares two `int256` values. Expects first value to be greater than second. + /// Includes error message into revert string on failure. + function assertGt(int256 left, int256 right, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be less than or equal to second. + /// Formats values with decimals in failure message. + function assertLeDecimal(uint256 left, uint256 right, uint256 decimals) external pure; + + /// Compares two `uint256` values. Expects first value to be less than or equal to second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertLeDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be less than or equal to second. + /// Formats values with decimals in failure message. + function assertLeDecimal(int256 left, int256 right, uint256 decimals) external pure; + + /// Compares two `int256` values. Expects first value to be less than or equal to second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertLeDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be less than or equal to second. + function assertLe(uint256 left, uint256 right) external pure; + + /// Compares two `uint256` values. Expects first value to be less than or equal to second. + /// Includes error message into revert string on failure. + function assertLe(uint256 left, uint256 right, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be less than or equal to second. + function assertLe(int256 left, int256 right) external pure; + + /// Compares two `int256` values. Expects first value to be less than or equal to second. + /// Includes error message into revert string on failure. + function assertLe(int256 left, int256 right, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be less than second. + /// Formats values with decimals in failure message. + function assertLtDecimal(uint256 left, uint256 right, uint256 decimals) external pure; + + /// Compares two `uint256` values. Expects first value to be less than second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertLtDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be less than second. + /// Formats values with decimals in failure message. + function assertLtDecimal(int256 left, int256 right, uint256 decimals) external pure; + + /// Compares two `int256` values. Expects first value to be less than second. + /// Formats values with decimals in failure message. Includes error message into revert string on failure. + function assertLtDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; + + /// Compares two `uint256` values. Expects first value to be less than second. + function assertLt(uint256 left, uint256 right) external pure; + + /// Compares two `uint256` values. Expects first value to be less than second. + /// Includes error message into revert string on failure. + function assertLt(uint256 left, uint256 right, string calldata error) external pure; + + /// Compares two `int256` values. Expects first value to be less than second. + function assertLt(int256 left, int256 right) external pure; + + /// Compares two `int256` values. Expects first value to be less than second. + /// Includes error message into revert string on failure. + function assertLt(int256 left, int256 right, string calldata error) external pure; + + /// Asserts that two `uint256` values are not equal, formatting them with decimals in failure message. + function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals) external pure; + + /// Asserts that two `uint256` values are not equal, formatting them with decimals in failure message. + /// Includes error message into revert string on failure. + function assertNotEqDecimal(uint256 left, uint256 right, uint256 decimals, string calldata error) external pure; + + /// Asserts that two `int256` values are not equal, formatting them with decimals in failure message. + function assertNotEqDecimal(int256 left, int256 right, uint256 decimals) external pure; + + /// Asserts that two `int256` values are not equal, formatting them with decimals in failure message. + /// Includes error message into revert string on failure. + function assertNotEqDecimal(int256 left, int256 right, uint256 decimals, string calldata error) external pure; + + /// Asserts that two `bool` values are not equal. + function assertNotEq(bool left, bool right) external pure; + + /// Asserts that two `bool` values are not equal and includes error message into revert string on failure. + function assertNotEq(bool left, bool right, string calldata error) external pure; + + /// Asserts that two `string` values are not equal. + function assertNotEq(string calldata left, string calldata right) external pure; + + /// Asserts that two `string` values are not equal and includes error message into revert string on failure. + function assertNotEq(string calldata left, string calldata right, string calldata error) external pure; + + /// Asserts that two `bytes` values are not equal. + function assertNotEq(bytes calldata left, bytes calldata right) external pure; + + /// Asserts that two `bytes` values are not equal and includes error message into revert string on failure. + function assertNotEq(bytes calldata left, bytes calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `bool` values are not equal. + function assertNotEq(bool[] calldata left, bool[] calldata right) external pure; + + /// Asserts that two arrays of `bool` values are not equal and includes error message into revert string on failure. + function assertNotEq(bool[] calldata left, bool[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `uint256` values are not equal. + function assertNotEq(uint256[] calldata left, uint256[] calldata right) external pure; + + /// Asserts that two arrays of `uint256` values are not equal and includes error message into revert string on failure. + function assertNotEq(uint256[] calldata left, uint256[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `int256` values are not equal. + function assertNotEq(int256[] calldata left, int256[] calldata right) external pure; + + /// Asserts that two arrays of `int256` values are not equal and includes error message into revert string on failure. + function assertNotEq(int256[] calldata left, int256[] calldata right, string calldata error) external pure; + + /// Asserts that two `uint256` values are not equal. + function assertNotEq(uint256 left, uint256 right) external pure; + + /// Asserts that two arrays of `address` values are not equal. + function assertNotEq(address[] calldata left, address[] calldata right) external pure; + + /// Asserts that two arrays of `address` values are not equal and includes error message into revert string on failure. + function assertNotEq(address[] calldata left, address[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `bytes32` values are not equal. + function assertNotEq(bytes32[] calldata left, bytes32[] calldata right) external pure; + + /// Asserts that two arrays of `bytes32` values are not equal and includes error message into revert string on failure. + function assertNotEq(bytes32[] calldata left, bytes32[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `string` values are not equal. + function assertNotEq(string[] calldata left, string[] calldata right) external pure; + + /// Asserts that two arrays of `string` values are not equal and includes error message into revert string on failure. + function assertNotEq(string[] calldata left, string[] calldata right, string calldata error) external pure; + + /// Asserts that two arrays of `bytes` values are not equal. + function assertNotEq(bytes[] calldata left, bytes[] calldata right) external pure; + + /// Asserts that two arrays of `bytes` values are not equal and includes error message into revert string on failure. + function assertNotEq(bytes[] calldata left, bytes[] calldata right, string calldata error) external pure; + + /// Asserts that two `uint256` values are not equal and includes error message into revert string on failure. + function assertNotEq(uint256 left, uint256 right, string calldata error) external pure; + + /// Asserts that two `int256` values are not equal. + function assertNotEq(int256 left, int256 right) external pure; + + /// Asserts that two `int256` values are not equal and includes error message into revert string on failure. + function assertNotEq(int256 left, int256 right, string calldata error) external pure; + + /// Asserts that two `address` values are not equal. + function assertNotEq(address left, address right) external pure; + + /// Asserts that two `address` values are not equal and includes error message into revert string on failure. + function assertNotEq(address left, address right, string calldata error) external pure; + + /// Asserts that two `bytes32` values are not equal. + function assertNotEq(bytes32 left, bytes32 right) external pure; + + /// Asserts that two `bytes32` values are not equal and includes error message into revert string on failure. + function assertNotEq(bytes32 left, bytes32 right, string calldata error) external pure; + + /// Asserts that the given condition is true. + function assertTrue(bool condition) external pure; + + /// Asserts that the given condition is true and includes error message into revert string on failure. + function assertTrue(bool condition, string calldata error) external pure; + + /// If the condition is false, discard this run's fuzz inputs and generate new ones. + function assume(bool condition) external pure; + + /// Discard this run's fuzz inputs and generate new ones if next call reverted. + function assumeNoRevert() external pure; + + /// Discard this run's fuzz inputs and generate new ones if next call reverts with the potential revert parameters. + function assumeNoRevert(PotentialRevert calldata potentialRevert) external pure; + + /// Discard this run's fuzz inputs and generate new ones if next call reverts with the any of the potential revert parameters. + function assumeNoRevert(PotentialRevert[] calldata potentialReverts) external pure; + + /// Writes a breakpoint to jump to in the debugger. + function breakpoint(string calldata char) external pure; + + /// Writes a conditional breakpoint to jump to in the debugger. + function breakpoint(string calldata char, bool value) external pure; + + /// Returns true if the current Foundry version is greater than or equal to the given version. + /// The given version string must be in the format `major.minor.patch`. + /// This is equivalent to `foundryVersionCmp(version) >= 0`. + function foundryVersionAtLeast(string calldata version) external view returns (bool); + + /// Compares the current Foundry version with the given version string. + /// The given version string must be in the format `major.minor.patch`. + /// Returns: + /// -1 if current Foundry version is less than the given version + /// 0 if current Foundry version equals the given version + /// 1 if current Foundry version is greater than the given version + /// This result can then be used with a comparison operator against `0`. + /// For example, to check if the current Foundry version is greater than or equal to `1.0.0`: + /// `if (foundryVersionCmp("1.0.0") >= 0) { ... }` + function foundryVersionCmp(string calldata version) external view returns (int256); + + /// Returns a Chain struct for specific alias + function getChain(string calldata chainAlias) external view returns (Chain memory chain); + + /// Returns a Chain struct for specific chainId + function getChain(uint256 chainId) external view returns (Chain memory chain); + + /// Returns the Foundry version. + /// Format: -+.. + /// Sample output: 0.3.0-nightly+3cb96bde9b.1737036656.debug + /// Note: Build timestamps may vary slightly across platforms due to separate CI jobs. + /// For reliable version comparisons, use UNIX format (e.g., >= 1700000000) + /// to compare timestamps while ignoring minor time differences. + function getFoundryVersion() external view returns (string memory version); + + /// Returns the RPC url for the given alias. + function rpcUrl(string calldata rpcAlias) external view returns (string memory json); + + /// Returns all rpc urls and their aliases as structs. + function rpcUrlStructs() external view returns (Rpc[] memory urls); + + /// Returns all rpc urls and their aliases `[alias, url][]`. + function rpcUrls() external view returns (string[2][] memory urls); + + /// Suspends execution of the main thread for `duration` milliseconds. + function sleep(uint256 duration) external; + + // ======== Toml ======== + + /// Checks if `key` exists in a TOML table. + function keyExistsToml(string calldata toml, string calldata key) external view returns (bool); + + /// Parses a string of TOML data at `key` and coerces it to `address`. + function parseTomlAddress(string calldata toml, string calldata key) external pure returns (address); + + /// Parses a string of TOML data at `key` and coerces it to `address[]`. + function parseTomlAddressArray(string calldata toml, string calldata key) external pure returns (address[] memory); + + /// Parses a string of TOML data at `key` and coerces it to `bool`. + function parseTomlBool(string calldata toml, string calldata key) external pure returns (bool); + + /// Parses a string of TOML data at `key` and coerces it to `bool[]`. + function parseTomlBoolArray(string calldata toml, string calldata key) external pure returns (bool[] memory); + + /// Parses a string of TOML data at `key` and coerces it to `bytes`. + function parseTomlBytes(string calldata toml, string calldata key) external pure returns (bytes memory); + + /// Parses a string of TOML data at `key` and coerces it to `bytes32`. + function parseTomlBytes32(string calldata toml, string calldata key) external pure returns (bytes32); + + /// Parses a string of TOML data at `key` and coerces it to `bytes32[]`. + function parseTomlBytes32Array(string calldata toml, string calldata key) external pure returns (bytes32[] memory); + + /// Parses a string of TOML data at `key` and coerces it to `bytes[]`. + function parseTomlBytesArray(string calldata toml, string calldata key) external pure returns (bytes[] memory); + + /// Parses a string of TOML data at `key` and coerces it to `int256`. + function parseTomlInt(string calldata toml, string calldata key) external pure returns (int256); + + /// Parses a string of TOML data at `key` and coerces it to `int256[]`. + function parseTomlIntArray(string calldata toml, string calldata key) external pure returns (int256[] memory); + + /// Returns an array of all the keys in a TOML table. + function parseTomlKeys(string calldata toml, string calldata key) external pure returns (string[] memory keys); + + /// Parses a string of TOML data at `key` and coerces it to `string`. + function parseTomlString(string calldata toml, string calldata key) external pure returns (string memory); + + /// Parses a string of TOML data at `key` and coerces it to `string[]`. + function parseTomlStringArray(string calldata toml, string calldata key) external pure returns (string[] memory); + + /// Parses a string of TOML data at `key` and coerces it to type array corresponding to `typeDescription`. + function parseTomlTypeArray(string calldata toml, string calldata key, string calldata typeDescription) + external + pure + returns (bytes memory); + + /// Parses a string of TOML data and coerces it to type corresponding to `typeDescription`. + function parseTomlType(string calldata toml, string calldata typeDescription) external pure returns (bytes memory); + + /// Parses a string of TOML data at `key` and coerces it to type corresponding to `typeDescription`. + function parseTomlType(string calldata toml, string calldata key, string calldata typeDescription) + external + pure + returns (bytes memory); + + /// Parses a string of TOML data at `key` and coerces it to `uint256`. + function parseTomlUint(string calldata toml, string calldata key) external pure returns (uint256); + + /// Parses a string of TOML data at `key` and coerces it to `uint256[]`. + function parseTomlUintArray(string calldata toml, string calldata key) external pure returns (uint256[] memory); + + /// ABI-encodes a TOML table. + function parseToml(string calldata toml) external pure returns (bytes memory abiEncodedData); + + /// ABI-encodes a TOML table at `key`. + function parseToml(string calldata toml, string calldata key) external pure returns (bytes memory abiEncodedData); + + /// Takes serialized JSON, converts to TOML and write a serialized TOML to a file. + function writeToml(string calldata json, string calldata path) external; + + /// Takes serialized JSON, converts to TOML and write a serialized TOML table to an **existing** TOML file, replacing a value with key = + /// This is useful to replace a specific value of a TOML file, without having to parse the entire thing. + /// This cheatcode will create new keys if they didn't previously exist. + function writeToml(string calldata json, string calldata path, string calldata valueKey) external; + + // ======== Utilities ======== + + /// Returns an uint256 value bounded in given range and different from the current one. + function bound(uint256 current, uint256 min, uint256 max) external view returns (uint256); + + /// Returns an int256 value bounded in given range and different from the current one. + function bound(int256 current, int256 min, int256 max) external view returns (int256); + + /// Compute the address of a contract created with CREATE2 using the given CREATE2 deployer. + function computeCreate2Address(bytes32 salt, bytes32 initCodeHash, address deployer) external pure returns (address); + + /// Compute the address of a contract created with CREATE2 using the default CREATE2 deployer. + function computeCreate2Address(bytes32 salt, bytes32 initCodeHash) external pure returns (address); + + /// Compute the address a contract will be deployed at for a given deployer address and nonce. + function computeCreateAddress(address deployer, uint256 nonce) external pure returns (address); + + /// Utility cheatcode to copy storage of `from` contract to another `to` contract. + function copyStorage(address from, address to) external; + + /// Generates the struct hash of the canonical EIP-712 type representation and its abi-encoded data. + /// Supports 2 different inputs: + /// 1. Name of the type (i.e. "PermitSingle"): + /// * requires previous binding generation with `forge bind-json`. + /// * bindings will be retrieved from the path configured in `foundry.toml`. + /// 2. String representation of the type (i.e. "Foo(Bar bar) Bar(uint256 baz)"). + /// * Note: the cheatcode will use the canonical type even if the input is malformated + /// with the wrong order of elements or with extra whitespaces. + function eip712HashStruct(string calldata typeNameOrDefinition, bytes calldata abiEncodedData) + external + pure + returns (bytes32 typeHash); + + /// Generates the struct hash of the canonical EIP-712 type representation and its abi-encoded data. + /// Requires previous binding generation with `forge bind-json`. + /// Params: + /// * `bindingsPath`: path where the output of `forge bind-json` is stored. + /// * `typeName`: Name of the type (i.e. "PermitSingle"). + /// * `abiEncodedData`: ABI-encoded data for the struct that is being hashed. + function eip712HashStruct(string calldata bindingsPath, string calldata typeName, bytes calldata abiEncodedData) + external + pure + returns (bytes32 typeHash); + + /// Generates the hash of the canonical EIP-712 type representation. + /// Supports 2 different inputs: + /// 1. Name of the type (i.e. "Transaction"): + /// * requires previous binding generation with `forge bind-json`. + /// * bindings will be retrieved from the path configured in `foundry.toml`. + /// 2. String representation of the type (i.e. "Foo(Bar bar) Bar(uint256 baz)"). + /// * Note: the cheatcode will output the canonical type even if the input is malformated + /// with the wrong order of elements or with extra whitespaces. + function eip712HashType(string calldata typeNameOrDefinition) external pure returns (bytes32 typeHash); + + /// Generates the hash of the canonical EIP-712 type representation. + /// Requires previous binding generation with `forge bind-json`. + /// Params: + /// * `bindingsPath`: path where the output of `forge bind-json` is stored. + /// * `typeName`: Name of the type (i.e. "Transaction"). + function eip712HashType(string calldata bindingsPath, string calldata typeName) + external + pure + returns (bytes32 typeHash); + + /// Generates a ready-to-sign digest of human-readable typed data following the EIP-712 standard. + function eip712HashTypedData(string calldata jsonData) external pure returns (bytes32 digest); + + /// Returns ENS namehash for provided string. + function ensNamehash(string calldata name) external pure returns (bytes32); + + /// RLP decodes an RLP payload into a list of bytes. + function fromRlp(bytes calldata rlp) external pure returns (bytes[] memory data); + + /// Gets the label for the specified address. + function getLabel(address account) external view returns (string memory currentLabel); + + /// Labels an address in call traces. + function label(address account, string calldata newLabel) external; + + /// Pauses collection of call traces. Useful in cases when you want to skip tracing of + /// complex calls which are not useful for debugging. + function pauseTracing() external view; + + /// Returns a random `address`. + function randomAddress() external view returns (address); + + /// Returns a random `bool`. + function randomBool() external view returns (bool); + + /// Returns a random byte array value of the given length. + function randomBytes(uint256 len) external view returns (bytes memory); + + /// Returns a random fixed-size byte array of length 4. + function randomBytes4() external view returns (bytes4); + + /// Returns a random fixed-size byte array of length 8. + function randomBytes8() external view returns (bytes8); + + /// Returns a random `int256` value. + function randomInt() external view returns (int256); + + /// Returns a random `int256` value of given bits. + function randomInt(uint256 bits) external view returns (int256); + + /// Returns a random uint256 value. + function randomUint() external view returns (uint256); + + /// Returns random uint256 value between the provided range (=min..=max). + function randomUint(uint256 min, uint256 max) external view returns (uint256); + + /// Returns a random `uint256` value of given bits. + function randomUint(uint256 bits) external view returns (uint256); + + /// Unpauses collection of call traces. + function resumeTracing() external view; + + /// Utility cheatcode to set arbitrary storage for given target address. + function setArbitraryStorage(address target) external; + + /// Utility cheatcode to set arbitrary storage for given target address and overwrite + /// any storage slots that have been previously set. + function setArbitraryStorage(address target, bool overwrite) external; + + /// Set RNG seed. + function setSeed(uint256 seed) external; + + /// Randomly shuffles an array. + function shuffle(uint256[] calldata array) external returns (uint256[] memory); + + /// Sorts an array in ascending order. + function sort(uint256[] calldata array) external returns (uint256[] memory); + + /// Encodes a `bytes` value to a base64url string. + function toBase64URL(bytes calldata data) external pure returns (string memory); + + /// Encodes a `string` value to a base64url string. + function toBase64URL(string calldata data) external pure returns (string memory); + + /// Encodes a `bytes` value to a base64 string. + function toBase64(bytes calldata data) external pure returns (string memory); + + /// Encodes a `string` value to a base64 string. + function toBase64(string calldata data) external pure returns (string memory); + + /// RLP encodes a list of bytes into an RLP payload. + function toRlp(bytes[] calldata data) external pure returns (bytes memory); +} + +/// The `Vm` interface does allow manipulation of the EVM state. These are all intended to be used +/// in tests, but it is not recommended to use these cheats in scripts. +interface Vm is VmSafe { + // ======== EVM ======== + + /// Utility cheatcode to set an EIP-2930 access list for all subsequent transactions. + function accessList(AccessListItem[] calldata access) external; + + /// Returns the identifier of the currently active fork. Reverts if no fork is currently active. + function activeFork() external view returns (uint256 forkId); + + /// In forking mode, explicitly grant the given address cheatcode access. + function allowCheatcodes(address account) external; + + /// Sets `block.blobbasefee` + function blobBaseFee(uint256 newBlobBaseFee) external; + + /// Sets the blobhashes in the transaction. + /// Not available on EVM versions before Cancun. + /// If used on unsupported EVM versions it will revert. + function blobhashes(bytes32[] calldata hashes) external; + + /// Sets `block.chainid`. + function chainId(uint256 newChainId) external; + + /// Clears all mocked calls. + function clearMockedCalls() external; + + /// Clones a source account code, state, balance and nonce to a target account and updates in-memory EVM state. + function cloneAccount(address source, address target) external; + + /// Sets `block.coinbase`. + function coinbase(address newCoinbase) external; + + /// Marks the slots of an account and the account address as cold. + function cool(address target) external; + + /// Utility cheatcode to mark specific storage slot as cold, simulating no prior read. + function coolSlot(address target, bytes32 slot) external; + + /// Creates a new fork with the given endpoint and the _latest_ block and returns the identifier of the fork. + function createFork(string calldata urlOrAlias) external returns (uint256 forkId); + + /// Creates a new fork with the given endpoint and block and returns the identifier of the fork. + function createFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); + + /// Creates a new fork with the given endpoint and at the block the given transaction was mined in, + /// replays all transaction mined in the block before the transaction, and returns the identifier of the fork. + function createFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); + + /// Creates and also selects a new fork with the given endpoint and the latest block and returns the identifier of the fork. + function createSelectFork(string calldata urlOrAlias) external returns (uint256 forkId); + + /// Creates and also selects a new fork with the given endpoint and block and returns the identifier of the fork. + function createSelectFork(string calldata urlOrAlias, uint256 blockNumber) external returns (uint256 forkId); + + /// Creates and also selects new fork with the given endpoint and at the block the given transaction was mined in, + /// replays all transaction mined in the block before the transaction, returns the identifier of the fork. + function createSelectFork(string calldata urlOrAlias, bytes32 txHash) external returns (uint256 forkId); + + /// Sets an address' balance. + function deal(address account, uint256 newBalance) external; + + /// Removes the snapshot with the given ID created by `snapshot`. + /// Takes the snapshot ID to delete. + /// Returns `true` if the snapshot was successfully deleted. + /// Returns `false` if the snapshot does not exist. + function deleteStateSnapshot(uint256 snapshotId) external returns (bool success); + + /// Removes _all_ snapshots previously created by `snapshot`. + function deleteStateSnapshots() external; + + /// Sets `block.difficulty`. + /// Not available on EVM versions from Paris onwards. Use `prevrandao` instead. + /// Reverts if used on unsupported EVM versions. + function difficulty(uint256 newDifficulty) external; + + /// Dump a genesis JSON file's `allocs` to disk. + function dumpState(string calldata pathToStateJson) external; + + /// Sets an address' code. + function etch(address target, bytes calldata newRuntimeBytecode) external; + + /// Sets `block.basefee`. + function fee(uint256 newBasefee) external; + + /// Gets the blockhashes from the current transaction. + /// Not available on EVM versions before Cancun. + /// If used on unsupported EVM versions it will revert. + function getBlobhashes() external view returns (bytes32[] memory hashes); + + /// Returns true if the account is marked as persistent. + function isPersistent(address account) external view returns (bool persistent); + + /// Load a genesis JSON file's `allocs` into the in-memory EVM state. + function loadAllocs(string calldata pathToAllocsJson) external; + + /// Marks that the account(s) should use persistent storage across fork swaps in a multifork setup + /// Meaning, changes made to the state of this account will be kept when switching forks. + function makePersistent(address account) external; + + /// See `makePersistent(address)`. + function makePersistent(address account0, address account1) external; + + /// See `makePersistent(address)`. + function makePersistent(address account0, address account1, address account2) external; + + /// See `makePersistent(address)`. + function makePersistent(address[] calldata accounts) external; + + /// Reverts a call to an address with specified revert data. + function mockCallRevert(address callee, bytes calldata data, bytes calldata revertData) external; + + /// Reverts a call to an address with a specific `msg.value`, with specified revert data. + function mockCallRevert(address callee, uint256 msgValue, bytes calldata data, bytes calldata revertData) external; + + /// Reverts a call to an address with specified revert data. + /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. + function mockCallRevert(address callee, bytes4 data, bytes calldata revertData) external; + + /// Reverts a call to an address with a specific `msg.value`, with specified revert data. + /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. + function mockCallRevert(address callee, uint256 msgValue, bytes4 data, bytes calldata revertData) external; + + /// Mocks a call to an address, returning specified data. + /// Calldata can either be strict or a partial match, e.g. if you only + /// pass a Solidity selector to the expected calldata, then the entire Solidity + /// function will be mocked. + function mockCall(address callee, bytes calldata data, bytes calldata returnData) external; + + /// Mocks a call to an address with a specific `msg.value`, returning specified data. + /// Calldata match takes precedence over `msg.value` in case of ambiguity. + function mockCall(address callee, uint256 msgValue, bytes calldata data, bytes calldata returnData) external; + + /// Mocks a call to an address, returning specified data. + /// Calldata can either be strict or a partial match, e.g. if you only + /// pass a Solidity selector to the expected calldata, then the entire Solidity + /// function will be mocked. + /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. + function mockCall(address callee, bytes4 data, bytes calldata returnData) external; + + /// Mocks a call to an address with a specific `msg.value`, returning specified data. + /// Calldata match takes precedence over `msg.value` in case of ambiguity. + /// Overload to pass the function selector directly `token.approve.selector` instead of `abi.encodeWithSelector(token.approve.selector)`. + function mockCall(address callee, uint256 msgValue, bytes4 data, bytes calldata returnData) external; + + /// Mocks multiple calls to an address, returning specified data for each call. + function mockCalls(address callee, bytes calldata data, bytes[] calldata returnData) external; + + /// Mocks multiple calls to an address with a specific `msg.value`, returning specified data for each call. + function mockCalls(address callee, uint256 msgValue, bytes calldata data, bytes[] calldata returnData) external; + + /// Whenever a call is made to `callee` with calldata `data`, this cheatcode instead calls + /// `target` with the same calldata. This functionality is similar to a delegate call made to + /// `target` contract from `callee`. + /// Can be used to substitute a call to a function with another implementation that captures + /// the primary logic of the original function but is easier to reason about. + /// If calldata is not a strict match then partial match by selector is attempted. + function mockFunction(address callee, address target, bytes calldata data) external; + + /// Utility cheatcode to remove any EIP-2930 access list set by `accessList` cheatcode. + function noAccessList() external; + + /// Sets the *next* call's `msg.sender` to be the input address. + function prank(address msgSender) external; + + /// Sets the *next* call's `msg.sender` to be the input address, and the `tx.origin` to be the second input. + function prank(address msgSender, address txOrigin) external; + + /// Sets the *next* delegate call's `msg.sender` to be the input address. + function prank(address msgSender, bool delegateCall) external; + + /// Sets the *next* delegate call's `msg.sender` to be the input address, and the `tx.origin` to be the second input. + function prank(address msgSender, address txOrigin, bool delegateCall) external; + + /// Sets `block.prevrandao`. + /// Not available on EVM versions before Paris. Use `difficulty` instead. + /// If used on unsupported EVM versions it will revert. + function prevrandao(bytes32 newPrevrandao) external; + + /// Sets `block.prevrandao`. + /// Not available on EVM versions before Paris. Use `difficulty` instead. + /// If used on unsupported EVM versions it will revert. + function prevrandao(uint256 newPrevrandao) external; + + /// Reads the current `msg.sender` and `tx.origin` from state and reports if there is any active caller modification. + function readCallers() external view returns (CallerMode callerMode, address msgSender, address txOrigin); + + /// Resets the nonce of an account to 0 for EOAs and 1 for contract accounts. + function resetNonce(address account) external; + + /// Revert the state of the EVM to a previous snapshot + /// Takes the snapshot ID to revert to. + /// Returns `true` if the snapshot was successfully reverted. + /// Returns `false` if the snapshot does not exist. + /// **Note:** This does not automatically delete the snapshot. To delete the snapshot use `deleteStateSnapshot`. + function revertToState(uint256 snapshotId) external returns (bool success); + + /// Revert the state of the EVM to a previous snapshot and automatically deletes the snapshots + /// Takes the snapshot ID to revert to. + /// Returns `true` if the snapshot was successfully reverted and deleted. + /// Returns `false` if the snapshot does not exist. + function revertToStateAndDelete(uint256 snapshotId) external returns (bool success); + + /// Revokes persistent status from the address, previously added via `makePersistent`. + function revokePersistent(address account) external; + + /// See `revokePersistent(address)`. + function revokePersistent(address[] calldata accounts) external; + + /// Sets `block.height`. + function roll(uint256 newHeight) external; + + /// Updates the currently active fork to given block number + /// This is similar to `roll` but for the currently active fork. + function rollFork(uint256 blockNumber) external; + + /// Updates the currently active fork to given transaction. This will `rollFork` with the number + /// of the block the transaction was mined in and replays all transaction mined before it in the block. + function rollFork(bytes32 txHash) external; + + /// Updates the given fork to given block number. + function rollFork(uint256 forkId, uint256 blockNumber) external; + + /// Updates the given fork to block number of the given transaction and replays all transaction mined before it in the block. + function rollFork(uint256 forkId, bytes32 txHash) external; + + /// Takes a fork identifier created by `createFork` and sets the corresponding forked state as active. + function selectFork(uint256 forkId) external; + + /// Set blockhash for the current block. + /// It only sets the blockhash for blocks where `block.number - 256 <= number < block.number`. + function setBlockhash(uint256 blockNumber, bytes32 blockHash) external; + + /// Sets the nonce of an account. Must be higher than the current nonce of the account. + function setNonce(address account, uint64 newNonce) external; + + /// Sets the nonce of an account to an arbitrary value. + function setNonceUnsafe(address account, uint64 newNonce) external; + + /// Snapshot capture the gas usage of the last call by name from the callee perspective. + function snapshotGasLastCall(string calldata name) external returns (uint256 gasUsed); + + /// Snapshot capture the gas usage of the last call by name in a group from the callee perspective. + function snapshotGasLastCall(string calldata group, string calldata name) external returns (uint256 gasUsed); + + /// Snapshot the current state of the evm. + /// Returns the ID of the snapshot that was created. + /// To revert a snapshot use `revertToState`. + function snapshotState() external returns (uint256 snapshotId); + + /// Snapshot capture an arbitrary numerical value by name. + /// The group name is derived from the contract name. + function snapshotValue(string calldata name, uint256 value) external; + + /// Snapshot capture an arbitrary numerical value by name in a group. + function snapshotValue(string calldata group, string calldata name, uint256 value) external; + + /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called. + function startPrank(address msgSender) external; + + /// Sets all subsequent calls' `msg.sender` to be the input address until `stopPrank` is called, and the `tx.origin` to be the second input. + function startPrank(address msgSender, address txOrigin) external; + + /// Sets all subsequent delegate calls' `msg.sender` to be the input address until `stopPrank` is called. + function startPrank(address msgSender, bool delegateCall) external; + + /// Sets all subsequent delegate calls' `msg.sender` to be the input address until `stopPrank` is called, and the `tx.origin` to be the second input. + function startPrank(address msgSender, address txOrigin, bool delegateCall) external; + + /// Start a snapshot capture of the current gas usage by name. + /// The group name is derived from the contract name. + function startSnapshotGas(string calldata name) external; + + /// Start a snapshot capture of the current gas usage by name in a group. + function startSnapshotGas(string calldata group, string calldata name) external; + + /// Resets subsequent calls' `msg.sender` to be `address(this)`. + function stopPrank() external; + + /// Stop the snapshot capture of the current gas by latest snapshot name, capturing the gas used since the start. + function stopSnapshotGas() external returns (uint256 gasUsed); + + /// Stop the snapshot capture of the current gas usage by name, capturing the gas used since the start. + /// The group name is derived from the contract name. + function stopSnapshotGas(string calldata name) external returns (uint256 gasUsed); + + /// Stop the snapshot capture of the current gas usage by name in a group, capturing the gas used since the start. + function stopSnapshotGas(string calldata group, string calldata name) external returns (uint256 gasUsed); + + /// Stores a value to an address' storage slot. + function store(address target, bytes32 slot, bytes32 value) external; + + /// Fetches the given transaction from the active fork and executes it on the current state. + function transact(bytes32 txHash) external; + + /// Fetches the given transaction from the given fork and executes it on the current state. + function transact(uint256 forkId, bytes32 txHash) external; + + /// Sets `tx.gasprice`. + function txGasPrice(uint256 newGasPrice) external; + + /// Utility cheatcode to mark specific storage slot as warm, simulating a prior read. + function warmSlot(address target, bytes32 slot) external; + + /// Sets `block.timestamp`. + function warp(uint256 newTimestamp) external; + + /// `deleteSnapshot` is being deprecated in favor of `deleteStateSnapshot`. It will be removed in future versions. + function deleteSnapshot(uint256 snapshotId) external returns (bool success); + + /// `deleteSnapshots` is being deprecated in favor of `deleteStateSnapshots`. It will be removed in future versions. + function deleteSnapshots() external; + + /// `revertToAndDelete` is being deprecated in favor of `revertToStateAndDelete`. It will be removed in future versions. + function revertToAndDelete(uint256 snapshotId) external returns (bool success); + + /// `revertTo` is being deprecated in favor of `revertToState`. It will be removed in future versions. + function revertTo(uint256 snapshotId) external returns (bool success); + + /// `snapshot` is being deprecated in favor of `snapshotState`. It will be removed in future versions. + function snapshot() external returns (uint256 snapshotId); + + // ======== Testing ======== + + /// Expect a call to an address with the specified `msg.value` and calldata, and a *minimum* amount of gas. + function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data) external; + + /// Expect given number of calls to an address with the specified `msg.value` and calldata, and a *minimum* amount of gas. + function expectCallMinGas(address callee, uint256 msgValue, uint64 minGas, bytes calldata data, uint64 count) + external; + + /// Expects a call to an address with the specified calldata. + /// Calldata can either be a strict or a partial match. + function expectCall(address callee, bytes calldata data) external; + + /// Expects given number of calls to an address with the specified calldata. + function expectCall(address callee, bytes calldata data, uint64 count) external; + + /// Expects a call to an address with the specified `msg.value` and calldata. + function expectCall(address callee, uint256 msgValue, bytes calldata data) external; + + /// Expects given number of calls to an address with the specified `msg.value` and calldata. + function expectCall(address callee, uint256 msgValue, bytes calldata data, uint64 count) external; + + /// Expect a call to an address with the specified `msg.value`, gas, and calldata. + function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data) external; + + /// Expects given number of calls to an address with the specified `msg.value`, gas, and calldata. + function expectCall(address callee, uint256 msgValue, uint64 gas, bytes calldata data, uint64 count) external; + + /// Expects the deployment of the specified bytecode by the specified address using the CREATE opcode + function expectCreate(bytes calldata bytecode, address deployer) external; + + /// Expects the deployment of the specified bytecode by the specified address using the CREATE2 opcode + function expectCreate2(bytes calldata bytecode, address deployer) external; + + /// Prepare an expected anonymous log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData.). + /// Call this function, then emit an anonymous event, then call a function. Internally after the call, we check if + /// logs were emitted in the expected order with the expected topics and data (as specified by the booleans). + function expectEmitAnonymous(bool checkTopic0, bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) + external; + + /// Same as the previous method, but also checks supplied address against emitting contract. + function expectEmitAnonymous( + bool checkTopic0, + bool checkTopic1, + bool checkTopic2, + bool checkTopic3, + bool checkData, + address emitter + ) external; + + /// Prepare an expected anonymous log with all topic and data checks enabled. + /// Call this function, then emit an anonymous event, then call a function. Internally after the call, we check if + /// logs were emitted in the expected order with the expected topics and data. + function expectEmitAnonymous() external; + + /// Same as the previous method, but also checks supplied address against emitting contract. + function expectEmitAnonymous(address emitter) external; + + /// Prepare an expected log with (bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData.). + /// Call this function, then emit an event, then call a function. Internally after the call, we check if + /// logs were emitted in the expected order with the expected topics and data (as specified by the booleans). + function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData) external; + + /// Same as the previous method, but also checks supplied address against emitting contract. + function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, address emitter) external; + + /// Prepare an expected log with all topic and data checks enabled. + /// Call this function, then emit an event, then call a function. Internally after the call, we check if + /// logs were emitted in the expected order with the expected topics and data. + function expectEmit() external; + + /// Same as the previous method, but also checks supplied address against emitting contract. + function expectEmit(address emitter) external; + + /// Expect a given number of logs with the provided topics. + function expectEmit(bool checkTopic1, bool checkTopic2, bool checkTopic3, bool checkData, uint64 count) external; + + /// Expect a given number of logs from a specific emitter with the provided topics. + function expectEmit( + bool checkTopic1, + bool checkTopic2, + bool checkTopic3, + bool checkData, + address emitter, + uint64 count + ) external; + + /// Expect a given number of logs with all topic and data checks enabled. + function expectEmit(uint64 count) external; + + /// Expect a given number of logs from a specific emitter with all topic and data checks enabled. + function expectEmit(address emitter, uint64 count) external; + + /// Expects an error on next call that starts with the revert data. + function expectPartialRevert(bytes4 revertData) external; + + /// Expects an error on next call to reverter address, that starts with the revert data. + function expectPartialRevert(bytes4 revertData, address reverter) external; + + /// Expects an error on next call with any revert data. + function expectRevert() external; + + /// Expects an error on next call that exactly matches the revert data. + function expectRevert(bytes4 revertData) external; + + /// Expects a `count` number of reverts from the upcoming calls from the reverter address that match the revert data. + function expectRevert(bytes4 revertData, address reverter, uint64 count) external; + + /// Expects a `count` number of reverts from the upcoming calls from the reverter address that exactly match the revert data. + function expectRevert(bytes calldata revertData, address reverter, uint64 count) external; + + /// Expects an error on next call that exactly matches the revert data. + function expectRevert(bytes calldata revertData) external; + + /// Expects an error with any revert data on next call to reverter address. + function expectRevert(address reverter) external; + + /// Expects an error from reverter address on next call, with any revert data. + function expectRevert(bytes4 revertData, address reverter) external; + + /// Expects an error from reverter address on next call, that exactly matches the revert data. + function expectRevert(bytes calldata revertData, address reverter) external; + + /// Expects a `count` number of reverts from the upcoming calls with any revert data or reverter. + function expectRevert(uint64 count) external; + + /// Expects a `count` number of reverts from the upcoming calls that match the revert data. + function expectRevert(bytes4 revertData, uint64 count) external; + + /// Expects a `count` number of reverts from the upcoming calls that exactly match the revert data. + function expectRevert(bytes calldata revertData, uint64 count) external; + + /// Expects a `count` number of reverts from the upcoming calls from the reverter address. + function expectRevert(address reverter, uint64 count) external; + + /// Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the current subcontext. If any other + /// memory is written to, the test will fail. Can be called multiple times to add more ranges to the set. + function expectSafeMemory(uint64 min, uint64 max) external; + + /// Only allows memory writes to offsets [0x00, 0x60) ∪ [min, max) in the next created subcontext. + /// If any other memory is written to, the test will fail. Can be called multiple times to add more ranges + /// to the set. + function expectSafeMemoryCall(uint64 min, uint64 max) external; + + /// Marks a test as skipped. Must be called at the top level of a test. + function skip(bool skipTest) external; + + /// Marks a test as skipped with a reason. Must be called at the top level of a test. + function skip(bool skipTest, string calldata reason) external; + + /// Stops all safe memory expectation in the current subcontext. + function stopExpectSafeMemory() external; + + // ======== Utilities ======== + + /// Causes the next contract creation (via new) to fail and return its initcode in the returndata buffer. + /// This allows type-safe access to the initcode payload that would be used for contract creation. + /// Example usage: + /// vm.interceptInitcode(); + /// bytes memory initcode; + /// try new MyContract(param1, param2) { assert(false); } + /// catch (bytes memory interceptedInitcode) { initcode = interceptedInitcode; } + function interceptInitcode() external; +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/console.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/console.sol new file mode 100644 index 00000000..4fdb6679 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/console.sol @@ -0,0 +1,1560 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +library console { + address constant CONSOLE_ADDRESS = + 0x000000000000000000636F6e736F6c652e6c6f67; + + function _sendLogPayloadImplementation(bytes memory payload) internal view { + address consoleAddress = CONSOLE_ADDRESS; + /// @solidity memory-safe-assembly + assembly { + pop( + staticcall( + gas(), + consoleAddress, + add(payload, 32), + mload(payload), + 0, + 0 + ) + ) + } + } + + function _castToPure( + function(bytes memory) internal view fnIn + ) internal pure returns (function(bytes memory) pure fnOut) { + assembly { + fnOut := fnIn + } + } + + function _sendLogPayload(bytes memory payload) internal pure { + _castToPure(_sendLogPayloadImplementation)(payload); + } + + function log() internal pure { + _sendLogPayload(abi.encodeWithSignature("log()")); + } + + function logInt(int256 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); + } + + function logUint(uint256 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); + } + + function logString(string memory p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function logBool(bool p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function logAddress(address p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function logBytes(bytes memory p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); + } + + function logBytes1(bytes1 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); + } + + function logBytes2(bytes2 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); + } + + function logBytes3(bytes3 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); + } + + function logBytes4(bytes4 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); + } + + function logBytes5(bytes5 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); + } + + function logBytes6(bytes6 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); + } + + function logBytes7(bytes7 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); + } + + function logBytes8(bytes8 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); + } + + function logBytes9(bytes9 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); + } + + function logBytes10(bytes10 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); + } + + function logBytes11(bytes11 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); + } + + function logBytes12(bytes12 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); + } + + function logBytes13(bytes13 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); + } + + function logBytes14(bytes14 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); + } + + function logBytes15(bytes15 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); + } + + function logBytes16(bytes16 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); + } + + function logBytes17(bytes17 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); + } + + function logBytes18(bytes18 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); + } + + function logBytes19(bytes19 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); + } + + function logBytes20(bytes20 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); + } + + function logBytes21(bytes21 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); + } + + function logBytes22(bytes22 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); + } + + function logBytes23(bytes23 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); + } + + function logBytes24(bytes24 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); + } + + function logBytes25(bytes25 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); + } + + function logBytes26(bytes26 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); + } + + function logBytes27(bytes27 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); + } + + function logBytes28(bytes28 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); + } + + function logBytes29(bytes29 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); + } + + function logBytes30(bytes30 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); + } + + function logBytes31(bytes31 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); + } + + function logBytes32(bytes32 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); + } + + function log(uint256 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256)", p0)); + } + + function log(int256 p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(int256)", p0)); + } + + function log(string memory p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function log(bool p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function log(address p0) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function log(uint256 p0, uint256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256)", p0, p1)); + } + + function log(uint256 p0, string memory p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string)", p0, p1)); + } + + function log(uint256 p0, bool p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool)", p0, p1)); + } + + function log(uint256 p0, address p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address)", p0, p1)); + } + + function log(string memory p0, uint256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256)", p0, p1)); + } + + function log(string memory p0, int256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,int256)", p0, p1)); + } + + function log(string memory p0, string memory p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); + } + + function log(string memory p0, bool p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); + } + + function log(string memory p0, address p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); + } + + function log(bool p0, uint256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256)", p0, p1)); + } + + function log(bool p0, string memory p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); + } + + function log(bool p0, bool p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); + } + + function log(bool p0, address p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); + } + + function log(address p0, uint256 p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256)", p0, p1)); + } + + function log(address p0, string memory p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); + } + + function log(address p0, bool p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); + } + + function log(address p0, address p1) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); + } + + function log(uint256 p0, uint256 p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool)", p0, p1, p2)); + } + + function log(uint256 p0, string memory p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool)", p0, p1, p2)); + } + + function log(uint256 p0, bool p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool)", p0, p1, p2)); + } + + function log(uint256 p0, address p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool)", p0, p1, p2)); + } + + function log(string memory p0, uint256 p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); + } + + function log(string memory p0, address p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256)", p0, p1, p2)); + } + + function log(string memory p0, address p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); + } + + function log(string memory p0, address p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); + } + + function log(string memory p0, address p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool)", p0, p1, p2)); + } + + function log(bool p0, uint256 p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); + } + + function log(bool p0, bool p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256)", p0, p1, p2)); + } + + function log(bool p0, bool p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); + } + + function log(bool p0, bool p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); + } + + function log(bool p0, bool p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); + } + + function log(bool p0, address p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256)", p0, p1, p2)); + } + + function log(bool p0, address p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); + } + + function log(bool p0, address p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); + } + + function log(bool p0, address p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool)", p0, p1, p2)); + } + + function log(address p0, uint256 p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address)", p0, p1, p2)); + } + + function log(address p0, string memory p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256)", p0, p1, p2)); + } + + function log(address p0, string memory p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); + } + + function log(address p0, string memory p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); + } + + function log(address p0, string memory p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); + } + + function log(address p0, bool p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256)", p0, p1, p2)); + } + + function log(address p0, bool p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); + } + + function log(address p0, bool p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); + } + + function log(address p0, bool p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); + } + + function log(address p0, address p1, uint256 p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256)", p0, p1, p2)); + } + + function log(address p0, address p1, string memory p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); + } + + function log(address p0, address p1, bool p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); + } + + function log(address p0, address p1, address p2) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, string memory p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,string,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, bool p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,bool,address,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,string,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,bool,address)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,string)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,bool)", p0, p1, p2, p3)); + } + + function log(uint256 p0, address p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(uint256,address,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint256 p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint256 p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint256 p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,uint256,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint256 p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint256,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, uint256 p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint256)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, string memory p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, bool p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, address p3) internal pure { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/console2.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/console2.sol new file mode 100644 index 00000000..03531d91 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/console2.sol @@ -0,0 +1,4 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.4.22 <0.9.0; + +import {console as console2} from "./console.sol"; diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC1155.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC1155.sol new file mode 100644 index 00000000..ffc82984 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC1155.sol @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC165} from "./IERC165.sol"; + +/// @title ERC-1155 Multi Token Standard +/// @dev See https://eips.ethereum.org/EIPS/eip-1155 +/// Note: The ERC-165 identifier for this interface is 0xd9b67a26. +interface IERC1155 is IERC165 { + /// @dev + /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). + /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). + /// - The `_from` argument MUST be the address of the holder whose balance is decreased. + /// - The `_to` argument MUST be the address of the recipient whose balance is increased. + /// - The `_id` argument MUST be the token type being transferred. + /// - The `_value` argument MUST be the number of tokens the holder balance is decreased by and match what the recipient balance is increased by. + /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). + /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). + event TransferSingle( + address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value + ); + + /// @dev + /// - Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). + /// - The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). + /// - The `_from` argument MUST be the address of the holder whose balance is decreased. + /// - The `_to` argument MUST be the address of the recipient whose balance is increased. + /// - The `_ids` argument MUST be the list of tokens being transferred. + /// - The `_values` argument MUST be the list of number of tokens (matching the list and order of tokens specified in _ids) the holder balance is decreased by and match what the recipient balance is increased by. + /// - When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). + /// - When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). + event TransferBatch( + address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values + ); + + /// @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absence of an event assumes disabled). + event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); + + /// @dev MUST emit when the URI is updated for a token ID. URIs are defined in RFC 3986. + /// The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema". + event URI(string _value, uint256 indexed _id); + + /// @notice Transfers `_value` amount of an `_id` from the `_from` address to the `_to` address specified (with safety call). + /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). + /// - MUST revert if `_to` is the zero address. + /// - MUST revert if balance of holder for token `_id` is lower than the `_value` sent. + /// - MUST revert on any other error. + /// - MUST emit the `TransferSingle` event to reflect the balance change (see "Safe Transfer Rules" section of the standard). + /// - After the above conditions are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call `onERC1155Received` on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). + /// @param _from Source address + /// @param _to Target address + /// @param _id ID of the token type + /// @param _value Transfer amount + /// @param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to` + function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; + + /// @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call). + /// @dev Caller must be approved to manage the tokens being transferred out of the `_from` account (see "Approval" section of the standard). + /// - MUST revert if `_to` is the zero address. + /// - MUST revert if length of `_ids` is not the same as length of `_values`. + /// - MUST revert if any of the balance(s) of the holder(s) for token(s) in `_ids` is lower than the respective amount(s) in `_values` sent to the recipient. + /// - MUST revert on any other error. + /// - MUST emit `TransferSingle` or `TransferBatch` event(s) such that all the balance changes are reflected (see "Safe Transfer Rules" section of the standard). + /// - Balance changes and events MUST follow the ordering of the arrays (_ids[0]/_values[0] before _ids[1]/_values[1], etc). + /// - After the above conditions for the transfer(s) in the batch are met, this function MUST check if `_to` is a smart contract (e.g. code size > 0). If so, it MUST call the relevant `ERC1155TokenReceiver` hook(s) on `_to` and act appropriately (see "Safe Transfer Rules" section of the standard). + /// @param _from Source address + /// @param _to Target address + /// @param _ids IDs of each token type (order and length must match _values array) + /// @param _values Transfer amounts per token type (order and length must match _ids array) + /// @param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to` + function safeBatchTransferFrom( + address _from, + address _to, + uint256[] calldata _ids, + uint256[] calldata _values, + bytes calldata _data + ) external; + + /// @notice Get the balance of an account's tokens. + /// @param _owner The address of the token holder + /// @param _id ID of the token + /// @return The _owner's balance of the token type requested + function balanceOf(address _owner, uint256 _id) external view returns (uint256); + + /// @notice Get the balance of multiple account/token pairs + /// @param _owners The addresses of the token holders + /// @param _ids ID of the tokens + /// @return The _owner's balance of the token types requested (i.e. balance for each (owner, id) pair) + function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) + external + view + returns (uint256[] memory); + + /// @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. + /// @dev MUST emit the ApprovalForAll event on success. + /// @param _operator Address to add to the set of authorized operators + /// @param _approved True if the operator is approved, false to revoke approval + function setApprovalForAll(address _operator, bool _approved) external; + + /// @notice Queries the approval status of an operator for a given owner. + /// @param _owner The owner of the tokens + /// @param _operator Address of authorized operator + /// @return True if the operator is approved, false if not + function isApprovedForAll(address _owner, address _operator) external view returns (bool); +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC165.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC165.sol new file mode 100644 index 00000000..9af4bf80 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC165.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +interface IERC165 { + /// @notice Query if a contract implements an interface + /// @param interfaceID The interface identifier, as specified in ERC-165 + /// @dev Interface identification is specified in ERC-165. This function + /// uses less than 30,000 gas. + /// @return `true` if the contract implements `interfaceID` and + /// `interfaceID` is not 0xffffffff, `false` otherwise + function supportsInterface(bytes4 interfaceID) external view returns (bool); +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC20.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC20.sol new file mode 100644 index 00000000..ba40806c --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC20.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +/// @dev Interface of the ERC20 standard as defined in the EIP. +/// @dev This includes the optional name, symbol, and decimals metadata. +interface IERC20 { + /// @dev Emitted when `value` tokens are moved from one account (`from`) to another (`to`). + event Transfer(address indexed from, address indexed to, uint256 value); + + /// @dev Emitted when the allowance of a `spender` for an `owner` is set, where `value` + /// is the new allowance. + event Approval(address indexed owner, address indexed spender, uint256 value); + + /// @notice Returns the amount of tokens in existence. + function totalSupply() external view returns (uint256); + + /// @notice Returns the amount of tokens owned by `account`. + function balanceOf(address account) external view returns (uint256); + + /// @notice Moves `amount` tokens from the caller's account to `to`. + function transfer(address to, uint256 amount) external returns (bool); + + /// @notice Returns the remaining number of tokens that `spender` is allowed + /// to spend on behalf of `owner` + function allowance(address owner, address spender) external view returns (uint256); + + /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens. + /// @dev Be aware of front-running risks: https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + function approve(address spender, uint256 amount) external returns (bool); + + /// @notice Moves `amount` tokens from `from` to `to` using the allowance mechanism. + /// `amount` is then deducted from the caller's allowance. + function transferFrom(address from, address to, uint256 amount) external returns (bool); + + /// @notice Returns the name of the token. + function name() external view returns (string memory); + + /// @notice Returns the symbol of the token. + function symbol() external view returns (string memory); + + /// @notice Returns the decimals places of the token. + function decimals() external view returns (uint8); +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC4626.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC4626.sol new file mode 100644 index 00000000..c645a0fe --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC4626.sol @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC20} from "./IERC20.sol"; + +/// @dev Interface of the ERC4626 "Tokenized Vault Standard", as defined in +/// https://eips.ethereum.org/EIPS/eip-4626 +interface IERC4626 is IERC20 { + event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); + + event Withdraw( + address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares + ); + + /// @notice Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. + /// @dev + /// - MUST be an ERC-20 token contract. + /// - MUST NOT revert. + function asset() external view returns (address assetTokenAddress); + + /// @notice Returns the total amount of the underlying asset that is “managed” by Vault. + /// @dev + /// - SHOULD include any compounding that occurs from yield. + /// - MUST be inclusive of any fees that are charged against assets in the Vault. + /// - MUST NOT revert. + function totalAssets() external view returns (uint256 totalManagedAssets); + + /// @notice Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal + /// scenario where all the conditions are met. + /// @dev + /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. + /// - MUST NOT show any variations depending on the caller. + /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. + /// - MUST NOT revert. + /// + /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the + /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and + /// from. + function convertToShares(uint256 assets) external view returns (uint256 shares); + + /// @notice Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal + /// scenario where all the conditions are met. + /// @dev + /// - MUST NOT be inclusive of any fees that are charged against assets in the Vault. + /// - MUST NOT show any variations depending on the caller. + /// - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. + /// - MUST NOT revert. + /// + /// NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the + /// “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and + /// from. + function convertToAssets(uint256 shares) external view returns (uint256 assets); + + /// @notice Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, + /// through a deposit call. + /// @dev + /// - MUST return a limited value if receiver is subject to some deposit limit. + /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. + /// - MUST NOT revert. + function maxDeposit(address receiver) external view returns (uint256 maxAssets); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given + /// current on-chain conditions. + /// @dev + /// - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit + /// call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called + /// in the same transaction. + /// - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the + /// deposit would be accepted, regardless if the user has enough tokens approved, etc. + /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by depositing. + function previewDeposit(uint256 assets) external view returns (uint256 shares); + + /// @notice Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. + /// @dev + /// - MUST emit the Deposit event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + /// deposit execution, and are accounted for during deposit. + /// - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not + /// approving enough underlying tokens to the Vault contract, etc). + /// + /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. + function deposit(uint256 assets, address receiver) external returns (uint256 shares); + + /// @notice Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. + /// @dev + /// - MUST return a limited value if receiver is subject to some mint limit. + /// - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. + /// - MUST NOT revert. + function maxMint(address receiver) external view returns (uint256 maxShares); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given + /// current on-chain conditions. + /// @dev + /// - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call + /// in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the + /// same transaction. + /// - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint + /// would be accepted, regardless if the user has enough tokens approved, etc. + /// - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by minting. + function previewMint(uint256 shares) external view returns (uint256 assets); + + /// @notice Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. + /// @dev + /// - MUST emit the Deposit event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint + /// execution, and are accounted for during mint. + /// - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not + /// approving enough underlying tokens to the Vault contract, etc). + /// + /// NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. + function mint(uint256 shares, address receiver) external returns (uint256 assets); + + /// @notice Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the + /// Vault, through a withdrawal call. + /// @dev + /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. + /// - MUST NOT revert. + function maxWithdraw(address owner) external view returns (uint256 maxAssets); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, + /// given current on-chain conditions. + /// @dev + /// - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw + /// call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if + /// called + /// in the same transaction. + /// - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though + /// the withdrawal would be accepted, regardless if the user has enough shares, etc. + /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by depositing. + function previewWithdraw(uint256 assets) external view returns (uint256 shares); + + /// @notice Burns shares from owner and sends exactly assets of underlying tokens to receiver. + /// @dev + /// - MUST emit the Withdraw event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + /// withdraw execution, and are accounted for during withdrawal. + /// - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner + /// not having enough shares, etc). + /// + /// Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. + /// Those methods should be performed separately. + function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); + + /// @notice Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, + /// through a redeem call. + /// @dev + /// - MUST return a limited value if owner is subject to some withdrawal limit or timelock. + /// - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. + /// - MUST NOT revert. + function maxRedeem(address owner) external view returns (uint256 maxShares); + + /// @notice Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, + /// given current on-chain conditions. + /// @dev + /// - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call + /// in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the + /// same transaction. + /// - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the + /// redemption would be accepted, regardless if the user has enough shares, etc. + /// - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. + /// - MUST NOT revert. + /// + /// NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in + /// share price or some other type of condition, meaning the depositor will lose assets by redeeming. + function previewRedeem(uint256 shares) external view returns (uint256 assets); + + /// @notice Burns exactly shares from owner and sends assets of underlying tokens to receiver. + /// @dev + /// - MUST emit the Withdraw event. + /// - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + /// redeem execution, and are accounted for during redeem. + /// - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner + /// not having enough shares, etc). + /// + /// NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. + /// Those methods should be performed separately. + function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC6909.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC6909.sol new file mode 100644 index 00000000..6e11cb46 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC6909.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC165} from "./IERC165.sol"; + +/// @dev Required interface of an ERC-6909 compliant contract, as defined in +/// https://eips.ethereum.org/EIPS/eip-6909 +interface IERC6909 is IERC165 { + /// @dev Emitted when the allowance of a `spender` for an `owner` is set for a token of type `id`. + event Approval(address indexed owner, address indexed spender, uint256 indexed id, uint256 amount); + + /// @dev Emitted when `owner` grants or revokes operator status for a `spender`. + event OperatorSet(address indexed owner, address indexed spender, bool approved); + + /// @dev Emitted when `amount` tokens of type `id` are moved from `sender` to `receiver` initiated by `caller`. + event Transfer( + address caller, address indexed sender, address indexed receiver, uint256 indexed id, uint256 amount + ); + + ///@dev Returns the amount of tokens of type `id` owned by `owner`. + function balanceOf(address owner, uint256 id) external view returns (uint256); + + /// @dev Returns the amount of tokens of type `id` that `spender` is allowed to spend on behalf of `owner`. + /// NOTE: Does not include operator allowances. + function allowance(address owner, address spender, uint256 id) external view returns (uint256); + + /// @dev Returns true if `spender` is set as an operator for `owner`. + function isOperator(address owner, address spender) external view returns (bool); + + /// @dev Sets an approval to `spender` for `amount` tokens of type `id` from the caller's tokens. + /// Must return true. + function approve(address spender, uint256 id, uint256 amount) external returns (bool); + + /// @dev Grants or revokes unlimited transfer permission of any token id to `spender` for the caller's tokens. + /// Must return true. + function setOperator(address spender, bool approved) external returns (bool); + + /// @dev Transfers `amount` of token type `id` from the caller's account to `receiver`. + /// Must return true. + function transfer(address receiver, uint256 id, uint256 amount) external returns (bool); + + /// @dev Transfers `amount` of token type `id` from `sender` to `receiver`. + /// Must return true. + function transferFrom(address sender, address receiver, uint256 id, uint256 amount) external returns (bool); +} + +/// @dev Optional extension of {IERC6909} that adds metadata functions. +interface IERC6909Metadata is IERC6909 { + /// @dev Returns the name of the token of type `id`. + function name(uint256 id) external view returns (string memory); + + /// @dev Returns the ticker symbol of the token of type `id`. + function symbol(uint256 id) external view returns (string memory); + + /// @dev Returns the number of decimals for the token of type `id`. + function decimals(uint256 id) external view returns (uint8); +} + +/// @dev Optional extension of {IERC6909} that adds content URI functions. +interface IERC6909ContentURI is IERC6909 { + /// @dev Returns URI for the contract. + function contractURI() external view returns (string memory); + + /// @dev Returns the URI for the token of type `id`. + function tokenURI(uint256 id) external view returns (string memory); +} + +/// @dev Optional extension of {IERC6909} that adds a token supply function. +interface IERC6909TokenSupply is IERC6909 { + /// @dev Returns the total supply of the token of type `id`. + function totalSupply(uint256 id) external view returns (uint256); +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC721.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC721.sol new file mode 100644 index 00000000..21a4a94d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC721.sol @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC165} from "./IERC165.sol"; + +/// @title ERC-721 Non-Fungible Token Standard +/// @dev See https://eips.ethereum.org/EIPS/eip-721 +/// Note: the ERC-165 identifier for this interface is 0x80ac58cd. +interface IERC721 is IERC165 { + /// @dev This emits when ownership of any NFT changes by any mechanism. + /// This event emits when NFTs are created (`from` == 0) and destroyed + /// (`to` == 0). Exception: during contract creation, any number of NFTs + /// may be created and assigned without emitting Transfer. At the time of + /// any transfer, the approved address for that NFT (if any) is reset to none. + event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); + + /// @dev This emits when the approved address for an NFT is changed or + /// reaffirmed. The zero address indicates there is no approved address. + /// When a Transfer event emits, this also indicates that the approved + /// address for that NFT (if any) is reset to none. + event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); + + /// @dev This emits when an operator is enabled or disabled for an owner. + /// The operator can manage all NFTs of the owner. + event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); + + /// @notice Count all NFTs assigned to an owner + /// @dev NFTs assigned to the zero address are considered invalid, and this + /// function throws for queries about the zero address. + /// @param _owner An address for whom to query the balance + /// @return The number of NFTs owned by `_owner`, possibly zero + function balanceOf(address _owner) external view returns (uint256); + + /// @notice Find the owner of an NFT + /// @dev NFTs assigned to zero address are considered invalid, and queries + /// about them do throw. + /// @param _tokenId The identifier for an NFT + /// @return The address of the owner of the NFT + function ownerOf(uint256 _tokenId) external view returns (address); + + /// @notice Transfers the ownership of an NFT from one address to another address + /// @dev Throws unless `msg.sender` is the current owner, an authorized + /// operator, or the approved address for this NFT. Throws if `_from` is + /// not the current owner. Throws if `_to` is the zero address. Throws if + /// `_tokenId` is not a valid NFT. When transfer is complete, this function + /// checks if `_to` is a smart contract (code size > 0). If so, it calls + /// `onERC721Received` on `_to` and throws if the return value is not + /// `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`. + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + /// @param data Additional data with no specified format, sent in call to `_to` + function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable; + + /// @notice Transfers the ownership of an NFT from one address to another address + /// @dev This works identically to the other function with an extra data parameter, + /// except this function just sets data to "". + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; + + /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE + /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE + /// THEY MAY BE PERMANENTLY LOST + /// @dev Throws unless `msg.sender` is the current owner, an authorized + /// operator, or the approved address for this NFT. Throws if `_from` is + /// not the current owner. Throws if `_to` is the zero address. Throws if + /// `_tokenId` is not a valid NFT. + /// @param _from The current owner of the NFT + /// @param _to The new owner + /// @param _tokenId The NFT to transfer + function transferFrom(address _from, address _to, uint256 _tokenId) external payable; + + /// @notice Change or reaffirm the approved address for an NFT + /// @dev The zero address indicates there is no approved address. + /// Throws unless `msg.sender` is the current NFT owner, or an authorized + /// operator of the current owner. + /// @param _approved The new approved NFT controller + /// @param _tokenId The NFT to approve + function approve(address _approved, uint256 _tokenId) external payable; + + /// @notice Enable or disable approval for a third party ("operator") to manage + /// all of `msg.sender`'s assets + /// @dev Emits the ApprovalForAll event. The contract MUST allow + /// multiple operators per owner. + /// @param _operator Address to add to the set of authorized operators + /// @param _approved True if the operator is approved, false to revoke approval + function setApprovalForAll(address _operator, bool _approved) external; + + /// @notice Get the approved address for a single NFT + /// @dev Throws if `_tokenId` is not a valid NFT. + /// @param _tokenId The NFT to find the approved address for + /// @return The approved address for this NFT, or the zero address if there is none + function getApproved(uint256 _tokenId) external view returns (address); + + /// @notice Query if an address is an authorized operator for another address + /// @param _owner The address that owns the NFTs + /// @param _operator The address that acts on behalf of the owner + /// @return True if `_operator` is an approved operator for `_owner`, false otherwise + function isApprovedForAll(address _owner, address _operator) external view returns (bool); +} + +/// @dev Note: the ERC-165 identifier for this interface is 0x150b7a02. +interface IERC721TokenReceiver { + /// @notice Handle the receipt of an NFT + /// @dev The ERC721 smart contract calls this function on the recipient + /// after a `transfer`. This function MAY throw to revert and reject the + /// transfer. Return of other than the magic value MUST result in the + /// transaction being reverted. + /// Note: the contract address is always the message sender. + /// @param _operator The address which called `safeTransferFrom` function + /// @param _from The address which previously owned the token + /// @param _tokenId The NFT identifier which is being transferred + /// @param _data Additional data with no specified format + /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` + /// unless throwing + function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) + external + returns (bytes4); +} + +/// @title ERC-721 Non-Fungible Token Standard, optional metadata extension +/// @dev See https://eips.ethereum.org/EIPS/eip-721 +/// Note: the ERC-165 identifier for this interface is 0x5b5e139f. +interface IERC721Metadata is IERC721 { + /// @notice A descriptive name for a collection of NFTs in this contract + function name() external view returns (string memory _name); + + /// @notice An abbreviated name for NFTs in this contract + function symbol() external view returns (string memory _symbol); + + /// @notice A distinct Uniform Resource Identifier (URI) for a given asset. + /// @dev Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC + /// 3986. The URI may point to a JSON file that conforms to the "ERC721 + /// Metadata JSON Schema". + function tokenURI(uint256 _tokenId) external view returns (string memory); +} + +/// @title ERC-721 Non-Fungible Token Standard, optional enumeration extension +/// @dev See https://eips.ethereum.org/EIPS/eip-721 +/// Note: the ERC-165 identifier for this interface is 0x780e9d63. +interface IERC721Enumerable is IERC721 { + /// @notice Count NFTs tracked by this contract + /// @return A count of valid NFTs tracked by this contract, where each one of + /// them has an assigned and queryable owner not equal to the zero address + function totalSupply() external view returns (uint256); + + /// @notice Enumerate valid NFTs + /// @dev Throws if `_index` >= `totalSupply()`. + /// @param _index A counter less than `totalSupply()` + /// @return The token identifier for the `_index`th NFT, + /// (sort order not specified) + function tokenByIndex(uint256 _index) external view returns (uint256); + + /// @notice Enumerate NFTs assigned to an owner + /// @dev Throws if `_index` >= `balanceOf(_owner)` or if + /// `_owner` is the zero address, representing invalid NFTs. + /// @param _owner An address where we are interested in NFTs owned by them + /// @param _index A counter less than `balanceOf(_owner)` + /// @return The token identifier for the `_index`th NFT assigned to `_owner`, + /// (sort order not specified) + function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256); +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC7540.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC7540.sol new file mode 100644 index 00000000..9b3ca08b --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC7540.sol @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC7575} from "./IERC7575.sol"; + +/// @dev Interface of the base operator logic of ERC7540, as defined in +/// https://eips.ethereum.org/EIPS/eip-7540 +interface IERC7540Operator { + /** + * @dev The event emitted when an operator is set. + * + * @param controller The address of the controller. + * @param operator The address of the operator. + * @param approved The approval status. + */ + event OperatorSet(address indexed controller, address indexed operator, bool approved); + + /** + * @dev Sets or removes an operator for the caller. + * + * @param operator The address of the operator. + * @param approved The approval status. + * @return Whether the call was executed successfully or not + */ + function setOperator(address operator, bool approved) external returns (bool); + + /** + * @dev Returns `true` if the `operator` is approved as an operator for an `controller`. + * + * @param controller The address of the controller. + * @param operator The address of the operator. + * @return status The approval status + */ + function isOperator(address controller, address operator) external view returns (bool status); +} + +/// @dev Interface of the asynchronous deposit Vault interface of ERC7540, as defined in +/// https://eips.ethereum.org/EIPS/eip-7540 +interface IERC7540Deposit is IERC7540Operator { + event DepositRequest( + address indexed controller, address indexed owner, uint256 indexed requestId, address sender, uint256 assets + ); + /** + * @dev Transfers assets from sender into the Vault and submits a Request for asynchronous deposit. + * + * - MUST support ERC-20 approve / transferFrom on asset as a deposit Request flow. + * - MUST revert if all of assets cannot be requested for deposit. + * - owner MUST be msg.sender unless some unspecified explicit approval is given by the caller, + * approval of ERC-20 tokens from owner to sender is NOT enough. + * + * @param assets the amount of deposit assets to transfer from owner + * @param controller the controller of the request who will be able to operate the request + * @param owner the source of the deposit assets + * + * NOTE: most implementations will require pre-approval of the Vault with the Vault's underlying asset token. + */ + + function requestDeposit(uint256 assets, address controller, address owner) external returns (uint256 requestId); + + /** + * @dev Returns the amount of requested assets in Pending state. + * + * - MUST NOT include any assets in Claimable state for deposit or mint. + * - MUST NOT show any variations depending on the caller. + * - MUST NOT revert unless due to integer overflow caused by an unreasonably large input. + */ + function pendingDepositRequest(uint256 requestId, address controller) external view returns (uint256 pendingAssets); + + /** + * @dev Returns the amount of requested assets in Claimable state for the controller to deposit or mint. + * + * - MUST NOT include any assets in Pending state. + * - MUST NOT show any variations depending on the caller. + * - MUST NOT revert unless due to integer overflow caused by an unreasonably large input. + */ + function claimableDepositRequest(uint256 requestId, address controller) + external + view + returns (uint256 claimableAssets); + + /** + * @dev Mints shares Vault shares to receiver by claiming the Request of the controller. + * + * - MUST emit the Deposit event. + * - controller MUST equal msg.sender unless the controller has approved the msg.sender as an operator. + */ + function deposit(uint256 assets, address receiver, address controller) external returns (uint256 shares); + + /** + * @dev Mints exactly shares Vault shares to receiver by claiming the Request of the controller. + * + * - MUST emit the Deposit event. + * - controller MUST equal msg.sender unless the controller has approved the msg.sender as an operator. + */ + function mint(uint256 shares, address receiver, address controller) external returns (uint256 assets); +} + +/// @dev Interface of the asynchronous deposit Vault interface of ERC7540, as defined in +/// https://eips.ethereum.org/EIPS/eip-7540 +interface IERC7540Redeem is IERC7540Operator { + event RedeemRequest( + address indexed controller, address indexed owner, uint256 indexed requestId, address sender, uint256 assets + ); + + /** + * @dev Assumes control of shares from sender into the Vault and submits a Request for asynchronous redeem. + * + * - MUST support a redeem Request flow where the control of shares is taken from sender directly + * where msg.sender has ERC-20 approval over the shares of owner. + * - MUST revert if all of shares cannot be requested for redeem. + * + * @param shares the amount of shares to be redeemed to transfer from owner + * @param controller the controller of the request who will be able to operate the request + * @param owner the source of the shares to be redeemed + * + * NOTE: most implementations will require pre-approval of the Vault with the Vault's share token. + */ + function requestRedeem(uint256 shares, address controller, address owner) external returns (uint256 requestId); + + /** + * @dev Returns the amount of requested shares in Pending state. + * + * - MUST NOT include any shares in Claimable state for redeem or withdraw. + * - MUST NOT show any variations depending on the caller. + * - MUST NOT revert unless due to integer overflow caused by an unreasonably large input. + */ + function pendingRedeemRequest(uint256 requestId, address controller) external view returns (uint256 pendingShares); + + /** + * @dev Returns the amount of requested shares in Claimable state for the controller to redeem or withdraw. + * + * - MUST NOT include any shares in Pending state for redeem or withdraw. + * - MUST NOT show any variations depending on the caller. + * - MUST NOT revert unless due to integer overflow caused by an unreasonably large input. + */ + function claimableRedeemRequest(uint256 requestId, address controller) + external + view + returns (uint256 claimableShares); +} + +/// @dev Interface of the fully asynchronous Vault interface of ERC7540, as defined in +/// https://eips.ethereum.org/EIPS/eip-7540 +interface IERC7540 is IERC7540Deposit, IERC7540Redeem, IERC7575 {} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC7575.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC7575.sol new file mode 100644 index 00000000..207e3e7f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IERC7575.sol @@ -0,0 +1,241 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2; + +import {IERC165} from "./IERC165.sol"; + +/// @dev Interface of the ERC7575 "Multi-Asset ERC-4626 Vaults", as defined in +/// https://eips.ethereum.org/EIPS/eip-7575 +interface IERC7575 is IERC165 { + event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); + event Withdraw( + address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares + ); + + /** + * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. + * + * - MUST be an ERC-20 token contract. + * - MUST NOT revert. + */ + function asset() external view returns (address assetTokenAddress); + + /** + * @dev Returns the address of the share token + * + * - MUST be an ERC-20 token contract. + * - MUST NOT revert. + */ + function share() external view returns (address shareTokenAddress); + + /** + * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal + * scenario where all the conditions are met. + * + * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. + * - MUST NOT show any variations depending on the caller. + * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. + * - MUST NOT revert. + * + * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the + * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and + * from. + */ + function convertToShares(uint256 assets) external view returns (uint256 shares); + + /** + * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal + * scenario where all the conditions are met. + * + * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. + * - MUST NOT show any variations depending on the caller. + * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. + * - MUST NOT revert. + * + * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the + * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and + * from. + */ + function convertToAssets(uint256 shares) external view returns (uint256 assets); + + /** + * @dev Returns the total amount of the underlying asset that is “managed” by Vault. + * + * - SHOULD include any compounding that occurs from yield. + * - MUST be inclusive of any fees that are charged against assets in the Vault. + * - MUST NOT revert. + */ + function totalAssets() external view returns (uint256 totalManagedAssets); + + /** + * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, + * through a deposit call. + * + * - MUST return a limited value if receiver is subject to some deposit limit. + * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. + * - MUST NOT revert. + */ + function maxDeposit(address receiver) external view returns (uint256 maxAssets); + + /** + * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given + * current on-chain conditions. + * + * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit + * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called + * in the same transaction. + * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the + * deposit would be accepted, regardless if the user has enough tokens approved, etc. + * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. + * - MUST NOT revert. + * + * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in + * share price or some other type of condition, meaning the depositor will lose assets by depositing. + */ + function previewDeposit(uint256 assets) external view returns (uint256 shares); + + /** + * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. + * + * - MUST emit the Deposit event. + * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + * deposit execution, and are accounted for during deposit. + * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not + * approving enough underlying tokens to the Vault contract, etc). + * + * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. + */ + function deposit(uint256 assets, address receiver) external returns (uint256 shares); + + /** + * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. + * - MUST return a limited value if receiver is subject to some mint limit. + * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. + * - MUST NOT revert. + */ + function maxMint(address receiver) external view returns (uint256 maxShares); + + /** + * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given + * current on-chain conditions. + * + * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call + * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the + * same transaction. + * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint + * would be accepted, regardless if the user has enough tokens approved, etc. + * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. + * - MUST NOT revert. + * + * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in + * share price or some other type of condition, meaning the depositor will lose assets by minting. + */ + function previewMint(uint256 shares) external view returns (uint256 assets); + + /** + * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. + * + * - MUST emit the Deposit event. + * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint + * execution, and are accounted for during mint. + * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not + * approving enough underlying tokens to the Vault contract, etc). + * + * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. + */ + function mint(uint256 shares, address receiver) external returns (uint256 assets); + + /** + * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the + * Vault, through a withdraw call. + * + * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. + * - MUST NOT revert. + */ + function maxWithdraw(address owner) external view returns (uint256 maxAssets); + + /** + * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, + * given current on-chain conditions. + * + * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw + * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if + * called + * in the same transaction. + * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though + * the withdrawal would be accepted, regardless if the user has enough shares, etc. + * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. + * - MUST NOT revert. + * + * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in + * share price or some other type of condition, meaning the depositor will lose assets by depositing. + */ + function previewWithdraw(uint256 assets) external view returns (uint256 shares); + + /** + * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. + * + * - MUST emit the Withdraw event. + * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + * withdraw execution, and are accounted for during withdraw. + * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner + * not having enough shares, etc). + * + * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. + * Those methods should be performed separately. + */ + function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); + + /** + * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, + * through a redeem call. + * + * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. + * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. + * - MUST NOT revert. + */ + function maxRedeem(address owner) external view returns (uint256 maxShares); + + /** + * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, + * given current on-chain conditions. + * + * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call + * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the + * same transaction. + * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the + * redemption would be accepted, regardless if the user has enough shares, etc. + * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. + * - MUST NOT revert. + * + * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in + * share price or some other type of condition, meaning the depositor will lose assets by redeeming. + */ + function previewRedeem(uint256 shares) external view returns (uint256 assets); + + /** + * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. + * + * - MUST emit the Withdraw event. + * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the + * redeem execution, and are accounted for during redeem. + * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner + * not having enough shares, etc). + * + * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. + * Those methods should be performed separately. + */ + function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); +} + +/// @dev Interface of the ERC20 share token, as defined in +/// https://eips.ethereum.org/EIPS/eip-7575 +interface IERC7575Share is IERC165 { + event VaultUpdate(address indexed asset, address vault); + + /** + * @dev Returns the address of the Vault for the given asset. + * + * @param asset the ERC-20 token to deposit with into the Vault + */ + function vault(address asset) external view returns (address); +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IMulticall3.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IMulticall3.sol new file mode 100644 index 00000000..3b79851b --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/interfaces/IMulticall3.sol @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +interface IMulticall3 { + struct Call { + address target; + bytes callData; + } + + struct Call3 { + address target; + bool allowFailure; + bytes callData; + } + + struct Call3Value { + address target; + bool allowFailure; + uint256 value; + bytes callData; + } + + struct Result { + bool success; + bytes returnData; + } + + function aggregate(Call[] calldata calls) external payable returns (uint256 blockNumber, bytes[] memory returnData); + + function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData); + + function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData); + + function blockAndAggregate(Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); + + function getBasefee() external view returns (uint256 basefee); + + function getBlockHash(uint256 blockNumber) external view returns (bytes32 blockHash); + + function getBlockNumber() external view returns (uint256 blockNumber); + + function getChainId() external view returns (uint256 chainid); + + function getCurrentBlockCoinbase() external view returns (address coinbase); + + function getCurrentBlockDifficulty() external view returns (uint256 difficulty); + + function getCurrentBlockGasLimit() external view returns (uint256 gaslimit); + + function getCurrentBlockTimestamp() external view returns (uint256 timestamp); + + function getEthBalance(address addr) external view returns (uint256 balance); + + function getLastBlockHash() external view returns (bytes32 blockHash); + + function tryAggregate(bool requireSuccess, Call[] calldata calls) + external + payable + returns (Result[] memory returnData); + + function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) + external + payable + returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/safeconsole.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/safeconsole.sol new file mode 100644 index 00000000..87c475a5 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/src/safeconsole.sol @@ -0,0 +1,13937 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +/// @author philogy +/// @dev Code generated automatically by script. +library safeconsole { + uint256 constant CONSOLE_ADDR = 0x000000000000000000000000000000000000000000636F6e736F6c652e6c6f67; + + // Credit to [0age](https://twitter.com/z0age/status/1654922202930888704) and [0xdapper](https://github.com/foundry-rs/forge-std/pull/374) + // for the view-to-pure log trick. + function _sendLogPayload(uint256 offset, uint256 size) private pure { + function(uint256, uint256) internal view fnIn = _sendLogPayloadView; + function(uint256, uint256) internal pure pureSendLogPayload; + /// @solidity memory-safe-assembly + assembly { + pureSendLogPayload := fnIn + } + pureSendLogPayload(offset, size); + } + + function _sendLogPayloadView(uint256 offset, uint256 size) private view { + /// @solidity memory-safe-assembly + assembly { + pop(staticcall(gas(), CONSOLE_ADDR, offset, size, 0x0, 0x0)) + } + } + + function _memcopy(uint256 fromOffset, uint256 toOffset, uint256 length) private pure { + function(uint256, uint256, uint256) internal view fnIn = _memcopyView; + function(uint256, uint256, uint256) internal pure pureMemcopy; + /// @solidity memory-safe-assembly + assembly { + pureMemcopy := fnIn + } + pureMemcopy(fromOffset, toOffset, length); + } + + function _memcopyView(uint256 fromOffset, uint256 toOffset, uint256 length) private view { + /// @solidity memory-safe-assembly + assembly { + pop(staticcall(gas(), 0x4, fromOffset, length, toOffset, length)) + } + } + + function logMemory(uint256 offset, uint256 length) internal pure { + if (offset >= 0x60) { + // Sufficient memory before slice to prepare call header. + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(sub(offset, 0x60)) + m1 := mload(sub(offset, 0x40)) + m2 := mload(sub(offset, 0x20)) + // Selector of `log(bytes)`. + mstore(sub(offset, 0x60), 0x0be77f56) + mstore(sub(offset, 0x40), 0x20) + mstore(sub(offset, 0x20), length) + } + _sendLogPayload(offset - 0x44, length + 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(sub(offset, 0x60), m0) + mstore(sub(offset, 0x40), m1) + mstore(sub(offset, 0x20), m2) + } + } else { + // Insufficient space, so copy slice forward, add header and reverse. + bytes32 m0; + bytes32 m1; + bytes32 m2; + uint256 endOffset = offset + length; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(add(endOffset, 0x00)) + m1 := mload(add(endOffset, 0x20)) + m2 := mload(add(endOffset, 0x40)) + } + _memcopy(offset, offset + 0x60, length); + /// @solidity memory-safe-assembly + assembly { + // Selector of `log(bytes)`. + mstore(add(offset, 0x00), 0x0be77f56) + mstore(add(offset, 0x20), 0x20) + mstore(add(offset, 0x40), length) + } + _sendLogPayload(offset + 0x1c, length + 0x44); + _memcopy(offset + 0x60, offset, length); + /// @solidity memory-safe-assembly + assembly { + mstore(add(endOffset, 0x00), m0) + mstore(add(endOffset, 0x20), m1) + mstore(add(endOffset, 0x40), m2) + } + } + } + + function log(address p0) internal pure { + bytes32 m0; + bytes32 m1; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + // Selector of `log(address)`. + mstore(0x00, 0x2c2ecbc2) + mstore(0x20, p0) + } + _sendLogPayload(0x1c, 0x24); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + } + } + + function log(bool p0) internal pure { + bytes32 m0; + bytes32 m1; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + // Selector of `log(bool)`. + mstore(0x00, 0x32458eed) + mstore(0x20, p0) + } + _sendLogPayload(0x1c, 0x24); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + } + } + + function log(uint256 p0) internal pure { + bytes32 m0; + bytes32 m1; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + // Selector of `log(uint256)`. + mstore(0x00, 0xf82c50f1) + mstore(0x20, p0) + } + _sendLogPayload(0x1c, 0x24); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + } + } + + function log(bytes32 p0) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(string)`. + mstore(0x00, 0x41304fac) + mstore(0x20, 0x20) + writeString(0x40, p0) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, address p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(address,address)`. + mstore(0x00, 0xdaf0d4aa) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(address p0, bool p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(address,bool)`. + mstore(0x00, 0x75b605d3) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(address p0, uint256 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(address,uint256)`. + mstore(0x00, 0x8309e8a8) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(address p0, bytes32 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,string)`. + mstore(0x00, 0x759f86bb) + mstore(0x20, p0) + mstore(0x40, 0x40) + writeString(0x60, p1) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(bool,address)`. + mstore(0x00, 0x853c4849) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(bool p0, bool p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(bool,bool)`. + mstore(0x00, 0x2a110e83) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(bool p0, uint256 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(bool,uint256)`. + mstore(0x00, 0x399174d3) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(bool p0, bytes32 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,string)`. + mstore(0x00, 0x8feac525) + mstore(0x20, p0) + mstore(0x40, 0x40) + writeString(0x60, p1) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(uint256,address)`. + mstore(0x00, 0x69276c86) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(uint256 p0, bool p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(uint256,bool)`. + mstore(0x00, 0x1c9d7eb3) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(uint256 p0, uint256 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + // Selector of `log(uint256,uint256)`. + mstore(0x00, 0xf666715a) + mstore(0x20, p0) + mstore(0x40, p1) + } + _sendLogPayload(0x1c, 0x44); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + } + } + + function log(uint256 p0, bytes32 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,string)`. + mstore(0x00, 0x643fd0df) + mstore(0x20, p0) + mstore(0x40, 0x40) + writeString(0x60, p1) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bytes32 p0, address p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(string,address)`. + mstore(0x00, 0x319af333) + mstore(0x20, 0x40) + mstore(0x40, p1) + writeString(0x60, p0) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bytes32 p0, bool p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(string,bool)`. + mstore(0x00, 0xc3b55635) + mstore(0x20, 0x40) + mstore(0x40, p1) + writeString(0x60, p0) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bytes32 p0, uint256 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(string,uint256)`. + mstore(0x00, 0xb60e72cc) + mstore(0x20, 0x40) + mstore(0x40, p1) + writeString(0x60, p0) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bytes32 p0, bytes32 p1) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,string)`. + mstore(0x00, 0x4b5c4277) + mstore(0x20, 0x40) + mstore(0x40, 0x80) + writeString(0x60, p0) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,address,address)`. + mstore(0x00, 0x018c84c2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, address p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,address,bool)`. + mstore(0x00, 0xf2a66286) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, address p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,address,uint256)`. + mstore(0x00, 0x17fe6185) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, address p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,address,string)`. + mstore(0x00, 0x007150be) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bool p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,bool,address)`. + mstore(0x00, 0xf11699ed) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, bool p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,bool,bool)`. + mstore(0x00, 0xeb830c92) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, bool p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,bool,uint256)`. + mstore(0x00, 0x9c4f99fb) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, bool p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,bool,string)`. + mstore(0x00, 0x212255cc) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, uint256 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,uint256,address)`. + mstore(0x00, 0x7bc0d848) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, uint256 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,uint256,bool)`. + mstore(0x00, 0x678209a8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, uint256 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(address,uint256,uint256)`. + mstore(0x00, 0xb69bcaf6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(address p0, uint256 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,uint256,string)`. + mstore(0x00, 0xa1f2e8aa) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bytes32 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,string,address)`. + mstore(0x00, 0xf08744e8) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bytes32 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,string,bool)`. + mstore(0x00, 0xcf020fb1) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bytes32 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(address,string,uint256)`. + mstore(0x00, 0x67dd6ff1) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(address p0, bytes32 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(address,string,string)`. + mstore(0x00, 0xfb772265) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, 0xa0) + writeString(0x80, p1) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bool p0, address p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,address,address)`. + mstore(0x00, 0xd2763667) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, address p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,address,bool)`. + mstore(0x00, 0x18c9c746) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, address p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,address,uint256)`. + mstore(0x00, 0x5f7b9afb) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, address p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,address,string)`. + mstore(0x00, 0xde9a9270) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bool p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,bool,address)`. + mstore(0x00, 0x1078f68d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, bool p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,bool,bool)`. + mstore(0x00, 0x50709698) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, bool p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,bool,uint256)`. + mstore(0x00, 0x12f21602) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, bool p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,bool,string)`. + mstore(0x00, 0x2555fa46) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, uint256 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,uint256,address)`. + mstore(0x00, 0x088ef9d2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, uint256 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,uint256,bool)`. + mstore(0x00, 0xe8defba9) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, uint256 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(bool,uint256,uint256)`. + mstore(0x00, 0x37103367) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(bool p0, uint256 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,uint256,string)`. + mstore(0x00, 0xc3fc3970) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bytes32 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,string,address)`. + mstore(0x00, 0x9591b953) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bytes32 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,string,bool)`. + mstore(0x00, 0xdbb4c247) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bytes32 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(bool,string,uint256)`. + mstore(0x00, 0x1093ee11) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(bool,string,string)`. + mstore(0x00, 0xb076847f) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, 0xa0) + writeString(0x80, p1) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(uint256 p0, address p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,address,address)`. + mstore(0x00, 0xbcfd9be0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, address p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,address,bool)`. + mstore(0x00, 0x9b6ec042) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, address p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,address,uint256)`. + mstore(0x00, 0x5a9b5ed5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, address p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,address,string)`. + mstore(0x00, 0x63cb41f9) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bool p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,bool,address)`. + mstore(0x00, 0x35085f7b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, bool p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,bool,bool)`. + mstore(0x00, 0x20718650) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, bool p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,bool,uint256)`. + mstore(0x00, 0x20098014) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, bool p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,bool,string)`. + mstore(0x00, 0x85775021) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, uint256 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,uint256,address)`. + mstore(0x00, 0x5c96b331) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, uint256 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,uint256,bool)`. + mstore(0x00, 0x4766da72) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + // Selector of `log(uint256,uint256,uint256)`. + mstore(0x00, 0xd1ed7a3c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + } + _sendLogPayload(0x1c, 0x64); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,uint256,string)`. + mstore(0x00, 0x71d04af2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x60) + writeString(0x80, p2) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bytes32 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,string,address)`. + mstore(0x00, 0x7afac959) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bytes32 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,string,bool)`. + mstore(0x00, 0x4ceda75a) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(uint256,string,uint256)`. + mstore(0x00, 0x37aa7d4c) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, p2) + writeString(0x80, p1) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(uint256,string,string)`. + mstore(0x00, 0xb115611f) + mstore(0x20, p0) + mstore(0x40, 0x60) + mstore(0x60, 0xa0) + writeString(0x80, p1) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, address p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,address,address)`. + mstore(0x00, 0xfcec75e0) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, address p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,address,bool)`. + mstore(0x00, 0xc91d5ed4) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, address p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,address,uint256)`. + mstore(0x00, 0x0d26b925) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, address p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,address,string)`. + mstore(0x00, 0xe0e9ad4f) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, 0xa0) + writeString(0x80, p0) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bool p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,bool,address)`. + mstore(0x00, 0x932bbb38) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, bool p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,bool,bool)`. + mstore(0x00, 0x850b7ad6) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, bool p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,bool,uint256)`. + mstore(0x00, 0xc95958d6) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,bool,string)`. + mstore(0x00, 0xe298f47d) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, 0xa0) + writeString(0x80, p0) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, uint256 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,uint256,address)`. + mstore(0x00, 0x1c7ec448) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, uint256 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,uint256,bool)`. + mstore(0x00, 0xca7733b1) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + // Selector of `log(string,uint256,uint256)`. + mstore(0x00, 0xca47c4eb) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, p2) + writeString(0x80, p0) + } + _sendLogPayload(0x1c, 0xa4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,uint256,string)`. + mstore(0x00, 0x5970e089) + mstore(0x20, 0x60) + mstore(0x40, p1) + mstore(0x60, 0xa0) + writeString(0x80, p0) + writeString(0xc0, p2) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bytes32 p1, address p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,string,address)`. + mstore(0x00, 0x95ed0195) + mstore(0x20, 0x60) + mstore(0x40, 0xa0) + mstore(0x60, p2) + writeString(0x80, p0) + writeString(0xc0, p1) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,string,bool)`. + mstore(0x00, 0xb0e0f9b5) + mstore(0x20, 0x60) + mstore(0x40, 0xa0) + mstore(0x60, p2) + writeString(0x80, p0) + writeString(0xc0, p1) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + // Selector of `log(string,string,uint256)`. + mstore(0x00, 0x5821efa1) + mstore(0x20, 0x60) + mstore(0x40, 0xa0) + mstore(0x60, p2) + writeString(0x80, p0) + writeString(0xc0, p1) + } + _sendLogPayload(0x1c, 0xe4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + // Selector of `log(string,string,string)`. + mstore(0x00, 0x2ced7cef) + mstore(0x20, 0x60) + mstore(0x40, 0xa0) + mstore(0x60, 0xe0) + writeString(0x80, p0) + writeString(0xc0, p1) + writeString(0x100, p2) + } + _sendLogPayload(0x1c, 0x124); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + } + } + + function log(address p0, address p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,address,address)`. + mstore(0x00, 0x665bf134) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,address,bool)`. + mstore(0x00, 0x0e378994) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,address,uint256)`. + mstore(0x00, 0x94250d77) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,address,string)`. + mstore(0x00, 0xf808da20) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,bool,address)`. + mstore(0x00, 0x9f1bc36e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,bool,bool)`. + mstore(0x00, 0x2cd4134a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,bool,uint256)`. + mstore(0x00, 0x3971e78c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,bool,string)`. + mstore(0x00, 0xaa6540c8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,uint256,address)`. + mstore(0x00, 0x8da6def5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,uint256,bool)`. + mstore(0x00, 0x9b4254e2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,address,uint256,uint256)`. + mstore(0x00, 0xbe553481) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, address p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,uint256,string)`. + mstore(0x00, 0xfdb4f990) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,string,address)`. + mstore(0x00, 0x8f736d16) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,string,bool)`. + mstore(0x00, 0x6f1a594e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,address,string,uint256)`. + mstore(0x00, 0xef1cefe7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, address p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,address,string,string)`. + mstore(0x00, 0x21bdaf25) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bool p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,address,address)`. + mstore(0x00, 0x660375dd) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,address,bool)`. + mstore(0x00, 0xa6f50b0f) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,address,uint256)`. + mstore(0x00, 0xa75c59de) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,address,string)`. + mstore(0x00, 0x2dd778e6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,bool,address)`. + mstore(0x00, 0xcf394485) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,bool,bool)`. + mstore(0x00, 0xcac43479) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,bool,uint256)`. + mstore(0x00, 0x8c4e5de6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,bool,string)`. + mstore(0x00, 0xdfc4a2e8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,uint256,address)`. + mstore(0x00, 0xccf790a1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,uint256,bool)`. + mstore(0x00, 0xc4643e20) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,bool,uint256,uint256)`. + mstore(0x00, 0x386ff5f4) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, bool p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,uint256,string)`. + mstore(0x00, 0x0aa6cfad) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,string,address)`. + mstore(0x00, 0x19fd4956) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,string,bool)`. + mstore(0x00, 0x50ad461d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,bool,string,uint256)`. + mstore(0x00, 0x80e6a20b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bool p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,bool,string,string)`. + mstore(0x00, 0x475c5c33) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, uint256 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,address,address)`. + mstore(0x00, 0x478d1c62) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,address,bool)`. + mstore(0x00, 0xa1bcc9b3) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,address,uint256)`. + mstore(0x00, 0x100f650e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,address,string)`. + mstore(0x00, 0x1da986ea) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,bool,address)`. + mstore(0x00, 0xa31bfdcc) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,bool,bool)`. + mstore(0x00, 0x3bf5e537) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,bool,uint256)`. + mstore(0x00, 0x22f6b999) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,bool,string)`. + mstore(0x00, 0xc5ad85f9) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,uint256,address)`. + mstore(0x00, 0x20e3984d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,uint256,bool)`. + mstore(0x00, 0x66f1bc67) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(address,uint256,uint256,uint256)`. + mstore(0x00, 0x34f0e636) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(address p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,uint256,string)`. + mstore(0x00, 0x4a28c017) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,string,address)`. + mstore(0x00, 0x5c430d47) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,string,bool)`. + mstore(0x00, 0xcf18105c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,uint256,string,uint256)`. + mstore(0x00, 0xbf01f891) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,uint256,string,string)`. + mstore(0x00, 0x88a8c406) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,address,address)`. + mstore(0x00, 0x0d36fa20) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,address,bool)`. + mstore(0x00, 0x0df12b76) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,address,uint256)`. + mstore(0x00, 0x457fe3cf) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,address,string)`. + mstore(0x00, 0xf7e36245) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,bool,address)`. + mstore(0x00, 0x205871c2) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,bool,bool)`. + mstore(0x00, 0x5f1d5c9f) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,bool,uint256)`. + mstore(0x00, 0x515e38b6) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,bool,string)`. + mstore(0x00, 0xbc0b61fe) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,uint256,address)`. + mstore(0x00, 0x63183678) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,uint256,bool)`. + mstore(0x00, 0x0ef7e050) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(address,string,uint256,uint256)`. + mstore(0x00, 0x1dc8e1b8) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(address p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,uint256,string)`. + mstore(0x00, 0x448830a8) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,string,address)`. + mstore(0x00, 0xa04e2f87) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,string,bool)`. + mstore(0x00, 0x35a5071f) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(address,string,string,uint256)`. + mstore(0x00, 0x159f8927) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(address p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(address,string,string,string)`. + mstore(0x00, 0x5d02c50b) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p1) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bool p0, address p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,address,address)`. + mstore(0x00, 0x1d14d001) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,address,bool)`. + mstore(0x00, 0x46600be0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,address,uint256)`. + mstore(0x00, 0x0c66d1be) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,address,string)`. + mstore(0x00, 0xd812a167) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,bool,address)`. + mstore(0x00, 0x1c41a336) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,bool,bool)`. + mstore(0x00, 0x6a9c478b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,bool,uint256)`. + mstore(0x00, 0x07831502) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,bool,string)`. + mstore(0x00, 0x4a66cb34) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,uint256,address)`. + mstore(0x00, 0x136b05dd) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,uint256,bool)`. + mstore(0x00, 0xd6019f1c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,address,uint256,uint256)`. + mstore(0x00, 0x7bf181a1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, address p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,uint256,string)`. + mstore(0x00, 0x51f09ff8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,string,address)`. + mstore(0x00, 0x6f7c603e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,string,bool)`. + mstore(0x00, 0xe2bfd60b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,address,string,uint256)`. + mstore(0x00, 0xc21f64c7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, address p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,address,string,string)`. + mstore(0x00, 0xa73c1db6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bool p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,address,address)`. + mstore(0x00, 0xf4880ea4) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,address,bool)`. + mstore(0x00, 0xc0a302d8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,address,uint256)`. + mstore(0x00, 0x4c123d57) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,address,string)`. + mstore(0x00, 0xa0a47963) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,bool,address)`. + mstore(0x00, 0x8c329b1a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,bool,bool)`. + mstore(0x00, 0x3b2a5ce0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,bool,uint256)`. + mstore(0x00, 0x6d7045c1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,bool,string)`. + mstore(0x00, 0x2ae408d4) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,uint256,address)`. + mstore(0x00, 0x54a7a9a0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,uint256,bool)`. + mstore(0x00, 0x619e4d0e) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,bool,uint256,uint256)`. + mstore(0x00, 0x0bb00eab) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, bool p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,uint256,string)`. + mstore(0x00, 0x7dd4d0e0) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,string,address)`. + mstore(0x00, 0xf9ad2b89) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,string,bool)`. + mstore(0x00, 0xb857163a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,bool,string,uint256)`. + mstore(0x00, 0xe3a9ca2f) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bool p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,bool,string,string)`. + mstore(0x00, 0x6d1e8751) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, uint256 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,address,address)`. + mstore(0x00, 0x26f560a8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,address,bool)`. + mstore(0x00, 0xb4c314ff) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,address,uint256)`. + mstore(0x00, 0x1537dc87) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,address,string)`. + mstore(0x00, 0x1bb3b09a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,bool,address)`. + mstore(0x00, 0x9acd3616) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,bool,bool)`. + mstore(0x00, 0xceb5f4d7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,bool,uint256)`. + mstore(0x00, 0x7f9bbca2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,bool,string)`. + mstore(0x00, 0x9143dbb1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,uint256,address)`. + mstore(0x00, 0x00dd87b9) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,uint256,bool)`. + mstore(0x00, 0xbe984353) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(bool,uint256,uint256,uint256)`. + mstore(0x00, 0x374bb4b2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(bool p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,uint256,string)`. + mstore(0x00, 0x8e69fb5d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,string,address)`. + mstore(0x00, 0xfedd1fff) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,string,bool)`. + mstore(0x00, 0xe5e70b2b) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,uint256,string,uint256)`. + mstore(0x00, 0x6a1199e2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,uint256,string,string)`. + mstore(0x00, 0xf5bc2249) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,address,address)`. + mstore(0x00, 0x2b2b18dc) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,address,bool)`. + mstore(0x00, 0x6dd434ca) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,address,uint256)`. + mstore(0x00, 0xa5cada94) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,address,string)`. + mstore(0x00, 0x12d6c788) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,bool,address)`. + mstore(0x00, 0x538e06ab) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,bool,bool)`. + mstore(0x00, 0xdc5e935b) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,bool,uint256)`. + mstore(0x00, 0x1606a393) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,bool,string)`. + mstore(0x00, 0x483d0416) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,uint256,address)`. + mstore(0x00, 0x1596a1ce) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,uint256,bool)`. + mstore(0x00, 0x6b0e5d53) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(bool,string,uint256,uint256)`. + mstore(0x00, 0x28863fcb) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bool p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,uint256,string)`. + mstore(0x00, 0x1ad96de6) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,string,address)`. + mstore(0x00, 0x97d394d8) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,string,bool)`. + mstore(0x00, 0x1e4b87e5) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(bool,string,string,uint256)`. + mstore(0x00, 0x7be0c3eb) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bool p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(bool,string,string,string)`. + mstore(0x00, 0x1762e32a) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p1) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(uint256 p0, address p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,address,address)`. + mstore(0x00, 0x2488b414) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,address,bool)`. + mstore(0x00, 0x091ffaf5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,address,uint256)`. + mstore(0x00, 0x736efbb6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,address,string)`. + mstore(0x00, 0x031c6f73) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,bool,address)`. + mstore(0x00, 0xef72c513) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,bool,bool)`. + mstore(0x00, 0xe351140f) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,bool,uint256)`. + mstore(0x00, 0x5abd992a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,bool,string)`. + mstore(0x00, 0x90fb06aa) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,uint256,address)`. + mstore(0x00, 0x15c127b5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,uint256,bool)`. + mstore(0x00, 0x5f743a7c) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,address,uint256,uint256)`. + mstore(0x00, 0x0c9cd9c1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, address p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,uint256,string)`. + mstore(0x00, 0xddb06521) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,string,address)`. + mstore(0x00, 0x9cba8fff) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,string,bool)`. + mstore(0x00, 0xcc32ab07) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,address,string,uint256)`. + mstore(0x00, 0x46826b5d) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, address p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,address,string,string)`. + mstore(0x00, 0x3e128ca3) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bool p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,address,address)`. + mstore(0x00, 0xa1ef4cbb) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,address,bool)`. + mstore(0x00, 0x454d54a5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,address,uint256)`. + mstore(0x00, 0x078287f5) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,address,string)`. + mstore(0x00, 0xade052c7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,bool,address)`. + mstore(0x00, 0x69640b59) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,bool,bool)`. + mstore(0x00, 0xb6f577a1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,bool,uint256)`. + mstore(0x00, 0x7464ce23) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,bool,string)`. + mstore(0x00, 0xdddb9561) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,uint256,address)`. + mstore(0x00, 0x88cb6041) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,uint256,bool)`. + mstore(0x00, 0x91a02e2a) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,bool,uint256,uint256)`. + mstore(0x00, 0xc6acc7a8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, bool p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,uint256,string)`. + mstore(0x00, 0xde03e774) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,string,address)`. + mstore(0x00, 0xef529018) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,string,bool)`. + mstore(0x00, 0xeb928d7f) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,bool,string,uint256)`. + mstore(0x00, 0x2c1d0746) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bool p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,bool,string,string)`. + mstore(0x00, 0x68c8b8bd) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, uint256 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,address,address)`. + mstore(0x00, 0x56a5d1b1) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,address,bool)`. + mstore(0x00, 0x15cac476) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,address,uint256)`. + mstore(0x00, 0x88f6e4b2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,address,string)`. + mstore(0x00, 0x6cde40b8) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,bool,address)`. + mstore(0x00, 0x9a816a83) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,bool,bool)`. + mstore(0x00, 0xab085ae6) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,bool,uint256)`. + mstore(0x00, 0xeb7f6fd2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,bool,string)`. + mstore(0x00, 0xa5b4fc99) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,uint256,address)`. + mstore(0x00, 0xfa8185af) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,uint256,bool)`. + mstore(0x00, 0xc598d185) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + /// @solidity memory-safe-assembly + assembly { + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + // Selector of `log(uint256,uint256,uint256,uint256)`. + mstore(0x00, 0x193fb800) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + } + _sendLogPayload(0x1c, 0x84); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + } + } + + function log(uint256 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,uint256,string)`. + mstore(0x00, 0x59cfcbe3) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0x80) + writeString(0xa0, p3) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,string,address)`. + mstore(0x00, 0x42d21db7) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,string,bool)`. + mstore(0x00, 0x7af6ab25) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,uint256,string,uint256)`. + mstore(0x00, 0x5da297eb) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, p3) + writeString(0xa0, p2) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,uint256,string,string)`. + mstore(0x00, 0x27d8afd2) + mstore(0x20, p0) + mstore(0x40, p1) + mstore(0x60, 0x80) + mstore(0x80, 0xc0) + writeString(0xa0, p2) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,address,address)`. + mstore(0x00, 0x6168ed61) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,address,bool)`. + mstore(0x00, 0x90c30a56) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,address,uint256)`. + mstore(0x00, 0xe8d3018d) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,address,string)`. + mstore(0x00, 0x9c3adfa1) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,bool,address)`. + mstore(0x00, 0xae2ec581) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,bool,bool)`. + mstore(0x00, 0xba535d9c) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,bool,uint256)`. + mstore(0x00, 0xcf009880) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,bool,string)`. + mstore(0x00, 0xd2d423cd) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,uint256,address)`. + mstore(0x00, 0x3b2279b4) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,uint256,bool)`. + mstore(0x00, 0x691a8f74) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(uint256,string,uint256,uint256)`. + mstore(0x00, 0x82c25b74) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p1) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(uint256 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,uint256,string)`. + mstore(0x00, 0xb7b914ca) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p1) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,string,address)`. + mstore(0x00, 0xd583c602) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,string,bool)`. + mstore(0x00, 0xb3a6b6bd) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(uint256,string,string,uint256)`. + mstore(0x00, 0xb028c9bd) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p1) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(uint256 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(uint256,string,string,string)`. + mstore(0x00, 0x21ad0683) + mstore(0x20, p0) + mstore(0x40, 0x80) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p1) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, address p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,address,address)`. + mstore(0x00, 0xed8f28f6) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,address,bool)`. + mstore(0x00, 0xb59dbd60) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,address,uint256)`. + mstore(0x00, 0x8ef3f399) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,address,string)`. + mstore(0x00, 0x800a1c67) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,bool,address)`. + mstore(0x00, 0x223603bd) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,bool,bool)`. + mstore(0x00, 0x79884c2b) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,bool,uint256)`. + mstore(0x00, 0x3e9f866a) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,bool,string)`. + mstore(0x00, 0x0454c079) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,uint256,address)`. + mstore(0x00, 0x63fb8bc5) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,uint256,bool)`. + mstore(0x00, 0xfc4845f0) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,address,uint256,uint256)`. + mstore(0x00, 0xf8f51b1e) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, address p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,uint256,string)`. + mstore(0x00, 0x5a477632) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,string,address)`. + mstore(0x00, 0xaabc9a31) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,string,bool)`. + mstore(0x00, 0x5f15d28c) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,address,string,uint256)`. + mstore(0x00, 0x91d1112e) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, address p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,address,string,string)`. + mstore(0x00, 0x245986f2) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bool p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,address,address)`. + mstore(0x00, 0x33e9dd1d) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,address,bool)`. + mstore(0x00, 0x958c28c6) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,address,uint256)`. + mstore(0x00, 0x5d08bb05) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,address,string)`. + mstore(0x00, 0x2d8e33a4) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,bool,address)`. + mstore(0x00, 0x7190a529) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,bool,bool)`. + mstore(0x00, 0x895af8c5) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,bool,uint256)`. + mstore(0x00, 0x8e3f78a9) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,bool,string)`. + mstore(0x00, 0x9d22d5dd) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,uint256,address)`. + mstore(0x00, 0x935e09bf) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,uint256,bool)`. + mstore(0x00, 0x8af7cf8a) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,bool,uint256,uint256)`. + mstore(0x00, 0x64b5bb67) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, bool p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,uint256,string)`. + mstore(0x00, 0x742d6ee7) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,string,address)`. + mstore(0x00, 0xe0625b29) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,string,bool)`. + mstore(0x00, 0x3f8a701d) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,bool,string,uint256)`. + mstore(0x00, 0x24f91465) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bool p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,bool,string,string)`. + mstore(0x00, 0xa826caeb) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, uint256 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,address,address)`. + mstore(0x00, 0x5ea2b7ae) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,address,bool)`. + mstore(0x00, 0x82112a42) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,address,uint256)`. + mstore(0x00, 0x4f04fdc6) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,address,string)`. + mstore(0x00, 0x9ffb2f93) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,bool,address)`. + mstore(0x00, 0xe0e95b98) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,bool,bool)`. + mstore(0x00, 0x354c36d6) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,bool,uint256)`. + mstore(0x00, 0xe41b6f6f) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,bool,string)`. + mstore(0x00, 0xabf73a98) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,uint256,address)`. + mstore(0x00, 0xe21de278) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,uint256,bool)`. + mstore(0x00, 0x7626db92) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + // Selector of `log(string,uint256,uint256,uint256)`. + mstore(0x00, 0xa7a87853) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + } + _sendLogPayload(0x1c, 0xc4); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + } + } + + function log(bytes32 p0, uint256 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,uint256,string)`. + mstore(0x00, 0x854b3496) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, p2) + mstore(0x80, 0xc0) + writeString(0xa0, p0) + writeString(0xe0, p3) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,string,address)`. + mstore(0x00, 0x7c4632a4) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,string,bool)`. + mstore(0x00, 0x7d24491d) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,uint256,string,uint256)`. + mstore(0x00, 0xc67ea9d1) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p2) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, uint256 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,uint256,string,string)`. + mstore(0x00, 0x5ab84e1f) + mstore(0x20, 0x80) + mstore(0x40, p1) + mstore(0x60, 0xc0) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p2) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, address p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,address,address)`. + mstore(0x00, 0x439c7bef) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, address p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,address,bool)`. + mstore(0x00, 0x5ccd4e37) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, address p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,address,uint256)`. + mstore(0x00, 0x7cc3c607) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, address p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,address,string)`. + mstore(0x00, 0xeb1bff80) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,bool,address)`. + mstore(0x00, 0xc371c7db) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,bool,bool)`. + mstore(0x00, 0x40785869) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,bool,uint256)`. + mstore(0x00, 0xd6aefad2) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, bool p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,bool,string)`. + mstore(0x00, 0x5e84b0ea) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,uint256,address)`. + mstore(0x00, 0x1023f7b2) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,uint256,bool)`. + mstore(0x00, 0xc3a8a654) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + // Selector of `log(string,string,uint256,uint256)`. + mstore(0x00, 0xf45d7d2c) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + } + _sendLogPayload(0x1c, 0x104); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + } + } + + function log(bytes32 p0, bytes32 p1, uint256 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,uint256,string)`. + mstore(0x00, 0x5d1a971a) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, p2) + mstore(0x80, 0x100) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p3) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2, address p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,string,address)`. + mstore(0x00, 0x6d572f44) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, 0x100) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p2) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2, bool p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,string,bool)`. + mstore(0x00, 0x2c1754ed) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, 0x100) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p2) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2, uint256 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + // Selector of `log(string,string,string,uint256)`. + mstore(0x00, 0x8eafb02b) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, 0x100) + mstore(0x80, p3) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p2) + } + _sendLogPayload(0x1c, 0x144); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + } + } + + function log(bytes32 p0, bytes32 p1, bytes32 p2, bytes32 p3) internal pure { + bytes32 m0; + bytes32 m1; + bytes32 m2; + bytes32 m3; + bytes32 m4; + bytes32 m5; + bytes32 m6; + bytes32 m7; + bytes32 m8; + bytes32 m9; + bytes32 m10; + bytes32 m11; + bytes32 m12; + /// @solidity memory-safe-assembly + assembly { + function writeString(pos, w) { + let length := 0 + for {} lt(length, 0x20) { length := add(length, 1) } { if iszero(byte(length, w)) { break } } + mstore(pos, length) + let shift := sub(256, shl(3, length)) + mstore(add(pos, 0x20), shl(shift, shr(shift, w))) + } + m0 := mload(0x00) + m1 := mload(0x20) + m2 := mload(0x40) + m3 := mload(0x60) + m4 := mload(0x80) + m5 := mload(0xa0) + m6 := mload(0xc0) + m7 := mload(0xe0) + m8 := mload(0x100) + m9 := mload(0x120) + m10 := mload(0x140) + m11 := mload(0x160) + m12 := mload(0x180) + // Selector of `log(string,string,string,string)`. + mstore(0x00, 0xde68f20a) + mstore(0x20, 0x80) + mstore(0x40, 0xc0) + mstore(0x60, 0x100) + mstore(0x80, 0x140) + writeString(0xa0, p0) + writeString(0xe0, p1) + writeString(0x120, p2) + writeString(0x160, p3) + } + _sendLogPayload(0x1c, 0x184); + /// @solidity memory-safe-assembly + assembly { + mstore(0x00, m0) + mstore(0x20, m1) + mstore(0x40, m2) + mstore(0x60, m3) + mstore(0x80, m4) + mstore(0xa0, m5) + mstore(0xc0, m6) + mstore(0xe0, m7) + mstore(0x100, m8) + mstore(0x120, m9) + mstore(0x140, m10) + mstore(0x160, m11) + mstore(0x180, m12) + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/CommonBase.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/CommonBase.t.sol new file mode 100644 index 00000000..4a6eb34f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/CommonBase.t.sol @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {CommonBase} from "../src/Base.sol"; +import {StdConstants} from "../src/StdConstants.sol"; +import {Test} from "../src/Test.sol"; + +contract CommonBaseTest is Test { + function testVmAddressValue() public pure { + assertEq(VM_ADDRESS, address(StdConstants.VM)); + } + + function testConsoleValue() public pure { + assertEq(CONSOLE, StdConstants.CONSOLE); + } + + function testCreate2FactoryValue() public pure { + assertEq(CREATE2_FACTORY, StdConstants.CREATE2_FACTORY); + } + + function testDefaultSenderValue() public pure { + assertEq(DEFAULT_SENDER, StdConstants.DEFAULT_SENDER); + } + + function testDefaultTestContractValue() public pure { + assertEq(DEFAULT_TEST_CONTRACT, StdConstants.DEFAULT_TEST_CONTRACT); + } + + function testMulticall3AddressValue() public pure { + assertEq(MULTICALL3_ADDRESS, address(StdConstants.MULTICALL3_ADDRESS)); + } + + function testSecp256k1OrderValue() public pure { + assertEq(SECP256K1_ORDER, StdConstants.SECP256K1_ORDER); + } + + function testUint256MaxValue() public pure { + assertEq(UINT256_MAX, type(uint256).max); + } + + function testVmValue() public pure { + assertEq(address(vm), address(StdConstants.VM)); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/Config.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/Config.t.sol new file mode 100644 index 00000000..8e2342ca --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/Config.t.sol @@ -0,0 +1,352 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import {Test} from "../src/Test.sol"; +import {Config} from "../src/Config.sol"; +import {StdConfig} from "../src/StdConfig.sol"; + +contract ConfigTest is Test, Config { + function setUp() public { + vm.setEnv("MAINNET_RPC", "https://eth.llamarpc.com"); + vm.setEnv("WETH_MAINNET", "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"); + vm.setEnv("OPTIMISM_RPC", "https://mainnet.optimism.io"); + vm.setEnv("WETH_OPTIMISM", "0x4200000000000000000000000000000000000006"); + } + + function test_loadConfig() public { + // Deploy the config contract with the test fixture. + _loadConfig("./test/fixtures/config.toml", false); + + // -- MAINNET -------------------------------------------------------------- + + // Read and assert RPC URL for Mainnet (chain ID 1) + assertEq(config.getRpcUrl(1), "https://eth.llamarpc.com"); + + // Read and assert boolean values + assertTrue(config.get(1, "is_live").toBool()); + bool[] memory bool_array = config.get(1, "bool_array").toBoolArray(); + assertTrue(bool_array[0]); + assertFalse(bool_array[1]); + + // Read and assert address values + assertEq(config.get(1, "weth").toAddress(), 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2); + address[] memory address_array = config.get(1, "deps").toAddressArray(); + assertEq(address_array[0], 0x0000000000000000000000000000000000000000); + assertEq(address_array[1], 0x1111111111111111111111111111111111111111); + + // Read and assert bytes32 values + assertEq(config.get(1, "word").toBytes32(), bytes32(uint256(1234))); + bytes32[] memory bytes32_array = config.get(1, "word_array").toBytes32Array(); + assertEq(bytes32_array[0], bytes32(uint256(5678))); + assertEq(bytes32_array[1], bytes32(uint256(9999))); + + // Read and assert uint values + assertEq(config.get(1, "number").toUint256(), 1234); + uint256[] memory uint_array = config.get(1, "number_array").toUint256Array(); + assertEq(uint_array[0], 5678); + assertEq(uint_array[1], 9999); + + // Read and assert int values + assertEq(config.get(1, "signed_number").toInt256(), -1234); + int256[] memory int_array = config.get(1, "signed_number_array").toInt256Array(); + assertEq(int_array[0], -5678); + assertEq(int_array[1], 9999); + + // Read and assert bytes values + assertEq(config.get(1, "b").toBytes(), hex"abcd"); + bytes[] memory bytes_array = config.get(1, "b_array").toBytesArray(); + assertEq(bytes_array[0], hex"dead"); + assertEq(bytes_array[1], hex"beef"); + + // Read and assert string values + assertEq(config.get(1, "str").toString(), "foo"); + string[] memory string_array = config.get(1, "str_array").toStringArray(); + assertEq(string_array[0], "bar"); + assertEq(string_array[1], "baz"); + + // -- OPTIMISM ------------------------------------------------------------ + + // Read and assert RPC URL for Optimism (chain ID 10) + assertEq(config.getRpcUrl(10), "https://mainnet.optimism.io"); + + // Read and assert boolean values + assertFalse(config.get(10, "is_live").toBool()); + bool_array = config.get(10, "bool_array").toBoolArray(); + assertFalse(bool_array[0]); + assertTrue(bool_array[1]); + + // Read and assert address values + assertEq(config.get(10, "weth").toAddress(), 0x4200000000000000000000000000000000000006); + address_array = config.get(10, "deps").toAddressArray(); + assertEq(address_array[0], 0x2222222222222222222222222222222222222222); + assertEq(address_array[1], 0x3333333333333333333333333333333333333333); + + // Read and assert bytes32 values + assertEq(config.get(10, "word").toBytes32(), bytes32(uint256(9999))); + bytes32_array = config.get(10, "word_array").toBytes32Array(); + assertEq(bytes32_array[0], bytes32(uint256(1234))); + assertEq(bytes32_array[1], bytes32(uint256(5678))); + + // Read and assert uint values + assertEq(config.get(10, "number").toUint256(), 9999); + uint_array = config.get(10, "number_array").toUint256Array(); + assertEq(uint_array[0], 1234); + assertEq(uint_array[1], 5678); + + // Read and assert int values + assertEq(config.get(10, "signed_number").toInt256(), 9999); + int_array = config.get(10, "signed_number_array").toInt256Array(); + assertEq(int_array[0], -1234); + assertEq(int_array[1], -5678); + + // Read and assert bytes values + assertEq(config.get(10, "b").toBytes(), hex"dcba"); + bytes_array = config.get(10, "b_array").toBytesArray(); + assertEq(bytes_array[0], hex"c0ffee"); + assertEq(bytes_array[1], hex"babe"); + + // Read and assert string values + assertEq(config.get(10, "str").toString(), "alice"); + string_array = config.get(10, "str_array").toStringArray(); + assertEq(string_array[0], "bob"); + assertEq(string_array[1], "charlie"); + } + + function test_loadConfigAndForks() public { + _loadConfigAndForks("./test/fixtures/config.toml", false); + + // assert that the map of chain id and fork ids is created and that the chain ids actually match + assertEq(forkOf[1], 0); + vm.selectFork(forkOf[1]); + assertEq(vm.getChainId(), 1); + + assertEq(forkOf[10], 1); + vm.selectFork(forkOf[10]); + assertEq(vm.getChainId(), 10); + } + + function test_writeConfig() public { + // Create a temporary copy of the config file to avoid modifying the original. + string memory originalConfig = "./test/fixtures/config.toml"; + string memory testConfig = "./test/fixtures/config.t.toml"; + vm.copyFile(originalConfig, testConfig); + + // Deploy the config contract with the temporary fixture. + _loadConfig(testConfig, false); + + // Enable writing to file bypassing the context check. + vm.store(address(config), bytes32(uint256(5)), bytes32(uint256(1))); + + { + // Update a single boolean value and verify the change. + config.set(1, "is_live", false); + + assertFalse(config.get(1, "is_live").toBool()); + + string memory content = vm.readFile(testConfig); + assertFalse(vm.parseTomlBool(content, "$.mainnet.bool.is_live")); + + // Update a single address value and verify the change. + address new_addr = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF; + config.set(1, "weth", new_addr); + + assertEq(config.get(1, "weth").toAddress(), new_addr); + + content = vm.readFile(testConfig); + assertEq(vm.parseTomlAddress(content, "$.mainnet.address.weth"), new_addr); + + // Update a uint array and verify the change. + uint256[] memory new_numbers = new uint256[](3); + new_numbers[0] = 1; + new_numbers[1] = 2; + new_numbers[2] = 3; + config.set(10, "number_array", new_numbers); + + uint256[] memory updated_numbers_mem = config.get(10, "number_array").toUint256Array(); + assertEq(updated_numbers_mem.length, 3); + assertEq(updated_numbers_mem[0], 1); + assertEq(updated_numbers_mem[1], 2); + assertEq(updated_numbers_mem[2], 3); + + content = vm.readFile(testConfig); + uint256[] memory updated_numbers_disk = vm.parseTomlUintArray(content, "$.optimism.uint.number_array"); + assertEq(updated_numbers_disk.length, 3); + assertEq(updated_numbers_disk[0], 1); + assertEq(updated_numbers_disk[1], 2); + assertEq(updated_numbers_disk[2], 3); + + // Update a string array and verify the change. + string[] memory new_strings = new string[](2); + new_strings[0] = "hello"; + new_strings[1] = "world"; + config.set(1, "str_array", new_strings); + + string[] memory updated_strings_mem = config.get(1, "str_array").toStringArray(); + assertEq(updated_strings_mem.length, 2); + assertEq(updated_strings_mem[0], "hello"); + assertEq(updated_strings_mem[1], "world"); + + content = vm.readFile(testConfig); + string[] memory updated_strings_disk = vm.parseTomlStringArray(content, "$.mainnet.string.str_array"); + assertEq(updated_strings_disk.length, 2); + assertEq(updated_strings_disk[0], "hello"); + assertEq(updated_strings_disk[1], "world"); + + // Create a new uint variable and verify the change. + config.set(1, "new_uint", uint256(42)); + + assertEq(config.get(1, "new_uint").toUint256(), 42); + + content = vm.readFile(testConfig); + assertEq(vm.parseTomlUint(content, "$.mainnet.uint.new_uint"), 42); + + // Create a new int variable and verify the change. + config.set(1, "new_int", int256(-42)); + + assertEq(config.get(1, "new_int").toInt256(), -42); + + content = vm.readFile(testConfig); + assertEq(vm.parseTomlInt(content, "$.mainnet.int.new_int"), -42); + + // Create a new int array and verify the change. + int256[] memory new_ints = new int256[](2); + new_ints[0] = -100; + new_ints[1] = 200; + config.set(10, "new_ints", new_ints); + + int256[] memory updated_ints_mem = config.get(10, "new_ints").toInt256Array(); + assertEq(updated_ints_mem.length, 2); + assertEq(updated_ints_mem[0], -100); + assertEq(updated_ints_mem[1], 200); + + content = vm.readFile(testConfig); + int256[] memory updated_ints_disk = vm.parseTomlIntArray(content, "$.optimism.int.new_ints"); + assertEq(updated_ints_disk.length, 2); + assertEq(updated_ints_disk[0], -100); + assertEq(updated_ints_disk[1], 200); + + // Create a new bytes32 array and verify the change. + bytes32[] memory new_words = new bytes32[](2); + new_words[0] = bytes32(uint256(0xDEAD)); + new_words[1] = bytes32(uint256(0xBEEF)); + config.set(10, "new_words", new_words); + + bytes32[] memory updated_words_mem = config.get(10, "new_words").toBytes32Array(); + assertEq(updated_words_mem.length, 2); + assertEq(updated_words_mem[0], new_words[0]); + assertEq(updated_words_mem[1], new_words[1]); + + content = vm.readFile(testConfig); + bytes32[] memory updated_words_disk = vm.parseTomlBytes32Array(content, "$.optimism.bytes32.new_words"); + assertEq(updated_words_disk.length, 2); + assertEq(vm.toString(updated_words_disk[0]), vm.toString(new_words[0])); + assertEq(vm.toString(updated_words_disk[1]), vm.toString(new_words[1])); + } + + // Clean up the temporary file. + vm.removeFile(testConfig); + } + + function test_writeUpdatesBackToFile() public { + // Create a temporary copy of the config file to avoid modifying the original. + string memory originalConfig = "./test/fixtures/config.toml"; + string memory testConfig = "./test/fixtures/write_config.t.toml"; + vm.copyFile(originalConfig, testConfig); + + // Deploy the config contract with `writeToFile = false` (disabled). + _loadConfig(testConfig, false); + + // Update a single boolean value and verify the file is NOT changed. + config.set(1, "is_live", false); + string memory content = vm.readFile(testConfig); + assertTrue(vm.parseTomlBool(content, "$.mainnet.bool.is_live"), "File should not be updated yet"); + + // Enable writing to file bypassing the context check. + vm.store(address(config), bytes32(uint256(5)), bytes32(uint256(1))); + + // Update the value again and verify the file IS changed. + config.set(1, "is_live", false); + content = vm.readFile(testConfig); + assertFalse(vm.parseTomlBool(content, "$.mainnet.bool.is_live"), "File should be updated now"); + + // Disable writing to file. + config.writeUpdatesBackToFile(false); + + // Update the value again and verify the file is NOT changed. + config.set(1, "is_live", true); + content = vm.readFile(testConfig); + assertFalse(vm.parseTomlBool(content, "$.mainnet.bool.is_live"), "File should not be updated again"); + + // Clean up the temporary file. + vm.removeFile(testConfig); + } + + function testRevert_WriteToFileInForbiddenCtxt() public { + // Cannot initialize enabling writing to file unless we are in SCRIPT mode. + vm.expectRevert(StdConfig.WriteToFileInForbiddenCtxt.selector); + _loadConfig("./test/fixtures/config.toml", true); + + // Initialize with `writeToFile = false`. + _loadConfig("./test/fixtures/config.toml", false); + + // Cannot enable writing to file unless we are in SCRIPT mode. + vm.expectRevert(StdConfig.WriteToFileInForbiddenCtxt.selector); + config.writeUpdatesBackToFile(true); + } + + function testRevert_InvalidChainKey() public { + // Create a fixture with an invalid chain key + string memory invalidChainConfig = "./test/fixtures/config_invalid_chain.toml"; + vm.writeFile( + invalidChainConfig, + string.concat( + "[mainnet]\n", + "endpoint_url = \"https://eth.llamarpc.com\"\n", + "\n", + "[mainnet.uint]\n", + "valid_number = 123\n", + "\n", + "# Invalid chain key (not a number and not a valid alias)\n", + "[invalid_chain]\n", + "endpoint_url = \"https://invalid.com\"\n", + "\n", + "[invalid_chain_9999.uint]\n", + "some_value = 456\n" + ) + ); + + vm.expectRevert(abi.encodeWithSelector(StdConfig.InvalidChainKey.selector, "invalid_chain")); + new StdConfig(invalidChainConfig, false); + vm.removeFile(invalidChainConfig); + } + + function testRevert_ChainNotInitialized() public { + _loadConfig("./test/fixtures/config.toml", false); + + // Enable writing to file bypassing the context check. + vm.store(address(config), bytes32(uint256(5)), bytes32(uint256(1))); + + // Try to write a value for a non-existent chain ID + vm.expectRevert(abi.encodeWithSelector(StdConfig.ChainNotInitialized.selector, uint256(999999))); + config.set(999999, "some_key", uint256(123)); + } + + function testRevert_UnableToParseVariable() public { + // Create a temporary fixture with an unparsable variable + string memory badParseConfig = "./test/fixtures/config_bad_parse.toml"; + vm.writeFile( + badParseConfig, + string.concat( + "[mainnet]\n", + "endpoint_url = \"https://eth.llamarpc.com\"\n", + "\n", + "[mainnet.uint]\n", + "bad_value = \"not_a_number\"\n" + ) + ); + + vm.expectRevert(abi.encodeWithSelector(StdConfig.UnableToParseVariable.selector, "bad_value")); + new StdConfig(badParseConfig, false); + vm.removeFile(badParseConfig); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/LibVariable.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/LibVariable.t.sol new file mode 100644 index 00000000..2fc00a91 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/LibVariable.t.sol @@ -0,0 +1,434 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.13; + +import {Test} from "../src/Test.sol"; +import {Variable, Type, TypeKind, LibVariable} from "../src/LibVariable.sol"; + +contract LibVariableTest is Test { + using LibVariable for Type; + using LibVariable for TypeKind; + + LibVariableHelper internal helper; + + bytes internal expectedErr; + Variable internal uninitVar; + Variable internal boolVar; + Variable internal addressVar; + Variable internal bytes32Var; + Variable internal uintVar; + Variable internal intVar; + Variable internal stringVar; + Variable internal bytesVar; + Variable internal boolArrayVar; + Variable internal addressArrayVar; + Variable internal bytes32ArrayVar; + Variable internal uintArrayVar; + Variable internal intArrayVar; + Variable internal stringArrayVar; + Variable internal bytesArrayVar; + + function setUp() public { + helper = new LibVariableHelper(); + + // UNINITIALIZED + uninitVar = Variable(Type(TypeKind.None, false), ""); + + // SINGLE VALUES + boolVar = Variable(Type(TypeKind.Bool, false), abi.encode(true)); + addressVar = Variable(Type(TypeKind.Address, false), abi.encode(address(0xdeadbeef))); + bytes32Var = Variable(Type(TypeKind.Bytes32, false), abi.encode(bytes32(uint256(42)))); + uintVar = Variable(Type(TypeKind.Uint256, false), abi.encode(uint256(123))); + intVar = Variable(Type(TypeKind.Int256, false), abi.encode(int256(-123))); + stringVar = Variable(Type(TypeKind.String, false), abi.encode("hello world")); + bytesVar = Variable(Type(TypeKind.Bytes, false), abi.encode(hex"c0ffee")); + + // ARRAY VALUES + bool[] memory bools = new bool[](2); + bools[0] = true; + bools[1] = false; + boolArrayVar = Variable(Type(TypeKind.Bool, true), abi.encode(bools)); + + address[] memory addrs = new address[](2); + addrs[0] = address(0x1); + addrs[1] = address(0x2); + addressArrayVar = Variable(Type(TypeKind.Address, true), abi.encode(addrs)); + + bytes32[] memory b32s = new bytes32[](2); + b32s[0] = bytes32(uint256(1)); + b32s[1] = bytes32(uint256(2)); + bytes32ArrayVar = Variable(Type(TypeKind.Bytes32, true), abi.encode(b32s)); + + uint256[] memory uints = new uint256[](2); + uints[0] = 1; + uints[1] = 2; + uintArrayVar = Variable(Type(TypeKind.Uint256, true), abi.encode(uints)); + + int256[] memory ints = new int256[](2); + ints[0] = -1; + ints[1] = 2; + intArrayVar = Variable(Type(TypeKind.Int256, true), abi.encode(ints)); + + string[] memory strings = new string[](2); + strings[0] = "one"; + strings[1] = "two"; + stringArrayVar = Variable(Type(TypeKind.String, true), abi.encode(strings)); + + bytes[] memory b = new bytes[](2); + b[0] = hex"01"; + b[1] = hex"02"; + bytesArrayVar = Variable(Type(TypeKind.Bytes, true), abi.encode(b)); + } + + // -- SUCCESS CASES -------------------------------------------------------- + + function test_TypeHelpers() public view { + // TypeKind.toString() + assertEq(TypeKind.None.toString(), "none"); + assertEq(TypeKind.Bool.toString(), "bool"); + assertEq(TypeKind.Address.toString(), "address"); + assertEq(TypeKind.Bytes32.toString(), "bytes32"); + assertEq(TypeKind.Uint256.toString(), "uint256"); + assertEq(TypeKind.Int256.toString(), "int256"); + assertEq(TypeKind.String.toString(), "string"); + assertEq(TypeKind.Bytes.toString(), "bytes"); + + // TypeKind.toTomlKey() + assertEq(TypeKind.Uint256.toTomlKey(), "uint"); + assertEq(TypeKind.Int256.toTomlKey(), "int"); + assertEq(TypeKind.Bytes32.toTomlKey(), "bytes32"); + + // Type.toString() + assertEq(boolVar.ty.toString(), "bool"); + assertEq(boolArrayVar.ty.toString(), "bool[]"); + assertEq(uintVar.ty.toString(), "uint256"); + assertEq(uintArrayVar.ty.toString(), "uint256[]"); + assertEq(uninitVar.ty.toString(), "none"); + + // Type.isEqual() + assertTrue(boolVar.ty.isEqual(Type(TypeKind.Bool, false))); + assertFalse(boolVar.ty.isEqual(Type(TypeKind.Bool, true))); + assertFalse(boolVar.ty.isEqual(Type(TypeKind.Address, false))); + + // Type.assertEq() + boolVar.ty.assertEq(Type(TypeKind.Bool, false)); + uintArrayVar.ty.assertEq(Type(TypeKind.Uint256, true)); + } + + function test_Coercion() public view { + // Single values + assertTrue(helper.toBool(boolVar)); + assertEq(helper.toAddress(addressVar), address(0xdeadbeef)); + assertEq(helper.toBytes32(bytes32Var), bytes32(uint256(42))); + assertEq(helper.toUint256(uintVar), 123); + assertEq(helper.toInt256(intVar), -123); + assertEq(helper.toString(stringVar), "hello world"); + assertEq(helper.toBytes(bytesVar), hex"c0ffee"); + + // Bool array + bool[] memory bools = helper.toBoolArray(boolArrayVar); + assertEq(bools.length, 2); + assertTrue(bools[0]); + assertFalse(bools[1]); + + // Address array + address[] memory addrs = helper.toAddressArray(addressArrayVar); + assertEq(addrs.length, 2); + assertEq(addrs[0], address(0x1)); + assertEq(addrs[1], address(0x2)); + + // String array + string[] memory strings = helper.toStringArray(stringArrayVar); + assertEq(strings.length, 2); + assertEq(strings[0], "one"); + assertEq(strings[1], "two"); + } + + function test_Downcasting() public view { + // Uint downcasting + Variable memory v_uint_small = Variable(Type(TypeKind.Uint256, false), abi.encode(uint256(100))); + assertEq(helper.toUint128(v_uint_small), 100); + assertEq(helper.toUint64(v_uint_small), 100); + assertEq(helper.toUint32(v_uint_small), 100); + assertEq(helper.toUint16(v_uint_small), 100); + assertEq(helper.toUint8(v_uint_small), 100); + + // Uint array downcasting + uint256[] memory small_uints = new uint256[](2); + small_uints[0] = 10; + small_uints[1] = 20; + Variable memory v_uint_array_small = Variable(Type(TypeKind.Uint256, true), abi.encode(small_uints)); + uint8[] memory u8_array = helper.toUint8Array(v_uint_array_small); + assertEq(u8_array[0], 10); + assertEq(u8_array[1], 20); + + // Int downcasting + Variable memory v_int_small_pos = Variable(Type(TypeKind.Int256, false), abi.encode(int256(100))); + Variable memory v_int_small_neg = Variable(Type(TypeKind.Int256, false), abi.encode(int256(-100))); + assertEq(helper.toInt128(v_int_small_pos), 100); + assertEq(helper.toInt64(v_int_small_neg), -100); + assertEq(helper.toInt32(v_int_small_pos), 100); + assertEq(helper.toInt16(v_int_small_neg), -100); + assertEq(helper.toInt8(v_int_small_pos), 100); + + // Int array downcasting + int256[] memory small_ints = new int256[](2); + small_ints[0] = -10; + small_ints[1] = 20; + Variable memory intArraySmall = Variable(Type(TypeKind.Int256, true), abi.encode(small_ints)); + int8[] memory i8_array = helper.toInt8Array(intArraySmall); + assertEq(i8_array[0], -10); + assertEq(i8_array[1], 20); + } + + // -- REVERT CASES --------------------------------------------------------- + + function testRevert_NotInitialized() public { + vm.expectRevert(LibVariable.NotInitialized.selector); + helper.toBool(uninitVar); + + vm.expectRevert(LibVariable.NotInitialized.selector); + helper.toAddressArray(uninitVar); + } + + function testRevert_assertExists() public { + vm.expectRevert(LibVariable.NotInitialized.selector); + helper.assertExists(uninitVar); + } + + function testRevert_TypeMismatch() public { + // Single values + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "uint256", "bool")); + helper.toUint256(boolVar); + + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "address", "string")); + helper.toAddress(stringVar); + + // Arrays + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "uint256[]", "bool[]")); + helper.toUint256Array(boolArrayVar); + + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "address[]", "string[]")); + helper.toAddressArray(stringArrayVar); + + // Single value to array + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "bool[]", "bool")); + helper.toBoolArray(boolVar); + + // Array to single value + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "bool", "bool[]")); + helper.toBool(boolArrayVar); + + // assertEq reverts + vm.expectRevert(abi.encodeWithSelector(LibVariable.TypeMismatch.selector, "uint256", "bool")); + helper.assertEq(boolVar.ty, Type(TypeKind.Uint256, false)); + } + + function testRevert_UnsafeCast() public { + // uint overflow + Variable memory uintLarge = Variable(Type(TypeKind.Uint256, false), abi.encode(uint256(type(uint128).max) + 1)); + expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value does not fit in 'uint128'"); + vm.expectRevert(expectedErr); + helper.toUint128(uintLarge); + + // int overflow + Variable memory intLarge = Variable(Type(TypeKind.Int256, false), abi.encode(int256(type(int128).max) + 1)); + expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value does not fit in 'int128'"); + + vm.expectRevert(expectedErr); + helper.toInt128(intLarge); + + // int underflow + Variable memory intSmall = Variable(Type(TypeKind.Int256, false), abi.encode(int256(type(int128).min) - 1)); + expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value does not fit in 'int128'"); + + vm.expectRevert(expectedErr); + helper.toInt128(intSmall); + + // uint array overflow + uint256[] memory uintArray = new uint256[](2); + uintArray[0] = 10; + uintArray[1] = uint256(type(uint64).max) + 1; + Variable memory uintArrayLarge = Variable(Type(TypeKind.Uint256, true), abi.encode(uintArray)); + expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value in array does not fit in 'uint64'"); + + vm.expectRevert(expectedErr); + helper.toUint64Array(uintArrayLarge); + + // int array overflow + int256[] memory intArray = new int256[](2); + intArray[0] = 10; + intArray[1] = int256(type(int64).max) + 1; + Variable memory intArrayLarge = Variable(Type(TypeKind.Int256, true), abi.encode(intArray)); + expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value in array does not fit in 'int64'"); + + vm.expectRevert(expectedErr); + helper.toInt64Array(intArrayLarge); + + // int array underflow + intArray[0] = 10; + intArray[1] = int256(type(int64).min) - 1; + Variable memory intArraySmall = Variable(Type(TypeKind.Int256, true), abi.encode(intArray)); + expectedErr = abi.encodeWithSelector(LibVariable.UnsafeCast.selector, "value in array does not fit in 'int64'"); + + vm.expectRevert(expectedErr); + helper.toInt64Array(intArraySmall); + } +} + +/// @dev We must use an external helper contract to ensure proper call depth for `vm.expectRevert`, +/// as direct library calls are inlined by the compiler, causing call depth issues. +contract LibVariableHelper { + using LibVariable for Type; + using LibVariable for TypeKind; + + // Assertions + function assertExists(Variable memory v) external pure { + v.assertExists(); + } + + function assertEq(Type memory t1, Type memory t2) external pure { + t1.assertEq(t2); + } + + // Single Value Coercion + function toBool(Variable memory v) external pure returns (bool) { + return v.toBool(); + } + + function toAddress(Variable memory v) external pure returns (address) { + return v.toAddress(); + } + + function toBytes32(Variable memory v) external pure returns (bytes32) { + return v.toBytes32(); + } + + function toUint256(Variable memory v) external pure returns (uint256) { + return v.toUint256(); + } + + function toInt256(Variable memory v) external pure returns (int256) { + return v.toInt256(); + } + + function toString(Variable memory v) external pure returns (string memory) { + return v.toString(); + } + + function toBytes(Variable memory v) external pure returns (bytes memory) { + return v.toBytes(); + } + + // Array Coercion + function toBoolArray(Variable memory v) external pure returns (bool[] memory) { + return v.toBoolArray(); + } + + function toAddressArray(Variable memory v) external pure returns (address[] memory) { + return v.toAddressArray(); + } + + function toBytes32Array(Variable memory v) external pure returns (bytes32[] memory) { + return v.toBytes32Array(); + } + + function toUint256Array(Variable memory v) external pure returns (uint256[] memory) { + return v.toUint256Array(); + } + + function toInt256Array(Variable memory v) external pure returns (int256[] memory) { + return v.toInt256Array(); + } + + function toStringArray(Variable memory v) external pure returns (string[] memory) { + return v.toStringArray(); + } + + function toBytesArray(Variable memory v) external pure returns (bytes[] memory) { + return v.toBytesArray(); + } + + // Uint Downcasting + function toUint128(Variable memory v) external pure returns (uint128) { + return v.toUint128(); + } + + function toUint64(Variable memory v) external pure returns (uint64) { + return v.toUint64(); + } + + function toUint32(Variable memory v) external pure returns (uint32) { + return v.toUint32(); + } + + function toUint16(Variable memory v) external pure returns (uint16) { + return v.toUint16(); + } + + function toUint8(Variable memory v) external pure returns (uint8) { + return v.toUint8(); + } + + // Int Downcasting + function toInt128(Variable memory v) external pure returns (int128) { + return v.toInt128(); + } + + function toInt64(Variable memory v) external pure returns (int64) { + return v.toInt64(); + } + + function toInt32(Variable memory v) external pure returns (int32) { + return v.toInt32(); + } + + function toInt16(Variable memory v) external pure returns (int16) { + return v.toInt16(); + } + + function toInt8(Variable memory v) external pure returns (int8) { + return v.toInt8(); + } + + // Uint Array Downcasting + function toUint128Array(Variable memory v) external pure returns (uint128[] memory) { + return v.toUint128Array(); + } + + function toUint64Array(Variable memory v) external pure returns (uint64[] memory) { + return v.toUint64Array(); + } + + function toUint32Array(Variable memory v) external pure returns (uint32[] memory) { + return v.toUint32Array(); + } + + function toUint16Array(Variable memory v) external pure returns (uint16[] memory) { + return v.toUint16Array(); + } + + function toUint8Array(Variable memory v) external pure returns (uint8[] memory) { + return v.toUint8Array(); + } + + // Int Array Downcasting + function toInt128Array(Variable memory v) external pure returns (int128[] memory) { + return v.toInt128Array(); + } + + function toInt64Array(Variable memory v) external pure returns (int64[] memory) { + return v.toInt64Array(); + } + + function toInt32Array(Variable memory v) external pure returns (int32[] memory) { + return v.toInt32Array(); + } + + function toInt16Array(Variable memory v) external pure returns (int16[] memory) { + return v.toInt16Array(); + } + + function toInt8Array(Variable memory v) external pure returns (int8[] memory) { + return v.toInt8Array(); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdAssertions.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdAssertions.t.sol new file mode 100644 index 00000000..acc0c1e8 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdAssertions.t.sol @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {StdAssertions} from "../src/StdAssertions.sol"; +import {Vm} from "../src/Vm.sol"; + +interface VmInternal is Vm { + function _expectCheatcodeRevert(bytes memory message) external; +} + +contract StdAssertionsTest is StdAssertions { + string constant errorMessage = "User provided message"; + uint256 constant maxDecimals = 77; + + bool constant SHOULD_REVERT = true; + bool constant SHOULD_RETURN = false; + + bool constant STRICT_REVERT_DATA = true; + bool constant NON_STRICT_REVERT_DATA = false; + + VmInternal constant vm = VmInternal(address(uint160(uint256(keccak256("hevm cheat code"))))); + + function testFuzz_AssertEqCall_Return_Pass( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnData, + bool strictRevertData + ) external { + address targetA = address(new TestMockCall(returnData, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnData, SHOULD_RETURN)); + + assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); + } + + function testFuzz_RevertWhenCalled_AssertEqCall_Return_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnDataA, + bytes memory returnDataB, + bool strictRevertData + ) external { + vm.assume(keccak256(returnDataA) != keccak256(returnDataB)); + + address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnDataB, SHOULD_RETURN)); + + vm._expectCheatcodeRevert( + bytes( + string.concat( + "Call return data does not match: ", vm.toString(returnDataA), " != ", vm.toString(returnDataB) + ) + ) + ); + assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); + } + + function testFuzz_AssertEqCall_Revert_Pass( + bytes memory callDataA, + bytes memory callDataB, + bytes memory revertDataA, + bytes memory revertDataB + ) external { + address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); + address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); + + assertEqCall(targetA, callDataA, targetB, callDataB, NON_STRICT_REVERT_DATA); + } + + function testFuzz_RevertWhenCalled_AssertEqCall_Revert_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory revertDataA, + bytes memory revertDataB + ) external { + vm.assume(keccak256(revertDataA) != keccak256(revertDataB)); + + address targetA = address(new TestMockCall(revertDataA, SHOULD_REVERT)); + address targetB = address(new TestMockCall(revertDataB, SHOULD_REVERT)); + + vm._expectCheatcodeRevert( + bytes( + string.concat( + "Call revert data does not match: ", vm.toString(revertDataA), " != ", vm.toString(revertDataB) + ) + ) + ); + assertEqCall(targetA, callDataA, targetB, callDataB, STRICT_REVERT_DATA); + } + + function testFuzz_RevertWhenCalled_AssertEqCall_Fail( + bytes memory callDataA, + bytes memory callDataB, + bytes memory returnDataA, + bytes memory returnDataB, + bool strictRevertData + ) external { + address targetA = address(new TestMockCall(returnDataA, SHOULD_RETURN)); + address targetB = address(new TestMockCall(returnDataB, SHOULD_REVERT)); + + vm.expectRevert(bytes("assertion failed")); + this.assertEqCallExternal(targetA, callDataA, targetB, callDataB, strictRevertData); + + vm.expectRevert(bytes("assertion failed")); + this.assertEqCallExternal(targetB, callDataB, targetA, callDataA, strictRevertData); + } + + // Helper function to test outcome of assertEqCall via `expect` cheatcodes + function assertEqCallExternal( + address targetA, + bytes memory callDataA, + address targetB, + bytes memory callDataB, + bool strictRevertData + ) public { + assertEqCall(targetA, callDataA, targetB, callDataB, strictRevertData); + } +} + +contract TestMockCall { + bytes returnData; + bool shouldRevert; + + constructor(bytes memory returnData_, bool shouldRevert_) { + returnData = returnData_; + shouldRevert = shouldRevert_; + } + + fallback() external payable { + bytes memory returnData_ = returnData; + + if (shouldRevert) { + assembly { + revert(add(returnData_, 0x20), mload(returnData_)) + } + } else { + assembly { + return(add(returnData_, 0x20), mload(returnData_)) + } + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdChains.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdChains.t.sol new file mode 100644 index 00000000..0394d180 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdChains.t.sol @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {Test} from "../src/Test.sol"; + +contract StdChainsMock is Test { + function exposed_getChain(string memory chainAlias) public returns (Chain memory) { + return getChain(chainAlias); + } + + function exposed_getChain(uint256 chainId) public returns (Chain memory) { + return getChain(chainId); + } + + function exposed_setChain(string memory chainAlias, ChainData memory chainData) public { + setChain(chainAlias, chainData); + } + + function exposed_setFallbackToDefaultRpcUrls(bool useDefault) public { + setFallbackToDefaultRpcUrls(useDefault); + } +} + +contract StdChainsTest is Test { + function test_ChainRpcInitialization() public { + // RPCs specified in `foundry.toml` should be updated. + assertEq(getChain(1).rpcUrl, "https://reth-ethereum.ithaca.xyz/rpc"); + assertEq(getChain("optimism_sepolia").rpcUrl, "https://sepolia.optimism.io/"); + assertEq(getChain("arbitrum_one_sepolia").rpcUrl, "https://sepolia-rollup.arbitrum.io/rpc/"); + + // Environment variables should be the next fallback + assertEq(getChain("arbitrum_nova").rpcUrl, "https://nova.arbitrum.io/rpc"); + vm.setEnv("ARBITRUM_NOVA_RPC_URL", "myoverride"); + assertEq(getChain("arbitrum_nova").rpcUrl, "myoverride"); + vm.setEnv("ARBITRUM_NOVA_RPC_URL", "https://nova.arbitrum.io/rpc"); + + // Cannot override RPCs defined in `foundry.toml` + vm.setEnv("MAINNET_RPC_URL", "myoverride2"); + assertEq(getChain("mainnet").rpcUrl, "https://reth-ethereum.ithaca.xyz/rpc"); + + // Other RPCs should remain unchanged. + assertEq(getChain(31337).rpcUrl, "http://127.0.0.1:8545"); + assertEq(getChain("sepolia").rpcUrl, "https://sepolia.infura.io/v3/b9794ad1ddf84dfb8c34d6bb5dca2001"); + } + + // Named with a leading underscore to clarify this is not intended to be run as a normal test, + // and is intended to be used in the below `test_Rpcs` test. + function _testRpc(string memory rpcAlias) internal { + string memory rpcUrl = getChain(rpcAlias).rpcUrl; + vm.createSelectFork(rpcUrl); + } + + // Ensure we can connect to the default RPC URL for each chain. + // Currently commented out since this is slow and public RPCs are flaky, often resulting in failing CI. + // function test_Rpcs() public { + // _testRpc("mainnet"); + // _testRpc("sepolia"); + // _testRpc("holesky"); + // _testRpc("optimism"); + // _testRpc("optimism_sepolia"); + // _testRpc("arbitrum_one"); + // _testRpc("arbitrum_one_sepolia"); + // _testRpc("arbitrum_nova"); + // _testRpc("polygon"); + // _testRpc("polygon_amoy"); + // _testRpc("avalanche"); + // _testRpc("avalanche_fuji"); + // _testRpc("bnb_smart_chain"); + // _testRpc("bnb_smart_chain_testnet"); + // _testRpc("gnosis_chain"); + // _testRpc("moonbeam"); + // _testRpc("moonriver"); + // _testRpc("moonbase"); + // _testRpc("base_sepolia"); + // _testRpc("base"); + // _testRpc("blast_sepolia"); + // _testRpc("blast"); + // _testRpc("fantom_opera"); + // _testRpc("fantom_opera_testnet"); + // _testRpc("fraxtal"); + // _testRpc("fraxtal_testnet"); + // _testRpc("berachain_bartio_testnet"); + // _testRpc("flare"); + // _testRpc("flare_coston2"); + // } + + function test_RevertIf_ChainNotFound() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(string): Chain with alias \"does_not_exist\" not found."); + stdChainsMock.exposed_getChain("does_not_exist"); + } + + function test_RevertIf_SetChain_ChainIdExist_FirstTest() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains setChain(string,ChainData): Chain ID 31337 already used by \"anvil\"."); + stdChainsMock.exposed_setChain("anvil2", ChainData("Anvil", 31337, "URL")); + } + + function test_RevertIf_ChainBubbleUp() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + stdChainsMock.exposed_setChain("needs_undefined_env_var", ChainData("", 123456789, "")); + // Forge environment variable error. + vm.expectRevert(); + stdChainsMock.exposed_getChain("needs_undefined_env_var"); + } + + function test_RevertIf_SetChain_ChainIdExists_SecondTest() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + stdChainsMock.exposed_setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + + vm.expectRevert('StdChains setChain(string,ChainData): Chain ID 123456789 already used by "custom_chain".'); + + stdChainsMock.exposed_setChain("another_custom_chain", ChainData("", 123456789, "")); + } + + function test_SetChain() public { + setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + Chain memory customChain = getChain("custom_chain"); + assertEq(customChain.name, "Custom Chain"); + assertEq(customChain.chainId, 123456789); + assertEq(customChain.chainAlias, "custom_chain"); + assertEq(customChain.rpcUrl, "https://custom.chain/"); + Chain memory chainById = getChain(123456789); + assertEq(chainById.name, customChain.name); + assertEq(chainById.chainId, customChain.chainId); + assertEq(chainById.chainAlias, customChain.chainAlias); + assertEq(chainById.rpcUrl, customChain.rpcUrl); + customChain.name = "Another Custom Chain"; + customChain.chainId = 987654321; + setChain("another_custom_chain", customChain); + Chain memory anotherCustomChain = getChain("another_custom_chain"); + assertEq(anotherCustomChain.name, "Another Custom Chain"); + assertEq(anotherCustomChain.chainId, 987654321); + assertEq(anotherCustomChain.chainAlias, "another_custom_chain"); + assertEq(anotherCustomChain.rpcUrl, "https://custom.chain/"); + // Verify the first chain data was not overwritten + chainById = getChain(123456789); + assertEq(chainById.name, "Custom Chain"); + assertEq(chainById.chainId, 123456789); + } + + function test_RevertIf_SetEmptyAlias() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains setChain(string,ChainData): Chain alias cannot be the empty string."); + stdChainsMock.exposed_setChain("", ChainData("", 123456789, "")); + } + + function test_RevertIf_SetNoChainId0() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains setChain(string,ChainData): Chain ID cannot be 0."); + stdChainsMock.exposed_setChain("alias", ChainData("", 0, "")); + } + + function test_RevertIf_GetNoChainId0() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(uint256): Chain ID cannot be 0."); + stdChainsMock.exposed_getChain(0); + } + + function test_RevertIf_GetNoEmptyAlias() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(string): Chain alias cannot be the empty string."); + stdChainsMock.exposed_getChain(""); + } + + function test_RevertIf_ChainNotInitialized() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(string): Chain with alias \"no_such_alias\" not found."); + stdChainsMock.exposed_getChain("no_such_alias"); + } + + function test_RevertIf_ChainAliasNotFound() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + vm.expectRevert("StdChains getChain(uint256): Chain with ID 321 not found."); + + stdChainsMock.exposed_getChain(321); + } + + function test_SetChain_ExistingOne() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + setChain("custom_chain", ChainData("Custom Chain", 123456789, "https://custom.chain/")); + assertEq(getChain(123456789).chainId, 123456789); + + setChain("custom_chain", ChainData("Modified Chain", 9999999999999999999, "https://modified.chain/")); + vm.expectRevert("StdChains getChain(uint256): Chain with ID 123456789 not found."); + stdChainsMock.exposed_getChain(123456789); + + Chain memory modifiedChain = getChain(9999999999999999999); + assertEq(modifiedChain.name, "Modified Chain"); + assertEq(modifiedChain.chainId, 9999999999999999999); + assertEq(modifiedChain.rpcUrl, "https://modified.chain/"); + } + + function test_RevertIf_DontUseDefaultRpcUrl() public { + // We deploy a mock to properly test the revert. + StdChainsMock stdChainsMock = new StdChainsMock(); + + // Should error if default RPCs flag is set to false. + stdChainsMock.exposed_setFallbackToDefaultRpcUrls(false); + vm.expectRevert(); + stdChainsMock.exposed_getChain(31337); + vm.expectRevert(); + stdChainsMock.exposed_getChain("sepolia"); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdCheats.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdCheats.t.sol new file mode 100644 index 00000000..57dbcc29 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdCheats.t.sol @@ -0,0 +1,639 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {StdCheats} from "../src/StdCheats.sol"; +import {Test} from "../src/Test.sol"; +import {stdJson} from "../src/StdJson.sol"; +import {stdToml} from "../src/StdToml.sol"; +import {IERC20} from "../src/interfaces/IERC20.sol"; + +contract StdCheatsTest is Test { + Bar test; + + using stdJson for string; + + function setUp() public { + test = new Bar(); + } + + function test_Skip() public { + vm.warp(100); + skip(25); + assertEq(block.timestamp, 125); + } + + function test_Rewind() public { + vm.warp(100); + rewind(25); + assertEq(block.timestamp, 75); + } + + function test_Hoax() public { + hoax(address(1337)); + test.bar{value: 100}(address(1337)); + } + + function test_HoaxOrigin() public { + hoax(address(1337), address(1337)); + test.origin{value: 100}(address(1337)); + } + + function test_HoaxDifferentAddresses() public { + hoax(address(1337), address(7331)); + test.origin{value: 100}(address(1337), address(7331)); + } + + function test_StartHoax() public { + startHoax(address(1337)); + test.bar{value: 100}(address(1337)); + test.bar{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } + + function test_StartHoaxOrigin() public { + startHoax(address(1337), address(1337)); + test.origin{value: 100}(address(1337)); + test.origin{value: 100}(address(1337)); + vm.stopPrank(); + test.bar(address(this)); + } + + function test_ChangePrankMsgSender() public { + vm.startPrank(address(1337)); + test.bar(address(1337)); + changePrank(address(0xdead)); + test.bar(address(0xdead)); + changePrank(address(1337)); + test.bar(address(1337)); + vm.stopPrank(); + } + + function test_ChangePrankMsgSenderAndTxOrigin() public { + vm.startPrank(address(1337), address(1338)); + test.origin(address(1337), address(1338)); + changePrank(address(0xdead), address(0xbeef)); + test.origin(address(0xdead), address(0xbeef)); + changePrank(address(1337), address(1338)); + test.origin(address(1337), address(1338)); + vm.stopPrank(); + } + + function test_MakeAccountEquivalence() public { + Account memory account = makeAccount("1337"); + (address addr, uint256 key) = makeAddrAndKey("1337"); + assertEq(account.addr, addr); + assertEq(account.key, key); + } + + function test_MakeAddrEquivalence() public { + (address addr,) = makeAddrAndKey("1337"); + assertEq(makeAddr("1337"), addr); + } + + function test_MakeAddrSigning() public { + (address addr, uint256 key) = makeAddrAndKey("1337"); + bytes32 hash = keccak256("some_message"); + + (uint8 v, bytes32 r, bytes32 s) = vm.sign(key, hash); + assertEq(ecrecover(hash, v, r, s), addr); + } + + function test_Deal() public { + deal(address(this), 1 ether); + assertEq(address(this).balance, 1 ether); + } + + function test_DealToken() public { + Bar barToken = new Bar(); + address bar = address(barToken); + deal(bar, address(this), 10000e18); + assertEq(barToken.balanceOf(address(this)), 10000e18); + } + + function test_DealTokenAdjustTotalSupply() public { + Bar barToken = new Bar(); + address bar = address(barToken); + deal(bar, address(this), 10000e18, true); + assertEq(barToken.balanceOf(address(this)), 10000e18); + assertEq(barToken.totalSupply(), 20000e18); + deal(bar, address(this), 0, true); + assertEq(barToken.balanceOf(address(this)), 0); + assertEq(barToken.totalSupply(), 10000e18); + } + + function test_DealERC1155Token() public { + BarERC1155 barToken = new BarERC1155(); + address bar = address(barToken); + dealERC1155(bar, address(this), 0, 10000e18, false); + assertEq(barToken.balanceOf(address(this), 0), 10000e18); + } + + function test_DealERC1155TokenAdjustTotalSupply() public { + BarERC1155 barToken = new BarERC1155(); + address bar = address(barToken); + dealERC1155(bar, address(this), 0, 10000e18, true); + assertEq(barToken.balanceOf(address(this), 0), 10000e18); + assertEq(barToken.totalSupply(0), 20000e18); + dealERC1155(bar, address(this), 0, 0, true); + assertEq(barToken.balanceOf(address(this), 0), 0); + assertEq(barToken.totalSupply(0), 10000e18); + } + + function test_DealERC721Token() public { + BarERC721 barToken = new BarERC721(); + address bar = address(barToken); + dealERC721(bar, address(2), 1); + assertEq(barToken.balanceOf(address(2)), 1); + assertEq(barToken.balanceOf(address(1)), 0); + dealERC721(bar, address(1), 2); + assertEq(barToken.balanceOf(address(1)), 1); + assertEq(barToken.balanceOf(bar), 1); + } + + function test_DeployCode() public { + address deployed = deployCode("StdCheats.t.sol:Bar", bytes("")); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + } + + function test_DestroyAccount() public { + // deploy something to destroy it + BarERC721 barToken = new BarERC721(); + address bar = address(barToken); + vm.setNonce(bar, 10); + deal(bar, 100); + + uint256 prevThisBalance = address(this).balance; + uint256 size; + assembly { + size := extcodesize(bar) + } + + assertGt(size, 0); + assertEq(bar.balance, 100); + assertEq(vm.getNonce(bar), 10); + + destroyAccount(bar, address(this)); + assembly { + size := extcodesize(bar) + } + assertEq(address(this).balance, prevThisBalance + 100); + assertEq(vm.getNonce(bar), 0); + assertEq(size, 0); + assertEq(bar.balance, 0); + } + + function test_DeployCodeNoArgs() public { + address deployed = deployCode("StdCheats.t.sol:Bar"); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + } + + function test_DeployCodeVal() public { + address deployed = deployCode("StdCheats.t.sol:Bar", bytes(""), 1 ether); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + assertEq(deployed.balance, 1 ether); + } + + function test_DeployCodeValNoArgs() public { + address deployed = deployCode("StdCheats.t.sol:Bar", 1 ether); + assertEq(string(getCode(deployed)), string(getCode(address(test)))); + assertEq(deployed.balance, 1 ether); + } + + // We need this so we can call "this.deployCode" rather than "deployCode" directly + function deployCodeHelper(string memory what) external { + deployCode(what); + } + + function test_RevertIf_DeployCodeFail() public { + vm.expectRevert(bytes("StdCheats deployCode(string): Deployment failed.")); + this.deployCodeHelper("StdCheats.t.sol:RevertingContract"); + } + + function getCode(address who) internal view returns (bytes memory o_code) { + /// @solidity memory-safe-assembly + assembly { + // retrieve the size of the code, this needs assembly + let size := extcodesize(who) + // allocate output byte array - this could also be done without assembly + // by using o_code = new bytes(size) + o_code := mload(0x40) + // new "memory end" including padding + mstore(0x40, add(o_code, and(add(add(size, 0x20), 0x1f), not(0x1f)))) + // store length in memory + mstore(o_code, size) + // actually retrieve the code, this needs assembly + extcodecopy(who, add(o_code, 0x20), 0, size) + } + } + + function test_DeriveRememberKey() public { + string memory mnemonic = "test test test test test test test test test test test junk"; + + (address deployer, uint256 privateKey) = deriveRememberKey(mnemonic, 0); + assertEq(deployer, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); + assertEq(privateKey, 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80); + } + + function test_BytesToUint() public pure { + assertEq(3, bytesToUint_test(hex"03")); + assertEq(2, bytesToUint_test(hex"02")); + assertEq(255, bytesToUint_test(hex"ff")); + assertEq(29625, bytesToUint_test(hex"73b9")); + } + + function test_ParseJsonTxDetail() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + string memory json = vm.readFile(path); + bytes memory transactionDetails = json.parseRaw(".transactions[0].tx"); + RawTx1559Detail memory rawTxDetail = abi.decode(transactionDetails, (RawTx1559Detail)); + Tx1559Detail memory txDetail = rawToConvertedEIP1559Detail(rawTxDetail); + assertEq(txDetail.from, 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266); + assertEq(txDetail.to, 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512); + assertEq( + txDetail.data, + hex"23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004" + ); + assertEq(txDetail.nonce, 3); + assertEq(txDetail.txType, 2); + assertEq(txDetail.gas, 29625); + assertEq(txDetail.value, 0); + } + + function test_ReadEIP1559Transaction() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + uint256 index = 0; + Tx1559 memory transaction = readTx1559(path, index); + transaction; + } + + function test_ReadEIP1559Transactions() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + Tx1559[] memory transactions = readTx1559s(path); + transactions; + } + + function test_ReadReceipt() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + uint256 index = 5; + Receipt memory receipt = readReceipt(path, index); + assertEq( + receipt.logsBloom, + hex"00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100" + ); + } + + function test_ReadReceipts() public view { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/test/fixtures/broadcast.log.json"); + Receipt[] memory receipts = readReceipts(path); + receipts; + } + + function test_GasMeteringModifier() public { + uint256 gas_start_normal = gasleft(); + addInLoop(); + uint256 gas_used_normal = gas_start_normal - gasleft(); + + uint256 gas_start_single = gasleft(); + addInLoopNoGas(); + uint256 gas_used_single = gas_start_single - gasleft(); + + uint256 gas_start_double = gasleft(); + addInLoopNoGasNoGas(); + uint256 gas_used_double = gas_start_double - gasleft(); + + assertTrue(gas_used_double + gas_used_single < gas_used_normal); + } + + function addInLoop() internal pure returns (uint256) { + uint256 b; + for (uint256 i; i < 10000; i++) { + b += i; + } + return b; + } + + function addInLoopNoGas() internal noGasMetering returns (uint256) { + return addInLoop(); + } + + function addInLoopNoGasNoGas() internal noGasMetering returns (uint256) { + return addInLoopNoGas(); + } + + function bytesToUint_test(bytes memory b) private pure returns (uint256) { + uint256 number; + for (uint256 i = 0; i < b.length; i++) { + number = number + uint256(uint8(b[i])) * (2 ** (8 * (b.length - (i + 1)))); + } + return number; + } + + function testFuzz_AssumeAddressIsNot(address addr) external { + // skip over Payable and NonPayable enums + for (uint8 i = 2; i < uint8(type(AddressType).max); i++) { + assumeAddressIsNot(addr, AddressType(i)); + } + assertTrue(addr != address(0)); + assertTrue(addr < address(1) || addr > address(9)); + assertTrue(addr != address(vm) || addr != 0x000000000000000000636F6e736F6c652e6c6f67); + } + + function test_AssumePayable() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + + // all should revert since these addresses are not payable + + // VM address + vm.expectRevert(); + stdCheatsMock.exposed_assumePayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + // Console address + vm.expectRevert(); + stdCheatsMock.exposed_assumePayable(0x000000000000000000636F6e736F6c652e6c6f67); + + // Create2Deployer + vm.expectRevert(); + stdCheatsMock.exposed_assumePayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); + + // all should pass since these addresses are payable + + // vitalik.eth + stdCheatsMock.exposed_assumePayable(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045); + + // mock payable contract + MockContractPayable cp = new MockContractPayable(); + stdCheatsMock.exposed_assumePayable(address(cp)); + } + + function test_AssumeNotPayable() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + + // all should pass since these addresses are not payable + + // VM address + stdCheatsMock.exposed_assumeNotPayable(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); + + // Console address + stdCheatsMock.exposed_assumeNotPayable(0x000000000000000000636F6e736F6c652e6c6f67); + + // Create2Deployer + stdCheatsMock.exposed_assumeNotPayable(0x4e59b44847b379578588920cA78FbF26c0B4956C); + + // all should revert since these addresses are payable + + // vitalik.eth + vm.expectRevert(); + stdCheatsMock.exposed_assumeNotPayable(0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045); + + // mock payable contract + MockContractPayable cp = new MockContractPayable(); + vm.expectRevert(); + stdCheatsMock.exposed_assumeNotPayable(address(cp)); + } + + function testFuzz_AssumeNotPrecompile(address addr) external { + assumeNotPrecompile(addr, getChain("optimism_sepolia").chainId); + assertTrue( + addr < address(1) || (addr > address(9) && addr < address(0x4200000000000000000000000000000000000000)) + || addr > address(0x4200000000000000000000000000000000000800) + ); + } + + function testFuzz_AssumeNotForgeAddress(address addr) external pure { + assumeNotForgeAddress(addr); + assertTrue( + addr != address(vm) && addr != 0x000000000000000000636F6e736F6c652e6c6f67 + && addr != 0x4e59b44847b379578588920cA78FbF26c0B4956C + ); + } + + function test_RevertIf_CannotDeployCodeTo() external { + vm.expectRevert("StdCheats deployCodeTo(string,bytes,uint256,address): Failed to create runtime bytecode."); + this._revertDeployCodeTo(); + } + + function _revertDeployCodeTo() external { + deployCodeTo("StdCheats.t.sol:RevertingContract", address(0)); + } + + function test_DeployCodeTo() external { + address arbitraryAddress = makeAddr("arbitraryAddress"); + + deployCodeTo( + "StdCheats.t.sol:MockContractWithConstructorArgs", + abi.encode(uint256(6), true, bytes20(arbitraryAddress)), + 1 ether, + arbitraryAddress + ); + + MockContractWithConstructorArgs ct = MockContractWithConstructorArgs(arbitraryAddress); + + assertEq(arbitraryAddress.balance, 1 ether); + assertEq(ct.x(), 6); + assertTrue(ct.y()); + assertEq(ct.z(), bytes20(arbitraryAddress)); + } +} + +contract StdCheatsMock is StdCheats { + function exposed_assumePayable(address addr) external { + assumePayable(addr); + } + + function exposed_assumeNotPayable(address addr) external { + assumeNotPayable(addr); + } + + // We deploy a mock version so we can properly test expected reverts. + function exposed_assumeNotBlacklisted(address token, address addr) external view { + return assumeNotBlacklisted(token, addr); + } +} + +contract StdCheatsForkTest is Test { + address internal constant USDC_BLACKLISTED_USER = 0x1E34A77868E19A6647b1f2F47B51ed72dEDE95DD; + address internal constant USDT_BLACKLISTED_USER = 0x8f8a8F4B54a2aAC7799d7bc81368aC27b852822A; + + MockUSDT public USDT; + MockUSDC public USDC; + + function setUp() public { + USDT = new MockUSDT(); + USDC = new MockUSDC(); + + USDC.setBlacklisted(USDC_BLACKLISTED_USER, true); + USDT.setBlacklisted(USDT_BLACKLISTED_USER, true); + } + + function test_RevertIf_CannotAssumeNoBlacklisted_EOA() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + address eoa = vm.addr({privateKey: 1}); + vm.expectRevert("StdCheats assumeNotBlacklisted(address,address): Token address is not a contract."); + stdCheatsMock.exposed_assumeNotBlacklisted(eoa, address(0)); + } + + function testFuzz_AssumeNotBlacklisted_TokenWithoutBlacklist(address addr) external view { + assumeNotBlacklisted(address(USDC), addr); + assumeNotBlacklisted(address(USDT), addr); + assertTrue(true); + } + + function test_RevertIf_AssumeNoBlacklisted_USDC() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + vm.expectRevert(); + stdCheatsMock.exposed_assumeNotBlacklisted(address(USDC), USDC_BLACKLISTED_USER); + } + + function testFuzz_AssumeNotBlacklisted_USDC(address addr) external view { + assumeNotBlacklisted(address(USDC), addr); + assertFalse(USDCLike(USDC).isBlacklisted(addr)); + } + + function test_RevertIf_AssumeNoBlacklisted_USDT() external { + // We deploy a mock version so we can properly test the revert. + StdCheatsMock stdCheatsMock = new StdCheatsMock(); + vm.expectRevert(); + stdCheatsMock.exposed_assumeNotBlacklisted(address(USDT), USDT_BLACKLISTED_USER); + } + + function testFuzz_AssumeNotBlacklisted_USDT(address addr) external view { + assumeNotBlacklisted(address(USDT), addr); + assertFalse(USDTLike(USDT).isBlackListed(addr)); + } +} + +/// @dev https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48#readProxyContract +interface USDCLike { + function isBlacklisted(address) external view returns (bool); +} + +/// @dev https://etherscan.io/token/0xdac17f958d2ee523a2206206994597c13d831ec7#readContract +interface USDTLike { + function isBlackListed(address) external view returns (bool); +} + +contract MockUSDT is USDTLike { + mapping(address => bool) private blacklist; + + function isBlackListed(address addr) external view returns (bool) { + return blacklist[addr]; + } + + function setBlacklisted(address addr, bool value) external { + blacklist[addr] = value; + } +} + +contract MockUSDC is USDCLike { + mapping(address => bool) private blacklist; + + function isBlacklisted(address addr) external view returns (bool) { + return blacklist[addr]; + } + + function setBlacklisted(address addr, bool value) external { + blacklist[addr] = value; + } +} + +contract Bar { + constructor() payable { + /// `DEAL` STDCHEAT + totalSupply = 10000e18; + balanceOf[address(this)] = totalSupply; + } + + /// `HOAX` and `CHANGEPRANK` STDCHEATS + function bar(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + } + + function origin(address expectedSender) public payable { + require(msg.sender == expectedSender, "!prank"); + require(tx.origin == expectedSender, "!prank"); + } + + function origin(address expectedSender, address expectedOrigin) public payable { + require(msg.sender == expectedSender, "!prank"); + require(tx.origin == expectedOrigin, "!prank"); + } + + /// `DEAL` STDCHEAT + mapping(address => uint256) public balanceOf; + uint256 public totalSupply; +} + +contract BarERC1155 { + constructor() payable { + /// `DEALERC1155` STDCHEAT + _totalSupply[0] = 10000e18; + _balances[0][address(this)] = _totalSupply[0]; + } + + function balanceOf(address account, uint256 id) public view virtual returns (uint256) { + return _balances[id][account]; + } + + function totalSupply(uint256 id) public view virtual returns (uint256) { + return _totalSupply[id]; + } + + /// `DEALERC1155` STDCHEAT + mapping(uint256 => mapping(address => uint256)) private _balances; + mapping(uint256 => uint256) private _totalSupply; +} + +contract BarERC721 { + constructor() payable { + /// `DEALERC721` STDCHEAT + _owners[1] = address(1); + _balances[address(1)] = 1; + _owners[2] = address(this); + _owners[3] = address(this); + _balances[address(this)] = 2; + } + + function balanceOf(address owner) public view virtual returns (uint256) { + return _balances[owner]; + } + + function ownerOf(uint256 tokenId) public view virtual returns (address) { + address owner = _owners[tokenId]; + return owner; + } + + mapping(uint256 => address) private _owners; + mapping(address => uint256) private _balances; +} + +contract RevertingContract { + constructor() { + revert(); + } +} + +contract MockContractWithConstructorArgs { + uint256 public immutable x; + bool public y; + bytes20 public z; + + constructor(uint256 _x, bool _y, bytes20 _z) payable { + x = _x; + y = _y; + z = _z; + } +} + +contract MockContractPayable { + receive() external payable {} +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdConstants.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdConstants.t.sol new file mode 100644 index 00000000..7a00530f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdConstants.t.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {StdConstants} from "../src/StdConstants.sol"; +import {Test} from "../src/Test.sol"; + +contract StdConstantsTest is Test { + function testVm() public view { + assertEq(StdConstants.VM.getBlockNumber(), 1); + } + + function testVmDerivation() public pure { + assertEq(address(StdConstants.VM), address(uint160(uint256(keccak256("hevm cheat code"))))); + } + + function testConsoleDerivation() public pure { + assertEq(StdConstants.CONSOLE, address(uint160(uint88(bytes11("console.log"))))); + } + + function testDefaultSender() public view { + assertEq(StdConstants.DEFAULT_SENDER, msg.sender); + } + + function testDefaultSenderDerivation() public pure { + assertEq(StdConstants.DEFAULT_SENDER, address(uint160(uint256(keccak256("foundry default caller"))))); + } + + function testDefaultTestContract() public { + assertEq(StdConstants.DEFAULT_TEST_CONTRACT, address(new Dummy())); + } + + function testDefaultTestContractDerivation() public view { + assertEq(address(this), StdConstants.VM.computeCreateAddress(StdConstants.DEFAULT_SENDER, 1)); + assertEq(StdConstants.DEFAULT_TEST_CONTRACT, StdConstants.VM.computeCreateAddress(address(this), 1)); + } +} + +contract Dummy {} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdError.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdError.t.sol new file mode 100644 index 00000000..29803d5d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdError.t.sol @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import {stdError} from "../src/StdError.sol"; +import {Test} from "../src/Test.sol"; + +contract StdErrorsTest is Test { + ErrorsTest test; + + function setUp() public { + test = new ErrorsTest(); + } + + function test_RevertIf_AssertionError() public { + vm.expectRevert(stdError.assertionError); + test.assertionError(); + } + + function test_RevertIf_ArithmeticError() public { + vm.expectRevert(stdError.arithmeticError); + test.arithmeticError(10); + } + + function test_RevertIf_DivisionError() public { + vm.expectRevert(stdError.divisionError); + test.divError(0); + } + + function test_RevertIf_ModError() public { + vm.expectRevert(stdError.divisionError); + test.modError(0); + } + + function test_RevertIf_EnumConversionError() public { + vm.expectRevert(stdError.enumConversionError); + test.enumConversion(1); + } + + function test_RevertIf_EncodeStgError() public { + vm.expectRevert(stdError.encodeStorageError); + test.encodeStgError(); + } + + function test_RevertIf_PopError() public { + vm.expectRevert(stdError.popError); + test.pop(); + } + + function test_RevertIf_IndexOOBError() public { + vm.expectRevert(stdError.indexOOBError); + test.indexOOBError(1); + } + + function test_RevertIf_MemOverflowError() public { + vm.expectRevert(stdError.memOverflowError); + test.mem(); + } + + function test_RevertIf_InternError() public { + vm.expectRevert(stdError.zeroVarError); + test.intern(); + } +} + +contract ErrorsTest { + enum T { + T1 + } + + uint256[] public someArr; + bytes someBytes; + + function assertionError() public pure { + assert(false); + } + + function arithmeticError(uint256 a) public pure { + a -= 100; + } + + function divError(uint256 a) public pure { + 100 / a; + } + + function modError(uint256 a) public pure { + 100 % a; + } + + function enumConversion(uint256 a) public pure { + T(a); + } + + function encodeStgError() public { + /// @solidity memory-safe-assembly + assembly { + sstore(someBytes.slot, 1) + } + keccak256(someBytes); + } + + function pop() public { + someArr.pop(); + } + + function indexOOBError(uint256 a) public pure { + uint256[] memory t = new uint256[](0); + t[a]; + } + + function mem() public pure { + uint256 l = 2 ** 256 / 32; + new uint256[](l); + } + + function intern() public returns (uint256) { + function(uint256) internal returns (uint256) x; + x(2); + return 7; + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdJson.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdJson.t.sol new file mode 100644 index 00000000..6bedfcc9 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdJson.t.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {Test, stdJson} from "../src/Test.sol"; + +contract StdJsonTest is Test { + using stdJson for string; + + string root; + string path; + + function setUp() public { + root = vm.projectRoot(); + path = string.concat(root, "/test/fixtures/test.json"); + } + + struct SimpleJson { + uint256 a; + string b; + } + + struct NestedJson { + uint256 a; + string b; + SimpleJson c; + } + + function test_readJson() public view { + string memory json = vm.readFile(path); + assertEq(json.readUint(".a"), 123); + } + + function test_writeJson() public { + string memory json = "json"; + json.serialize("a", uint256(123)); + string memory semiFinal = json.serialize("b", string("test")); + string memory finalJson = json.serialize("c", semiFinal); + finalJson.write(path); + + string memory json_ = vm.readFile(path); + bytes memory data = json_.parseRaw("$"); + NestedJson memory decodedData = abi.decode(data, (NestedJson)); + + assertEq(decodedData.a, 123); + assertEq(decodedData.b, "test"); + assertEq(decodedData.c.a, 123); + assertEq(decodedData.c.b, "test"); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdMath.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdMath.t.sol new file mode 100644 index 00000000..0198378f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdMath.t.sol @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import {stdMath} from "../src/StdMath.sol"; +import {Test, stdError} from "../src/Test.sol"; + +contract StdMathMock is Test { + function exposed_percentDelta(uint256 a, uint256 b) public pure returns (uint256) { + return stdMath.percentDelta(a, b); + } + + function exposed_percentDelta(int256 a, int256 b) public pure returns (uint256) { + return stdMath.percentDelta(a, b); + } +} + +contract StdMathTest is Test { + function test_GetAbs() external pure { + assertEq(stdMath.abs(-50), 50); + assertEq(stdMath.abs(50), 50); + assertEq(stdMath.abs(-1337), 1337); + assertEq(stdMath.abs(0), 0); + + assertEq(stdMath.abs(type(int256).min), (type(uint256).max >> 1) + 1); + assertEq(stdMath.abs(type(int256).max), (type(uint256).max >> 1)); + } + + function testFuzz_GetAbs(int256 a) external pure { + uint256 manualAbs = getAbs(a); + + uint256 abs = stdMath.abs(a); + + assertEq(abs, manualAbs); + } + + function test_GetDelta_Uint() external pure { + assertEq(stdMath.delta(uint256(0), uint256(0)), 0); + assertEq(stdMath.delta(uint256(0), uint256(1337)), 1337); + assertEq(stdMath.delta(uint256(0), type(uint64).max), type(uint64).max); + assertEq(stdMath.delta(uint256(0), type(uint128).max), type(uint128).max); + assertEq(stdMath.delta(uint256(0), type(uint256).max), type(uint256).max); + + assertEq(stdMath.delta(0, uint256(0)), 0); + assertEq(stdMath.delta(1337, uint256(0)), 1337); + assertEq(stdMath.delta(type(uint64).max, uint256(0)), type(uint64).max); + assertEq(stdMath.delta(type(uint128).max, uint256(0)), type(uint128).max); + assertEq(stdMath.delta(type(uint256).max, uint256(0)), type(uint256).max); + + assertEq(stdMath.delta(1337, uint256(1337)), 0); + assertEq(stdMath.delta(type(uint256).max, type(uint256).max), 0); + assertEq(stdMath.delta(5000, uint256(1250)), 3750); + } + + function testFuzz_GetDelta_Uint(uint256 a, uint256 b) external pure { + uint256 manualDelta = a > b ? a - b : b - a; + + uint256 delta = stdMath.delta(a, b); + + assertEq(delta, manualDelta); + } + + function test_GetDelta_Int() external pure { + assertEq(stdMath.delta(int256(0), int256(0)), 0); + assertEq(stdMath.delta(int256(0), int256(1337)), 1337); + assertEq(stdMath.delta(int256(0), type(int64).max), type(uint64).max >> 1); + assertEq(stdMath.delta(int256(0), type(int128).max), type(uint128).max >> 1); + assertEq(stdMath.delta(int256(0), type(int256).max), type(uint256).max >> 1); + + assertEq(stdMath.delta(0, int256(0)), 0); + assertEq(stdMath.delta(1337, int256(0)), 1337); + assertEq(stdMath.delta(type(int64).max, int256(0)), type(uint64).max >> 1); + assertEq(stdMath.delta(type(int128).max, int256(0)), type(uint128).max >> 1); + assertEq(stdMath.delta(type(int256).max, int256(0)), type(uint256).max >> 1); + + assertEq(stdMath.delta(-0, int256(0)), 0); + assertEq(stdMath.delta(-1337, int256(0)), 1337); + assertEq(stdMath.delta(type(int64).min, int256(0)), (type(uint64).max >> 1) + 1); + assertEq(stdMath.delta(type(int128).min, int256(0)), (type(uint128).max >> 1) + 1); + assertEq(stdMath.delta(type(int256).min, int256(0)), (type(uint256).max >> 1) + 1); + + assertEq(stdMath.delta(int256(0), -0), 0); + assertEq(stdMath.delta(int256(0), -1337), 1337); + assertEq(stdMath.delta(int256(0), type(int64).min), (type(uint64).max >> 1) + 1); + assertEq(stdMath.delta(int256(0), type(int128).min), (type(uint128).max >> 1) + 1); + assertEq(stdMath.delta(int256(0), type(int256).min), (type(uint256).max >> 1) + 1); + + assertEq(stdMath.delta(1337, int256(1337)), 0); + assertEq(stdMath.delta(type(int256).max, type(int256).max), 0); + assertEq(stdMath.delta(type(int256).min, type(int256).min), 0); + assertEq(stdMath.delta(type(int256).min, type(int256).max), type(uint256).max); + assertEq(stdMath.delta(5000, int256(1250)), 3750); + } + + function testFuzz_GetDelta_Int(int256 a, int256 b) external pure { + uint256 absA = getAbs(a); + uint256 absB = getAbs(b); + uint256 absDelta = absA > absB ? absA - absB : absB - absA; + + uint256 manualDelta; + if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { + manualDelta = absDelta; + } + // (a < 0 && b >= 0) || (a >= 0 && b < 0) + else { + manualDelta = absA + absB; + } + + uint256 delta = stdMath.delta(a, b); + + assertEq(delta, manualDelta); + } + + function test_GetPercentDelta_Uint() external { + StdMathMock stdMathMock = new StdMathMock(); + + assertEq(stdMath.percentDelta(uint256(0), uint256(1337)), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint64).max), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint128).max), 1e18); + assertEq(stdMath.percentDelta(uint256(0), type(uint192).max), 1e18); + + assertEq(stdMath.percentDelta(1337, uint256(1337)), 0); + assertEq(stdMath.percentDelta(type(uint192).max, type(uint192).max), 0); + assertEq(stdMath.percentDelta(0, uint256(2500)), 1e18); + assertEq(stdMath.percentDelta(2500, uint256(2500)), 0); + assertEq(stdMath.percentDelta(5000, uint256(2500)), 1e18); + assertEq(stdMath.percentDelta(7500, uint256(2500)), 2e18); + + vm.expectRevert("stdMath percentDelta(uint256,uint256): Divisor is zero"); + stdMathMock.exposed_percentDelta(uint256(1), 0); + } + + function testFuzz_GetPercentDelta_Uint(uint192 a, uint192 b) external pure { + vm.assume(b != 0); + uint256 manualDelta = a > b ? a - b : b - a; + + uint256 manualPercentDelta = manualDelta * 1e18 / b; + uint256 percentDelta = stdMath.percentDelta(a, b); + + assertEq(percentDelta, manualPercentDelta); + } + + function test_GetPercentDelta_Int() external { + // We deploy a mock version so we can properly test the revert. + StdMathMock stdMathMock = new StdMathMock(); + + assertEq(stdMath.percentDelta(int256(0), int256(1337)), 1e18); + assertEq(stdMath.percentDelta(int256(0), -1337), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int64).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int128).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int192).min), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int64).max), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int128).max), 1e18); + assertEq(stdMath.percentDelta(int256(0), type(int192).max), 1e18); + + assertEq(stdMath.percentDelta(1337, int256(1337)), 0); + assertEq(stdMath.percentDelta(type(int192).max, type(int192).max), 0); + assertEq(stdMath.percentDelta(type(int192).min, type(int192).min), 0); + + assertEq(stdMath.percentDelta(type(int192).min, type(int192).max), 2e18); // rounds the 1 wei diff down + assertEq(stdMath.percentDelta(type(int192).max, type(int192).min), 2e18 - 1); // rounds the 1 wei diff down + assertEq(stdMath.percentDelta(0, int256(2500)), 1e18); + assertEq(stdMath.percentDelta(2500, int256(2500)), 0); + assertEq(stdMath.percentDelta(5000, int256(2500)), 1e18); + assertEq(stdMath.percentDelta(7500, int256(2500)), 2e18); + + vm.expectRevert("stdMath percentDelta(int256,int256): Divisor is zero"); + stdMathMock.exposed_percentDelta(int256(1), 0); + } + + function testFuzz_GetPercentDelta_Int(int192 a, int192 b) external pure { + vm.assume(b != 0); + uint256 absA = getAbs(a); + uint256 absB = getAbs(b); + uint256 absDelta = absA > absB ? absA - absB : absB - absA; + + uint256 manualDelta; + if ((a >= 0 && b >= 0) || (a < 0 && b < 0)) { + manualDelta = absDelta; + } + // (a < 0 && b >= 0) || (a >= 0 && b < 0) + else { + manualDelta = absA + absB; + } + + uint256 manualPercentDelta = manualDelta * 1e18 / absB; + uint256 percentDelta = stdMath.percentDelta(a, b); + + assertEq(percentDelta, manualPercentDelta); + } + + /*////////////////////////////////////////////////////////////////////////// + HELPERS + //////////////////////////////////////////////////////////////////////////*/ + + function getAbs(int256 a) private pure returns (uint256) { + if (a < 0) { + return a == type(int256).min ? uint256(type(int256).max) + 1 : uint256(-a); + } + + return uint256(a); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdStorage.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdStorage.t.sol new file mode 100644 index 00000000..d59465b5 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdStorage.t.sol @@ -0,0 +1,486 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {stdStorage, StdStorage} from "../src/StdStorage.sol"; +import {Test} from "../src/Test.sol"; + +contract StdStorageTest is Test { + using stdStorage for StdStorage; + + StorageTest internal test; + + function setUp() public { + test = new StorageTest(); + } + + function test_StorageHidden() public { + assertEq(uint256(keccak256("my.random.var")), stdstore.target(address(test)).sig("hidden()").find()); + } + + function test_StorageObvious() public { + assertEq(uint256(0), stdstore.target(address(test)).sig("exists()").find()); + } + + function test_StorageExtraSload() public { + assertEq(16, stdstore.target(address(test)).sig(test.extra_sload.selector).find()); + } + + function test_StorageCheckedWriteHidden() public { + stdstore.target(address(test)).sig(test.hidden.selector).checked_write(100); + assertEq(uint256(test.hidden()), 100); + } + + function test_StorageCheckedWriteObvious() public { + stdstore.target(address(test)).sig(test.exists.selector).checked_write(100); + assertEq(test.exists(), 100); + } + + function test_StorageCheckedWriteSignedIntegerHidden() public { + stdstore.target(address(test)).sig(test.hidden.selector).checked_write_int(-100); + assertEq(int256(uint256(test.hidden())), -100); + } + + function test_StorageCheckedWriteSignedIntegerObvious() public { + stdstore.target(address(test)).sig(test.tG.selector).checked_write_int(-100); + assertEq(test.tG(), -100); + } + + function test_StorageMapStructA() public { + uint256 slot = + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).find(); + assertEq(uint256(keccak256(abi.encode(address(this), 4))), slot); + } + + function test_StorageMapStructB() public { + uint256 slot = + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).find(); + assertEq(uint256(keccak256(abi.encode(address(this), 4))) + 1, slot); + } + + function test_StorageDeepMap() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)) + .with_key(address(this)).find(); + assertEq(uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(5)))))), slot); + } + + function test_StorageCheckedWriteDeepMap() public { + stdstore.target(address(test)).sig(test.deep_map.selector).with_key(address(this)).with_key(address(this)) + .checked_write(100); + assertEq(100, test.deep_map(address(this), address(this))); + } + + function test_StorageDeepMapStructA() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) + .with_key(address(this)).depth(0).find(); + assertEq( + bytes32( + uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 0 + ), + bytes32(slot) + ); + } + + function test_StorageDeepMapStructB() public { + uint256 slot = stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) + .with_key(address(this)).depth(1).find(); + assertEq( + bytes32( + uint256(keccak256(abi.encode(address(this), keccak256(abi.encode(address(this), uint256(6)))))) + 1 + ), + bytes32(slot) + ); + } + + function test_StorageCheckedWriteDeepMapStructA() public { + stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) + .with_key(address(this)).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); + assertEq(100, a); + assertEq(0, b); + } + + function test_StorageCheckedWriteDeepMapStructB() public { + stdstore.target(address(test)).sig(test.deep_map_struct.selector).with_key(address(this)) + .with_key(address(this)).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.deep_map_struct(address(this), address(this)); + assertEq(0, a); + assertEq(100, b); + } + + function test_StorageCheckedWriteMapStructA() public { + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.map_struct(address(this)); + assertEq(a, 100); + assertEq(b, 0); + } + + function test_StorageCheckedWriteMapStructB() public { + stdstore.target(address(test)).sig(test.map_struct.selector).with_key(address(this)).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.map_struct(address(this)); + assertEq(a, 0); + assertEq(b, 100); + } + + function test_StorageStructA() public { + uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(0).find(); + assertEq(uint256(7), slot); + } + + function test_StorageStructB() public { + uint256 slot = stdstore.target(address(test)).sig(test.basic.selector).depth(1).find(); + assertEq(uint256(7) + 1, slot); + } + + function test_StorageCheckedWriteStructA() public { + stdstore.target(address(test)).sig(test.basic.selector).depth(0).checked_write(100); + (uint256 a, uint256 b) = test.basic(); + assertEq(a, 100); + assertEq(b, 1337); + } + + function test_StorageCheckedWriteStructB() public { + stdstore.target(address(test)).sig(test.basic.selector).depth(1).checked_write(100); + (uint256 a, uint256 b) = test.basic(); + assertEq(a, 1337); + assertEq(b, 100); + } + + function test_StorageMapAddrFound() public { + uint256 slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).find(); + assertEq(uint256(keccak256(abi.encode(address(this), uint256(1)))), slot); + } + + function test_StorageMapAddrRoot() public { + (uint256 slot, bytes32 key) = + stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).parent(); + assertEq(address(uint160(uint256(key))), address(this)); + assertEq(uint256(1), slot); + slot = stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).root(); + assertEq(uint256(1), slot); + } + + function test_StorageMapUintFound() public { + uint256 slot = stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).find(); + assertEq(uint256(keccak256(abi.encode(100, uint256(2)))), slot); + } + + function test_StorageCheckedWriteMapUint() public { + stdstore.target(address(test)).sig(test.map_uint.selector).with_key(100).checked_write(100); + assertEq(100, test.map_uint(100)); + } + + function test_StorageCheckedWriteMapAddr() public { + stdstore.target(address(test)).sig(test.map_addr.selector).with_key(address(this)).checked_write(100); + assertEq(100, test.map_addr(address(this))); + } + + function test_StorageCheckedWriteMapBool() public { + stdstore.target(address(test)).sig(test.map_bool.selector).with_key(address(this)).checked_write(true); + assertTrue(test.map_bool(address(this))); + } + + function testFuzz_StorageCheckedWriteMapPacked(address addr, uint128 value) public { + stdstore.enable_packed_slots().target(address(test)).sig(test.read_struct_lower.selector).with_key(addr) + .checked_write(value); + assertEq(test.read_struct_lower(addr), value); + + stdstore.enable_packed_slots().target(address(test)).sig(test.read_struct_upper.selector).with_key(addr) + .checked_write(value); + assertEq(test.read_struct_upper(addr), value); + } + + function test_StorageCheckedWriteMapPackedFullSuccess() public { + uint256 full = test.map_packed(address(1337)); + // keep upper 128, set lower 128 to 1337 + full = (full & (uint256((1 << 128) - 1) << 128)) | 1337; + stdstore.target(address(test)).sig(test.map_packed.selector).with_key(address(uint160(1337))) + .checked_write(full); + assertEq(1337, test.read_struct_lower(address(1337))); + } + + function test_RevertStorageConst() public { + StorageTestTarget target = new StorageTestTarget(test); + + vm.expectRevert("stdStorage find(StdStorage): No storage use detected for target."); + target.expectRevertStorageConst(); + } + + function testFuzz_StorageNativePack(uint248 val1, uint248 val2, bool boolVal1, bool boolVal2) public { + stdstore.enable_packed_slots().target(address(test)).sig(test.tA.selector).checked_write(val1); + stdstore.enable_packed_slots().target(address(test)).sig(test.tB.selector).checked_write(boolVal1); + stdstore.enable_packed_slots().target(address(test)).sig(test.tC.selector).checked_write(boolVal2); + stdstore.enable_packed_slots().target(address(test)).sig(test.tD.selector).checked_write(val2); + + assertEq(test.tA(), val1); + assertEq(test.tB(), boolVal1); + assertEq(test.tC(), boolVal2); + assertEq(test.tD(), val2); + } + + function test_StorageReadBytes32() public { + bytes32 val = stdstore.target(address(test)).sig(test.tE.selector).read_bytes32(); + assertEq(val, hex"1337"); + } + + function test_StorageReadBool_False() public { + bool val = stdstore.target(address(test)).sig(test.tB.selector).read_bool(); + assertEq(val, false); + } + + function test_StorageReadBool_True() public { + bool val = stdstore.target(address(test)).sig(test.tH.selector).read_bool(); + assertEq(val, true); + } + + function test_RevertIf_ReadingNonBoolValue() public { + vm.expectRevert("stdStorage read_bool(StdStorage): Cannot decode. Make sure you are reading a bool."); + this.readNonBoolValue(); + } + + function readNonBoolValue() public { + stdstore.target(address(test)).sig(test.tE.selector).read_bool(); + } + + function test_StorageReadAddress() public { + address val = stdstore.target(address(test)).sig(test.tF.selector).read_address(); + assertEq(val, address(1337)); + } + + function test_StorageReadUint() public { + uint256 val = stdstore.target(address(test)).sig(test.exists.selector).read_uint(); + assertEq(val, 1); + } + + function test_StorageReadInt() public { + int256 val = stdstore.target(address(test)).sig(test.tG.selector).read_int(); + assertEq(val, type(int256).min); + } + + function testFuzz_Packed(uint256 val, uint8 elemToGet) public { + // This function tries an assortment of packed slots, shifts meaning number of elements + // that are packed. Shiftsizes are the size of each element, i.e. 8 means a data type that is 8 bits, 16 == 16 bits, etc. + // Combined, these determine how a slot is packed. Making it random is too hard to avoid global rejection limit + // and make it performant. + + // change the number of shifts + for (uint256 i = 1; i < 5; i++) { + uint256 shifts = i; + + elemToGet = uint8(bound(elemToGet, 0, shifts - 1)); + + uint256[] memory shiftSizes = new uint256[](shifts); + for (uint256 j; j < shifts; j++) { + shiftSizes[j] = 8 * (j + 1); + } + + test.setRandomPacking(val); + + uint256 leftBits; + uint256 rightBits; + for (uint256 j; j < shiftSizes.length; j++) { + if (j < elemToGet) { + leftBits += shiftSizes[j]; + } else if (elemToGet != j) { + rightBits += shiftSizes[j]; + } + } + + // we may have some right bits unaccounted for + leftBits += 256 - (leftBits + shiftSizes[elemToGet] + rightBits); + // clear left bits, then clear right bits and realign + uint256 expectedValToRead = (val << leftBits) >> (leftBits + rightBits); + + uint256 readVal = stdstore.target(address(test)).enable_packed_slots() + .sig("getRandomPacked(uint8,uint8[],uint8)").with_calldata(abi.encode(shifts, shiftSizes, elemToGet)) + .read_uint(); + + assertEq(readVal, expectedValToRead); + } + } + + function testFuzz_Packed2(uint256 nvars, uint256 seed) public { + // Number of random variables to generate. + nvars = bound(nvars, 1, 20); + + // This will decrease as we generate values in the below loop. + uint256 bitsRemaining = 256; + + // Generate a random value and size for each variable. + uint256[] memory vals = new uint256[](nvars); + uint256[] memory sizes = new uint256[](nvars); + uint256[] memory offsets = new uint256[](nvars); + + for (uint256 i = 0; i < nvars; i++) { + // Generate a random value and size. + offsets[i] = i == 0 ? 0 : offsets[i - 1] + sizes[i - 1]; + + uint256 nvarsRemaining = nvars - i; + uint256 maxVarSize = bitsRemaining - nvarsRemaining + 1; + sizes[i] = bound(uint256(keccak256(abi.encodePacked(seed, i + 256))), 1, maxVarSize); + bitsRemaining -= sizes[i]; + + uint256 maxVal; + uint256 varSize = sizes[i]; + assembly { + // mask = (1 << varSize) - 1 + maxVal := sub(shl(varSize, 1), 1) + } + vals[i] = bound(uint256(keccak256(abi.encodePacked(seed, i))), 0, maxVal); + } + + // Pack all values into the slot. + for (uint256 i = 0; i < nvars; i++) { + stdstore.enable_packed_slots().target(address(test)).sig("getRandomPacked(uint256,uint256)") + .with_key(sizes[i]).with_key(offsets[i]).checked_write(vals[i]); + } + + // Verify the read data matches. + for (uint256 i = 0; i < nvars; i++) { + uint256 readVal = stdstore.enable_packed_slots().target(address(test)) + .sig("getRandomPacked(uint256,uint256)").with_key(sizes[i]).with_key(offsets[i]).read_uint(); + + uint256 retVal = test.getRandomPacked(sizes[i], offsets[i]); + + assertEq(readVal, vals[i]); + assertEq(retVal, vals[i]); + } + } + + function testEdgeCaseArray() public { + stdstore.target(address(test)).sig("edgeCaseArray(uint256)").with_key(uint256(0)).checked_write(1); + assertEq(test.edgeCaseArray(0), 1); + } +} + +contract StorageTestTarget { + using stdStorage for StdStorage; + + StdStorage internal stdstore; + StorageTest internal test; + + constructor(StorageTest test_) { + test = test_; + } + + function expectRevertStorageConst() public { + stdstore.target(address(test)).sig("const()").find(); + } +} + +contract StorageTest { + uint256 public exists = 1; + mapping(address => uint256) public map_addr; + mapping(uint256 => uint256) public map_uint; + mapping(address => uint256) public map_packed; + mapping(address => UnpackedStruct) public map_struct; + mapping(address => mapping(address => uint256)) public deep_map; + mapping(address => mapping(address => UnpackedStruct)) public deep_map_struct; + UnpackedStruct public basic; + + uint248 public tA; + bool public tB; + + bool public tC = false; + uint248 public tD = 1; + + struct UnpackedStruct { + uint256 a; + uint256 b; + } + + mapping(address => bool) public map_bool; + + bytes32 public tE = hex"1337"; + address public tF = address(1337); + int256 public tG = type(int256).min; + bool public tH = true; + bytes32 private tI = ~bytes32(hex"1337"); + + uint256 randomPacking; + + // Array with length matching values of elements. + uint256[] public edgeCaseArray = [3, 3, 3]; + + constructor() { + basic = UnpackedStruct({a: 1337, b: 1337}); + + uint256 two = (1 << 128) | 1; + map_packed[msg.sender] = two; + map_packed[address(uint160(1337))] = 1 << 128; + } + + function read_struct_upper(address who) public view returns (uint256) { + return map_packed[who] >> 128; + } + + function read_struct_lower(address who) public view returns (uint256) { + return map_packed[who] & ((1 << 128) - 1); + } + + function hidden() public view returns (bytes32 t) { + bytes32 slot = keccak256("my.random.var"); + /// @solidity memory-safe-assembly + assembly { + t := sload(slot) + } + } + + function const() public pure returns (bytes32 t) { + t = bytes32(hex"1337"); + } + + function extra_sload() public view returns (bytes32 t) { + // trigger read on slot `tE`, and make a staticcall to make sure compiler doesn't optimize this SLOAD away + assembly { + pop(staticcall(gas(), sload(tE.slot), 0, 0, 0, 0)) + } + t = tI; + } + + function setRandomPacking(uint256 val) public { + randomPacking = val; + } + + function _getMask(uint256 size) internal pure returns (uint256 mask) { + assembly { + // mask = (1 << size) - 1 + mask := sub(shl(size, 1), 1) + } + } + + function setRandomPacking(uint256 val, uint256 size, uint256 offset) public { + // Generate mask based on the size of the value + uint256 mask = _getMask(size); + // Zero out all bits for the word we're about to set + uint256 cleanedWord = randomPacking & ~(mask << offset); + // Place val in the correct spot of the cleaned word + randomPacking = cleanedWord | val << offset; + } + + function getRandomPacked(uint256 size, uint256 offset) public view returns (uint256) { + // Generate mask based on the size of the value + uint256 mask = _getMask(size); + // Shift to place the bits in the correct position, and use mask to zero out remaining bits + return (randomPacking >> offset) & mask; + } + + function getRandomPacked(uint8 shifts, uint8[] memory shiftSizes, uint8 elem) public view returns (uint256) { + require(elem < shifts, "!elem"); + uint256 leftBits; + uint256 rightBits; + + for (uint256 i; i < shiftSizes.length; i++) { + if (i < elem) { + leftBits += shiftSizes[i]; + } else if (elem != i) { + rightBits += shiftSizes[i]; + } + } + + // we may have some right bits unaccounted for + leftBits += 256 - (leftBits + shiftSizes[elem] + rightBits); + + // clear left bits, then clear right bits and realign + return (randomPacking << leftBits) >> (leftBits + rightBits); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdStyle.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdStyle.t.sol new file mode 100644 index 00000000..974e756f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdStyle.t.sol @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {Test, console2, StdStyle} from "../src/Test.sol"; + +contract StdStyleTest is Test { + function test_StyleColor() public pure { + console2.log(StdStyle.red("StdStyle.red String Test")); + console2.log(StdStyle.red(uint256(10e18))); + console2.log(StdStyle.red(int256(-10e18))); + console2.log(StdStyle.red(true)); + console2.log(StdStyle.red(address(0))); + console2.log(StdStyle.redBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.redBytes32("StdStyle.redBytes32")); + console2.log(StdStyle.green("StdStyle.green String Test")); + console2.log(StdStyle.green(uint256(10e18))); + console2.log(StdStyle.green(int256(-10e18))); + console2.log(StdStyle.green(true)); + console2.log(StdStyle.green(address(0))); + console2.log(StdStyle.greenBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.greenBytes32("StdStyle.greenBytes32")); + console2.log(StdStyle.yellow("StdStyle.yellow String Test")); + console2.log(StdStyle.yellow(uint256(10e18))); + console2.log(StdStyle.yellow(int256(-10e18))); + console2.log(StdStyle.yellow(true)); + console2.log(StdStyle.yellow(address(0))); + console2.log(StdStyle.yellowBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.yellowBytes32("StdStyle.yellowBytes32")); + console2.log(StdStyle.blue("StdStyle.blue String Test")); + console2.log(StdStyle.blue(uint256(10e18))); + console2.log(StdStyle.blue(int256(-10e18))); + console2.log(StdStyle.blue(true)); + console2.log(StdStyle.blue(address(0))); + console2.log(StdStyle.blueBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.blueBytes32("StdStyle.blueBytes32")); + console2.log(StdStyle.magenta("StdStyle.magenta String Test")); + console2.log(StdStyle.magenta(uint256(10e18))); + console2.log(StdStyle.magenta(int256(-10e18))); + console2.log(StdStyle.magenta(true)); + console2.log(StdStyle.magenta(address(0))); + console2.log(StdStyle.magentaBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.magentaBytes32("StdStyle.magentaBytes32")); + console2.log(StdStyle.cyan("StdStyle.cyan String Test")); + console2.log(StdStyle.cyan(uint256(10e18))); + console2.log(StdStyle.cyan(int256(-10e18))); + console2.log(StdStyle.cyan(true)); + console2.log(StdStyle.cyan(address(0))); + console2.log(StdStyle.cyanBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.cyanBytes32("StdStyle.cyanBytes32")); + } + + function test_StyleFontWeight() public pure { + console2.log(StdStyle.bold("StdStyle.bold String Test")); + console2.log(StdStyle.bold(uint256(10e18))); + console2.log(StdStyle.bold(int256(-10e18))); + console2.log(StdStyle.bold(address(0))); + console2.log(StdStyle.bold(true)); + console2.log(StdStyle.boldBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.boldBytes32("StdStyle.boldBytes32")); + console2.log(StdStyle.dim("StdStyle.dim String Test")); + console2.log(StdStyle.dim(uint256(10e18))); + console2.log(StdStyle.dim(int256(-10e18))); + console2.log(StdStyle.dim(address(0))); + console2.log(StdStyle.dim(true)); + console2.log(StdStyle.dimBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.dimBytes32("StdStyle.dimBytes32")); + console2.log(StdStyle.italic("StdStyle.italic String Test")); + console2.log(StdStyle.italic(uint256(10e18))); + console2.log(StdStyle.italic(int256(-10e18))); + console2.log(StdStyle.italic(address(0))); + console2.log(StdStyle.italic(true)); + console2.log(StdStyle.italicBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.italicBytes32("StdStyle.italicBytes32")); + console2.log(StdStyle.underline("StdStyle.underline String Test")); + console2.log(StdStyle.underline(uint256(10e18))); + console2.log(StdStyle.underline(int256(-10e18))); + console2.log(StdStyle.underline(address(0))); + console2.log(StdStyle.underline(true)); + console2.log(StdStyle.underlineBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.underlineBytes32("StdStyle.underlineBytes32")); + console2.log(StdStyle.inverse("StdStyle.inverse String Test")); + console2.log(StdStyle.inverse(uint256(10e18))); + console2.log(StdStyle.inverse(int256(-10e18))); + console2.log(StdStyle.inverse(address(0))); + console2.log(StdStyle.inverse(true)); + console2.log(StdStyle.inverseBytes(hex"7109709ECfa91a80626fF3989D68f67F5b1DD12D")); + console2.log(StdStyle.inverseBytes32("StdStyle.inverseBytes32")); + } + + function test_StyleCombined() public pure { + console2.log(StdStyle.red(StdStyle.bold("Red Bold String Test"))); + console2.log(StdStyle.green(StdStyle.dim(uint256(10e18)))); + console2.log(StdStyle.yellow(StdStyle.italic(int256(-10e18)))); + console2.log(StdStyle.blue(StdStyle.underline(address(0)))); + console2.log(StdStyle.magenta(StdStyle.inverse(true))); + } + + function test_StyleCustom() public pure { + console2.log(h1("Custom Style 1")); + console2.log(h2("Custom Style 2")); + } + + function h1(string memory a) private pure returns (string memory) { + return StdStyle.cyan(StdStyle.inverse(StdStyle.bold(a))); + } + + function h2(string memory a) private pure returns (string memory) { + return StdStyle.magenta(StdStyle.bold(StdStyle.underline(a))); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdToml.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdToml.t.sol new file mode 100644 index 00000000..5a45f4f5 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdToml.t.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {Test, stdToml} from "../src/Test.sol"; + +contract StdTomlTest is Test { + using stdToml for string; + + string root; + string path; + + function setUp() public { + root = vm.projectRoot(); + path = string.concat(root, "/test/fixtures/test.toml"); + } + + struct SimpleToml { + uint256 a; + string b; + } + + struct NestedToml { + uint256 a; + string b; + SimpleToml c; + } + + function test_readToml() public view { + string memory json = vm.readFile(path); + assertEq(json.readUint(".a"), 123); + } + + function test_writeToml() public { + string memory json = "json"; + json.serialize("a", uint256(123)); + string memory semiFinal = json.serialize("b", string("test")); + string memory finalJson = json.serialize("c", semiFinal); + finalJson.write(path); + + string memory toml = vm.readFile(path); + bytes memory data = toml.parseRaw("$"); + NestedToml memory decodedData = abi.decode(data, (NestedToml)); + + assertEq(decodedData.a, 123); + assertEq(decodedData.b, "test"); + assertEq(decodedData.c.a, 123); + assertEq(decodedData.c.b, "test"); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdUtils.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdUtils.t.sol new file mode 100644 index 00000000..aee801b2 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/StdUtils.t.sol @@ -0,0 +1,342 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +import {Test, StdUtils} from "../src/Test.sol"; + +contract StdUtilsMock is StdUtils { + // We deploy a mock version so we can properly test expected reverts. + function exposed_getTokenBalances(address token, address[] memory addresses) + external + returns (uint256[] memory balances) + { + return getTokenBalances(token, addresses); + } + + function exposed_bound(int256 num, int256 min, int256 max) external pure returns (int256) { + return bound(num, min, max); + } + + function exposed_bound(uint256 num, uint256 min, uint256 max) external pure returns (uint256) { + return bound(num, min, max); + } + + function exposed_bytesToUint(bytes memory b) external pure returns (uint256) { + return bytesToUint(b); + } +} + +contract StdUtilsTest is Test { + /*////////////////////////////////////////////////////////////////////////// + BOUND UINT + //////////////////////////////////////////////////////////////////////////*/ + + function test_Bound() public pure { + assertEq(bound(uint256(5), 0, 4), 0); + assertEq(bound(uint256(0), 69, 69), 69); + assertEq(bound(uint256(0), 68, 69), 68); + assertEq(bound(uint256(10), 150, 190), 174); + assertEq(bound(uint256(300), 2800, 3200), 3107); + assertEq(bound(uint256(9999), 1337, 6666), 4669); + } + + function test_Bound_WithinRange() public pure { + assertEq(bound(uint256(51), 50, 150), 51); + assertEq(bound(uint256(51), 50, 150), bound(bound(uint256(51), 50, 150), 50, 150)); + assertEq(bound(uint256(149), 50, 150), 149); + assertEq(bound(uint256(149), 50, 150), bound(bound(uint256(149), 50, 150), 50, 150)); + } + + function test_Bound_EdgeCoverage() public pure { + assertEq(bound(uint256(0), 50, 150), 50); + assertEq(bound(uint256(1), 50, 150), 51); + assertEq(bound(uint256(2), 50, 150), 52); + assertEq(bound(uint256(3), 50, 150), 53); + assertEq(bound(type(uint256).max, 50, 150), 150); + assertEq(bound(type(uint256).max - 1, 50, 150), 149); + assertEq(bound(type(uint256).max - 2, 50, 150), 148); + assertEq(bound(type(uint256).max - 3, 50, 150), 147); + } + + function testFuzz_Bound_DistributionIsEven(uint256 min, uint256 size) public pure { + size = size % 100 + 1; + min = bound(min, UINT256_MAX / 2, UINT256_MAX / 2 + size); + uint256 max = min + size - 1; + uint256 result; + + for (uint256 i = 1; i <= size * 4; ++i) { + // x > max + result = bound(max + i, min, max); + assertEq(result, min + (i - 1) % size); + // x < min + result = bound(min - i, min, max); + assertEq(result, max - (i - 1) % size); + } + } + + function testFuzz_Bound(uint256 num, uint256 min, uint256 max) public pure { + if (min > max) (min, max) = (max, min); + + uint256 result = bound(num, min, max); + + assertGe(result, min); + assertLe(result, max); + assertEq(result, bound(result, min, max)); + if (num >= min && num <= max) assertEq(result, num); + } + + function test_BoundUint256Max() public pure { + assertEq(bound(0, type(uint256).max - 1, type(uint256).max), type(uint256).max - 1); + assertEq(bound(1, type(uint256).max - 1, type(uint256).max), type(uint256).max); + } + + function test_RevertIf_BoundMaxLessThanMin() public { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); + stdUtils.exposed_bound(uint256(5), 100, 10); + } + + function testFuzz_RevertIf_BoundMaxLessThanMin(uint256 num, uint256 min, uint256 max) public { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + vm.assume(min > max); + vm.expectRevert(bytes("StdUtils bound(uint256,uint256,uint256): Max is less than min.")); + stdUtils.exposed_bound(num, min, max); + } + + /*////////////////////////////////////////////////////////////////////////// + BOUND INT + //////////////////////////////////////////////////////////////////////////*/ + + function test_BoundInt() public pure { + assertEq(bound(-3, 0, 4), 2); + assertEq(bound(0, -69, -69), -69); + assertEq(bound(0, -69, -68), -68); + assertEq(bound(-10, 150, 190), 154); + assertEq(bound(-300, 2800, 3200), 2908); + assertEq(bound(9999, -1337, 6666), 1995); + } + + function test_BoundInt_WithinRange() public pure { + assertEq(bound(51, -50, 150), 51); + assertEq(bound(51, -50, 150), bound(bound(51, -50, 150), -50, 150)); + assertEq(bound(149, -50, 150), 149); + assertEq(bound(149, -50, 150), bound(bound(149, -50, 150), -50, 150)); + } + + function test_BoundInt_EdgeCoverage() public pure { + assertEq(bound(type(int256).min, -50, 150), -50); + assertEq(bound(type(int256).min + 1, -50, 150), -49); + assertEq(bound(type(int256).min + 2, -50, 150), -48); + assertEq(bound(type(int256).min + 3, -50, 150), -47); + assertEq(bound(type(int256).min, 10, 150), 10); + assertEq(bound(type(int256).min + 1, 10, 150), 11); + assertEq(bound(type(int256).min + 2, 10, 150), 12); + assertEq(bound(type(int256).min + 3, 10, 150), 13); + + assertEq(bound(type(int256).max, -50, 150), 150); + assertEq(bound(type(int256).max - 1, -50, 150), 149); + assertEq(bound(type(int256).max - 2, -50, 150), 148); + assertEq(bound(type(int256).max - 3, -50, 150), 147); + assertEq(bound(type(int256).max, -50, -10), -10); + assertEq(bound(type(int256).max - 1, -50, -10), -11); + assertEq(bound(type(int256).max - 2, -50, -10), -12); + assertEq(bound(type(int256).max - 3, -50, -10), -13); + } + + function testFuzz_BoundInt_DistributionIsEven(int256 min, uint256 size) public pure { + size = size % 100 + 1; + min = bound(min, -int256(size / 2), int256(size - size / 2)); + int256 max = min + int256(size) - 1; + int256 result; + + for (uint256 i = 1; i <= size * 4; ++i) { + // x > max + result = bound(max + int256(i), min, max); + assertEq(result, min + int256((i - 1) % size)); + // x < min + result = bound(min - int256(i), min, max); + assertEq(result, max - int256((i - 1) % size)); + } + } + + function testFuzz_BoundInt(int256 num, int256 min, int256 max) public pure { + if (min > max) (min, max) = (max, min); + + int256 result = bound(num, min, max); + + assertGe(result, min); + assertLe(result, max); + assertEq(result, bound(result, min, max)); + if (num >= min && num <= max) assertEq(result, num); + } + + function test_BoundIntInt256Max() public pure { + assertEq(bound(0, type(int256).max - 1, type(int256).max), type(int256).max - 1); + assertEq(bound(1, type(int256).max - 1, type(int256).max), type(int256).max); + } + + function test_BoundIntInt256Min() public pure { + assertEq(bound(0, type(int256).min, type(int256).min + 1), type(int256).min); + assertEq(bound(1, type(int256).min, type(int256).min + 1), type(int256).min + 1); + } + + function test_RevertIf_BoundIntMaxLessThanMin() public { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); + stdUtils.exposed_bound(-5, 100, 10); + } + + function testFuzz_RevertIf_BoundIntMaxLessThanMin(int256 num, int256 min, int256 max) public { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + vm.assume(min > max); + vm.expectRevert(bytes("StdUtils bound(int256,int256,int256): Max is less than min.")); + stdUtils.exposed_bound(num, min, max); + } + + /*////////////////////////////////////////////////////////////////////////// + BOUND PRIVATE KEY + //////////////////////////////////////////////////////////////////////////*/ + + function test_BoundPrivateKey() public pure { + assertEq(boundPrivateKey(0), 1); + assertEq(boundPrivateKey(1), 1); + assertEq(boundPrivateKey(300), 300); + assertEq(boundPrivateKey(9999), 9999); + assertEq(boundPrivateKey(SECP256K1_ORDER - 1), SECP256K1_ORDER - 1); + assertEq(boundPrivateKey(SECP256K1_ORDER), 1); + assertEq(boundPrivateKey(SECP256K1_ORDER + 1), 2); + assertEq(boundPrivateKey(UINT256_MAX), UINT256_MAX & SECP256K1_ORDER - 1); // x&y is equivalent to x-x%y + } + + /*////////////////////////////////////////////////////////////////////////// + BYTES TO UINT + //////////////////////////////////////////////////////////////////////////*/ + + function test_BytesToUint() external pure { + bytes memory maxUint = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + bytes memory two = hex"02"; + bytes memory millionEther = hex"d3c21bcecceda1000000"; + + assertEq(bytesToUint(maxUint), type(uint256).max); + assertEq(bytesToUint(two), 2); + assertEq(bytesToUint(millionEther), 1_000_000 ether); + } + + function test_RevertIf_BytesLengthExceeds32() external { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + bytes memory thirty3Bytes = hex"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"; + vm.expectRevert("StdUtils bytesToUint(bytes): Bytes length exceeds 32."); + stdUtils.exposed_bytesToUint(thirty3Bytes); + } + + /*////////////////////////////////////////////////////////////////////////// + COMPUTE CREATE ADDRESS + //////////////////////////////////////////////////////////////////////////*/ + + function test_ComputeCreateAddress() external pure { + address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; + uint256 nonce = 14; + address createAddress = computeCreateAddress(deployer, nonce); + assertEq(createAddress, 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45); + } + + /*////////////////////////////////////////////////////////////////////////// + COMPUTE CREATE2 ADDRESS + //////////////////////////////////////////////////////////////////////////*/ + + function test_ComputeCreate2Address() external pure { + bytes32 salt = bytes32(uint256(31415)); + bytes32 initcodeHash = keccak256(abi.encode(0x6080)); + address deployer = 0x6C9FC64A53c1b71FB3f9Af64d1ae3A4931A5f4E9; + address create2Address = computeCreate2Address(salt, initcodeHash, deployer); + assertEq(create2Address, 0xB147a5d25748fda14b463EB04B111027C290f4d3); + } + + function test_ComputeCreate2AddressWithDefaultDeployer() external pure { + bytes32 salt = 0xc290c670fde54e5ef686f9132cbc8711e76a98f0333a438a92daa442c71403c0; + bytes32 initcodeHash = hashInitCode(hex"6080", ""); + assertEq(initcodeHash, 0x1a578b7a4b0b5755db6d121b4118d4bc68fe170dca840c59bc922f14175a76b0); + address create2Address = computeCreate2Address(salt, initcodeHash); + assertEq(create2Address, 0xc0ffEe2198a06235aAbFffe5Db0CacF1717f5Ac6); + } +} + +contract StdUtilsForkTest is Test { + /*////////////////////////////////////////////////////////////////////////// + GET TOKEN BALANCES + //////////////////////////////////////////////////////////////////////////*/ + + address internal SHIB = 0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE; + address internal SHIB_HOLDER_0 = 0x855F5981e831D83e6A4b4EBFCAdAa68D92333170; + address internal SHIB_HOLDER_1 = 0x8F509A90c2e47779cA408Fe00d7A72e359229AdA; + address internal SHIB_HOLDER_2 = 0x0e3bbc0D04fF62211F71f3e4C45d82ad76224385; + + address internal USDC = 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48; + address internal USDC_HOLDER_0 = 0xDa9CE944a37d218c3302F6B82a094844C6ECEb17; + address internal USDC_HOLDER_1 = 0x3e67F4721E6d1c41a015f645eFa37BEd854fcf52; + + function setUp() public { + // All tests of the `getTokenBalances` method are fork tests using live contracts. + vm.createSelectFork({urlOrAlias: "mainnet", blockNumber: 16_428_900}); + } + + function test_RevertIf_CannotGetTokenBalances_NonTokenContract() external { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + // The UniswapV2Factory contract has neither a `balanceOf` function nor a fallback function, + // so the `balanceOf` call should revert. + address token = address(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f); + address[] memory addresses = new address[](1); + addresses[0] = USDC_HOLDER_0; + + vm.expectRevert("Multicall3: call failed"); + stdUtils.exposed_getTokenBalances(token, addresses); + } + + function test_RevertIf_CannotGetTokenBalances_EOA() external { + // We deploy a mock version so we can properly test the revert. + StdUtilsMock stdUtils = new StdUtilsMock(); + + address eoa = vm.addr({privateKey: 1}); + address[] memory addresses = new address[](1); + addresses[0] = USDC_HOLDER_0; + vm.expectRevert("StdUtils getTokenBalances(address,address[]): Token address is not a contract."); + stdUtils.exposed_getTokenBalances(eoa, addresses); + } + + function test_GetTokenBalances_Empty() external { + address[] memory addresses = new address[](0); + uint256[] memory balances = getTokenBalances(USDC, addresses); + assertEq(balances.length, 0); + } + + function test_GetTokenBalances_USDC() external { + address[] memory addresses = new address[](2); + addresses[0] = USDC_HOLDER_0; + addresses[1] = USDC_HOLDER_1; + uint256[] memory balances = getTokenBalances(USDC, addresses); + assertEq(balances[0], 159_000_000_000_000); + assertEq(balances[1], 131_350_000_000_000); + } + + function test_GetTokenBalances_SHIB() external { + address[] memory addresses = new address[](3); + addresses[0] = SHIB_HOLDER_0; + addresses[1] = SHIB_HOLDER_1; + addresses[2] = SHIB_HOLDER_2; + uint256[] memory balances = getTokenBalances(SHIB, addresses); + assertEq(balances[0], 3_323_256_285_484.42e18); + assertEq(balances[1], 1_271_702_771_149.99999928e18); + assertEq(balances[2], 606_357_106_247e18); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/Vm.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/Vm.t.sol new file mode 100644 index 00000000..4b6e48a4 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/Vm.t.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0 <0.9.0; + +import {Test} from "../src/Test.sol"; +import {Vm, VmSafe} from "../src/Vm.sol"; + +// These tests ensure that functions are never accidentally removed from a Vm interface, or +// inadvertently moved between Vm and VmSafe. These tests must be updated each time a function is +// added to or removed from Vm or VmSafe. +contract VmTest is Test { + function test_VmInterfaceId() public pure { + assertEq(type(Vm).interfaceId, bytes4(0xe835828d), "Vm"); + } + + function test_VmSafeInterfaceId() public pure { + assertEq(type(VmSafe).interfaceId, bytes4(0x7f58f7be), "VmSafe"); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationScript.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationScript.sol new file mode 100644 index 00000000..d3d88a0b --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationScript.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {Script} from "../../src/Script.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationScript is Script {} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationScriptBase.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationScriptBase.sol new file mode 100644 index 00000000..65b5bedb --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationScriptBase.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {ScriptBase} from "../../src/Script.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationScriptBase is ScriptBase {} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationTest.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationTest.sol new file mode 100644 index 00000000..2a9dec57 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationTest.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {Test} from "../../src/Test.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationTest is Test {} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationTestBase.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationTestBase.sol new file mode 100644 index 00000000..32b3fc5b --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/compilation/CompilationTestBase.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.6.2 <0.9.0; + +pragma experimental ABIEncoderV2; + +import {TestBase} from "../../src/Test.sol"; + +// The purpose of this contract is to benchmark compilation time to avoid accidentally introducing +// a change that results in very long compilation times with via-ir. See https://github.com/foundry-rs/forge-std/issues/207 +contract CompilationTestBase is TestBase {} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/broadcast.log.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/broadcast.log.json new file mode 100644 index 00000000..0a0200bc --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/broadcast.log.json @@ -0,0 +1,187 @@ +{ + "transactions": [ + { + "hash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", + "type": "CALL", + "contractName": "Test", + "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "function": "multiple_arguments(uint256,address,uint256[]):(uint256)", + "arguments": ["1", "0000000000000000000000000000000000001337", "[3,4]"], + "tx": { + "type": "0x02", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "gas": "0x73b9", + "value": "0x0", + "data": "0x23e99187000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000013370000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004", + "nonce": "0x3", + "accessList": [] + } + }, + { + "hash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", + "type": "CALL", + "contractName": "Test", + "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "function": "inc():(uint256)", + "arguments": [], + "tx": { + "type": "0x02", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "gas": "0xdcb2", + "value": "0x0", + "data": "0x371303c0", + "nonce": "0x4", + "accessList": [] + } + }, + { + "hash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", + "type": "CALL", + "contractName": "Test", + "contractAddress": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "function": "t(uint256):(uint256)", + "arguments": ["1"], + "tx": { + "type": "0x02", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "gas": "0x8599", + "value": "0x0", + "data": "0xafe29f710000000000000000000000000000000000000000000000000000000000000001", + "nonce": "0x5", + "accessList": [] + } + } + ], + "receipts": [ + { + "transactionHash": "0x481dc86e40bba90403c76f8e144aa9ff04c1da2164299d0298573835f0991181", + "transactionIndex": "0x0", + "blockHash": "0xef0730448490304e5403be0fa8f8ce64f118e9adcca60c07a2ae1ab921d748af", + "blockNumber": "0x1", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": null, + "cumulativeGasUsed": "0x13f3a", + "gasUsed": "0x13f3a", + "contractAddress": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0x6a187183545b8a9e7f1790e847139379bf5622baff2cb43acf3f5c79470af782", + "transactionIndex": "0x0", + "blockHash": "0xf3acb96a90071640c2a8c067ae4e16aad87e634ea8d8bbbb5b352fba86ba0148", + "blockNumber": "0x2", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": null, + "cumulativeGasUsed": "0x45d80", + "gasUsed": "0x45d80", + "contractAddress": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0x064ad173b4867bdef2fb60060bbdaf01735fbf10414541ea857772974e74ea9d", + "transactionIndex": "0x0", + "blockHash": "0x8373d02109d3ee06a0225f23da4c161c656ccc48fe0fcee931d325508ae73e58", + "blockNumber": "0x3", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x4e59b44847b379578588920ca78fbf26c0b4956c", + "cumulativeGasUsed": "0x45feb", + "gasUsed": "0x45feb", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0xc6006863c267735a11476b7f15b15bc718e117e2da114a2be815dd651e1a509f", + "transactionIndex": "0x0", + "blockHash": "0x16712fae5c0e18f75045f84363fb6b4d9a9fe25e660c4ce286833a533c97f629", + "blockNumber": "0x4", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "cumulativeGasUsed": "0x5905", + "gasUsed": "0x5905", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0xedf2b38d8d896519a947a1acf720f859bb35c0c5ecb8dd7511995b67b9853298", + "transactionIndex": "0x0", + "blockHash": "0x156b88c3eb9a1244ba00a1834f3f70de735b39e3e59006dd03af4fe7d5480c11", + "blockNumber": "0x5", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0xe7f1725e7734ce288f8367e1bb143e90bb3f0512", + "cumulativeGasUsed": "0xa9c4", + "gasUsed": "0xa9c4", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", + "transactionIndex": "0x0", + "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", + "blockNumber": "0x6", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "cumulativeGasUsed": "0x66c5", + "gasUsed": "0x66c5", + "contractAddress": null, + "logs": [ + { + "address": "0x7c6b4bbe207d642d98d5c537142d85209e585087", + "topics": [ + "0x0b2e13ff20ac7b474198655583edf70dedd2c1dc980e329c4fbb2fc0748b796b" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000046865726500000000000000000000000000000000000000000000000000000000", + "blockHash": "0xcf61faca67dbb2c28952b0b8a379e53b1505ae0821e84779679390cb8571cadb", + "blockNumber": "0x6", + "transactionHash": "0xa57e8e3981a6c861442e46c9471bd19cb3e21f9a8a6c63a72e7b5c47c6675a7c", + "transactionIndex": "0x1", + "logIndex": "0x0", + "transactionLogIndex": "0x0", + "removed": false + } + ], + "status": "0x1", + "logsBloom": "0x00000000000800000000000000000010000000000000000000000000000180000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100", + "effectiveGasPrice": "0xee6b2800" + }, + { + "transactionHash": "0x11fbb10230c168ca1e36a7e5c69a6dbcd04fd9e64ede39d10a83e36ee8065c16", + "transactionIndex": "0x0", + "blockHash": "0xf1e0ed2eda4e923626ec74621006ed50b3fc27580dc7b4cf68a07ca77420e29c", + "blockNumber": "0x7", + "from": "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + "to": "0x0000000000000000000000000000000000001337", + "cumulativeGasUsed": "0x5208", + "gasUsed": "0x5208", + "contractAddress": null, + "logs": [], + "status": "0x1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "effectiveGasPrice": "0xee6b2800" + } + ], + "libraries": [ + "src/Broadcast.t.sol:F:0x5fbdb2315678afecb367f032d93f642f64180aa3" + ], + "pending": [], + "path": "broadcast/Broadcast.t.sol/31337/run-latest.json", + "returns": {}, + "timestamp": 1655140035 +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/config.toml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/config.toml new file mode 100644 index 00000000..e6dcccca --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/config.toml @@ -0,0 +1,81 @@ +# ------------------------------------------------ +# EXAMPLE DEPLOYMENT CONFIG +# ------------------------------------------------ + +# -- MAINNET ------------------------------------- + +[mainnet] +endpoint_url = "${MAINNET_RPC}" + +[mainnet.bool] +is_live = true +bool_array = [true, false] + +[mainnet.address] +weth = "${WETH_MAINNET}" +deps = [ + "0x0000000000000000000000000000000000000000", + "0x1111111111111111111111111111111111111111", +] + +[mainnet.uint] +number = 1234 +number_array = [5678, 9999] + +[mainnet.int] +signed_number = -1234 +signed_number_array = [-5678, 9999] + +[mainnet.bytes32] +word = "0x00000000000000000000000000000000000000000000000000000000000004d2" # 1234 +word_array = [ + "0x000000000000000000000000000000000000000000000000000000000000162e", # 5678 + "0x000000000000000000000000000000000000000000000000000000000000270f", # 9999 +] + +[mainnet.bytes] +b = "0xabcd" +b_array = ["0xdead", "0xbeef"] + +[mainnet.string] +str = "foo" +str_array = ["bar", "baz"] + +# -- OPTIMISM ------------------------------------ + +[optimism] +endpoint_url = "${OPTIMISM_RPC}" + +[optimism.bool] +is_live = false +bool_array = [false, true] + +[optimism.address] +weth = "${WETH_OPTIMISM}" +deps = [ + "0x2222222222222222222222222222222222222222", + "0x3333333333333333333333333333333333333333", +] + +[optimism.uint] +number = 9999 +number_array = [1234, 5678] + +[optimism.int] +signed_number = 9999 +signed_number_array = [-1234, -5678] + +[optimism.bytes32] +word = "0x000000000000000000000000000000000000000000000000000000000000270f" # 9999 +word_array = [ + "0x00000000000000000000000000000000000000000000000000000000000004d2", # 1234 + "0x000000000000000000000000000000000000000000000000000000000000162e", # 5678 +] + +[optimism.bytes] +b = "0xdcba" +b_array = ["0xc0ffee", "0xbabe"] + +[optimism.string] +str = "alice" +str_array = ["bob", "charlie"] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/test.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/test.json new file mode 100644 index 00000000..caebf6d9 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/test.json @@ -0,0 +1,8 @@ +{ + "a": 123, + "b": "test", + "c": { + "a": 123, + "b": "test" + } +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/test.toml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/test.toml new file mode 100644 index 00000000..60692bc7 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/forge-std/test/fixtures/test.toml @@ -0,0 +1,6 @@ +a = 123 +b = "test" + +[c] +a = 123 +b = "test" diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.changeset/README.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.changeset/README.md new file mode 100644 index 00000000..e5b6d8d6 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.changeset/README.md @@ -0,0 +1,8 @@ +# Changesets + +Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works +with multi-package repos, or single-package repos to help you version and publish your code. You can +find the full documentation for it [in our repository](https://github.com/changesets/changesets) + +We have a quick list of common questions to get you started engaging with this project in +[our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.changeset/config.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.changeset/config.json new file mode 100644 index 00000000..0ec7b188 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.changeset/config.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://unpkg.com/@changesets/config@2.3.0/schema.json", + "changelog": "@changesets/cli/changelog", + "commit": false, + "fixed": [], + "linked": [], + "access": "public", + "baseBranch": "main", + "updateInternalDependencies": "patch", + "ignore": [ + "@hyperbridge/indexer" + ] +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.dockerignore b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.dockerignore new file mode 100644 index 00000000..f2a3d71f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.dockerignore @@ -0,0 +1,51 @@ +# Version Control +.git/ +.github/ +.gitignore +.gitmodules +.changeset/ +.claude/ + +# Development +**/tests/ +**/*.test.ts +**/*.spec.ts +**/__tests__/ +**/vitest.config.ts +**/jest.config.js +**/coverage/ + +# We need node_modules and dist for building +# Don't exclude: node_modules/, **/node_modules/, **/dist/ + +# Environment +.env +.env.* +**/.env +**/.env.* + +# Documentation +**/*.md +!README.md + +# Misc +.DS_Store +.vscode/ +.idea/ +.eslintcache +.npm +.yarn/ +.yarnrc.yml +.npmrc + +# Docker +**/Dockerfile +**/docker-compose.yml +**/docker-compose.*.yml +.dockerignore + +# Temporary files +**/tmp/ +**/temp/ +**/logs/ +**/.log diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.eslintrc.js b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.eslintrc.js new file mode 100644 index 00000000..8a1bf0ba --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.eslintrc.js @@ -0,0 +1,23 @@ +module.exports = { + root: true, + parser: "@typescript-eslint/parser", + plugins: ["@typescript-eslint"], + extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"], + env: { + node: true, + browser: true, + es6: true, + }, + parserOptions: { + ecmaVersion: 2020, + sourceType: "module", + project: ["./tsconfig.base.json", "./packages/*/tsconfig.json"], + }, + ignorePatterns: ["node_modules", "dist", "build", "**/*.js", "!.eslintrc.js"], + rules: { + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-explicit-any": "warn", + "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], + "no-console": ["warn", { allow: ["warn", "error"] }], + }, +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/filler-docker.yml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/filler-docker.yml new file mode 100644 index 00000000..eabb5829 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/filler-docker.yml @@ -0,0 +1,63 @@ +name: "Publish @hyperbridge/filler" + +on: + push: + tags: + - "filler-v[0-9]+.[0-9]+.[0-9]+" + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: true + +jobs: + build_and_publish: + runs-on: ubuntu-latest + steps: + - name: Checkout sources + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: "24" + registry-url: "https://registry.npmjs.org" + + - name: Install pnpm + run: npm install -g pnpm@9.15.0 + + - name: Extract version from tag + id: get-version + run: echo "VERSION=${GITHUB_REF#refs/tags/filler-v}" >> $GITHUB_ENV + + - name: Install dependencies + run: pnpm install + + - name: Build SDK (dependency for filler) + run: cd packages/sdk && pnpm build + + - name: Build Filler + run: cd packages/filler && pnpm build + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_ACCESS_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Build and push Docker image + uses: docker/build-push-action@v4 + with: + context: . + file: ./packages/filler/scripts/Dockerfile + push: true + tags: | + polytopelabs/hyperbridge-filler:v${{ env.VERSION }} + polytopelabs/hyperbridge-filler:latest + platforms: linux/amd64 + cache-from: type=gha + cache-to: type=gha,mode=max diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/publish-core.yml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/publish-core.yml new file mode 100644 index 00000000..2cc0059c --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/publish-core.yml @@ -0,0 +1,124 @@ +name: "Publish @hyperbridge/core" + +on: + push: + tags: + - "core-v*" + +jobs: + build-and-publish: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "22" + registry-url: "https://registry.npmjs.org" + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + with: + version: "7" + + - name: Install dependencies + run: pnpm install + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Build dependencies + run: pnpm --filter="@hyperbridge/core^..." build + + - name: Build Core + run: pnpm --filter="@hyperbridge/core" build + + - name: Publish to npm + run: | + echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" > ~/.npmrc + pnpm --filter="@hyperbridge/core" publish --no-git-checks + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + generate-changelog: + runs-on: ubuntu-latest + needs: build-and-publish + permissions: + contents: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get previous tag + id: previous-tag + run: | + CURRENT_TAG=${GITHUB_REF#refs/tags/} + PREVIOUS_TAG=$(git tag -l "core-v*" --sort=-version:refname | grep -v "^${CURRENT_TAG}$" | head -n1) + echo "previous_tag=${PREVIOUS_TAG}" >> $GITHUB_OUTPUT + echo "current_tag=${CURRENT_TAG}" >> $GITHUB_OUTPUT + echo "clean_tag=${CURRENT_TAG#core-}" >> $GITHUB_OUTPUT + + - name: Generate changelog + id: changelog + run: | + CURRENT_TAG=${{ steps.previous-tag.outputs.current_tag }} + PREVIOUS_TAG=${{ steps.previous-tag.outputs.previous_tag }} + CLEAN_TAG=${{ steps.previous-tag.outputs.clean_tag }} + + echo "Generating changelog for ${CURRENT_TAG}" + echo "Previous tag: ${PREVIOUS_TAG}" + + # If no previous tag exists, get all commits + if [ -z "$PREVIOUS_TAG" ]; then + COMMIT_RANGE="HEAD" + else + COMMIT_RANGE="${PREVIOUS_TAG}..${CURRENT_TAG}" + fi + + # Generate changelog from commit messages + CHANGELOG=$(git log --pretty=format:"* %s (%h)" $COMMIT_RANGE --reverse) + + # Create a more structured changelog + echo "# Changelog for ${CURRENT_TAG}" > CHANGELOG.md + echo "" >> CHANGELOG.md + echo "## Changes" >> CHANGELOG.md + echo "" >> CHANGELOG.md + echo "$CHANGELOG" >> CHANGELOG.md + echo "" >> CHANGELOG.md + + # Also create a release body + echo "changelog<> $GITHUB_OUTPUT + echo "## What's Changed" >> $GITHUB_OUTPUT + echo "" >> $GITHUB_OUTPUT + echo "$CHANGELOG" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Create GitHub Release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.POLYTOPE_GITHUB_TOKEN }} + with: + tag_name: ${{ steps.previous-tag.outputs.current_tag }} + release_name: "@hyperbridge/core ${{ steps.previous-tag.outputs.clean_tag }}" + body: ${{ steps.changelog.outputs.changelog }} + draft: true + prerelease: false + + - name: Commit and push changelog + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add CHANGELOG.md + git commit -m "docs: update changelog for ${{ steps.previous-tag.outputs.current_tag }}" || exit 0 + git push origin HEAD:main || true diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/publish-sdk.yml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/publish-sdk.yml new file mode 100644 index 00000000..159be54a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/publish-sdk.yml @@ -0,0 +1,121 @@ +name: "Publish @hyperbridge/sdk" + +on: + push: + tags: + - "sdk-v*" + +jobs: + build-and-publish: + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "22" + registry-url: "https://registry.npmjs.org" + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + with: + version: "7" + + - name: Install dependencies + run: pnpm install + + - name: Build dependencies + run: pnpm --filter="@hyperbridge/sdk^..." build + + - name: Build SDK + run: pnpm --filter="@hyperbridge/sdk" build + + - name: Publish to npm + run: | + echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" > ~/.npmrc + pnpm --filter="@hyperbridge/sdk" publish --no-git-checks + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + generate-changelog: + runs-on: ubuntu-latest + needs: build-and-publish + permissions: + contents: write + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Get previous tag + id: previous-tag + run: | + CURRENT_TAG=${GITHUB_REF#refs/tags/} + PREVIOUS_TAG=$(git tag -l "sdk-v*" --sort=-version:refname | grep -v "^${CURRENT_TAG}$" | head -n1) + # Remove 'sdk-' prefix for clean tag name + CLEAN_TAG=${CURRENT_TAG#sdk-} + echo "previous_tag=${PREVIOUS_TAG}" >> $GITHUB_OUTPUT + echo "current_tag=${CURRENT_TAG}" >> $GITHUB_OUTPUT + echo "clean_tag=${CLEAN_TAG}" >> $GITHUB_OUTPUT + + - name: Generate changelog + id: changelog + run: | + CURRENT_TAG=${{ steps.previous-tag.outputs.current_tag }} + PREVIOUS_TAG=${{ steps.previous-tag.outputs.previous_tag }} + CLEAN_TAG=${{ steps.previous-tag.outputs.clean_tag }} + + echo "Generating changelog for ${CLEAN_TAG}" + echo "Previous tag: ${PREVIOUS_TAG}" + + # If no previous tag exists, get all commits + if [ -z "$PREVIOUS_TAG" ]; then + COMMIT_RANGE="HEAD" + else + COMMIT_RANGE="${PREVIOUS_TAG}..${CURRENT_TAG}" + fi + + # Generate changelog from commit messages + CHANGELOG=$(git log --pretty=format:"* %s (%h)" $COMMIT_RANGE --reverse) + + # Create a more structured changelog + echo "# Changelog for ${CLEAN_TAG}" > CHANGELOG.md + echo "" >> CHANGELOG.md + echo "## Changes" >> CHANGELOG.md + echo "" >> CHANGELOG.md + echo "$CHANGELOG" >> CHANGELOG.md + echo "" >> CHANGELOG.md + + # Also create a release body + echo "changelog<> $GITHUB_OUTPUT + echo "## What's Changed" >> $GITHUB_OUTPUT + echo "" >> $GITHUB_OUTPUT + echo "$CHANGELOG" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Create GitHub Release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.POLYTOPE_GITHUB_TOKEN }} + with: + tag_name: ${{ steps.previous-tag.outputs.clean_tag }} + release_name: SDK Release ${{ steps.previous-tag.outputs.clean_tag }} + body: ${{ steps.changelog.outputs.changelog }} + draft: true + prerelease: false + + - name: Commit and push changelog + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add CHANGELOG.md + git commit -m "docs: update changelog for ${{ steps.previous-tag.outputs.current_tag }}" || exit 0 + git push origin HEAD:main || true diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/test-core.yml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/test-core.yml new file mode 100644 index 00000000..c1a47ceb --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/test-core.yml @@ -0,0 +1,69 @@ +name: "@hyperbridge/core" + +on: + push: + branches: + - main + paths: + - "packages/core/**" + - ".github/workflows/test-core.yml" + pull_request: + branches: + - main + paths: + - "packages/core/**" + - ".github/workflows/test-core.yml" + +concurrency: + group: ${{ github.ref }}-core + cancel-in-progress: true + +env: + FOUNDRY_PROFILE: ci + +jobs: + compile: + name: Compile + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: "18" + + - name: Install pnpm + uses: pnpm/action-setup@v2 + with: + version: 8 + run_install: false + + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + + - name: Setup pnpm cache + uses: actions/cache@v3 + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + + - name: Install dependencies + run: pnpm install + + - name: Compile SDK + working-directory: packages/core + run: | + echo "Compiling Solidity SDK with Forge..." + forge build --contracts contracts/ --skip test --skip script --sizes + echo "✅ All contracts compiled successfully" diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/test-nexus-ci.yml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/test-nexus-ci.yml new file mode 100644 index 00000000..00917c66 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/test-nexus-ci.yml @@ -0,0 +1,108 @@ +name: Indexer GraphQL Test + +# Cancel running workflows from the same PR +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +on: + push: + branches: [main] + paths: + - "packages/indexer/**" + pull_request: + branches: [main] + paths: + - "packages/indexer/**" + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "22" + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + with: + version: "7" + + - name: Install dependencies + run: pnpm install + + - name: Set up environment variables + run: | + # Set up environment variables from secrets + cat > .env.nexus-ci << EOF + HYPERBRIDGE_NEXUS=${{ secrets.HYPERBRIDGE_NEXUS }} + GNOSIS_CHIADO=${{ secrets.GNOSIS_CHIADO }} + INDEXER_URL=${{ secrets.INDEXER_URL }} + PRIVATE_KEY=${{ secrets.PRIVATE_KEY }} + SECRET_PHRASE=${{ secrets.SECRET_PHRASE }} + EOF + + - name: Build packages + run: pnpm build + env: + ENV: nexus-ci + + - name: Install Docker Compose + run: | + sudo apt-get update + sudo apt-get install -y docker-compose + docker compose version + + - name: Start Nexus CI indexer (in background) + env: + DB_USER: "postgres" + DB_PASS: "postgres" + DB_DATABASE: "postgres" + DB_HOST: "postgres" + DB_PORT: 5432 + DB_PATH: "./.indexer" + LOG_LEVEL: ${{ secrets.ACTIONS_RUNNER_DEBUG == 'true' && 'debug' || 'info' }} + run: | + cd packages/indexer + nohup pnpm start:nexus-ci > indexer_output.log 2>&1 & + echo "Started indexer process in background" + + - name: Wait for GraphQL server to be available + run: | + echo "Waiting for GraphQL server to be available on port 3100..." + timeout=300 # 5 minutes timeout + elapsed=0 + interval=5 + while ! nc -z localhost 3100; do + if [ "$elapsed" -ge "$timeout" ]; then + echo "Timed out waiting for GraphQL server on port 3100" + cat packages/indexer/indexer_output.log + exit 1 + fi + echo "Waiting for GraphQL server (elapsed: ${elapsed}s)..." + sleep $interval + elapsed=$((elapsed + interval)) + done + echo "GraphQL server is available!" + sleep 120 # Give it a few more seconds to fully initialize + + - name: Run Indexer Graphql tests + run: | + cd packages/indexer + pnpm test graphql + + - name: Clean up + if: always() + run: | + # Stop any containers started by the indexer + docker compose -f packages/indexer/docker/docker-compose.nexus-ci.yml down || true + # Show logs in case of failure + if [ -f packages/indexer/indexer_output.log ]; then + echo "Indexer logs:" + cat packages/indexer/indexer_output.log + fi diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/test-sdk.yml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/test-sdk.yml new file mode 100644 index 00000000..8974570f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.github/workflows/test-sdk.yml @@ -0,0 +1,128 @@ +name: "@hyperbridge/sdk" + +# Cancel running workflows from the same PR +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +on: + push: + branches: [main] + paths: + - "packages/sdk/**" + - "packages/indexer/**" + - "packages/filler/**" + - ".github/workflows/test-sdk.yml" + pull_request: + branches: [main] + paths: + - "packages/sdk/**" + - "packages/indexer/**" + - "packages/filler/**" + - ".github/workflows/test-sdk.yml" + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "22" + + - name: Setup pnpm + uses: pnpm/action-setup@v2 + with: + version: "7" + + - name: Install dependencies + run: pnpm install + + - name: Set up environment variables + run: | + # Set up environment variables from secrets + cat > .env.local << EOF + BSC_CHAPEL=${{ secrets.BSC_CHAPEL }} + GNOSIS_CHIADO=${{ secrets.GNOSIS_CHIADO }} + HYPERBRIDGE_GARGANTUA=${{ secrets.HYPERBRIDGE_GARGANTUA }} + PASEO_RPC_URL=${{ secrets.PASEO_RPC_URL }} + BIFROST_PASEO=${{ secrets.BIFROST_PASEO }} + CERE_LOCAL=${{ secrets.CERE_RPC_URL }} + INDEXER_URL=${{ secrets.INDEXER_URL }} + PRIVATE_KEY=${{ secrets.PRIVATE_KEY }} + SECRET_PHRASE=${{ secrets.SECRET_PHRASE }} + ETH_MAINNET=${{ secrets.ETH_MAINNET }} + BSC_MAINNET=${{ secrets.BSC_MAINNET }} + BASE_MAINNET=${{ secrets.BASE_MAINNET }} + POLYGON_MAINNET=${{ secrets.POLYGON_MAINNET }} + ARBITRUM_MAINNET=${{ secrets.ARBITRUM_MAINNET }} + SEPOLIA=${{ secrets.SEPOLIA }} + COINGECKO=${{secrets.COINGECKO}} + PING_MODULE_ADDRESS: "0xFE9f23F0F2fE83b8B9576d3FC94e9a7458DdDD35" + TOKEN_GATEWAY_ADDRESS: "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6" + EOF + + - name: Build packages + run: pnpm build + env: + ENV: local + + - name: Install Docker Compose + run: | + sudo apt-get update + sudo apt-get install -y docker-compose + docker compose version + + - name: Start local indexer (in background) + env: + DB_USER: "postgres" + DB_PASS: "postgres" + DB_DATABASE: "postgres" + DB_HOST: "postgres" + DB_PORT: 5432 + DB_PATH: "./.indexer" + LOG_LEVEL: ${{ secrets.ACTIONS_RUNNER_DEBUG == 'true' && 'debug' || 'info' }} + run: | + cd packages/indexer + nohup pnpm start:local > indexer_output.log 2>&1 & + echo "Started indexer process in background" + + - name: Wait for GraphQL server to be available + run: | + echo "Waiting for GraphQL server to be available on port 3100..." + timeout=300 # 5 minutes timeout + elapsed=0 + interval=5 + while ! nc -z localhost 3100; do + if [ "$elapsed" -ge "$timeout" ]; then + echo "Timed out waiting for GraphQL server on port 3100" + cat packages/indexer/indexer_output.log + exit 1 + fi + echo "Waiting for GraphQL server (elapsed: ${elapsed}s)..." + sleep $interval + elapsed=$((elapsed + interval)) + done + echo "GraphQL server is available!" + sleep 10 # Give it a few more seconds to fully initialize + + - name: Run SDK tests + run: pnpm --filter="@hyperbridge/sdk" test + + - name: Run Intent Filler tests + run: pnpm --filter="filler" test + + - name: Clean up + if: always() + run: | + # Stop any containers started by the indexer + docker compose -f packages/indexer/docker/docker-compose.local.yml down || true + # Show logs in case of failure + if [ -f packages/indexer/indexer_output.log ]; then + echo "Indexer logs:" + cat packages/indexer/indexer_output.log + fi diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.gitignore b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.gitignore new file mode 100644 index 00000000..0a77556c --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.gitignore @@ -0,0 +1,95 @@ +# These are some examples of commonly ignored file patterns. +# You should customize this list as applicable to your project. +# Learn more about .gitignore: +# https://www.atlassian.com/git/tutorials/saving-changes/gitignore + +# Node artifact files +node_modules/ +dist/ +local/ + +config.toml + +# lock files +yarn.lock +package-lock.json + +packages/indexer/configs/*.yaml +packages/indexer/src/configs/*.yaml +packages/indexer/configs/src/types* +packages/indexer/src/configs/src/types* +packages/indexer/docker/testnet/ +packages/indexer/docker/mainnet/ +.claude/ + +packages/filler/src/config/chain.ts +packages/filler/src/filler-config.toml +# Compiled Java class files +*.class + +# Compiled Python bytecode +*.py[cod] + +# Log files +*.log + +# Package files +*.jar + +# Generated files +target/ +dist/ +src/types +configs/src/types +project.yaml + +# JetBrains IDE +.idea/ + +# VSCode +.vscode/ + +# Unit test reports +TEST*.xml + +# Generated by MacOS +.DS_Store + +# Generated by Windows +Thumbs.db + +# Applications +*.app +*.exe +*.war + +# Large media files +*.mp4 +*.tiff +*.avi +*.flv +*.mov +*.wmv + +.data +.yarn + +cache +out + +.DS_Store + +.env* +.tsconfig +.tsbuildinfo + +env-config.json +chain-ids-by-genesis.ts +chains-by-ismp-host.ts +token-gateway-addresses.ts +intent-gateway-addresses.ts +testnet-state-machine-ids.ts +l2-state-machine.helper.ts + +# Cache +*hyperbridge-cache/ \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.npmrc b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.npmrc new file mode 100644 index 00000000..9bd8630c --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/.npmrc @@ -0,0 +1,2 @@ +hoist=true +shared-workspace-lockfile=false diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/LICENSE b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/LICENSE new file mode 100644 index 00000000..8aa26455 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [year] [fullname] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/README.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/README.md new file mode 100644 index 00000000..ddc57c80 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/README.md @@ -0,0 +1,71 @@ +# Hyperbridge SDK + +![CI](https://github.com/polytope-labs/hyperbridge-sdk/actions/workflows/test-sdk.yml/badge.svg) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + +Hyperbridge SDK is a comprehensive solution for cross-chain message indexing and retrieval. This monorepo contains two main packages: + +- **@hyperbridge/indexer**: A SubQuery-based indexer for tracking cross-chain messages +- **@hyperbridge/sdk**: A JavaScript/TypeScript SDK for interacting with the indexed data + +## Packages + +| Package | Description | +| ------------------------------------------ | ------------------------------------------------------------------ | +| [@hyperbridge/indexer](./packages/indexer) | The indexer service that processes and stores cross-chain messages | +| [@hyperbridge/sdk](./packages/sdk) | SDK for developers to query and monitor cross-chain messages | + +## Getting Started + +### Prerequisites + +- Node.js 22+ +- pnpm 7+ + +### Installation + +```bash +# Clone the repository +git clone https://github.com/polytope-labs/hyperbridge-sdk.git +cd hyperbridge-sdk + +# Install dependencies +pnpm install + +# Build all packages +pnpm build +``` + +### Development + +```bash +# Run tests +pnpm test + +# Lint code +pnpm lint + +# Format code +pnpm format +``` + +## Contributing + +Create a changeset when making changes: + +```bash +pnpm changeset + +Commit your changes along with the changeset: + +git add . +git commit -m "feat: your feature description" +git push +``` + +## License +This project is licensed under the MIT License - see the [LICENSE](/LICENSE) file for details. + +## Acknowledgments +- [SubQuery](https://subquery.network) - The indexing framework +- [Polkadot](https://polkadot.com) - The interoperability protocol diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/package.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/package.json new file mode 100644 index 00000000..410a1b7e --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/package.json @@ -0,0 +1,77 @@ +{ + "name": "hyperbridge-sdk", + "private": true, + "version": "0.1.0", + "description": "Hyperbridge SDK workspace", + "workspaces": [ + "packages/*" + ], + "scripts": { + "build": "pnpm --filter=\"@hyperbridge/sdk\" build && pnpm --filter=\"@hyperbridge/indexer\" build && pnpm --filter=\"@hyperbridge/filler\" build", + "test": "pnpm --filter=\"*\" test", + "lint": "pnpm --filter=\"*\" lint", + "format": "pnpm --filter=\"*\" format", + "clean": "rm -rf node_modules packages/*/node_modules packages/*/dist", + "changeset": "changeset", + "version-packages": "changeset version", + "release": "pnpm build && pnpm changeset publish" + }, + "devDependencies": { + "@changesets/cli": "^2.28.1", + "@typescript-eslint/eslint-plugin": "^8.25.0", + "@typescript-eslint/parser": "^8.25.0", + "eslint": "^9.21.0", + "eslint-config-prettier": "^10.0.2", + "husky": "9.1.7", + "lint-staged": "15.4.3", + "prettier": "3.5.2", + "typescript": "5.7.3" + }, + "prettier": { + "arrowParens": "always", + "bracketSameLine": false, + "objectWrap": "preserve", + "bracketSpacing": true, + "semi": false, + "experimentalOperatorPosition": "end", + "experimentalTernaries": false, + "singleQuote": false, + "jsxSingleQuote": false, + "quoteProps": "as-needed", + "trailingComma": "all", + "singleAttributePerLine": false, + "htmlWhitespaceSensitivity": "css", + "vueIndentScriptAndStyle": false, + "proseWrap": "preserve", + "insertPragma": false, + "printWidth": 120, + "requirePragma": false, + "tabWidth": 4, + "useTabs": true, + "embeddedLanguageFormatting": "auto" + }, + "lint-staged": { + "*.{js,ts,tsx}": [ + "prettier --write", + "eslint --fix" + ] + }, + "overrides": { + "chalk": "5.3.0", + "strip-ansi": "7.1.0", + "color-convert": "2.0.1", + "color-name": "1.1.4", + "is-core-module": "2.13.1", + "error-ex": "1.3.2", + "has-ansi": "5.0.1" + }, + "engines": { + "node": ">=22", + "pnpm": ">=7" + }, + "packageManager": "pnpm@9.15.0+sha256.09a8fe31a34fda706354680619f4002f4ccef6dadff93240d24ef6c831f0fd28", + "dependencies": { + "jest": "^29.7.0", + "ts-node": "^10.9.2" + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/.gitignore b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/.gitignore new file mode 100644 index 00000000..c61b6b40 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/.gitignore @@ -0,0 +1,17 @@ +# Dotenv file +.env* + +# Node modules +node_modules/ + +# IDE files +.idea +.vscode/ + +# OS files +.DS_Store +Thumbs.db + +# Foundry artifacts +out/ +cache/ diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/.prettierrc b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/.prettierrc new file mode 100644 index 00000000..40a584a8 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/.prettierrc @@ -0,0 +1,5 @@ +{ + "printWidth": 120, + "tabWidth": 4, + "useTabs": true +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/LICENSE b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/LICENSE new file mode 100644 index 00000000..3a23e7f2 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/LICENSE @@ -0,0 +1,51 @@ +Apache License +Version 2.0, January 2004 +http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + +You must give any other recipients of the Work or Derivative Works a copy of this License; and +You must cause any modified files to carry prominent notices stating that You changed the files; and +You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. +5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/README.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/README.md new file mode 100644 index 00000000..e2e06707 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/README.md @@ -0,0 +1,30 @@ +# @hyperbridge/core + +![Unit Tests](https://github.com/polytope-labs/hyperbridge-sdk/actions/workflows/test-core.yml/badge.svg) +[![NPM](https://img.shields.io/npm/v/@hyperbridge/core?label=%40hyperbridge%2Fcore)](https://www.npmjs.com/package/@hyperbridge/core) + +Hyperbridge SDK for EVM environments. This contains libraries & interfaces for working with hyperbridge contracts. These contracts can be used for sending data (Post requests), pulling data (Get requests), and working with token transfers (TokenGateway & IntentGateway) + +### Interfaces + + - [`IHost`](contracts/interfaces/IHost.sol) - The protocol host interface + - [`IDispatcher`](contracts/interfaces/IDispatcher.sol) - The protocol dispatcher interface + - [`IHandler`](contracts/interfaces/IHandler.sol) - The protocol message handler interface + - [`IConsensus`](contracts/interfaces/IConsensus.sol) - The consensus interface + - [`IApp`](contracts/interfaces/IApp.sol) - The protocol application interface + +### Libraries + + - [`Message`](contracts/libraries/Message.sol) - The protocol message types and data structures + - [`StateMachine`](contracts/libraries/StateMachine.sol) - State machine identifier utilities + +### Apps + + - [`HyperApp`](contracts/apps/HyperApp.sol) - Abstract base contract that implements `IApp` for building cross-chain applications with built-in fee estimation and host authorization + - [`HyperFungibleToken`](contracts/apps/HyperFungibleToken.sol) - Abstract ERC20 token implementation with gateway-restricted minting and burning capabilities for cross-chain bridging + - [`ITokenGateway`](contracts/apps/TokenGateway.sol) - Interface for the TokenGateway contract that enables transfers of hyper-fungible tokens using Hyperbridge. Supports both ERC20 token custody and ERC6160 token burn-and-mint mechanisms + - [`IIntentGateway`](contracts/apps/IntentGateway.sol) - Interface for the IntentGateway contract that facilitates cross-chain intent-based orders. Allows users to place orders that can be filled by market makers across different chains + +## License + +This library is licensed under the Apache 2.0 License, Copyright (c) 2025 Polytope Labs. \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/HyperApp.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/HyperApp.sol new file mode 100644 index 00000000..b07818e3 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/HyperApp.sol @@ -0,0 +1,179 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +pragma solidity ^0.8.17; + +import {PostRequest, PostResponse, GetRequest} from "../libraries/Message.sol"; +import {DispatchPost, DispatchPostResponse, DispatchGet, IDispatcher} from "../interfaces/IDispatcher.sol"; +import {IApp, IncomingPostRequest, IncomingPostResponse, IncomingGetResponse} from "../interfaces/IApp.sol"; + +/** + * @dev Uniswap interface for estimating fees in the native token + */ +interface IUniswapV2Router02 { + function WETH() external pure returns (address); + + function getAmountsIn(uint256, address[] calldata) external pure returns (uint256[] memory); +} + +/** + * @title HyperApp + * @notice Abstract base contract for building cross-chain applications on Hyperbridge + * @dev Provides a simplified interface for implementing `IApp` with built-in utilities for fee estimation, + * host authorization, and cross-chain message handling. Extend this contract to build your Hyperbridge application. + */ +abstract contract HyperApp is IApp { + /** + * @dev Call was not expected + */ + error UnexpectedCall(); + + /** + * @dev Account is unauthorized + */ + error UnauthorizedCall(); + + /** + * @dev restricts caller to the local `Host` + */ + modifier onlyHost() { + if (msg.sender != host()) revert UnauthorizedCall(); + _; + } + + /** + * @dev Should return the `Host` address for the current chain. + * The `Host` is an immutable contract that will never change. + */ + function host() public view virtual returns (address); + + /** + * @dev returns the quoted fee in the feeToken for dispatching a POST request + */ + function quote(DispatchPost memory request) public view returns (uint256) { + uint256 len = 32 > request.body.length ? 32 : request.body.length; + return request.fee + (len * IDispatcher(host()).perByteFee(request.dest)); + } + + /** + * @dev returns the quoted fee in the native token for dispatching a POST request + */ + function quoteNative(DispatchPost memory request) public view returns (uint256) { + uint256 fee = quote(request); + address _host = host(); + address _uniswap = IDispatcher(_host).uniswapV2Router(); + address[] memory path = new address[](2); + path[0] = IUniswapV2Router02(_uniswap).WETH(); + path[1] = IDispatcher(_host).feeToken(); + return IUniswapV2Router02(_uniswap).getAmountsIn(fee, path)[0]; + } + + /** + * @dev returns the quoted fee in the feeToken for dispatching a GET request + */ + function quote(DispatchGet memory request) public view returns (uint256) { + address _host = host(); + uint256 pbf = IDispatcher(_host).perByteFee(IDispatcher(_host).host()); + uint256 minimumFee = 32 * pbf; + uint256 totalFee = request.fee + (pbf * request.context.length); + return minimumFee > totalFee ? minimumFee : totalFee; + } + + /** + * @dev returns the quoted fee in the native token for dispatching a GET request + */ + function quoteNative(DispatchGet memory request) public view returns (uint256) { + uint256 fee = quote(request); + address _host = host(); + address _uniswap = IDispatcher(_host).uniswapV2Router(); + address[] memory path = new address[](2); + path[0] = IUniswapV2Router02(_uniswap).WETH(); + path[1] = IDispatcher(_host).feeToken(); + return IUniswapV2Router02(_uniswap).getAmountsIn(fee, path)[0]; + } + + /** + * @dev returns the quoted fee in the feeToken for dispatching a POST response + */ + function quote(DispatchPostResponse memory response) public view returns (uint256) { + uint256 len = 32 > response.response.length ? 32 : response.response.length; + return response.fee + (len * IDispatcher(host()).perByteFee(response.request.source)); + } + + /** + * @dev returns the quoted fee in the native token for dispatching a POST response + */ + function quoteNative(DispatchPostResponse memory request) public view returns (uint256) { + uint256 fee = quote(request); + address _host = host(); + address _uniswap = IDispatcher(_host).uniswapV2Router(); + address[] memory path = new address[](2); + path[0] = IUniswapV2Router02(_uniswap).WETH(); + path[1] = IDispatcher(_host).feeToken(); + return IUniswapV2Router02(_uniswap).getAmountsIn(fee, path)[0]; + } + + /** + * @notice Callback for receiving incoming POST requests + * @dev Called by the Host when a new POST request is received for this app. + * Override this method to implement request handling logic. The default implementation reverts. + */ + function onAccept(IncomingPostRequest calldata) external virtual onlyHost { + revert UnexpectedCall(); + } + + /** + * @notice Callback for handling POST request timeouts + * @dev Called by the Host when a previously dispatched POST request has timed out. + * Override this method to implement cleanup or retry logic. The default implementation reverts. + */ + function onPostRequestTimeout(PostRequest memory) external virtual onlyHost { + revert UnexpectedCall(); + } + + /** + * @notice Callback for receiving POST responses + * @dev Called by the Host when a response is received for a previously dispatched POST request. + * Override this method to process response data. The default implementation reverts. + */ + function onPostResponse(IncomingPostResponse memory) external virtual onlyHost { + revert UnexpectedCall(); + } + + /** + * @notice Callback for handling POST response timeouts + * @dev Called by the Host when a POST response that was sent has timed out. + * Override this method to handle response timeout scenarios. The default implementation reverts. + */ + function onPostResponseTimeout(PostResponse memory) external virtual onlyHost { + revert UnexpectedCall(); + } + + /** + * @notice Callback for receiving GET responses + * @dev Called by the Host when a response is received for a previously dispatched GET request. + * Override this method to process the retrieved state data. The default implementation reverts. + */ + function onGetResponse(IncomingGetResponse memory) external virtual onlyHost { + revert UnexpectedCall(); + } + + /** + * @notice Callback for handling GET request timeouts + * @dev Called by the Host when a previously dispatched GET request has timed out. + * Override this method to handle GET timeout scenarios. The default implementation reverts. + */ + function onGetTimeout(GetRequest memory) external virtual onlyHost { + revert UnexpectedCall(); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/HyperFungibleToken.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/HyperFungibleToken.sol new file mode 100644 index 00000000..8daf4098 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/HyperFungibleToken.sol @@ -0,0 +1,72 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +pragma solidity ^0.8.17; + +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; + +/** + * @title HyperFungibleToken + * @notice An cross-chain fungible token implementation that can only be minted and burned by a designated gateway address. + * @dev This abstract contract extends OpenZeppelin's ERC20 implementation and adds gateway-restricted minting and burning capabilities. + * It is designed to be used in cross-chain bridge scenarios where a trusted gateway manages token supply. + * Derived contracts must implement the gateway() function to return their specific gateway address. + */ +abstract contract HyperFungibleToken is ERC20 { + /// @notice Custom error thrown when a non-gateway address attempts to mint or burn + error OnlyGateway(); + + /** + * @notice Restricts function access to only the gateway address + * @dev Reverts with OnlyGateway error if called by any address other than the gateway + */ + modifier onlyGateway() { + if (msg.sender != gateway()) revert OnlyGateway(); + _; + } + + /** + * @notice Initializes the token with a name and symbol + * @param name The name of the token + * @param symbol The symbol of the token + */ + constructor(string memory name, string memory symbol) ERC20(name, symbol) {} + + /** + * @notice Returns the gateway address + * @dev Must be implemented by derived contracts to return their specific gateway address + * The `gateway` should be an immutable contract that will never change. + * @return The address of the gateway contract + */ + function gateway() public view virtual returns (address); + + /** + * @notice Mints tokens to the specified account + * @dev Can only be called by the gateway address + * @param to The address that will receive the minted tokens + * @param amount The amount of tokens to mint + */ + function mint(address to, uint256 amount) external onlyGateway { + _mint(to, amount); + } + + /** + * @notice Burns tokens from the specified account + * @dev Can only be called by the gateway address. The account must have sufficient balance. + * @param from The address from which tokens will be burned + * @param amount The amount of tokens to burn + */ + function burn(address from, uint256 amount) external onlyGateway { + _burn(from, amount); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/IntentGateway.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/IntentGateway.sol new file mode 100644 index 00000000..67fb42c5 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/IntentGateway.sol @@ -0,0 +1,228 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +pragma solidity ^0.8.17; + +/** + * @notice Tokens that must be received for a valid order fulfillment + */ +struct PaymentInfo { + /// @dev The address of the ERC20 token on the destination chain + /// @dev address(0) used as a sentinel for the native token + bytes32 token; + /// @dev The amount of the token to be sent + uint256 amount; + /// @dev The address to receive the output tokens + bytes32 beneficiary; +} + +/** + * @notice Tokens that must be escrowed for an order + */ +struct TokenInfo { + /// @dev The address of the ERC20 token on the destination chain + /// @dev address(0) used as a sentinel for the native token + bytes32 token; + /// @dev The amount of the token to be sent + uint256 amount; +} + +/** + * @dev Represents an order in the IntentGateway module. + * @param Order The structure defining an order. + */ +struct Order { + /// @dev The address of the user who is initiating the transfer + bytes32 user; + /// @dev The state machine identifier of the origin chain + bytes sourceChain; + /// @dev The state machine identifier of the destination chain + bytes destChain; + /// @dev The block number by which the order must be filled on the destination chain + uint256 deadline; + /// @dev The nonce of the order + uint256 nonce; + /// @dev Represents the dispatch fees associated with the IntentGateway. + uint256 fees; + /// @dev The tokens that the filler will provide. + PaymentInfo[] outputs; + /// @dev The tokens that are escrowed for the filler. + TokenInfo[] inputs; + /// @dev A bytes array to store the calls if any. + bytes callData; +} + +/** + * @dev Struct to define the parameters for the IntentGateway module. + */ +struct Params { + /// @dev The address of the host contract + address host; + /// @dev Address of the dispatcher contract responsible for handling intents. + address dispatcher; +} + +/** + * @notice A struct representing the options for filling an intent. + * @dev This struct is used to specify various parameters and options + * when filling an intent in the IntentGateway contract. + */ +struct FillOptions { + /// @dev The fee paid to the relayer for processing transactions. + uint256 relayerFee; +} + +/** + * @dev Struct representing the options for canceling an intent. + */ +struct CancelOptions { + /// @dev The fee paid to the relayer for processing transactions. + uint256 relayerFee; + /// @dev Stores the height value. + uint256 height; +} + +/** + * @title IIntentGateway + * @author Polytope Labs (hello@polytope.technology) + * + * @dev Interface for the IntentGateway that allows for the creation and fulfillment of cross-chain orders. + */ +interface IIntentGateway { + /** + * @dev Emitted when an order is placed. + */ + event OrderPlaced( + /// @dev The address of the user who is initiating the transfer + bytes32 user, + /// @dev The state machine identifier of the origin chain + bytes sourceChain, + /// @dev The state machine identifier of the destination chain + bytes destChain, + /// @dev The block number by which the order must be filled on the destination chain + uint256 deadline, + /// @dev The nonce of the order + uint256 nonce, + /// @dev Represents the dispatch fees associated with the IntentGateway. + uint256 fees, + /// @dev The tokens that the filler will provide. + PaymentInfo[] outputs, + /// @dev The tokens that are escrowed for the filler. + TokenInfo[] inputs, + /// @dev A bytes array to store the calls if any. + bytes callData + ); + + /** + * @dev Emitted when an order is filled. + * @param commitment The unique identifier of the order. + * @param filler The address of the entity that filled the order. + */ + event OrderFilled(bytes32 indexed commitment, address filler); + + /** + * @dev Emitted when an escrow is released. + * @param commitment The unique identifier of the order. + */ + event EscrowReleased(bytes32 indexed commitment); + + /** + * @dev Emitted when an escrow is refunded. + * @param commitment The unique identifier of the order. + */ + event EscrowRefunded(bytes32 indexed commitment); + + /// @notice Thrown when an unauthorized action is attempted. + error Unauthorized(); + + /// @notice Thrown when an invalid input is provided. + error InvalidInput(); + + /// @notice Thrown when an action is attempted on an expired order. + error Expired(); + + /// @notice Thrown when there are insufficient native tokens to complete an action. + error InsufficientNativeToken(); + + /// @notice Thrown when an action is attempted on an order that has not yet expired. + error NotExpired(); + + /// @notice Thrown when an action is attempted on an order that has already been filled. + error Filled(); + + /// @notice Thrown when an action is attempted on the wrong chain. + error WrongChain(); + + /// @notice Thrown when an action is attempted on an unknown order. + error UnknownOrder(); + + /** + * @notice Fallback function to receive ether + * @dev This function is called when ether is sent to the contract without data + * @custom:note The function is marked payable to allow receiving ether + */ + receive() external payable; + + /** + * @dev Should return the `IsmpHost` address for the current chain. + * The `IsmpHost` is an immutable contract that will never change. + */ + function host() external view returns (address); + + /** + * @dev Fetch the IntentGateway contract instance for a chain. + */ + function instance(bytes calldata stateMachineId) external view returns (bytes32); + + /** + * @notice Retrieves the current parameter settings for the IntentGateway module + * @dev Returns a struct containing all configurable parameters + * @return Params A struct containing the module's current parameters + */ + function params() external view returns (Params memory); + + /** + * @notice Calculates the commitment slot hash required for storage queries. + * @dev The commitment slot hash is used as part of the proof verification process + * @param commitment The commitment value as a bytes32 hash + * @return bytes The calculated commitment slot hash + */ + function calculateCommitmentSlotHash(bytes32 commitment) external pure returns (bytes memory); + + /** + * @notice Places an order with the given order details. + * @dev This function allows users to place an order by providing the order details. + * @param order The order details to be placed. + * @param graffiti Additional data that can be attached to the order + */ + function placeOrder(Order memory order, bytes32 graffiti) external payable; + + /** + * @notice Fills an order with the specified options. + * @param order The order to be filled. + * @param options The options to be used when filling the order. + * @dev This function is payable and can accept Ether. + */ + function fillOrder(Order calldata order, FillOptions memory options) external payable; + + /** + * @notice Cancels an existing order. + * @param order The order to be canceled. + * @param options Additional options for the cancellation process. + * @dev This function can only be called by the order owner and requires a payment. + * It will initiate a storage query on the source chain to verify the order has not + * yet been filled. If the order has not been filled, the tokens will be released. + */ + function cancelOrder(Order calldata order, CancelOptions memory options) external payable; +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/TokenGateway.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/TokenGateway.sol new file mode 100644 index 00000000..5dc3b1f4 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/apps/TokenGateway.sol @@ -0,0 +1,142 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +pragma solidity ^0.8.17; + +struct TeleportParams { + // amount to be sent + uint256 amount; + // Relayer fee + uint256 relayerFee; + // The token identifier to send + bytes32 assetId; + // Redeem ERC20 on the destination? + bool redeem; + // recipient address + bytes32 to; + // recipient state machine + bytes dest; + // request timeout in seconds + uint64 timeout; + // Amount of native token to pay for dispatching the request + // if 0 will use the `IIsmpHost.feeToken` + uint256 nativeCost; + // destination contract call data + bytes data; +} + +// Params for the TokenGateway contract +struct TokenGatewayParams { + // address of the IsmpHost contract on this chain + address host; + // dispatcher for delegating external calls + address dispatcher; +} + +/** + * @title ITokenGateway + * @author Polytope Labs (hello@polytope.technology) + * + * @notice Interface for the TokenGateway contract that allows users to send either ERC20 or hyper-fungible tokens + * using Hyperbridge as a message-passing layer. + * + * @dev ERC20 tokens are custodied in exchange for hyper-fungible tokens to be minted on the destination chain, + * Otherwise if hyper-fungible tokens are sent, then it simply performs a burn-and-mint. + */ +interface ITokenGateway { + // User has received some assets + event AssetReceived( + // The amount that was provided to the user + uint256 amount, + // The associated request commitment + bytes32 commitment, + // The source of the funds + bytes32 indexed from, + // The beneficiary of the funds + address indexed beneficiary, + // The provided assetId + bytes32 indexed assetId + ); + + // User has sent some assets + event AssetTeleported( + // The beneficiary of the funds + bytes32 to, + // The destination chain + string dest, + // The amount that was requested to be sent + uint256 amount, + // The associated request commitment + bytes32 commitment, + // The source of the funds + address indexed from, + // The provided assetId + bytes32 indexed assetId, + // Flag to redeem funds from the TokenGateway + bool redeem + ); + + // User assets could not be delivered and have been refunded. + event AssetRefunded( + // The amount that was requested to be sent + uint256 amount, + // The associated request commitment + bytes32 commitment, + // The beneficiary of the funds + address indexed beneficiary, + // The provided assetId + bytes32 indexed assetId + ); + + // @dev Unexpected zero address + error ZeroAddress(); + + // @dev Provided amount was invalid + error InvalidAmount(); + + // @dev Provided token was unknown + error UnknownAsset(); + + // @dev Protocol invariant violated + error InconsistentState(); + + /** + * @dev Read the protocol parameters + */ + function params() external view returns (TokenGatewayParams memory); + + /** + * @dev Fetch the address for an ERC20 asset + */ + function erc20(bytes32 assetId) external view returns (address); + + /** + * @dev Fetch the address for a hyper-fungible asset + */ + function erc6160(bytes32 assetId) external view returns (address); + + /** + * @dev Fetch the TokenGateway instance for a destination. + */ + function instance(bytes calldata destination) external view returns (address); + + /** + * @dev Teleports a local ERC20/hyper-fungible asset to the destination chain. Allows users to pay + * the Hyperbridge fees in the native token or `IIsmpHost.feeToken` + * + * @notice If a request times out, users can request a refund permissionlessly through + * `HandlerV1.handlePostRequestTimeouts`. + */ + function teleport(TeleportParams calldata teleportParams) external payable; +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IApp.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IApp.sol new file mode 100644 index 00000000..18416583 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IApp.sol @@ -0,0 +1,98 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +pragma solidity ^0.8.17; + +import {PostRequest, PostResponse, GetResponse, GetRequest} from "../libraries/Message.sol"; + +/** + * @title IncomingPostRequest + * @notice Encapsulates an incoming POST request with relayer information + * @dev Used by the Host to deliver POST requests to applications + */ +struct IncomingPostRequest { + // The Post request containing source, dest, nonce, from, to, timeout, and body + PostRequest request; + // Relayer responsible for delivering the request + address relayer; +} + +/** + * @title IncomingPostResponse + * @notice Encapsulates an incoming POST response with relayer information + * @dev Used by the Host to deliver POST responses to applications + */ +struct IncomingPostResponse { + // The Post response containing the original request, response data, and timeout + PostResponse response; + // Relayer responsible for delivering the response + address relayer; +} + +/** + * @title IncomingGetResponse + * @notice Encapsulates an incoming GET response with relayer information + * @dev Used by the Host to deliver GET responses containing state data to applications + */ +struct IncomingGetResponse { + // The Get response containing the request and retrieved state values + GetResponse response; + // Relayer responsible for delivering the response + address relayer; +} + +/** + * @title IApp + * @author Polytope Labs (hello@polytope.technology) + * @notice Interface for cross-chain applications built on Hyperbridge + * @dev Applications must implement this interface to receive and handle cross-chain messages. + * The Host calls these methods to deliver messages, responses, and timeout notifications. + * All methods are permissioned and should only be callable by the Host contract. + */ +interface IApp { + /** + * @dev Called by the `Host` to notify an app of a new request the app may choose to respond immediately, or in a later block + * @param incoming post request + */ + function onAccept(IncomingPostRequest memory incoming) external; + + /** + * @dev Called by the `Host` to notify an app of a post response to a previously sent out request + * @param incoming post response + */ + function onPostResponse(IncomingPostResponse memory incoming) external; + + /** + * @dev Called by the `Host` to notify an app of a get response to a previously sent out request + * @param incoming get response + */ + function onGetResponse(IncomingGetResponse memory incoming) external; + + /** + * @dev Called by the `Host` to notify an app of post requests that were previously sent but have now timed-out + * @param request post request + */ + function onPostRequestTimeout(PostRequest memory request) external; + + /** + * @dev Called by the `Host` to notify an app of post responses that were previously sent but have now timed-out + * @param response post response + */ + function onPostResponseTimeout(PostResponse memory response) external; + + /** + * @dev Called by the `Host` to notify an app of get requests that were previously sent but have now timed-out + * @param request get request + */ + function onGetTimeout(GetRequest memory request) external; +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IConsensus.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IConsensus.sol new file mode 100644 index 00000000..2f2a7dec --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IConsensus.sol @@ -0,0 +1,86 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +pragma solidity ^0.8.17; + +/** + * @title StateCommitment + * @notice Represents a commitment to an intermediate state in the state machine + * @dev Contains metadata about the state machine including timestamp and merkle roots + */ +struct StateCommitment { + /// @notice Unix timestamp of the state machine at the time of this commitment + /// @dev Used for calculating request timeouts and enforcing time-based logic + uint256 timestamp; + /// @notice Merkle root of the overlay trie containing all ISMP requests and responses + /// @dev Used to verify inclusion proofs for cross-chain messages + bytes32 overlayRoot; + /// @notice Merkle root of the state trie at the given block height + /// @dev Represents the complete state of the state machine at this height + bytes32 stateRoot; +} + +/** + * @title StateMachineHeight + * @notice Uniquely identifies a specific height in a state machine + * @dev Consensus clients may track multiple concurrent state machines, hence the need for an identifier + */ +struct StateMachineHeight { + /// @notice Unique identifier for the state machine (e.g., parachain ID, chain ID) + /// @dev Each blockchain or parachain in the network has a unique identifier + uint256 stateMachineId; + /// @notice Block height or number in the state machine + /// @dev Represents the sequential position in the blockchain + uint256 height; +} + +/** + * @title IntermediateState + * @notice Represents an intermediate state in the state transition sequence of a state machine + * @dev Used to track finalized states that have been verified through consensus + */ +struct IntermediateState { + /// @notice Unique identifier for the state machine + /// @dev Same as StateMachineHeight.stateMachineId + uint256 stateMachineId; + /// @notice Block height of this intermediate state + /// @dev The specific height at which this state was committed + uint256 height; + /// @notice The state commitment at this height + /// @dev Contains the timestamp and merkle roots for this state + StateCommitment commitment; +} + +/** + * @title IConsensus + * @author Polytope Labs (hello@polytope.technology) + * @notice Interface for consensus verification in the Hyperbridge protocol + * @dev Consensus clients implement this interface to verify state transitions from different chains. + * The internals are intentionally opaque to the ISMP framework, allowing consensus mechanisms + * to evolve independently (e.g., GRANDPA for Polkadot, Sync Committee for Ethereum). + * Different consensus mechanisms can be plugged in as long as they conform to this interface. + */ +interface IConsensus { + /** + * @notice Verifies a consensus proof and returns the updated consensus state + * @dev This function is called by the Handler to verify incoming consensus updates. + * The implementation details vary based on the consensus mechanism being verified. + * @param trustedState The current trusted consensus state (encoded based on consensus type) + * @param proof The consensus proof to be verified (e.g., validator signatures, merkle proofs) + * @return The new consensus state after verification (encoded) + * @return Array of newly finalized intermediate states that can be trusted + */ + function verifyConsensus(bytes memory trustedState, bytes memory proof) + external + returns (bytes memory, IntermediateState[] memory); +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IDispatcher.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IDispatcher.sol new file mode 100644 index 00000000..69728faf --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IDispatcher.sol @@ -0,0 +1,228 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +pragma solidity ^0.8.17; + +import {PostRequest, FrozenStatus} from "../libraries/Message.sol"; + +/** + * @title DispatchPost + * @notice Parameters for dispatching a POST request through Hyperbridge + * @dev Used to send arbitrary data to applications on other chains + */ +struct DispatchPost { + /// @notice Destination chain identifier (e.g., "POLKADOT-1000", "EVM-1") + /// @dev Must be a valid state machine identifier recognized by the protocol + bytes dest; + /// @notice Destination application address or identifier + /// @dev The receiving application on the destination chain + bytes to; + /// @notice The request payload + /// @dev Arbitrary bytes that will be delivered to the destination application + bytes body; + /// @notice Timeout duration in seconds from the current timestamp + /// @dev Request will be considered timed out after this duration + uint64 timeout; + /// @notice Fee paid to relayers for delivery & execution + /// @dev Paid in the fee token specified by IHost.feeToken() + uint256 fee; + /// @notice Account responsible for paying the fees + /// @dev If different from msg.sender, must have approved the Host contract + address payer; +} + +/** + * @title DispatchGet + * @notice Parameters for dispatching a GET request to query state on another chain + * @dev Used to read storage values from other chains at a specific height + */ +struct DispatchGet { + /// @notice Destination chain identifier + /// @dev Must be a valid state machine identifier + bytes dest; + /// @notice Block height at which to read the state + /// @dev Use 0 for latest available state + uint64 height; + /// @notice Storage keys to query + /// @dev Array of storage keys whose values will be retrieved + bytes[] keys; + /// @notice Timeout duration in seconds + /// @dev Query will be considered timed out after this duration + uint64 timeout; + /// @notice Fee amount for the query operation + /// @dev Covers both protocol fees and relayer incentives + uint256 fee; + /// @notice Application-specific metadata + /// @dev Can be used to track the query purpose or pass additional context + bytes context; +} + +/** + * @title DispatchPostResponse + * @notice Parameters for dispatching a response to a previously received POST request + * @dev Used by applications to respond to cross-chain requests + */ +struct DispatchPostResponse { + /// @notice The original request being responded to + /// @dev Must be a valid request that was previously received + PostRequest request; + /// @notice Response payload + /// @dev Data to send back to the requesting application + bytes response; + /// @notice Timeout duration in seconds for the response + /// @dev Response will be considered timed out after this duration + uint64 timeout; + /// @notice Fee paid to relayers for delivery & execution + /// @dev Paid in the fee token specified by IHost.feeToken() + uint256 fee; + /// @notice Account responsible for paying the fees + /// @dev If different from msg.sender, must have approved the Host contract + address payer; +} + +/** + * @title IDispatcher + * @author Polytope Labs (hello@polytope.technology) + * @notice Interface for dispatching cross-chain messages through Hyperbridge + * @dev This interface provides methods for sending POST requests, GET queries, and responses. + * All dispatch methods support both native token and fee token payments for relayer fees. + * The dispatcher handles message routing, fee collection, and timeout management. + */ +interface IDispatcher { + /** + * @return the host state machine id + */ + function host() external view returns (bytes memory); + + /** + * @return the state machine identifier for the connected hyperbridge instance + */ + function hyperbridge() external view returns (bytes memory); + + /** + * @return the `frozen` status + */ + function frozen() external view returns (FrozenStatus); + + /** + * @dev Returns the address for the Uniswap V2 Router implementation used for swaps + * @return routerAddress - The address to the in-use RouterV02 implementation + */ + function uniswapV2Router() external view returns (address); + + /** + * @dev Returns the nonce immediately available for requests + * @return the `nonce` + */ + function nonce() external view returns (uint256); + + /** + * @dev Returns the address of the ERC-20 fee token contract configured for this state machine. + * + * @notice Hyperbridge collects it's dispatch fees in the provided token denomination. This will typically be in stablecoins. + * + * @return feeToken - The ERC20 contract address for fees. + */ + function feeToken() external view returns (address); + + /** + * @dev Returns the address of the per byte fee configured for the destination state machine. + * + * @notice Hyperbridge collects it's dispatch fees per every byte of the outgoing message. + * + * @param dest - The destination chain for the per byte fee. + * @return perByteFee - The per byte fee for outgoing messages. + */ + function perByteFee(bytes memory dest) external view returns (uint256); + + /** + * @dev Dispatch a POST request to Hyperbridge + * + * @notice Payment for the request can be made with either the native token or the IHost.feeToken. + * If native tokens are supplied, it will perform a swap under the hood using the local uniswap router. + * Will revert if enough native tokens are not provided. + * + * If no native tokens are provided then it will try to collect payment from the calling contract in + * the IHost.feeToken. + * + * @param request - post request + * @return commitment - the request commitment + */ + function dispatch(DispatchPost memory request) external payable returns (bytes32 commitment); + + /** + * @dev Dispatch a GET request to Hyperbridge + * + * @notice Payment for the request can be made with either the native token or the IHost.feeToken. + * If native tokens are supplied, it will perform a swap under the hood using the local uniswap router. + * Will revert if enough native tokens are not provided. + * + * If no native tokens are provided then it will try to collect payment from the calling contract in + * the IHost.feeToken. + * + * @param request - get request + * @return commitment - the request commitment + */ + function dispatch(DispatchGet memory request) external payable returns (bytes32 commitment); + + /** + * @dev Dispatch a POST response to Hyperbridge + * + * @notice Payment for the request can be made with either the native token or the IHost.feeToken. + * If native tokens are supplied, it will perform a swap under the hood using the local uniswap router. + * Will revert if enough native tokens are not provided. + * + * If no native tokens are provided then it will try to collect payment from the calling contract in + * the IHost.feeToken. + * + * @param response - post response + * @return commitment - the request commitment + */ + function dispatch(DispatchPostResponse memory response) external payable returns (bytes32 commitment); + + /** + * @dev Increase the relayer fee for a previously dispatched request. + * This is provided for use only on pending requests, such that when they timeout, + * the user can recover the entire relayer fee. + * + * @notice Payment can be made with either the native token or the IHost.feeToken. + * If native tokens are supplied, it will perform a swap under the hood using the local uniswap router. + * Will revert if enough native tokens are not provided. + * + * If no native tokens are provided then it will try to collect payment from the calling contract in + * the IHost.feeToken. + * + * If called on an already delivered request, these funds will be seen as a donation to the hyperbridge protocol. + * @param commitment - The request commitment + * @param amount - The amount provided in `IHost.feeToken()` + */ + function fundRequest(bytes32 commitment, uint256 amount) external payable; + + /** + * @dev Increase the relayer fee for a previously dispatched response. + * This is provided for use only on pending responses, such that when they timeout, + * the user can recover the entire relayer fee. + * + * @notice Payment can be made with either the native token or the IHost.feeToken. + * If native tokens are supplied, it will perform a swap under the hood using the local uniswap router. + * Will revert if enough native tokens are not provided. + * + * If no native tokens are provided then it will try to collect payment from the calling contract in + * the IHost.feeToken. + * + * If called on an already delivered response, these funds will be seen as a donation to the hyperbridge protocol. + * @param commitment - The response commitment + * @param amount - The amount to be provided in `IHost.feeToken()` + */ + function fundResponse(bytes32 commitment, uint256 amount) external payable; +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IHandler.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IHandler.sol new file mode 100644 index 00000000..cbe91d5a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IHandler.sol @@ -0,0 +1,97 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +pragma solidity ^0.8.17; + +import {IHost} from "./IHost.sol"; +import { + PostRequestMessage, + PostResponseMessage, + GetResponseMessage, + PostRequestTimeoutMessage, + PostResponseTimeoutMessage, + GetTimeoutMessage +} from "../libraries/Message.sol"; + +/** + * @title IHandler + * @author Polytope Labs (hello@polytope.technology) + * @notice Interface for handling incoming cross-chain messages and consensus updates + * @dev The Handler is responsible for verifying and processing all incoming ISMP protocol messages. + * It validates consensus proofs, message proofs, and ensures messages are delivered to the correct applications. + * This interface serves as the entry point for all cross-chain communication through Hyperbridge. + */ +interface IHandler { + /** + * @notice Process an incoming consensus update + * @dev Verifies the consensus proof using the registered IConsensus implementation and updates the trusted state. + * This enables the protocol to track state changes on remote chains. + * @param host The Host contract that stores protocol state + * @param proof Consensus proof data (format depends on the consensus mechanism) + */ + function handleConsensus(IHost host, bytes memory proof) external; + + /** + * @notice Process a batch of incoming POST requests + * @dev Verifies request proofs, checks for timeouts, validates message delays, and dispatches valid requests to destination apps. + * Ensures requests haven't expired and come from verified state commitments. + * @param host The Host contract that stores protocol state + * @param request Batch of POST requests with their merkle proofs + */ + function handlePostRequests(IHost host, PostRequestMessage memory request) external; + + /** + * @notice Process a batch of incoming POST responses + * @dev Verifies response proofs, checks for timeouts, validates message delays, and dispatches valid responses to requesting apps. + * Matches responses to their original requests and ensures they haven't expired. + * @param host The Host contract that stores protocol state + * @param response Batch of POST responses with their merkle proofs + */ + function handlePostResponses(IHost host, PostResponseMessage memory response) external; + + /** + * @notice Process a batch of GET responses (state queries) + * @dev Verifies state proofs, checks for timeouts, and delivers the queried state data to requesting apps. + * Ensures the state data comes from the requested height and hasn't expired. + * @param host The Host contract that stores protocol state + * @param message Batch of GET responses with their state proofs + */ + function handleGetResponses(IHost host, GetResponseMessage memory message) external; + + /** + * @notice Process POST request timeouts + * @dev Verifies non-membership proofs to confirm requests were not processed before timeout. + * Notifies source apps about timed-out requests and allows them to handle refunds or retries. + * @param host The Host contract that stores protocol state + * @param message Batch of timed-out POST requests with non-membership proofs + */ + function handlePostRequestTimeouts(IHost host, PostRequestTimeoutMessage memory message) external; + + /** + * @notice Process POST response timeouts + * @dev Verifies non-membership proofs to confirm responses were not processed before timeout. + * Notifies responding apps about timed-out responses. + * @param host The Host contract that stores protocol state + * @param message Batch of timed-out POST responses with non-membership proofs + */ + function handlePostResponseTimeouts(IHost host, PostResponseTimeoutMessage memory message) external; + + /** + * @notice Process GET request timeouts + * @dev Verifies non-membership proofs to confirm queries were not answered before timeout. + * Notifies requesting apps about timed-out state queries so they can implement fallback logic. + * @param host The Host contract that stores protocol state + * @param message Batch of timed-out GET requests with non-membership proofs + */ + function handleGetRequestTimeouts(IHost host, GetTimeoutMessage memory message) external; +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IHost.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IHost.sol new file mode 100644 index 00000000..0da1568f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/interfaces/IHost.sol @@ -0,0 +1,209 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +pragma solidity ^0.8.17; + +import {StateCommitment, StateMachineHeight} from "./IConsensus.sol"; +import {IDispatcher} from "./IDispatcher.sol"; +import {PostRequest, PostResponse, GetResponse, GetRequest, FrozenStatus} from "../libraries/Message.sol"; + +// Some metadata about the request fee +struct FeeMetadata { + // the relayer fee + uint256 fee; + // user who initiated the request + address sender; +} + +struct ResponseReceipt { + // commitment of the response object + bytes32 responseCommitment; + // address of the relayer responsible for this response delivery + address relayer; +} + +/** + * @title The Host Interface + * @author Polytope Labs (hello@polytope.technology) + * + * @notice The Host interface sits at the core of the interoperable state machine protocol, + * It which encapsulates the interfaces required for ISMP datagram handlers and modules. + * + * @dev The Host provides the necessary storage interface for the ISMP handlers to process + * ISMP messages, the Dispatcher provides the interfaces applications use for dispatching requests + * and responses. This host implementation delegates all verification logic to the IHandler contract. + * It is only responsible for dispatching incoming & outgoing messages as well as managing + * the state of the ISMP protocol. + */ +interface IHost is IDispatcher { + /** + * @return the host admin + */ + function admin() external returns (address); + + /** + * @return the host timestamp + */ + function timestamp() external view returns (uint256); + + /** + * @dev Returns the fisherman responsible for vetoing the given state machine height. + * @return the `fisherman` address + */ + function vetoes(uint256 paraId, uint256 height) external view returns (address); + + /** + * @dev Returns the fee required for 3rd party applications to access hyperbridge state commitments. + * @return the `stateCommitmentFee` + */ + function stateCommitmentFee() external view returns (uint256); + + /** + * @notice Charges the stateCommitmentFee to 3rd party applications. + * If native tokens are provided, will attempt to swap them for the stateCommitmentFee. + * If not enough native tokens are supplied, will revert. + * + * If no native tokens are provided then it will try to collect payment from the calling contract in + * the IHost.feeToken. + * + * @param height - state machine height + * @return the state commitment at `height` + */ + function stateMachineCommitment(StateMachineHeight memory height) external payable returns (StateCommitment memory); + + /** + * @param height - state machine height + * @return the state machine commitment update time at `height` + */ + function stateMachineCommitmentUpdateTime(StateMachineHeight memory height) external returns (uint256); + + /** + * @return the consensus client contract + */ + function consensusClient() external view returns (address); + + /** + * @return the last updated time of the consensus client + */ + function consensusUpdateTime() external view returns (uint256); + + /** + * @return the latest state machine height for the given stateMachineId. If it returns 0, the state machine is unsupported. + */ + function latestStateMachineHeight(uint256 stateMachineId) external view returns (uint256); + + /** + * @return the state of the consensus client + */ + function consensusState() external view returns (bytes memory); + + /** + * @dev Check the response status for a given request. + * @return `response` status + */ + function responded(bytes32 commitment) external view returns (bool); + + /** + * @param commitment - commitment to the request + * @return relayer address + */ + function requestReceipts(bytes32 commitment) external view returns (address); + + /** + * @param commitment - commitment to the request of the response + * @return response receipt + */ + function responseReceipts(bytes32 commitment) external view returns (ResponseReceipt memory); + + /** + * @param commitment - commitment to the request + * @return existence status of an outgoing request commitment + */ + function requestCommitments(bytes32 commitment) external view returns (FeeMetadata memory); + + /** + * @param commitment - commitment to the response + * @return existence status of an outgoing response commitment + */ + function responseCommitments(bytes32 commitment) external view returns (FeeMetadata memory); + + /** + * @return the challenge period + */ + function challengePeriod() external view returns (uint256); + + /** + * @return the unstaking period + */ + function unStakingPeriod() external view returns (uint256); + + /** + * @dev set the new frozen state of the host, only the admin or handler can call this. + * @param newState - the new frozen state + */ + function setFrozenState(FrozenStatus newState) external; + + /** + * @dev Store an encoded consensus state + * @param state new consensus state + */ + function storeConsensusState(bytes memory state) external; + + /** + * @dev Store the commitment at `state height` + * @param height state machine height + * @param commitment state commitment + */ + function storeStateMachineCommitment(StateMachineHeight memory height, StateCommitment memory commitment) external; + + /** + * @dev Delete the state commitment at given state height. + */ + function deleteStateMachineCommitment(StateMachineHeight memory height, address fisherman) external; + + /** + * @dev Dispatch an incoming request to destination app + * @param request - post request + */ + function dispatchIncoming(PostRequest memory request, address relayer) external; + + /** + * @dev Dispatch an incoming post response to source app + * @param response - post response + */ + function dispatchIncoming(PostResponse memory response, address relayer) external; + + /** + * @dev Dispatch an incoming get response to source app + * @param response - get response + */ + function dispatchIncoming(GetResponse memory response, address relayer) external; + + /** + * @dev Dispatch an incoming get timeout to source app + * @param timeout - timed-out get request + */ + function dispatchTimeOut(GetRequest memory timeout, FeeMetadata memory meta, bytes32 commitment) external; + + /** + * @dev Dispatch an incoming post timeout to source app + * @param timeout - timed-out post request + */ + function dispatchTimeOut(PostRequest memory timeout, FeeMetadata memory meta, bytes32 commitment) external; + + /** + * @dev Dispatch an incoming post response timeout to source app + * @param timeout - timed-out post response + */ + function dispatchTimeOut(PostResponse memory timeout, FeeMetadata memory meta, bytes32 commitment) external; +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/libraries/Message.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/libraries/Message.sol new file mode 100644 index 00000000..e48c19ab --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/libraries/Message.sol @@ -0,0 +1,335 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +pragma solidity ^0.8.17; + +import {StorageValue} from "@polytope-labs/solidity-merkle-trees/src/Types.sol"; +import {StateMachineHeight} from "../interfaces/IConsensus.sol"; + +/** + * @title FrozenStatus + * @notice Represents the frozen state of the Host for security and emergency situations + * @dev Used to halt specific protocol operations during security incidents or upgrades + */ +enum FrozenStatus { + /// @notice Normal operation - all functions are enabled + None, + /// @notice Incoming messages are blocked - prevents receiving cross-chain messages + Incoming, + /// @notice Outgoing messages are blocked - prevents sending cross-chain messages + Outgoing, + /// @notice All operations are frozen - complete protocol halt + All +} + +/** + * @title PostRequest + * @notice Represents a cross-chain message request + * @dev Contains all necessary information for routing and processing a cross-chain message + */ +struct PostRequest { + /// @notice Source chain identifier (e.g., "POLKADOT-1000", "EVM-1") + bytes source; + /// @notice Destination chain identifier + bytes dest; + /// @notice Unique nonce for this request on the source chain + uint64 nonce; + /// @notice Source application address that initiated this request + bytes from; + /// @notice Destination application address to receive this request + bytes to; + /// @notice Unix timestamp when this request expires + uint64 timeoutTimestamp; + /// @notice Request payload to be delivered to the destination + bytes body; +} + +/** + * @title GetRequest + * @notice Represents a cross-chain state query request + * @dev Used to read storage values from other chains at specific heights + */ +struct GetRequest { + /// @notice Source chain identifier where the query originated + bytes source; + /// @notice Destination chain identifier to query + bytes dest; + /// @notice Unique nonce for this request on the source chain + uint64 nonce; + /// @notice Address of the application that initiated this query + address from; + /// @notice Unix timestamp when this query expires + uint64 timeoutTimestamp; + /// @notice Storage keys to retrieve from the destination chain + bytes[] keys; + /// @notice Block height at which to read the state (0 for latest) + uint64 height; + /// @notice Application-specific metadata for tracking the query + bytes context; +} + +/** + * @title GetResponse + * @notice Represents a response to a cross-chain state query + * @dev Contains the original query request and the retrieved storage values + */ +struct GetResponse { + /// @notice The original GET request being responded to + GetRequest request; + /// @notice Retrieved storage values from the queried chain + StorageValue[] values; +} + +/** + * @title PostResponse + * @notice Represents a response to a cross-chain POST request + * @dev Contains the original request and the response data + */ +struct PostResponse { + /// @notice The original request being responded to + PostRequest request; + /// @notice Response payload to send back to the requester + bytes response; + /// @notice Unix timestamp when this response expires + uint64 timeoutTimestamp; +} + +/** + * @title PostRequestLeaf + * @notice Represents a POST request as a leaf in a Merkle Mountain Range tree + * @dev Used for generating and verifying merkle proofs of requests + */ +struct PostRequestLeaf { + /// @notice The POST request data + PostRequest request; + /// @notice Position in the MMR leaves array + uint256 index; + /// @notice K-index for MMR proof generation + uint256 kIndex; +} + +/** + * @title PostResponseLeaf + * @notice Represents a POST response as a leaf in a Merkle Mountain Range tree + * @dev Used for generating and verifying merkle proofs of responses + */ +struct PostResponseLeaf { + /// @notice The POST response data + PostResponse response; + /// @notice Position in the MMR leaves array + uint256 index; + /// @notice K-index for MMR proof generation + uint256 kIndex; +} + +// A get response as a leaf in a merkle mountain range tree +/** + * @title GetResponseLeaf + * @notice Represents a GET response as a leaf in a Merkle Mountain Range tree + * @dev Used for generating and verifying merkle proofs of state query responses + */ +struct GetResponseLeaf { + /// @notice The GET response data + GetResponse response; + /// @notice Position in the MMR leaves array + uint256 index; + /// @notice K-index for MMR proof generation + uint256 kIndex; +} + +/** + * @title Proof + * @notice Merkle Mountain Range proof for message verification + * @dev Used to prove inclusion of messages in the protocol's merkle tree + */ +struct Proof { + /// @notice State machine height where this proof is anchored + StateMachineHeight height; + /// @notice Array of merkle tree nodes forming the inclusion proof + bytes32[] multiproof; + /// @notice Total number of leaves in the MMR at this height + uint256 leafCount; +} + +// A message for handling incoming requests +/** + * @title PostRequestMessage + * @notice Batch of POST requests with their merkle proof + * @dev Used by the Handler to verify and process incoming POST requests + */ +struct PostRequestMessage { + /// @notice Merkle proof for verifying the requests + Proof proof; + /// @notice Array of POST requests as MMR leaves + PostRequestLeaf[] requests; +} + +// A message for handling incoming GET responses +struct GetResponseMessage { + // proof for the responses + Proof proof; + // The responses, contained in the merkle mountain range tree + GetResponseLeaf[] responses; +} + +/** + * @title GetTimeoutMessage + * @notice Batch of timed-out GET requests with their non-membership proof + * @dev Used to prove that GET requests were not responded to before timeout + */ +struct GetTimeoutMessage { + /// @notice Array of GET requests that have timed out + GetRequest[] timeouts; + /// @notice Height at which the timeout proof is generated + StateMachineHeight height; + /// @notice Non-membership proof showing requests were not processed + bytes[] proof; +} + +/** + * @title PostRequestTimeoutMessage + * @notice Batch of timed-out POST requests with their non-membership proof + * @dev Used to prove that POST requests were not responded to before timeout + */ +struct PostRequestTimeoutMessage { + /// @notice Array of POST requests that have timed out + PostRequest[] timeouts; + /// @notice Height at which the timeout proof is generated + StateMachineHeight height; + /// @notice Non-membership proof showing requests were not processed + bytes[] proof; +} + +/** + * @title PostResponseTimeoutMessage + * @notice Batch of timed-out POST responses with their non-membership proof + * @dev Used to prove that POST responses were not acknowledged before timeout + */ +struct PostResponseTimeoutMessage { + /// @notice Array of POST responses that have timed out + PostResponse[] timeouts; + /// @notice Height at which the timeout proof is generated + StateMachineHeight height; + /// @notice Non-membership proof showing responses were not processed + bytes[] proof; +} + +// A message for handling incoming responses +/** + * @title PostResponseMessage + * @notice Batch of POST responses with their merkle proof + * @dev Used by the Handler to verify and process incoming POST responses + */ +struct PostResponseMessage { + /// @notice Merkle proof for verifying the responses + Proof proof; + /// @notice Array of POST responses as MMR leaves + PostResponseLeaf[] responses; +} + +library Message { + /** + * @dev Calculates the absolute timeout value for a PostRequest + */ + function timeout(PostRequest memory req) internal pure returns (uint64) { + if (req.timeoutTimestamp == 0) { + return type(uint64).max; + } else { + return req.timeoutTimestamp; + } + } + + /** + * @dev Calculates the absolute timeout value for a GetRequest + */ + function timeout(GetRequest memory req) internal pure returns (uint64) { + if (req.timeoutTimestamp == 0) { + return type(uint64).max; + } else { + return req.timeoutTimestamp; + } + } + + /** + * @dev Calculates the absolute timeout value for a PostResponse + */ + function timeout(PostResponse memory res) internal pure returns (uint64) { + if (res.timeoutTimestamp == 0) { + return type(uint64).max; + } else { + return res.timeoutTimestamp; + } + } + + /** + * @dev Encode the given post request for commitment + */ + function encode(PostRequest memory req) internal pure returns (bytes memory) { + return abi.encodePacked(req.source, req.dest, req.nonce, req.timeoutTimestamp, req.from, req.to, req.body); + } + + /** + * @dev Encode the given get request for commitment + */ + function encode(GetRequest memory req) internal pure returns (bytes memory) { + bytes memory keysEncoding = bytes(""); + uint256 len = req.keys.length; + for (uint256 i = 0; i < len; i++) { + keysEncoding = bytes.concat(keysEncoding, req.keys[i]); + } + + return abi.encodePacked( + req.source, + req.dest, + req.nonce, + req.height, + req.timeoutTimestamp, + abi.encodePacked(req.from), + keysEncoding, + req.context + ); + } + + /** + * @dev Returns the commitment for the given post response + */ + function hash(PostResponse memory res) internal pure returns (bytes32) { + return keccak256(bytes.concat(encode(res.request), abi.encodePacked(res.response, res.timeoutTimestamp))); + } + + /** + * @dev Returns the commitment for the given post request + */ + function hash(PostRequest memory req) internal pure returns (bytes32) { + return keccak256(encode(req)); + } + + /** + * @dev Returns the commitment for the given get request + */ + function hash(GetRequest memory req) internal pure returns (bytes32) { + return keccak256(encode(req)); + } + + /** + * @dev Returns the commitment for the given get response + */ + function hash(GetResponse memory res) internal pure returns (bytes32) { + bytes memory response = bytes(""); + uint256 len = res.values.length; + for (uint256 i = 0; i < len; i++) { + response = bytes.concat(response, bytes.concat(res.values[i].key, res.values[i].value)); + } + return keccak256(bytes.concat(encode(res.request), response)); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/libraries/StateMachine.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/libraries/StateMachine.sol new file mode 100644 index 00000000..6d8d0008 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/contracts/libraries/StateMachine.sol @@ -0,0 +1,75 @@ +// Copyright (C) Polytope Labs Ltd. +// SPDX-License-Identifier: Apache-2.0 +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +pragma solidity ^0.8.17; + +import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; + +/** + * @title StateMachine + * @author Polytope Labs (hello@polytope.technology) + * @notice Utility library for generating standardized state machine identifiers + * @dev This library provides helper functions to create consistent identifiers for different + * blockchain networks and state machines in the Hyperbridge protocol. Each blockchain type + * has its own identifier format to ensure uniqueness across the ecosystem. + * These identifiers are used throughout the protocol for routing messages between chains. + */ +library StateMachine { + /// @notice The identifier for relay chains (Polkadot/Kusama relay chain) + /// @dev Used to identify the main relay chain in the Polkadot ecosystem + uint256 public constant RELAY_CHAIN = 0; + + /** + * @notice Generate an identifier for a Polkadot parachain + * @dev Creates a standardized identifier in the format "POLKADOT-{id}" + * @param id The parachain ID on the Polkadot network + * @return The formatted state machine identifier as bytes + * @custom:example polkadot(1000) returns "POLKADOT-1000" + */ + function polkadot(uint256 id) internal pure returns (bytes memory) { + return bytes(string.concat("POLKADOT-", Strings.toString(id))); + } + + /** + * @notice Generate an identifier for a Kusama parachain + * @dev Creates a standardized identifier in the format "KUSAMA-{id}" + * @param id The parachain ID on the Kusama network + * @return The formatted state machine identifier as bytes + * @custom:example kusama(2000) returns "KUSAMA-2000" + */ + function kusama(uint256 id) internal pure returns (bytes memory) { + return bytes(string.concat("KUSAMA-", Strings.toString(id))); + } + + /** + * @notice Generate an identifier for an EVM-compatible chain + * @dev Creates a standardized identifier in the format "EVM-{chainId}" + * @param chainid The chain ID of the EVM network (e.g., 1 for Ethereum mainnet) + * @return The formatted state machine identifier as bytes + * @custom:example evm(1) returns "EVM-1" for Ethereum mainnet + */ + function evm(uint256 chainid) internal pure returns (bytes memory) { + return bytes(string.concat("EVM-", Strings.toString(chainid))); + } + + /** + * @notice Generate an identifier for a Substrate-based chain + * @dev Creates a standardized identifier in the format "SUBSTRATE-{id}" + * @param id The 4-byte identifier for the Substrate chain + * @return The formatted state machine identifier as bytes + * @custom:example substrate(0x12345678) returns "SUBSTRATE-0x12345678" + */ + function substrate(bytes4 id) internal pure returns (bytes memory) { + return bytes(string.concat("SUBSTRATE-", string(abi.encodePacked(id)))); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/foundry.toml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/foundry.toml new file mode 100644 index 00000000..9ea9d645 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/foundry.toml @@ -0,0 +1,11 @@ +[profile.default] +src = 'interfaces' +out = 'out' +libs = ['lib'] + +[lint] +exclude_lints = [ + "unwrapped-modifier-logic", + "asm-keccak256", + "mixed-case-function", +] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/package.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/package.json new file mode 100644 index 00000000..01eecf54 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/package.json @@ -0,0 +1,43 @@ +{ + "name": "@hyperbridge/core", + "version": "1.0.1", + "description": "Hyperbridge Solidity SDK for dispatching & receiving cross-chain messages", + "author": "Polytope Labs ", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/polytope-labs/hyperbridge-sdk/issues" + }, + "homepage": "https://github.com/polytope-labs/hyperbridge-sdk/tree/main/packages/core#readme", + "directories": { + "lib": "contracts" + }, + "files": [ + "./contracts/**/*.sol" + ], + "publishConfig": { + "access": "public" + }, + "scripts": { + "build": "forge build --contracts contracts/ --skip test --skip script", + "format": "forge fmt contracts/", + "format:check": "forge fmt --check contracts/" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/polytope-labs/hyperbridge-sdk.git" + }, + "keywords": [ + "hyperbridge", + "ethereum", + "polkadot", + "interoperability", + "cross-chain", + "bridges" + ], + "dependencies": { + "@polytope-labs/solidity-merkle-trees": "^0.3.3", + "openzeppelin-solidity": "^4.8.1", + "prettier": "^3.3.3", + "prettier-plugin-solidity": "^1.3.1" + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/pnpm-lock.yaml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/pnpm-lock.yaml new file mode 100644 index 00000000..88a116cd --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/pnpm-lock.yaml @@ -0,0 +1,72 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@polytope-labs/solidity-merkle-trees': + specifier: ^0.3.3 + version: 0.3.4 + openzeppelin-solidity: + specifier: ^4.8.1 + version: 4.8.1 + prettier: + specifier: ^3.3.3 + version: 3.6.2 + prettier-plugin-solidity: + specifier: ^1.3.1 + version: 1.4.3(prettier@3.6.2) + +packages: + + '@polytope-labs/solidity-merkle-trees@0.3.4': + resolution: {integrity: sha512-ldLirdWNd7qNi8iRfpwlHCwy/FrVMd5wbsu9qVxx/IyOnbQnzzU816AfL3Zn01iN8DhB5UFLMkQ/HmF+VOLGFA==} + + '@solidity-parser/parser@0.20.2': + resolution: {integrity: sha512-rbu0bzwNvMcwAjH86hiEAcOeRI2EeK8zCkHDrFykh/Al8mvJeFmjy3UrE7GYQjNwOgbGUUtCn5/k8CB8zIu7QA==} + + openzeppelin-solidity@4.8.1: + resolution: {integrity: sha512-KM0pVpfrCBdifqN2ZeJZFvFuoGz3GmI4Ty/ceKNkcaf7VVWo/rLOfc5EiLh+Ukb5NadNmYo8WMeGhFA8hVWDpg==} + hasBin: true + + prettier-plugin-solidity@1.4.3: + resolution: {integrity: sha512-Mrr/iiR9f9IaeGRMZY2ApumXcn/C5Gs3S7B7hWB3gigBFML06C0yEyW86oLp0eqiA0qg+46FaChgLPJCj/pIlg==} + engines: {node: '>=18'} + peerDependencies: + prettier: '>=2.3.0' + + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} + hasBin: true + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + +snapshots: + + '@polytope-labs/solidity-merkle-trees@0.3.4': + dependencies: + openzeppelin-solidity: 4.8.1 + prettier: 3.6.2 + prettier-plugin-solidity: 1.4.3(prettier@3.6.2) + + '@solidity-parser/parser@0.20.2': {} + + openzeppelin-solidity@4.8.1: {} + + prettier-plugin-solidity@1.4.3(prettier@3.6.2): + dependencies: + '@solidity-parser/parser': 0.20.2 + prettier: 3.6.2 + semver: 7.7.2 + + prettier@3.6.2: {} + + semver@7.7.2: {} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/remappings.txt b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/remappings.txt new file mode 100644 index 00000000..927fde26 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/core/remappings.txt @@ -0,0 +1,2 @@ +@openzeppelin/=node_modules/openzeppelin-solidity +@polytope-labs/solidity-merkle-trees/=node_modules/@polytope-labs/solidity-merkle-trees diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/.dockerignore b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/.dockerignore new file mode 100644 index 00000000..55270750 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/.dockerignore @@ -0,0 +1,66 @@ +# Dependencies +node_modules/ +.pnp +.pnp.js + +# Testing +coverage/ +.nyc_output/ + +# Production builds +dist/ +build/ + +# Misc +.DS_Store +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +# Editor directories and files +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# Environment files +.env +.env.local +.env.*.local + +# Config files (should be mounted, not built in) +filler-config.toml +*.toml +!filler-config.example.toml + +# Scripts (not needed in container) +scripts/ + +# Documentation +*.md +!README.md + +# Git +.git/ +.gitignore + +# Docker files (avoid recursive builds) +Dockerfile +docker-compose.yml +.dockerignore + +# Test files +src/tests/ +*.test.ts +*.spec.ts +vitest.config.ts + +# Development files +.eslintrc.js +.prettierrc +tsconfig.json +tsup.config.ts diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/.eslintrc.js b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/.eslintrc.js new file mode 100644 index 00000000..7cea2048 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/.eslintrc.js @@ -0,0 +1,3 @@ +module.exports = { + extends: ["../../.eslintrc.js"], +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/CHANGELOG.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/CHANGELOG.md new file mode 100644 index 00000000..198b6a0b --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/CHANGELOG.md @@ -0,0 +1,16 @@ +# @hyperbridge/filler + +## 0.1.4 + +### Patch Changes + +- Updated fee value +- Updated dependencies + - @hyperbridge/sdk@1.3.22 + +## 0.1.1 + +### Patch Changes + +- Updated dependencies + - @hyperbridge/sdk@1.3.0 diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/README.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/README.md new file mode 100644 index 00000000..be6d0c54 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/README.md @@ -0,0 +1,196 @@ +# Hyperbridge Intent Filler + +A high-performance intent filler for the Hyperbridge IntentGateway protocol. This package provides both a library interface and a CLI binary for running an intent filler that monitors and fills cross-chain orders. + +## Installation + +### Binary + +```bash +npm install -g @hyperbridge/filler +# or +pnpm add -g @hyperbridge/filler +``` + +### Library + +```bash +npm install @hyperbridge/filler +# or +pnpm add @hyperbridge/filler +``` + +## Quick Start + +### 1. Generate Configuration + +```bash +filler init -o filler-config.toml +``` + +### 2. Edit Configuration + +Update `filler-config.toml` with: + +- Your private key +- Chain configurations (chainId, rpcUrl, intentGatewayAddress) +- Confirmation policies for each chain + +### 3. Run the Filler + +```bash +filler run -c filler-config.toml +``` + +## Docker Usage + +We provide a simple script for Docker operations: + +```bash +# Build Docker image +./scripts/docker.sh build + +# Run as container +./scripts/docker.sh run + +# Use Docker Compose +./scripts/docker.sh up +./scripts/docker.sh down +./scripts/docker.sh logs +``` + +## Configuration + +The filler uses a TOML configuration file: + +```toml +[filler] +privateKey = "0xYourPrivateKey" +maxConcurrentOrders = 5 + +[filler.pendingQueue] +maxRechecks = 10 +recheckDelayMs = 30000 + +[[strategies]] +type = "basic" +privateKey = "0xYourPrivateKey" + +# Chain configurations +[[chains]] +chainId = 97 +rpcUrl = "https://bsc-testnet.public.blastapi.io" +intentGatewayAddress = "0xFC91c1932F70D36E35Ae7F622cE6C8B86CCeE8e9" + +[[chains]] +chainId = 10200 +rpcUrl = "https://rpc.chiadochain.net" +intentGatewayAddress = "0xFC91c1932F70D36E35Ae7F622cE6C8B86CCeE8e9" + +[confirmationPolicies."97"] +minAmount = "1000000000000000000" +maxAmount = "1000000000000000000000" +minConfirmations = 1 +maxConfirmations = 5 + +[confirmationPolicies."10200"] +minAmount = "1000000000000000000" +maxAmount = "1000000000000000000000" +minConfirmations = 1 +maxConfirmations = 5 +``` + +## CLI Commands + +- `filler init` - Generate a sample configuration file +- `filler validate -c ` - Validate a configuration file +- `filler run -c ` - Run the filler with the specified configuration + +## Library Usage + +```typescript +import { IntentFiller, BasicFiller } from "@hyperbridge/filler" + +// Configure chains +const chainConfigs = [ + { + chainId: 97, + rpcUrl: "https://bsc-testnet.public.blastapi.io", + intentGatewayAddress: "0xFC91c1932F70D36E35Ae7F622cE6C8B86CCeE8e9", + }, + { + chainId: 10200, + rpcUrl: "https://rpc.chiadochain.net", + intentGatewayAddress: "0xFC91c1932F70D36E35Ae7F622cE6C8B86CCeE8e9", + }, +] + +// Configure filler +const fillerConfig = { + confirmationPolicy: { + getConfirmationBlocks: (chainId, amount) => 1, + }, + maxConcurrentOrders: 5, + pendingQueueConfig: { + maxRechecks: 10, + recheckDelayMs: 30000, + }, +} + +// Initialize strategies +const strategies = [new BasicFiller("0xYourPrivateKey")] + +// Create and start filler +const intentFiller = new IntentFiller(chainConfigs, strategies, fillerConfig) +intentFiller.start() + +// Listen to events +const monitor = intentFiller.monitor +monitor.on("newOrder", (data) => console.log("New order:", data.order)) +monitor.on("orderFilled", (data) => console.log("Order filled:", data.orderId)) + +// Stop when done +intentFiller.stop() +``` + +## Strategies + +### Basic Filler + +- Direct token transfers between chains +- No swapping capability +- Lower gas costs + +### Stable Swap Filler + +- Supports token swapping via Uniswap V2 +- Can capture arbitrage opportunities +- Higher gas costs + +## Development + +```bash +# Install dependencies +pnpm install + +# Build +pnpm build + +# Run tests +pnpm test + +# Run CLI in development +pnpm cli run -c filler-config.toml +``` + +## Security + +⚠️ **Never commit private keys to version control!** + +- Use environment variables or secure key management in production +- Run fillers in isolated environments +- Monitor for unusual activity + +## License + +Part of the Hyperbridge SDK. diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/filler-config-example.toml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/filler-config-example.toml new file mode 100644 index 00000000..0a6f37ae --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/filler-config-example.toml @@ -0,0 +1,119 @@ +# Hyperbridge Intent Filler Simplified Configuration +# This is a minimal configuration file that leverages the SDK's built-in chain configurations +# Copy this file to filler-config.toml and update with your actual values + +# Filler configuration +[filler] +privateKey = "" # Replace with your actual private key +maxConcurrentOrders = 5 + +# Logging configuration +[filler.logging] +level = "debug" # Options: trace, debug, info, warn, error + +# CoinGecko API configuration (optional) +[filler.coingecko] +apiKey = "" # Optional: Add your CoinGecko Pro API key for higher rate limits + + +[filler.etherscan] +apiKey = "" # Optional: Add your Etherscan API key for higher rate limits + +# Pending queue configuration +[filler.pendingQueue] +maxRechecks = 10 +recheckDelayMs = 30000 # 30 seconds + +# Strategy configuration +# You can configure multiple strategies +[[strategies]] +type = "basic" +privateKey = "" # Replace with your actual private key + +# stable swap strategy not officially supported yet, but very soon! +# [[strategies]] +# type = "stable-swap" +# privateKey = "0x0000000000000000000000000000000000000000000000000000000000000000" + +# Chain configuration - RPC URLs are required +# All other chain data (addresses, assets, etc.) comes from the SDK automatically +[[chains]] +chainId = 1 # Ethereum Mainnet +rpcUrl = "" # Required: your RPC URL + +[[chains]] +chainId = 56 # BSC Mainnet +rpcUrl = "" # Required: your RPC URL + +[[chains]] +chainId = 42161 # Arbitrum Mainnet +rpcUrl = "" # Required: your RPC URL + +[[chains]] +chainId = 8453 # Base Mainnet +rpcUrl = "" # Required: your RPC URL + +[[chains]] +chainId = 137 # Polygon Mainnet +rpcUrl = "" # Required: your RPC URL + +[[chains]] +chainId = 130 # Unichain Mainnet +rpcUrl = "" # Required: your RPC URL + + +# Confirmation policies per chain +# The chain ID should match the numeric ID from the chain configuration +[confirmationPolicies."97"] # BSC Testnet +minAmount = "1" # 1 USD +maxAmount = "1000" # 1000 USD +minConfirmations = 1 +maxConfirmations = 5 + +[confirmationPolicies."10200"] # Gnosis Chiado +minAmount = "1" # 1 USD +maxAmount = "1000" # 1000 USD +minConfirmations = 1 +maxConfirmations = 5 + +[confirmationPolicies."1"] # Ethereum Mainnet +minAmount = "5" # 5 USD +maxAmount = "5000" # 5000 USD +minConfirmations = 3 +maxConfirmations = 12 + +[confirmationPolicies."56"] # BSC Mainnet +minAmount = "1" # 1 USD +maxAmount = "5000" # 5000 USD +minConfirmations = 3 +maxConfirmations = 15 + +[confirmationPolicies."11155111"] # Sepolia +minAmount = "1" # 1 USD +maxAmount = "1000" # 1000 USD +minConfirmations = 1 +maxConfirmations = 5 + +[confirmationPolicies."42161"] # Arbitrum Mainnet +minAmount = "2" # 2 USD +maxAmount = "8000" # 8000 USD +minConfirmations = 2 +maxConfirmations = 10 + +[confirmationPolicies."8453"] # Base Mainnet +minAmount = "2" # 2 USD +maxAmount = "8000" # 8000 USD +minConfirmations = 2 +maxConfirmations = 10 + +[confirmationPolicies."137"] # Polygon Mainnet +minAmount = "2" # 2 USD +maxAmount = "8000" # 8000 USD +minConfirmations = 2 +maxConfirmations = 10 + +[confirmationPolicies."130"] # Unichain Mainnet +minAmount = "2" # 2 USD +maxAmount = "8000" # 8000 USD +minConfirmations = 2 +maxConfirmations = 10 \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/package.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/package.json new file mode 100644 index 00000000..192c48dd --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/package.json @@ -0,0 +1,102 @@ +{ + "name": "@hyperbridge/filler", + "version": "0.1.9", + "description": "IntentGateway filler package for hyperbridge", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "type": "module", + "bin": { + "filler": "./dist/bin/filler.js" + }, + "exports": { + ".": { + "import": "./dist/index.js", + "require": "./dist/index.cjs" + } + }, + "files": [ + "dist" + ], + "scripts": { + "build": "tsup", + "prepublishOnly": "npm run build", + "test": "vitest --watch=false --maxConcurrency=1", + "test:services": "vitest --watch=false --maxConcurrency=1 --testTimeout=1000000 src/tests/services.test.ts", + "test:watch": "vitest", + "lint": "biome lint .", + "lint:fix": "biome lint --write .", + "format": "prettier --write \"src/**/*.ts\"", + "cli": "NODE_NO_WARNINGS=1 tsx src/bin/filler.ts", + "cli:dev": "nodemon --watch src --ext ts --exec tsx src/bin/filler.ts" + }, + "devDependencies": { + "@biomejs/biome": "^1.9.4", + "@types/node": "^22.13.5", + "@vitest/coverage-v8": "^3.0.7", + "nodemon": "^3.1.0", + "tsup": "^8.4.0", + "tsx": "^4.16.2", + "typescript": "^5.7.3", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.0.7" + }, + "publishConfig": { + "access": "public" + }, + "engineStrict": true, + "engines": { + "node": ">=18.0.0" + }, + "dependencies": { + "@hyperbridge/sdk": "workspace:*", + "@polkadot/api": "latest", + "@polkadot/util-crypto": "latest", + "@safe-global/api-kit": "^3.0.1", + "@safe-global/protocol-kit": "^6.0.4", + "@safe-global/types-kit": "^2.0.1", + "async-mutex": "^0.5.0", + "ckb-mmr-wasm": "link:wasm-b", + "commander": "^12.0.0", + "decimal.js": "^10.5.0", + "dotenv": "^16.4.7", + "ethers": "^5.7.2", + "p-queue": "^8.1.0", + "pino": "^9.9.5", + "pino-pretty": "^11.3.0", + "scale-ts": "^1.6.1", + "toml": "^3.0.0", + "viem": "^2.34.0" + }, + "resolutions": { + "@polkadot/api": "^16.4.6", + "@polkadot/api-augment": "^16.4.6", + "@polkadot/api-base": "^16.4.6", + "@polkadot/api-contract": "^16.4.6", + "@polkadot/api-derive": "^16.4.6", + "@polkadot/hw-ledger": "^13.5.6", + "@polkadot/keyring": "^13.5.6", + "@polkadot/networks": "^13.5.6", + "@polkadot/phishing": "^0.25.18", + "@polkadot/rpc-augment": "^16.4.6", + "@polkadot/rpc-core": "^16.4.6", + "@polkadot/rpc-provider": "^16.4.6", + "@polkadot/typegen": "^16.4.6", + "@polkadot/types": "^16.4.6", + "@polkadot/types-augment": "^16.4.6", + "@polkadot/types-codec": "^16.4.6", + "@polkadot/types-create": "^16.4.6", + "@polkadot/types-known": "^16.4.6", + "@polkadot/types-support": "^16.4.6", + "@polkadot/util": "^13.5.6", + "@polkadot/util-crypto": "^13.5.6", + "@polkadot/wasm-crypto": "^7.5.1", + "@polkadot/x-bigint": "^13.5.6", + "@polkadot/x-fetch": "^13.5.6", + "@polkadot/x-global": "^13.5.6", + "@polkadot/x-randomvalues": "^13.5.6", + "@polkadot/x-textdecoder": "^13.5.6", + "@polkadot/x-textencoder": "^13.5.6", + "@polkadot/x-ws": "^13.5.6", + "typescript": "^5.5.4" + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/pnpm-lock.yaml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/pnpm-lock.yaml new file mode 100644 index 00000000..65bedc2f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/pnpm-lock.yaml @@ -0,0 +1,3750 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +overrides: + '@polkadot/api': ^16.4.6 + '@polkadot/api-augment': ^16.4.6 + '@polkadot/api-base': ^16.4.6 + '@polkadot/api-contract': ^16.4.6 + '@polkadot/api-derive': ^16.4.6 + '@polkadot/hw-ledger': ^13.5.6 + '@polkadot/keyring': ^13.5.6 + '@polkadot/networks': ^13.5.6 + '@polkadot/phishing': ^0.25.18 + '@polkadot/rpc-augment': ^16.4.6 + '@polkadot/rpc-core': ^16.4.6 + '@polkadot/rpc-provider': ^16.4.6 + '@polkadot/typegen': ^16.4.6 + '@polkadot/types': ^16.4.6 + '@polkadot/types-augment': ^16.4.6 + '@polkadot/types-codec': ^16.4.6 + '@polkadot/types-create': ^16.4.6 + '@polkadot/types-known': ^16.4.6 + '@polkadot/types-support': ^16.4.6 + '@polkadot/util': ^13.5.6 + '@polkadot/util-crypto': ^13.5.6 + '@polkadot/wasm-crypto': ^7.5.1 + '@polkadot/x-bigint': ^13.5.6 + '@polkadot/x-fetch': ^13.5.6 + '@polkadot/x-global': ^13.5.6 + '@polkadot/x-randomvalues': ^13.5.6 + '@polkadot/x-textdecoder': ^13.5.6 + '@polkadot/x-textencoder': ^13.5.6 + '@polkadot/x-ws': ^13.5.6 + typescript: ^5.5.4 + +importers: + + .: + dependencies: + '@hyperbridge/sdk': + specifier: workspace:* + version: link:../sdk + '@polkadot/api': + specifier: ^16.4.6 + version: 16.4.7 + '@polkadot/util-crypto': + specifier: ^13.5.6 + version: 13.5.6(@polkadot/util@13.5.6) + '@safe-global/api-kit': + specifier: ^3.0.1 + version: 3.0.1(typescript@5.8.3) + '@safe-global/protocol-kit': + specifier: ^6.0.4 + version: 6.0.4(typescript@5.8.3) + '@safe-global/types-kit': + specifier: ^2.0.1 + version: 2.0.1(typescript@5.8.3) + async-mutex: + specifier: ^0.5.0 + version: 0.5.0 + ckb-mmr-wasm: + specifier: link:wasm-b + version: link:wasm-b + commander: + specifier: ^12.0.0 + version: 12.1.0 + decimal.js: + specifier: ^10.5.0 + version: 10.6.0 + dotenv: + specifier: ^16.4.7 + version: 16.5.0 + ethers: + specifier: ^5.7.2 + version: 5.8.0 + p-queue: + specifier: ^8.1.0 + version: 8.1.0 + pino: + specifier: ^9.9.5 + version: 9.9.5 + pino-pretty: + specifier: ^11.3.0 + version: 11.3.0 + scale-ts: + specifier: ^1.6.1 + version: 1.6.1 + toml: + specifier: ^3.0.0 + version: 3.0.0 + viem: + specifier: ^2.34.0 + version: 2.34.0(typescript@5.8.3) + devDependencies: + '@biomejs/biome': + specifier: ^1.9.4 + version: 1.9.4 + '@types/node': + specifier: ^22.13.5 + version: 22.14.0 + '@vitest/coverage-v8': + specifier: ^3.0.7 + version: 3.1.1(vitest@3.1.1(@types/node@22.14.0)(tsx@4.20.5)) + nodemon: + specifier: ^3.1.0 + version: 3.1.10 + tsup: + specifier: ^8.4.0 + version: 8.4.0(postcss@8.5.3)(tsx@4.20.5)(typescript@5.8.3) + tsx: + specifier: ^4.16.2 + version: 4.20.5 + typescript: + specifier: ^5.5.4 + version: 5.8.3 + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.8.3)(vite@6.2.5(@types/node@22.14.0)(tsx@4.20.5)) + vitest: + specifier: ^3.0.7 + version: 3.1.1(@types/node@22.14.0)(tsx@4.20.5) + +packages: + + '@adraffy/ens-normalize@1.11.0': + resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.27.0': + resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.27.0': + resolution: {integrity: sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + + '@biomejs/biome@1.9.4': + resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@1.9.4': + resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@1.9.4': + resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@1.9.4': + resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@1.9.4': + resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@1.9.4': + resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@1.9.4': + resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@1.9.4': + resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@1.9.4': + resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@esbuild/aix-ppc64@0.25.2': + resolution: {integrity: sha512-wCIboOL2yXZym2cgm6mlA742s9QeJ8DjGVaL39dLN4rRwrOgOyYSnOaFPhKZGLb2ngj4EyfAFjsNJwPXZvseag==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.2': + resolution: {integrity: sha512-5ZAX5xOmTligeBaeNEPnPaeEuah53Id2tX4c2CVP3JaROTH+j4fnfHCkr1PjXMd78hMst+TlkfKcW/DlTq0i4w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.2': + resolution: {integrity: sha512-NQhH7jFstVY5x8CKbcfa166GoV0EFkaPkCKBQkdPJFvo5u+nGXLEH/ooniLb3QI8Fk58YAx7nsPLozUWfCBOJA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.2': + resolution: {integrity: sha512-Ffcx+nnma8Sge4jzddPHCZVRvIfQ0kMsUsCMcJRHkGJ1cDmhe4SsrYIjLUKn1xpHZybmOqCWwB0zQvsjdEHtkg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.2': + resolution: {integrity: sha512-MpM6LUVTXAzOvN4KbjzU/q5smzryuoNjlriAIx+06RpecwCkL9JpenNzpKd2YMzLJFOdPqBpuub6eVRP5IgiSA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.2': + resolution: {integrity: sha512-5eRPrTX7wFyuWe8FqEFPG2cU0+butQQVNcT4sVipqjLYQjjh8a8+vUTfgBKM88ObB85ahsnTwF7PSIt6PG+QkA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.2': + resolution: {integrity: sha512-mLwm4vXKiQ2UTSX4+ImyiPdiHjiZhIaE9QvC7sw0tZ6HoNMjYAqQpGyui5VRIi5sGd+uWq940gdCbY3VLvsO1w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.2': + resolution: {integrity: sha512-6qyyn6TjayJSwGpm8J9QYYGQcRgc90nmfdUb0O7pp1s4lTY+9D0H9O02v5JqGApUyiHOtkz6+1hZNvNtEhbwRQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.2': + resolution: {integrity: sha512-gq/sjLsOyMT19I8obBISvhoYiZIAaGF8JpeXu1u8yPv8BE5HlWYobmlsfijFIZ9hIVGYkbdFhEqC0NvM4kNO0g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.2': + resolution: {integrity: sha512-UHBRgJcmjJv5oeQF8EpTRZs/1knq6loLxTsjc3nxO9eXAPDLcWW55flrMVc97qFPbmZP31ta1AZVUKQzKTzb0g==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.2': + resolution: {integrity: sha512-bBYCv9obgW2cBP+2ZWfjYTU+f5cxRoGGQ5SeDbYdFCAZpYWrfjjfYwvUpP8MlKbP0nwZ5gyOU/0aUzZ5HWPuvQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.2': + resolution: {integrity: sha512-SHNGiKtvnU2dBlM5D8CXRFdd+6etgZ9dXfaPCeJtz+37PIUlixvlIhI23L5khKXs3DIzAn9V8v+qb1TRKrgT5w==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.2': + resolution: {integrity: sha512-hDDRlzE6rPeoj+5fsADqdUZl1OzqDYow4TB4Y/3PlKBD0ph1e6uPHzIQcv2Z65u2K0kpeByIyAjCmjn1hJgG0Q==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.2': + resolution: {integrity: sha512-tsHu2RRSWzipmUi9UBDEzc0nLc4HtpZEI5Ba+Omms5456x5WaNuiG3u7xh5AO6sipnJ9r4cRWQB2tUjPyIkc6g==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.2': + resolution: {integrity: sha512-k4LtpgV7NJQOml/10uPU0s4SAXGnowi5qBSjaLWMojNCUICNu7TshqHLAEbkBdAszL5TabfvQ48kK84hyFzjnw==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.2': + resolution: {integrity: sha512-GRa4IshOdvKY7M/rDpRR3gkiTNp34M0eLTaC1a08gNrh4u488aPhuZOCpkF6+2wl3zAN7L7XIpOFBhnaE3/Q8Q==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.2': + resolution: {integrity: sha512-QInHERlqpTTZ4FRB0fROQWXcYRD64lAoiegezDunLpalZMjcUcld3YzZmVJ2H/Cp0wJRZ8Xtjtj0cEHhYc/uUg==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.2': + resolution: {integrity: sha512-talAIBoY5M8vHc6EeI2WW9d/CkiO9MQJ0IOWX8hrLhxGbro/vBXJvaQXefW2cP0z0nQVTdQ/eNyGFV1GSKrxfw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.2': + resolution: {integrity: sha512-voZT9Z+tpOxrvfKFyfDYPc4DO4rk06qamv1a/fkuzHpiVBMOhpjK+vBmWM8J1eiB3OLSMFYNaOaBNLXGChf5tg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.2': + resolution: {integrity: sha512-dcXYOC6NXOqcykeDlwId9kB6OkPUxOEqU+rkrYVqJbK2hagWOMrsTGsMr8+rW02M+d5Op5NNlgMmjzecaRf7Tg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.2': + resolution: {integrity: sha512-t/TkWwahkH0Tsgoq1Ju7QfgGhArkGLkF1uYz8nQS/PPFlXbP5YgRpqQR3ARRiC2iXoLTWFxc6DJMSK10dVXluw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.25.2': + resolution: {integrity: sha512-cfZH1co2+imVdWCjd+D1gf9NjkchVhhdpgb1q5y6Hcv9TP6Zi9ZG/beI3ig8TvwT9lH9dlxLq5MQBBgwuj4xvA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.2': + resolution: {integrity: sha512-7Loyjh+D/Nx/sOTzV8vfbB3GJuHdOQyrOryFdZvPHLf42Tk9ivBU5Aedi7iyX+x6rbn2Mh68T4qq1SDqJBQO5Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.2': + resolution: {integrity: sha512-WRJgsz9un0nqZJ4MfhabxaD9Ft8KioqU3JMinOTvobbX6MOSUigSBlogP8QB3uxpJDsFS6yN+3FDBdqE5lg9kg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.2': + resolution: {integrity: sha512-kM3HKb16VIXZyIeVrM1ygYmZBKybX8N4p754bw390wGO3Tf2j4L2/WYL+4suWujpgf6GBYs3jv7TyUivdd05JA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@ethersproject/abi@5.8.0': + resolution: {integrity: sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==} + + '@ethersproject/abstract-provider@5.8.0': + resolution: {integrity: sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==} + + '@ethersproject/abstract-signer@5.8.0': + resolution: {integrity: sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==} + + '@ethersproject/address@5.8.0': + resolution: {integrity: sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==} + + '@ethersproject/base64@5.8.0': + resolution: {integrity: sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==} + + '@ethersproject/basex@5.8.0': + resolution: {integrity: sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q==} + + '@ethersproject/bignumber@5.8.0': + resolution: {integrity: sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==} + + '@ethersproject/bytes@5.8.0': + resolution: {integrity: sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==} + + '@ethersproject/constants@5.8.0': + resolution: {integrity: sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==} + + '@ethersproject/contracts@5.8.0': + resolution: {integrity: sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==} + + '@ethersproject/hash@5.8.0': + resolution: {integrity: sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==} + + '@ethersproject/hdnode@5.8.0': + resolution: {integrity: sha512-4bK1VF6E83/3/Im0ERnnUeWOY3P1BZml4ZD3wcH8Ys0/d1h1xaFt6Zc+Dh9zXf9TapGro0T4wvO71UTCp3/uoA==} + + '@ethersproject/json-wallets@5.8.0': + resolution: {integrity: sha512-HxblNck8FVUtNxS3VTEYJAcwiKYsBIF77W15HufqlBF9gGfhmYOJtYZp8fSDZtn9y5EaXTE87zDwzxRoTFk11w==} + + '@ethersproject/keccak256@5.8.0': + resolution: {integrity: sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==} + + '@ethersproject/logger@5.8.0': + resolution: {integrity: sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==} + + '@ethersproject/networks@5.8.0': + resolution: {integrity: sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==} + + '@ethersproject/pbkdf2@5.8.0': + resolution: {integrity: sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==} + + '@ethersproject/properties@5.8.0': + resolution: {integrity: sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==} + + '@ethersproject/providers@5.8.0': + resolution: {integrity: sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==} + + '@ethersproject/random@5.8.0': + resolution: {integrity: sha512-E4I5TDl7SVqyg4/kkA/qTfuLWAQGXmSOgYyO01So8hLfwgKvYK5snIlzxJMk72IFdG/7oh8yuSqY2KX7MMwg+A==} + + '@ethersproject/rlp@5.8.0': + resolution: {integrity: sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==} + + '@ethersproject/sha2@5.8.0': + resolution: {integrity: sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==} + + '@ethersproject/signing-key@5.8.0': + resolution: {integrity: sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==} + + '@ethersproject/solidity@5.8.0': + resolution: {integrity: sha512-4CxFeCgmIWamOHwYN9d+QWGxye9qQLilpgTU0XhYs1OahkclF+ewO+3V1U0mvpiuQxm5EHHmv8f7ClVII8EHsA==} + + '@ethersproject/strings@5.8.0': + resolution: {integrity: sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==} + + '@ethersproject/transactions@5.8.0': + resolution: {integrity: sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==} + + '@ethersproject/units@5.8.0': + resolution: {integrity: sha512-lxq0CAnc5kMGIiWW4Mr041VT8IhNM+Pn5T3haO74XZWFulk7wH1Gv64HqE96hT4a7iiNMdOCFEBgaxWuk8ETKQ==} + + '@ethersproject/wallet@5.8.0': + resolution: {integrity: sha512-G+jnzmgg6UxurVKRKvw27h0kvG75YKXZKdlLYmAHeF32TGUzHkOFd7Zn6QHOTYRFWnfjtSSFjBowKo7vfrXzPA==} + + '@ethersproject/web@5.8.0': + resolution: {integrity: sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==} + + '@ethersproject/wordlists@5.8.0': + resolution: {integrity: sha512-2df9bbXicZws2Sb5S6ET493uJ0Z84Fjr3pC4tu/qlnZERibZCeUVuqdtt+7Tv9xxhUxHoIekIA7avrKUWHrezg==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.6': + resolution: {integrity: sha512-GIKz/j99FRthB8icyJQA51E8Uk5hXmdyThjgQXRKiv9h0zeRlzSCLIzFw6K1LotZ3XuB7yzlf76qk7uBmTdFqA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@peculiar/asn1-schema@2.3.15': + resolution: {integrity: sha512-QPeD8UA8axQREpgR5UTAfu2mqQmm97oUqahDtNdBcfj3qAnoXzFdQW+aNf/tD2WVXF8Fhmftxoj0eMIT++gX2w==} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@polkadot-api/json-rpc-provider-proxy@0.1.0': + resolution: {integrity: sha512-8GSFE5+EF73MCuLQm8tjrbCqlgclcHBSRaswvXziJ0ZW7iw3UEMsKkkKvELayWyBuOPa2T5i1nj6gFOeIsqvrg==} + + '@polkadot-api/json-rpc-provider@0.0.1': + resolution: {integrity: sha512-/SMC/l7foRjpykLTUTacIH05H3mr9ip8b5xxfwXlVezXrNVLp3Cv0GX6uItkKd+ZjzVPf3PFrDF2B2/HLSNESA==} + + '@polkadot-api/metadata-builders@0.3.2': + resolution: {integrity: sha512-TKpfoT6vTb+513KDzMBTfCb/ORdgRnsS3TDFpOhAhZ08ikvK+hjHMt5plPiAX/OWkm1Wc9I3+K6W0hX5Ab7MVg==} + + '@polkadot-api/observable-client@0.3.2': + resolution: {integrity: sha512-HGgqWgEutVyOBXoGOPp4+IAq6CNdK/3MfQJmhCJb8YaJiaK4W6aRGrdQuQSTPHfERHCARt9BrOmEvTXAT257Ug==} + peerDependencies: + '@polkadot-api/substrate-client': 0.1.4 + rxjs: '>=7.8.0' + + '@polkadot-api/substrate-bindings@0.6.0': + resolution: {integrity: sha512-lGuhE74NA1/PqdN7fKFdE5C1gNYX357j1tWzdlPXI0kQ7h3kN0zfxNOpPUN7dIrPcOFZ6C0tRRVrBylXkI6xPw==} + + '@polkadot-api/substrate-client@0.1.4': + resolution: {integrity: sha512-MljrPobN0ZWTpn++da9vOvt+Ex+NlqTlr/XT7zi9sqPtDJiQcYl+d29hFAgpaeTqbeQKZwz3WDE9xcEfLE8c5A==} + + '@polkadot-api/utils@0.1.0': + resolution: {integrity: sha512-MXzWZeuGxKizPx2Xf/47wx9sr/uxKw39bVJUptTJdsaQn/TGq+z310mHzf1RCGvC1diHM8f593KrnDgc9oNbJA==} + + '@polkadot/api-augment@16.4.7': + resolution: {integrity: sha512-euQOOSxpozB2VEWf4H8RuEyjkMrL7ARcdYG95tkoBUbHDACublPmGcR/v5fYkfEEap8gWcXaMfXvdGFaKw7DQQ==} + engines: {node: '>=18'} + + '@polkadot/api-base@16.4.7': + resolution: {integrity: sha512-YTvPY9gu25HfnIURFmnejXGoqyEQkdGk7i9SG4a5wUxf6McKssNpUYZcyfhD13xjN8Tu3VBO19eSFY2xa7R13A==} + engines: {node: '>=18'} + + '@polkadot/api-derive@16.4.7': + resolution: {integrity: sha512-B5iephoFa7Hy+cCI4QxKgm9zYLQ93wMqKnd388DHuEsvCQ9exShtM3HdzTZUZAGl7GxWvustGOkConL4Ys0LKw==} + engines: {node: '>=18'} + + '@polkadot/api@16.4.7': + resolution: {integrity: sha512-aQypyQOmCUFmxmQ46jqLJYcptQ6xvceVrHuoUac4hFavejBjsGl2yM1uZo1ixpOTCCaK1/Dve8soF03YVedKLg==} + engines: {node: '>=18'} + + '@polkadot/keyring@13.5.6': + resolution: {integrity: sha512-Ybe6Mflrh96FKR5tfEaf/93RxJD7x9UigseNOJW6Yd8LF+GesdxrqmZD7zh+53Hb7smGQWf/0FCfwhoWZVgPUQ==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': ^13.5.6 + '@polkadot/util-crypto': ^13.5.6 + + '@polkadot/networks@13.5.6': + resolution: {integrity: sha512-9HqUIBOHnz9x/ssPb0aOD/7XcU8vGokEYpLoNgexFNIJzqDgrDHXR197iFpkbMqA/+98zagrvYUyPYj1yYs9Jw==} + engines: {node: '>=18'} + + '@polkadot/rpc-augment@16.4.7': + resolution: {integrity: sha512-CWrvtaYIOEB7Em8zGHuEq921WwVanWZomWudW1Sea3mHDuOvM46C6j5yQV8S9udLghqSNZjIemPyRPfyP/VgrA==} + engines: {node: '>=18'} + + '@polkadot/rpc-core@16.4.7': + resolution: {integrity: sha512-bm7WsbhHjrmKziRPQ7/2ua6BDl5f+7DCBqdMBbIMaOQtRtzA/hU2NkEnR71GsJ5A7awJBTNjnfaufvty9E4fnA==} + engines: {node: '>=18'} + + '@polkadot/rpc-provider@16.4.7': + resolution: {integrity: sha512-AW2eA+5/kJbCYPYcPZTmFyP4oedjcI+Qwu3mMtA42+rxVr67H8Rxm+rbooWd4MzwZB3LrKUo9fh40nKlQsc31w==} + engines: {node: '>=18'} + + '@polkadot/types-augment@16.4.7': + resolution: {integrity: sha512-MIuzMdrshbNtCJUR4QhVZUulAmcyXVkSo+6N9yMdMdhprKdfMt5WOlEt0iVEex39oDp2mlIqI8txMyYEK/GJcA==} + engines: {node: '>=18'} + + '@polkadot/types-codec@16.4.7': + resolution: {integrity: sha512-IA/KLpebFDcT/uwkXlt08BkpRdDeo29xLRt9+dTtNZjd5L+gJzph+W6VV/L/mOzRDhWUwz2C1a2VZJdqZQeWmQ==} + engines: {node: '>=18'} + + '@polkadot/types-create@16.4.7': + resolution: {integrity: sha512-KTqMikEr/Lef8J8ftrRQIz68xoG53I3mBbDMFk3QKURIQnbxSPo39tlJ7KFYdiJduyTO9E2wI3sYfbZic9jXxw==} + engines: {node: '>=18'} + + '@polkadot/types-known@16.4.7': + resolution: {integrity: sha512-L5n6Lc/J96p0sFh6TsiTMO1kKIdQQVYtafvqo4MQuoGCKzdpkeDiq9wujJYyegeeiVXqmUdezDyYGdNlbjbwUg==} + engines: {node: '>=18'} + + '@polkadot/types-support@16.4.7': + resolution: {integrity: sha512-/378JPqrIuMmw/ae845p295++w5//e8/4foRzms1Q5bK0RpsLqPFuh/b24iPEdzIpdRqSvdSJg9rJPGBeESfkw==} + engines: {node: '>=18'} + + '@polkadot/types@16.4.7': + resolution: {integrity: sha512-Z6EPaUuulGI1ohd3c9gCVhc4UeVE0/uNAUjlo0M5FTo+FDrLWLBL3fITuTHtKlLUwq+btwAT92cZUPderXaJjQ==} + engines: {node: '>=18'} + + '@polkadot/util-crypto@13.5.6': + resolution: {integrity: sha512-1l+t5lVc9UWxvbJe7/3V+QK8CwrDPuQjDK6FKtDZgZCU0JRrjySOxV0J4PeDIv8TgXZtbIcQFVUhIsJTyKZZJQ==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': ^13.5.6 + + '@polkadot/util@13.5.6': + resolution: {integrity: sha512-V+CkW2VdhcMWvl7eXdmlCLGqLxrKvXZtXE76KBbPP5n0Z+8DqQ58IHNOE9xe2LOgqDwIzdLlOUwkyF9Zj19y+Q==} + engines: {node: '>=18'} + + '@polkadot/wasm-bridge@7.5.1': + resolution: {integrity: sha512-E+N3CSnX3YaXpAmfIQ+4bTyiAqJQKvVcMaXjkuL8Tp2zYffClWLG5e+RY15Uh+EWfUl9If4y6cLZi3D5NcpAGQ==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': ^13.5.6 + '@polkadot/x-randomvalues': ^13.5.6 + + '@polkadot/wasm-crypto-asmjs@7.5.1': + resolution: {integrity: sha512-jAg7Uusk+xeHQ+QHEH4c/N3b1kEGBqZb51cWe+yM61kKpQwVGZhNdlWetW6U23t/BMyZArIWMsZqmK/Ij0PHog==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': ^13.5.6 + + '@polkadot/wasm-crypto-init@7.5.1': + resolution: {integrity: sha512-Obu4ZEo5jYO6sN31eqCNOXo88rPVkP9TrUOyynuFCnXnXr8V/HlmY/YkAd9F87chZnkTJRlzak17kIWr+i7w3A==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': ^13.5.6 + '@polkadot/x-randomvalues': ^13.5.6 + + '@polkadot/wasm-crypto-wasm@7.5.1': + resolution: {integrity: sha512-S2yQSGbOGTcaV6UdipFVyEGanJvG6uD6Tg7XubxpiGbNAblsyYKeFcxyH1qCosk/4qf+GIUwlOL4ydhosZflqg==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': ^13.5.6 + + '@polkadot/wasm-crypto@7.5.1': + resolution: {integrity: sha512-acjt4VJ3w19v7b/SIPsV/5k9s6JsragHKPnwoZ0KTfBvAFXwzz80jUzVGxA06SKHacfCUe7vBRlz7M5oRby1Pw==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': ^13.5.6 + '@polkadot/x-randomvalues': ^13.5.6 + + '@polkadot/wasm-util@7.5.1': + resolution: {integrity: sha512-sbvu71isFhPXpvMVX+EkRnUg/+54Tx7Sf9BEMqxxoPj7cG1I/MKeDEwbQz6MaU4gm7xJqvEWCAemLFcXfHQ/2A==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': ^13.5.6 + + '@polkadot/x-bigint@13.5.6': + resolution: {integrity: sha512-HpqZJ9ud94iK/+0Ofacw7QdtvzFp6SucBBml4XwWZTWoLaLOGDsO7FoWE7yCuwPbX8nLgIM6YmQBeUoZmBtVqQ==} + engines: {node: '>=18'} + + '@polkadot/x-fetch@13.5.6': + resolution: {integrity: sha512-gqx8c6lhnD7Qht+56J+4oeTA8YZ9bAPqzOt2cRJf9MTplMy44W6671T2p6hA3QMvzy4aBTxMie3uKc4tGpLu4A==} + engines: {node: '>=18'} + + '@polkadot/x-global@13.5.6': + resolution: {integrity: sha512-iw97n0Bnl2284WgAK732LYR4DW6w5+COfBfHzkhiHqs5xwPEwWMgWGrf2hM8WAQqNIz6Ni8w/jagucPyQBur3Q==} + engines: {node: '>=18'} + + '@polkadot/x-randomvalues@13.5.6': + resolution: {integrity: sha512-w1F9G7FxrJ7+hGC8bh9/VpPH4KN8xmyzgiQdR7+rVB2V8KsKQBQidG69pj5Kwsh3oODOz0yQYsTG6Rm6TAJbGA==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': ^13.5.6 + '@polkadot/wasm-util': '*' + + '@polkadot/x-textdecoder@13.5.6': + resolution: {integrity: sha512-jTGeYCxFh89KRrP7bNj1CPqKO36Onsi0iA6A+5YtRS5wjdQU+/OFM/EHLTP2nvkvZo/tOkOewMR9sausisUvVQ==} + engines: {node: '>=18'} + + '@polkadot/x-textencoder@13.5.6': + resolution: {integrity: sha512-iVwz9+OrYCEF9QbNfr9M206mmWvY/AhDmGPfAIeTR4fRgKGVYqcP8RIF8iu/x0MVQWqiVO3vlhlUk7MfrmAnoQ==} + engines: {node: '>=18'} + + '@polkadot/x-ws@13.5.6': + resolution: {integrity: sha512-247ktVp/iE57NTXjFpHaoPoDcvoEPb8+16r2Eq0IBQ2umOV7P6KmxvdNx5eFUvRsgXvBpNwUXE1WVnXjK/eDtA==} + engines: {node: '>=18'} + + '@rollup/rollup-android-arm-eabi@4.39.0': + resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.39.0': + resolution: {integrity: sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.39.0': + resolution: {integrity: sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.39.0': + resolution: {integrity: sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.39.0': + resolution: {integrity: sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.39.0': + resolution: {integrity: sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.39.0': + resolution: {integrity: sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.39.0': + resolution: {integrity: sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.39.0': + resolution: {integrity: sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.39.0': + resolution: {integrity: sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.39.0': + resolution: {integrity: sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': + resolution: {integrity: sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.39.0': + resolution: {integrity: sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.39.0': + resolution: {integrity: sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.39.0': + resolution: {integrity: sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.39.0': + resolution: {integrity: sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.39.0': + resolution: {integrity: sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.39.0': + resolution: {integrity: sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.39.0': + resolution: {integrity: sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.39.0': + resolution: {integrity: sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==} + cpu: [x64] + os: [win32] + + '@safe-global/api-kit@3.0.1': + resolution: {integrity: sha512-ks7vFMU3l/xl1TWKL2c+a8l5aQRCtOtSMMpxfJIMsJvtvPSTAUx/WDFKqtVlMhVP/QrqaL7YiTw8hM2vhkTdDQ==} + + '@safe-global/protocol-kit@6.0.4': + resolution: {integrity: sha512-zwUk7qqtdcjgj+PoDziFXU/rIdAJ1sbwSJBJ48EwsRQIUwT0QdNje3xvvAm22gCOVTvOBTwOwECO5koLEJPqSw==} + + '@safe-global/safe-deployments@1.37.32': + resolution: {integrity: sha512-3XRy6TnVz0uymPxMNo7WkaK88sL12ZpIMKOfrNHkODUZCxCO4GFA0FFfjByAPS1LAXfmV7Mulk9Zx1n9vqR8Cg==} + + '@safe-global/safe-modules-deployments@2.2.8': + resolution: {integrity: sha512-XqRhEUzO8PNs5kCXztlPmQJBZO+YTDCRbiumCr5JBuS8RhU0pRSkG5Gs8qjKlZicxZvy3IdXZ14APVwb6+dj/Q==} + + '@safe-global/types-kit@2.0.1': + resolution: {integrity: sha512-4xKjTBlyFSIKziqvjrGMBAgs7Z2+s/5A2wjAXg2gBA1BuvV6w1THk1Y/WMZg8+6/PlRaVMVo4LoSNMRSsZZhjw==} + + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + + '@substrate/connect-extension-protocol@2.2.2': + resolution: {integrity: sha512-t66jwrXA0s5Goq82ZtjagLNd7DPGCNjHeehRlE/gcJmJ+G56C0W+2plqOMRicJ8XGR1/YFnUSEqUFiSNbjGrAA==} + + '@substrate/connect-known-chains@1.10.0': + resolution: {integrity: sha512-k0GwwxJE1twaob6qMOBalENDfOEnMt/zdAuUjbrqhjBD6EL1SAWVuTu+bpwXrznd/ims6NSN4TLp9aTf1yE5tg==} + + '@substrate/connect@0.8.11': + resolution: {integrity: sha512-ofLs1PAO9AtDdPbdyTYj217Pe+lBfTLltdHDs3ds8no0BseoLeAGxpz1mHfi7zB4IxI3YyAiLjH6U8cw4pj4Nw==} + deprecated: versions below 1.x are no longer maintained + + '@substrate/light-client-extension-helpers@1.0.0': + resolution: {integrity: sha512-TdKlni1mBBZptOaeVrKnusMg/UBpWUORNDv5fdCaJklP4RJiFOzBCrzC+CyVI5kQzsXBisZ+2pXm+rIjS38kHg==} + peerDependencies: + smoldot: 2.x + + '@substrate/ss58-registry@1.51.0': + resolution: {integrity: sha512-TWDurLiPxndFgKjVavCniytBIw+t4ViOi7TYp9h/D0NMmkEc9klFTo+827eyEJ0lELpqO207Ey7uGxUa+BS1jQ==} + + '@types/bn.js@5.1.6': + resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/node@22.14.0': + resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==} + + '@vitest/coverage-v8@3.1.1': + resolution: {integrity: sha512-MgV6D2dhpD6Hp/uroUoAIvFqA8AuvXEFBC2eepG3WFc1pxTfdk1LEqqkWoWhjz+rytoqrnUUCdf6Lzco3iHkLQ==} + peerDependencies: + '@vitest/browser': 3.1.1 + vitest: 3.1.1 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@3.1.1': + resolution: {integrity: sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==} + + '@vitest/mocker@3.1.1': + resolution: {integrity: sha512-bmpJJm7Y7i9BBELlLuuM1J1Q6EQ6K5Ye4wcyOpOMXMcePYKSIYlpcrCm4l/O6ja4VJA5G2aMJiuZkZdnxlC3SA==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@3.1.1': + resolution: {integrity: sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==} + + '@vitest/runner@3.1.1': + resolution: {integrity: sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==} + + '@vitest/snapshot@3.1.1': + resolution: {integrity: sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==} + + '@vitest/spy@3.1.1': + resolution: {integrity: sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==} + + '@vitest/utils@3.1.1': + resolution: {integrity: sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==} + + abitype@1.0.8: + resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==} + peerDependencies: + typescript: ^5.5.4 + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + aes-js@3.0.0: + resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + asn1js@3.0.6: + resolution: {integrity: sha512-UOCGPYbl0tv8+006qks/dTgV9ajs97X2p0FAbyS2iyCRrmLSRolDaHdp+v/CLgnzHc3fVB+CwYiUmei7ndFcgA==} + engines: {node: '>=12.0.0'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + async-mutex@0.5.0: + resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} + + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bech32@1.1.4: + resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bn.js@4.12.1: + resolution: {integrity: sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==} + + bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + + brace-expansion@1.1.12: + resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} + + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + dateformat@4.6.3: + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + dotenv@16.5.0: + resolution: {integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==} + engines: {node: '>=12'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + elliptic@6.6.1: + resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + es-module-lexer@1.6.0: + resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} + + esbuild@0.25.2: + resolution: {integrity: sha512-16854zccKPnC+toMywC+uKNeYSv+/eXkevRAfwRD/G9Cleq66m8XFIrigkbvauLLlCfDL45Q2cWegSg53gGBnQ==} + engines: {node: '>=18'} + hasBin: true + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + ethers@5.8.0: + resolution: {integrity: sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + expect-type@1.2.1: + resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} + engines: {node: '>=12.0.0'} + + fast-copy@3.0.2: + resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==} + + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fdir@6.4.3: + resolution: {integrity: sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + + help-me@5.0.0: + resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} + + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isows@1.0.7: + resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} + peerDependencies: + ws: '*' + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + + js-sha3@0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + + loupe@3.1.3: + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mock-socket@9.3.1: + resolution: {integrity: sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==} + engines: {node: '>= 8'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nock@13.5.6: + resolution: {integrity: sha512-o2zOYiCpzRqSzPj0Zt/dQ/DqZeYoaQ7TUonc/xUPjCGl9WeHpNbxgVvOquXYAaJzI0M9BXV3HTzG0p8IUAbBTQ==} + engines: {node: '>= 10.13'} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + nodemon@3.1.10: + resolution: {integrity: sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==} + engines: {node: '>=10'} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + ox@0.8.7: + resolution: {integrity: sha512-W1f0FiMf9NZqtHPEDEAEkyzZDwbIKfmH2qmQx8NNiQ/9JhxrSblmtLJsSfTtQG5YKowLOnBlLVguCyxm/7ztxw==} + peerDependencies: + typescript: ^5.5.4 + peerDependenciesMeta: + typescript: + optional: true + + p-queue@8.1.0: + resolution: {integrity: sha512-mxLDbbGIBEXTJL0zEx8JIylaj3xQ7Z/7eEVjcF9fJX4DBiH9oqe+oahYnlKKxm0Ci9TlWTyhSHgygxMxjIB2jw==} + engines: {node: '>=18'} + + p-timeout@6.1.4: + resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} + engines: {node: '>=14.16'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + + pino-pretty@11.3.0: + resolution: {integrity: sha512-oXwn7ICywaZPHmu3epHGU2oJX4nPmKvHvB/bwrJHlGcbEWaVcotkpyVHMKLKmiVryWYByNp0jpgAcXpFJDXJzA==} + hasBin: true + + pino-std-serializers@7.0.0: + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} + + pino@9.9.5: + resolution: {integrity: sha512-d1s98p8/4TfYhsJ09r/Azt30aYELRi6NNnZtEbqFw6BoGsdPVf5lKNK3kUwH8BmJJfpTLNuicjUQjaMbd93dVg==} + hasBin: true + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + process-warning@5.0.0: + resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + propagate@2.0.1: + resolution: {integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==} + engines: {node: '>= 8'} + + pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + + pump@3.0.3: + resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pvtsutils@1.3.6: + resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + + pvutils@1.1.3: + resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} + engines: {node: '>=6.0.0'} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + readable-stream@4.7.0: + resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + rollup@4.39.0: + resolution: {integrity: sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + scale-ts@1.6.1: + resolution: {integrity: sha512-PBMc2AWc6wSEqJYBDPcyCLUj9/tMKnLX70jLOSndMtcUoLQucP/DM0vnQo1wJAYjTrQiq8iG9rD0q6wFzgjH7g==} + + scrypt-js@3.0.1: + resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} + + secure-json-parse@2.7.0: + resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + + smoldot@2.0.26: + resolution: {integrity: sha512-F+qYmH4z2s2FK+CxGj8moYcd1ekSIKH8ywkdqlOz88Dat35iB1DIYL11aILN46YSGMzQW/lbJNS307zBSDN5Ig==} + + sonic-boom@4.2.0: + resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + deprecated: The work that was done in this beta branch won't be included in future versions + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.12: + resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} + engines: {node: '>=12.0.0'} + + tinypool@1.0.2: + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + + touch@3.1.1: + resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} + hasBin: true + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + tsconfck@3.1.5: + resolution: {integrity: sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.5.4 + peerDependenciesMeta: + typescript: + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsup@8.4.0: + resolution: {integrity: sha512-b+eZbPCjz10fRryaAA7C8xlIHnf8VnsaRqydheLIqwG/Mcpfk8Z5zp3HayX7GaTygkigHl5cBUs+IhcySiIexQ==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: ^5.5.4 + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + + tsx@4.20.5: + resolution: {integrity: sha512-+wKjMNU9w/EaQayHXb7WA7ZaHY6hN8WgfvHNQ3t1PnU91/7O8TcTnIhCDYTZwnt8JsO9IBqZ30Ln1r7pPF52Aw==} + engines: {node: '>=18.0.0'} + hasBin: true + + typescript@5.8.3: + resolution: {integrity: sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==} + engines: {node: '>=14.17'} + hasBin: true + + undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + viem@2.34.0: + resolution: {integrity: sha512-HJZG9Wt0DLX042MG0PK17tpataxtdAEhpta9/Q44FqKwy3xZMI5Lx4jF+zZPuXFuYjZ68R0PXqRwlswHs6r4gA==} + peerDependencies: + typescript: ^5.5.4 + peerDependenciesMeta: + typescript: + optional: true + + vite-node@3.1.1: + resolution: {integrity: sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite-tsconfig-paths@5.1.4: + resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + + vite@6.2.5: + resolution: {integrity: sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@3.1.1: + resolution: {integrity: sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.1.1 + '@vitest/ui': 3.1.1 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + 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 + + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + 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 + +snapshots: + + '@adraffy/ens-normalize@1.11.0': {} + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/parser@7.27.0': + dependencies: + '@babel/types': 7.27.0 + + '@babel/types@7.27.0': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@bcoe/v8-coverage@1.0.2': {} + + '@biomejs/biome@1.9.4': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.9.4 + '@biomejs/cli-darwin-x64': 1.9.4 + '@biomejs/cli-linux-arm64': 1.9.4 + '@biomejs/cli-linux-arm64-musl': 1.9.4 + '@biomejs/cli-linux-x64': 1.9.4 + '@biomejs/cli-linux-x64-musl': 1.9.4 + '@biomejs/cli-win32-arm64': 1.9.4 + '@biomejs/cli-win32-x64': 1.9.4 + + '@biomejs/cli-darwin-arm64@1.9.4': + optional: true + + '@biomejs/cli-darwin-x64@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64@1.9.4': + optional: true + + '@biomejs/cli-linux-x64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-x64@1.9.4': + optional: true + + '@biomejs/cli-win32-arm64@1.9.4': + optional: true + + '@biomejs/cli-win32-x64@1.9.4': + optional: true + + '@esbuild/aix-ppc64@0.25.2': + optional: true + + '@esbuild/android-arm64@0.25.2': + optional: true + + '@esbuild/android-arm@0.25.2': + optional: true + + '@esbuild/android-x64@0.25.2': + optional: true + + '@esbuild/darwin-arm64@0.25.2': + optional: true + + '@esbuild/darwin-x64@0.25.2': + optional: true + + '@esbuild/freebsd-arm64@0.25.2': + optional: true + + '@esbuild/freebsd-x64@0.25.2': + optional: true + + '@esbuild/linux-arm64@0.25.2': + optional: true + + '@esbuild/linux-arm@0.25.2': + optional: true + + '@esbuild/linux-ia32@0.25.2': + optional: true + + '@esbuild/linux-loong64@0.25.2': + optional: true + + '@esbuild/linux-mips64el@0.25.2': + optional: true + + '@esbuild/linux-ppc64@0.25.2': + optional: true + + '@esbuild/linux-riscv64@0.25.2': + optional: true + + '@esbuild/linux-s390x@0.25.2': + optional: true + + '@esbuild/linux-x64@0.25.2': + optional: true + + '@esbuild/netbsd-arm64@0.25.2': + optional: true + + '@esbuild/netbsd-x64@0.25.2': + optional: true + + '@esbuild/openbsd-arm64@0.25.2': + optional: true + + '@esbuild/openbsd-x64@0.25.2': + optional: true + + '@esbuild/sunos-x64@0.25.2': + optional: true + + '@esbuild/win32-arm64@0.25.2': + optional: true + + '@esbuild/win32-ia32@0.25.2': + optional: true + + '@esbuild/win32-x64@0.25.2': + optional: true + + '@ethersproject/abi@5.8.0': + dependencies: + '@ethersproject/address': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/hash': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/strings': 5.8.0 + + '@ethersproject/abstract-provider@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/networks': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/transactions': 5.8.0 + '@ethersproject/web': 5.8.0 + + '@ethersproject/abstract-signer@5.8.0': + dependencies: + '@ethersproject/abstract-provider': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + + '@ethersproject/address@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/rlp': 5.8.0 + + '@ethersproject/base64@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + + '@ethersproject/basex@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/properties': 5.8.0 + + '@ethersproject/bignumber@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + bn.js: 5.2.1 + + '@ethersproject/bytes@5.8.0': + dependencies: + '@ethersproject/logger': 5.8.0 + + '@ethersproject/constants@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + + '@ethersproject/contracts@5.8.0': + 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 + + '@ethersproject/hash@5.8.0': + dependencies: + '@ethersproject/abstract-signer': 5.8.0 + '@ethersproject/address': 5.8.0 + '@ethersproject/base64': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/strings': 5.8.0 + + '@ethersproject/hdnode@5.8.0': + 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 + + '@ethersproject/json-wallets@5.8.0': + 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 + + '@ethersproject/keccak256@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + js-sha3: 0.8.0 + + '@ethersproject/logger@5.8.0': {} + + '@ethersproject/networks@5.8.0': + dependencies: + '@ethersproject/logger': 5.8.0 + + '@ethersproject/pbkdf2@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/sha2': 5.8.0 + + '@ethersproject/properties@5.8.0': + dependencies: + '@ethersproject/logger': 5.8.0 + + '@ethersproject/providers@5.8.0': + 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 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@ethersproject/random@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@ethersproject/rlp@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@ethersproject/sha2@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + hash.js: 1.1.7 + + '@ethersproject/signing-key@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + bn.js: 5.2.1 + elliptic: 6.6.1 + hash.js: 1.1.7 + + '@ethersproject/solidity@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/sha2': 5.8.0 + '@ethersproject/strings': 5.8.0 + + '@ethersproject/strings@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@ethersproject/transactions@5.8.0': + dependencies: + '@ethersproject/address': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/rlp': 5.8.0 + '@ethersproject/signing-key': 5.8.0 + + '@ethersproject/units@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@ethersproject/wallet@5.8.0': + 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 + + '@ethersproject/web@5.8.0': + dependencies: + '@ethersproject/base64': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/strings': 5.8.0 + + '@ethersproject/wordlists@5.8.0': + 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 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.9.6': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.8.0': {} + + '@peculiar/asn1-schema@2.3.15': + dependencies: + asn1js: 3.0.6 + pvtsutils: 1.3.6 + tslib: 2.8.1 + optional: true + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@polkadot-api/json-rpc-provider-proxy@0.1.0': + optional: true + + '@polkadot-api/json-rpc-provider@0.0.1': + optional: true + + '@polkadot-api/metadata-builders@0.3.2': + dependencies: + '@polkadot-api/substrate-bindings': 0.6.0 + '@polkadot-api/utils': 0.1.0 + optional: true + + '@polkadot-api/observable-client@0.3.2(@polkadot-api/substrate-client@0.1.4)(rxjs@7.8.2)': + dependencies: + '@polkadot-api/metadata-builders': 0.3.2 + '@polkadot-api/substrate-bindings': 0.6.0 + '@polkadot-api/substrate-client': 0.1.4 + '@polkadot-api/utils': 0.1.0 + rxjs: 7.8.2 + optional: true + + '@polkadot-api/substrate-bindings@0.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@polkadot-api/utils': 0.1.0 + '@scure/base': 1.2.6 + scale-ts: 1.6.1 + optional: true + + '@polkadot-api/substrate-client@0.1.4': + dependencies: + '@polkadot-api/json-rpc-provider': 0.0.1 + '@polkadot-api/utils': 0.1.0 + optional: true + + '@polkadot-api/utils@0.1.0': + optional: true + + '@polkadot/api-augment@16.4.7': + dependencies: + '@polkadot/api-base': 16.4.7 + '@polkadot/rpc-augment': 16.4.7 + '@polkadot/types': 16.4.7 + '@polkadot/types-augment': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/api-base@16.4.7': + dependencies: + '@polkadot/rpc-core': 16.4.7 + '@polkadot/types': 16.4.7 + '@polkadot/util': 13.5.6 + rxjs: 7.8.2 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/api-derive@16.4.7': + dependencies: + '@polkadot/api': 16.4.7 + '@polkadot/api-augment': 16.4.7 + '@polkadot/api-base': 16.4.7 + '@polkadot/rpc-core': 16.4.7 + '@polkadot/types': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/util': 13.5.6 + '@polkadot/util-crypto': 13.5.6(@polkadot/util@13.5.6) + rxjs: 7.8.2 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/api@16.4.7': + dependencies: + '@polkadot/api-augment': 16.4.7 + '@polkadot/api-base': 16.4.7 + '@polkadot/api-derive': 16.4.7 + '@polkadot/keyring': 13.5.6(@polkadot/util-crypto@13.5.6(@polkadot/util@13.5.6))(@polkadot/util@13.5.6) + '@polkadot/rpc-augment': 16.4.7 + '@polkadot/rpc-core': 16.4.7 + '@polkadot/rpc-provider': 16.4.7 + '@polkadot/types': 16.4.7 + '@polkadot/types-augment': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/types-create': 16.4.7 + '@polkadot/types-known': 16.4.7 + '@polkadot/util': 13.5.6 + '@polkadot/util-crypto': 13.5.6(@polkadot/util@13.5.6) + eventemitter3: 5.0.1 + rxjs: 7.8.2 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/keyring@13.5.6(@polkadot/util-crypto@13.5.6(@polkadot/util@13.5.6))(@polkadot/util@13.5.6)': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/util-crypto': 13.5.6(@polkadot/util@13.5.6) + tslib: 2.8.1 + + '@polkadot/networks@13.5.6': + dependencies: + '@polkadot/util': 13.5.6 + '@substrate/ss58-registry': 1.51.0 + tslib: 2.8.1 + + '@polkadot/rpc-augment@16.4.7': + dependencies: + '@polkadot/rpc-core': 16.4.7 + '@polkadot/types': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/rpc-core@16.4.7': + dependencies: + '@polkadot/rpc-augment': 16.4.7 + '@polkadot/rpc-provider': 16.4.7 + '@polkadot/types': 16.4.7 + '@polkadot/util': 13.5.6 + rxjs: 7.8.2 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/rpc-provider@16.4.7': + dependencies: + '@polkadot/keyring': 13.5.6(@polkadot/util-crypto@13.5.6(@polkadot/util@13.5.6))(@polkadot/util@13.5.6) + '@polkadot/types': 16.4.7 + '@polkadot/types-support': 16.4.7 + '@polkadot/util': 13.5.6 + '@polkadot/util-crypto': 13.5.6(@polkadot/util@13.5.6) + '@polkadot/x-fetch': 13.5.6 + '@polkadot/x-global': 13.5.6 + '@polkadot/x-ws': 13.5.6 + eventemitter3: 5.0.1 + mock-socket: 9.3.1 + nock: 13.5.6 + tslib: 2.8.1 + optionalDependencies: + '@substrate/connect': 0.8.11 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/types-augment@16.4.7': + dependencies: + '@polkadot/types': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + + '@polkadot/types-codec@16.4.7': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/x-bigint': 13.5.6 + tslib: 2.8.1 + + '@polkadot/types-create@16.4.7': + dependencies: + '@polkadot/types-codec': 16.4.7 + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + + '@polkadot/types-known@16.4.7': + dependencies: + '@polkadot/networks': 13.5.6 + '@polkadot/types': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/types-create': 16.4.7 + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + + '@polkadot/types-support@16.4.7': + dependencies: + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + + '@polkadot/types@16.4.7': + dependencies: + '@polkadot/keyring': 13.5.6(@polkadot/util-crypto@13.5.6(@polkadot/util@13.5.6))(@polkadot/util@13.5.6) + '@polkadot/types-augment': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/types-create': 16.4.7 + '@polkadot/util': 13.5.6 + '@polkadot/util-crypto': 13.5.6(@polkadot/util@13.5.6) + rxjs: 7.8.2 + tslib: 2.8.1 + + '@polkadot/util-crypto@13.5.6(@polkadot/util@13.5.6)': + dependencies: + '@noble/curves': 1.9.6 + '@noble/hashes': 1.8.0 + '@polkadot/networks': 13.5.6 + '@polkadot/util': 13.5.6 + '@polkadot/wasm-crypto': 7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6))) + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/x-bigint': 13.5.6 + '@polkadot/x-randomvalues': 13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)) + '@scure/base': 1.2.6 + tslib: 2.8.1 + + '@polkadot/util@13.5.6': + dependencies: + '@polkadot/x-bigint': 13.5.6 + '@polkadot/x-global': 13.5.6 + '@polkadot/x-textdecoder': 13.5.6 + '@polkadot/x-textencoder': 13.5.6 + '@types/bn.js': 5.1.6 + bn.js: 5.2.1 + tslib: 2.8.1 + + '@polkadot/wasm-bridge@7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)))': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/x-randomvalues': 13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)) + tslib: 2.8.1 + + '@polkadot/wasm-crypto-asmjs@7.5.1(@polkadot/util@13.5.6)': + dependencies: + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + + '@polkadot/wasm-crypto-init@7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)))': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/wasm-bridge': 7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6))) + '@polkadot/wasm-crypto-asmjs': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/wasm-crypto-wasm': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/x-randomvalues': 13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)) + tslib: 2.8.1 + + '@polkadot/wasm-crypto-wasm@7.5.1(@polkadot/util@13.5.6)': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.6) + tslib: 2.8.1 + + '@polkadot/wasm-crypto@7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)))': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/wasm-bridge': 7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6))) + '@polkadot/wasm-crypto-asmjs': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/wasm-crypto-init': 7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6))) + '@polkadot/wasm-crypto-wasm': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/x-randomvalues': 13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)) + tslib: 2.8.1 + + '@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)': + dependencies: + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + + '@polkadot/x-bigint@13.5.6': + dependencies: + '@polkadot/x-global': 13.5.6 + tslib: 2.8.1 + + '@polkadot/x-fetch@13.5.6': + dependencies: + '@polkadot/x-global': 13.5.6 + node-fetch: 3.3.2 + tslib: 2.8.1 + + '@polkadot/x-global@13.5.6': + dependencies: + tslib: 2.8.1 + + '@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6))': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/x-global': 13.5.6 + tslib: 2.8.1 + + '@polkadot/x-textdecoder@13.5.6': + dependencies: + '@polkadot/x-global': 13.5.6 + tslib: 2.8.1 + + '@polkadot/x-textencoder@13.5.6': + dependencies: + '@polkadot/x-global': 13.5.6 + tslib: 2.8.1 + + '@polkadot/x-ws@13.5.6': + dependencies: + '@polkadot/x-global': 13.5.6 + tslib: 2.8.1 + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@rollup/rollup-android-arm-eabi@4.39.0': + optional: true + + '@rollup/rollup-android-arm64@4.39.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.39.0': + optional: true + + '@rollup/rollup-darwin-x64@4.39.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.39.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.39.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.39.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.39.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.39.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.39.0': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.39.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.39.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.39.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.39.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.39.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.39.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.39.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.39.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.39.0': + optional: true + + '@safe-global/api-kit@3.0.1(typescript@5.8.3)': + dependencies: + '@safe-global/protocol-kit': 6.0.4(typescript@5.8.3) + '@safe-global/types-kit': 2.0.1(typescript@5.8.3) + node-fetch: 2.7.0 + viem: 2.34.0(typescript@5.8.3) + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + '@safe-global/protocol-kit@6.0.4(typescript@5.8.3)': + dependencies: + '@safe-global/safe-deployments': 1.37.32 + '@safe-global/safe-modules-deployments': 2.2.8 + '@safe-global/types-kit': 2.0.1(typescript@5.8.3) + abitype: 1.0.8(typescript@5.8.3) + semver: 7.7.1 + viem: 2.34.0(typescript@5.8.3) + optionalDependencies: + '@noble/curves': 1.9.6 + '@peculiar/asn1-schema': 2.3.15 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-deployments@1.37.32': + dependencies: + semver: 7.7.1 + + '@safe-global/safe-modules-deployments@2.2.8': {} + + '@safe-global/types-kit@2.0.1(typescript@5.8.3)': + dependencies: + abitype: 1.0.8(typescript@5.8.3) + transitivePeerDependencies: + - typescript + - zod + + '@scure/base@1.2.6': {} + + '@scure/bip32@1.7.0': + dependencies: + '@noble/curves': 1.9.6 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@scure/bip39@1.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@substrate/connect-extension-protocol@2.2.2': + optional: true + + '@substrate/connect-known-chains@1.10.0': + optional: true + + '@substrate/connect@0.8.11': + dependencies: + '@substrate/connect-extension-protocol': 2.2.2 + '@substrate/connect-known-chains': 1.10.0 + '@substrate/light-client-extension-helpers': 1.0.0(smoldot@2.0.26) + smoldot: 2.0.26 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + optional: true + + '@substrate/light-client-extension-helpers@1.0.0(smoldot@2.0.26)': + dependencies: + '@polkadot-api/json-rpc-provider': 0.0.1 + '@polkadot-api/json-rpc-provider-proxy': 0.1.0 + '@polkadot-api/observable-client': 0.3.2(@polkadot-api/substrate-client@0.1.4)(rxjs@7.8.2) + '@polkadot-api/substrate-client': 0.1.4 + '@substrate/connect-extension-protocol': 2.2.2 + '@substrate/connect-known-chains': 1.10.0 + rxjs: 7.8.2 + smoldot: 2.0.26 + optional: true + + '@substrate/ss58-registry@1.51.0': {} + + '@types/bn.js@5.1.6': + dependencies: + '@types/node': 22.14.0 + + '@types/estree@1.0.7': {} + + '@types/node@22.14.0': + dependencies: + undici-types: 6.21.0 + + '@vitest/coverage-v8@3.1.1(vitest@3.1.1(@types/node@22.14.0)(tsx@4.20.5))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 1.0.2 + debug: 4.4.0(supports-color@5.5.0) + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.17 + magicast: 0.3.5 + std-env: 3.9.0 + test-exclude: 7.0.1 + tinyrainbow: 2.0.0 + vitest: 3.1.1(@types/node@22.14.0)(tsx@4.20.5) + transitivePeerDependencies: + - supports-color + + '@vitest/expect@3.1.1': + dependencies: + '@vitest/spy': 3.1.1 + '@vitest/utils': 3.1.1 + chai: 5.2.0 + tinyrainbow: 2.0.0 + + '@vitest/mocker@3.1.1(vite@6.2.5(@types/node@22.14.0)(tsx@4.20.5))': + dependencies: + '@vitest/spy': 3.1.1 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 6.2.5(@types/node@22.14.0)(tsx@4.20.5) + + '@vitest/pretty-format@3.1.1': + dependencies: + tinyrainbow: 2.0.0 + + '@vitest/runner@3.1.1': + dependencies: + '@vitest/utils': 3.1.1 + pathe: 2.0.3 + + '@vitest/snapshot@3.1.1': + dependencies: + '@vitest/pretty-format': 3.1.1 + magic-string: 0.30.17 + pathe: 2.0.3 + + '@vitest/spy@3.1.1': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@3.1.1': + dependencies: + '@vitest/pretty-format': 3.1.1 + loupe: 3.1.3 + tinyrainbow: 2.0.0 + + abitype@1.0.8(typescript@5.8.3): + optionalDependencies: + typescript: 5.8.3 + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + aes-js@3.0.0: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + asn1js@3.0.6: + dependencies: + pvtsutils: 1.3.6 + pvutils: 1.1.3 + tslib: 2.8.1 + optional: true + + assertion-error@2.0.1: {} + + async-mutex@0.5.0: + dependencies: + tslib: 2.8.1 + + atomic-sleep@1.0.0: {} + + balanced-match@1.0.2: {} + + base64-js@1.5.1: {} + + bech32@1.1.4: {} + + binary-extensions@2.3.0: {} + + bn.js@4.12.1: {} + + bn.js@5.2.1: {} + + brace-expansion@1.1.12: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + brorand@1.1.0: {} + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bundle-require@5.1.0(esbuild@0.25.2): + dependencies: + esbuild: 0.25.2 + load-tsconfig: 0.2.5 + + cac@6.7.14: {} + + chai@5.2.0: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 + + check-error@2.1.1: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colorette@2.0.20: {} + + commander@12.1.0: {} + + commander@4.1.1: {} + + concat-map@0.0.1: {} + + consola@3.4.2: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + data-uri-to-buffer@4.0.1: {} + + dateformat@4.6.3: {} + + debug@4.4.0(supports-color@5.5.0): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 5.5.0 + + decimal.js@10.6.0: {} + + deep-eql@5.0.2: {} + + dotenv@16.5.0: {} + + eastasianwidth@0.2.0: {} + + elliptic@6.6.1: + dependencies: + bn.js: 4.12.1 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + es-module-lexer@1.6.0: {} + + esbuild@0.25.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.2 + '@esbuild/android-arm': 0.25.2 + '@esbuild/android-arm64': 0.25.2 + '@esbuild/android-x64': 0.25.2 + '@esbuild/darwin-arm64': 0.25.2 + '@esbuild/darwin-x64': 0.25.2 + '@esbuild/freebsd-arm64': 0.25.2 + '@esbuild/freebsd-x64': 0.25.2 + '@esbuild/linux-arm': 0.25.2 + '@esbuild/linux-arm64': 0.25.2 + '@esbuild/linux-ia32': 0.25.2 + '@esbuild/linux-loong64': 0.25.2 + '@esbuild/linux-mips64el': 0.25.2 + '@esbuild/linux-ppc64': 0.25.2 + '@esbuild/linux-riscv64': 0.25.2 + '@esbuild/linux-s390x': 0.25.2 + '@esbuild/linux-x64': 0.25.2 + '@esbuild/netbsd-arm64': 0.25.2 + '@esbuild/netbsd-x64': 0.25.2 + '@esbuild/openbsd-arm64': 0.25.2 + '@esbuild/openbsd-x64': 0.25.2 + '@esbuild/sunos-x64': 0.25.2 + '@esbuild/win32-arm64': 0.25.2 + '@esbuild/win32-ia32': 0.25.2 + '@esbuild/win32-x64': 0.25.2 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.7 + + ethers@5.8.0: + 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 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + event-target-shim@5.0.1: {} + + eventemitter3@5.0.1: {} + + events@3.3.0: {} + + expect-type@1.2.1: {} + + fast-copy@3.0.2: {} + + fast-redact@3.5.0: {} + + fast-safe-stringify@2.1.1: {} + + fdir@6.4.3(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + fsevents@2.3.3: + optional: true + + get-tsconfig@4.10.1: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + globrex@0.1.2: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + hash.js@1.1.7: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + help-me@5.0.0: {} + + hmac-drbg@1.0.1: + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + html-escaper@2.0.2: {} + + ieee754@1.2.1: {} + + ignore-by-default@1.0.1: {} + + inherits@2.0.4: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + isexe@2.0.0: {} + + isows@1.0.7(ws@8.18.3): + dependencies: + ws: 8.18.3 + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.4.0(supports-color@5.5.0) + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + joycon@3.1.1: {} + + js-sha3@0.8.0: {} + + json-stringify-safe@5.0.1: {} + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + + lodash.sortby@4.7.0: {} + + loupe@3.1.3: {} + + lru-cache@10.4.3: {} + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magicast@0.3.5: + dependencies: + '@babel/parser': 7.27.0 + '@babel/types': 7.27.0 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.7.1 + + minimalistic-assert@1.0.1: {} + + minimalistic-crypto-utils@1.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.12 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + mock-socket@9.3.1: {} + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.11: {} + + nock@13.5.6: + dependencies: + debug: 4.4.0(supports-color@5.5.0) + json-stringify-safe: 5.0.1 + propagate: 2.0.1 + transitivePeerDependencies: + - supports-color + + node-domexception@1.0.0: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + nodemon@3.1.10: + dependencies: + chokidar: 3.6.0 + debug: 4.4.0(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.2 + pstree.remy: 1.1.8 + semver: 7.7.1 + simple-update-notifier: 2.0.0 + supports-color: 5.5.0 + touch: 3.1.1 + undefsafe: 2.0.5 + + normalize-path@3.0.0: {} + + object-assign@4.1.1: {} + + on-exit-leak-free@2.1.2: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + ox@0.8.7(typescript@5.8.3): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.6 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.0.8(typescript@5.8.3) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - zod + + p-queue@8.1.0: + dependencies: + eventemitter3: 5.0.1 + p-timeout: 6.1.4 + + p-timeout@6.1.4: {} + + package-json-from-dist@1.0.1: {} + + path-key@3.1.1: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + pathe@2.0.3: {} + + pathval@2.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + pino-abstract-transport@2.0.0: + dependencies: + split2: 4.2.0 + + pino-pretty@11.3.0: + dependencies: + colorette: 2.0.20 + dateformat: 4.6.3 + fast-copy: 3.0.2 + fast-safe-stringify: 2.1.1 + help-me: 5.0.0 + joycon: 3.1.1 + minimist: 1.2.8 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pump: 3.0.3 + readable-stream: 4.7.0 + secure-json-parse: 2.7.0 + sonic-boom: 4.2.0 + strip-json-comments: 3.1.1 + + pino-std-serializers@7.0.0: {} + + pino@9.9.5: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pino-std-serializers: 7.0.0 + process-warning: 5.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 4.2.0 + thread-stream: 3.1.0 + + pirates@4.0.7: {} + + postcss-load-config@6.0.1(postcss@8.5.3)(tsx@4.20.5): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + postcss: 8.5.3 + tsx: 4.20.5 + + postcss@8.5.3: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + process-warning@5.0.0: {} + + process@0.11.10: {} + + propagate@2.0.1: {} + + pstree.remy@1.1.8: {} + + pump@3.0.3: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + punycode@2.3.1: {} + + pvtsutils@1.3.6: + dependencies: + tslib: 2.8.1 + optional: true + + pvutils@1.1.3: + optional: true + + quick-format-unescaped@4.0.4: {} + + readable-stream@4.7.0: + dependencies: + abort-controller: 3.0.0 + buffer: 6.0.3 + events: 3.3.0 + process: 0.11.10 + string_decoder: 1.3.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.1.2: {} + + real-require@0.2.0: {} + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + rollup@4.39.0: + dependencies: + '@types/estree': 1.0.7 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.39.0 + '@rollup/rollup-android-arm64': 4.39.0 + '@rollup/rollup-darwin-arm64': 4.39.0 + '@rollup/rollup-darwin-x64': 4.39.0 + '@rollup/rollup-freebsd-arm64': 4.39.0 + '@rollup/rollup-freebsd-x64': 4.39.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.39.0 + '@rollup/rollup-linux-arm-musleabihf': 4.39.0 + '@rollup/rollup-linux-arm64-gnu': 4.39.0 + '@rollup/rollup-linux-arm64-musl': 4.39.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.39.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.39.0 + '@rollup/rollup-linux-riscv64-gnu': 4.39.0 + '@rollup/rollup-linux-riscv64-musl': 4.39.0 + '@rollup/rollup-linux-s390x-gnu': 4.39.0 + '@rollup/rollup-linux-x64-gnu': 4.39.0 + '@rollup/rollup-linux-x64-musl': 4.39.0 + '@rollup/rollup-win32-arm64-msvc': 4.39.0 + '@rollup/rollup-win32-ia32-msvc': 4.39.0 + '@rollup/rollup-win32-x64-msvc': 4.39.0 + fsevents: 2.3.3 + + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + safe-buffer@5.2.1: {} + + safe-stable-stringify@2.5.0: {} + + scale-ts@1.6.1: {} + + scrypt-js@3.0.1: {} + + secure-json-parse@2.7.0: {} + + semver@7.7.1: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + simple-update-notifier@2.0.0: + dependencies: + semver: 7.7.1 + + smoldot@2.0.26: + dependencies: + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + optional: true + + sonic-boom@4.2.0: + dependencies: + atomic-sleep: 1.0.0 + + source-map-js@1.2.1: {} + + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + + split2@4.2.0: {} + + stackback@0.0.2: {} + + std-env@3.9.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-json-comments@3.1.1: {} + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.7 + ts-interface-checker: 0.1.13 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + test-exclude@7.0.1: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 10.4.5 + minimatch: 9.0.5 + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + thread-stream@3.1.0: + dependencies: + real-require: 0.2.0 + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinyglobby@0.2.12: + dependencies: + fdir: 6.4.3(picomatch@4.0.2) + picomatch: 4.0.2 + + tinypool@1.0.2: {} + + tinyrainbow@2.0.0: {} + + tinyspy@3.0.2: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toml@3.0.0: {} + + touch@3.1.1: {} + + tr46@0.0.3: {} + + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + + tree-kill@1.2.2: {} + + ts-interface-checker@0.1.13: {} + + tsconfck@3.1.5(typescript@5.8.3): + optionalDependencies: + typescript: 5.8.3 + + tslib@2.8.1: {} + + tsup@8.4.0(postcss@8.5.3)(tsx@4.20.5)(typescript@5.8.3): + dependencies: + bundle-require: 5.1.0(esbuild@0.25.2) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.0(supports-color@5.5.0) + esbuild: 0.25.2 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(postcss@8.5.3)(tsx@4.20.5) + resolve-from: 5.0.0 + rollup: 4.39.0 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.12 + tree-kill: 1.2.2 + optionalDependencies: + postcss: 8.5.3 + typescript: 5.8.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + + tsx@4.20.5: + dependencies: + esbuild: 0.25.2 + get-tsconfig: 4.10.1 + optionalDependencies: + fsevents: 2.3.3 + + typescript@5.8.3: {} + + undefsafe@2.0.5: {} + + undici-types@6.21.0: {} + + viem@2.34.0(typescript@5.8.3): + dependencies: + '@noble/curves': 1.9.6 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.0.8(typescript@5.8.3) + isows: 1.0.7(ws@8.18.3) + ox: 0.8.7(typescript@5.8.3) + ws: 8.18.3 + optionalDependencies: + typescript: 5.8.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + vite-node@3.1.1(@types/node@22.14.0)(tsx@4.20.5): + dependencies: + cac: 6.7.14 + debug: 4.4.0(supports-color@5.5.0) + es-module-lexer: 1.6.0 + pathe: 2.0.3 + vite: 6.2.5(@types/node@22.14.0)(tsx@4.20.5) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite-tsconfig-paths@5.1.4(typescript@5.8.3)(vite@6.2.5(@types/node@22.14.0)(tsx@4.20.5)): + dependencies: + debug: 4.4.0(supports-color@5.5.0) + globrex: 0.1.2 + tsconfck: 3.1.5(typescript@5.8.3) + optionalDependencies: + vite: 6.2.5(@types/node@22.14.0)(tsx@4.20.5) + transitivePeerDependencies: + - supports-color + - typescript + + vite@6.2.5(@types/node@22.14.0)(tsx@4.20.5): + dependencies: + esbuild: 0.25.2 + postcss: 8.5.3 + rollup: 4.39.0 + optionalDependencies: + '@types/node': 22.14.0 + fsevents: 2.3.3 + tsx: 4.20.5 + + vitest@3.1.1(@types/node@22.14.0)(tsx@4.20.5): + dependencies: + '@vitest/expect': 3.1.1 + '@vitest/mocker': 3.1.1(vite@6.2.5(@types/node@22.14.0)(tsx@4.20.5)) + '@vitest/pretty-format': 3.1.1 + '@vitest/runner': 3.1.1 + '@vitest/snapshot': 3.1.1 + '@vitest/spy': 3.1.1 + '@vitest/utils': 3.1.1 + chai: 5.2.0 + debug: 4.4.0(supports-color@5.5.0) + expect-type: 1.2.1 + magic-string: 0.30.17 + pathe: 2.0.3 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinypool: 1.0.2 + tinyrainbow: 2.0.0 + vite: 6.2.5(@types/node@22.14.0)(tsx@4.20.5) + vite-node: 3.1.1(@types/node@22.14.0)(tsx@4.20.5) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.14.0 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + web-streams-polyfill@3.3.3: {} + + webidl-conversions@3.0.1: {} + + webidl-conversions@4.0.2: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + ws@8.18.0: {} + + ws@8.18.3: {} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/Dockerfile b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/Dockerfile new file mode 100644 index 00000000..df35b893 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/Dockerfile @@ -0,0 +1,57 @@ +# Dockerfile for Hyperbridge Intent Filler +FROM node:24-alpine + +# Install dependencies required for builds +RUN apk add --no-cache python3 make g++ git curl + +# Create non-root user +RUN addgroup -g 1001 -S filler && \ + adduser -S filler -u 1001 + +# Set working directory +WORKDIR /app + +# Create config directories (support both /app/config and /app/packages/filler/config) +RUN mkdir -p /app/config /app/packages/filler/config + +# Install pnpm +RUN npm install -g pnpm@9.15.0 + +# Copy the entire workspace +COPY . . + +# Install dependencies for the monorepo +RUN pnpm install --frozen-lockfile + +# Build the SDK first (dependency of filler) +RUN cd packages/sdk && pnpm build + +# Build the filler +RUN cd packages/filler && pnpm build + +# Configure permissions +RUN chown -R filler:filler /app + +# Switch to non-root user +USER filler + +# Set environment variables +ENV NODE_ENV=production + +# Create a healthcheck script +RUN echo '#!/bin/sh' > /app/healthcheck.sh && \ + echo 'ps -ef | grep "node" | grep -v grep > /dev/null || exit 1' >> /app/healthcheck.sh && \ + chmod +x /app/healthcheck.sh + +# Set up healthcheck +HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 CMD [ "/app/healthcheck.sh" ] + +# Working directory for running the application +# Set working directory to filler package +WORKDIR /app/packages/filler + +# Create symbolic link between config locations for compatibility +RUN ln -sf /app/config/config.toml /app/packages/filler/config/config.toml + +# Command to run the application +CMD ["node", "./dist/bin/filler.js", "run", "-c", "/app/config/config.toml"] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/README.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/README.md new file mode 100644 index 00000000..67989b3d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/README.md @@ -0,0 +1,43 @@ +# Scripts Directory + +This directory contains utility scripts for the Hyperbridge Filler. + +## Docker Script + +A single, simplified script to handle all Docker operations: + +- **docker.sh**: All-in-one Docker operations for building, running, and managing containers +- **Dockerfile**: Used to build the filler Docker image +- **docker-compose.yml**: Configuration for running the filler using Docker Compose + +Note: The `.dockerignore` file is located in the parent directory as it needs to be in the root of the Docker build context. + +### Usage + +```bash +./docker.sh [command] + +# Commands: +# build Build the Docker image +# run Run the filler in a Docker container +# up Start using Docker Compose +# down Stop and remove Docker Compose containers +# logs View logs from Docker Compose containers +# help Show this help message +``` + +## Other Scripts + +- **make-executable.sh**: Utility to make scripts executable + +## Configuration + +The Docker script is configured to use the config file from the parent directory (`../config.toml`). + +## Development Notes + +If you modify any of these scripts, make sure they remain executable: + +```bash +chmod +x scripts/*.sh +``` diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/docker-compose.yml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/docker-compose.yml new file mode 100644 index 00000000..7b21d951 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/docker-compose.yml @@ -0,0 +1,31 @@ +version: "3.8" + +services: + filler: + image: polytopelabs/hyperbridge-filler:latest + build: + context: ../../.. + dockerfile: packages/filler/scripts/Dockerfile + container_name: hyperbridge-filler + restart: unless-stopped + volumes: + - ${CONFIG_PATH:-../config.toml}:/app/packages/filler/config/config.toml:ro + environment: + - NODE_ENV=production + networks: + - filler-network + logging: + driver: "json-file" + options: + max-size: "10m" + max-file: "3" + healthcheck: + test: ["CMD", "/app/healthcheck.sh"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 5s + +networks: + filler-network: + driver: bridge diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/docker.sh b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/docker.sh new file mode 100755 index 00000000..09e0d69f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/scripts/docker.sh @@ -0,0 +1,136 @@ +#!/bin/bash +set -e + +# Simple Docker script for Hyperbridge Filler +# Handles the essential Docker operations: build, run, and docker-compose + +# Color codes for output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +# Get the script directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ROOT_DIR="$(dirname "$SCRIPT_DIR")" +CONFIG_FILE="$ROOT_DIR/config.toml" +DOCKERFILE="$SCRIPT_DIR/Dockerfile" +COMPOSE_FILE="$SCRIPT_DIR/docker-compose.yml" + +# Show help +show_help() { + echo "Usage: $0 [command]" + echo + echo "Commands:" + echo " build Build the Docker image" + echo " run Run the filler in a Docker container" + echo " up Start using Docker Compose" + echo " down Stop and remove Docker Compose containers" + echo " logs View logs from Docker Compose containers" + echo " help Show this help message" +} + +# Check if Docker is installed +if ! command -v docker &> /dev/null; then + echo -e "${RED}Error: Docker is not installed${NC}" + exit 1 +fi + +# No arguments provided +if [ $# -eq 0 ]; then + show_help + exit 1 +fi + +# Parse command +COMMAND="$1" +shift + +case "$COMMAND" in + build) + echo -e "${YELLOW}Building Docker image...${NC}" + echo -e "$(dirname "$(dirname "$ROOT_DIR")")" + docker build -t polytopelabs/hyperbridge-filler:latest -f "$DOCKERFILE" "$(dirname "$(dirname "$ROOT_DIR")")" + echo -e "${GREEN}✓ Docker image built successfully!${NC}" + ;; + + run) + echo -e "${YELLOW}Running Docker container...${NC}" + + # Check if config file exists + if [ ! -f "$CONFIG_FILE" ]; then + echo -e "${RED}Error: Config file not found at $CONFIG_FILE${NC}" + exit 1 + fi + + # Check if image exists + if ! docker image inspect polytopelabs/hyperbridge-filler:latest &> /dev/null; then + echo -e "${YELLOW}Image not found, building first...${NC}" + docker build -t polytopelabs/hyperbridge-filler:latest -f "$DOCKERFILE" "$(dirname "$(dirname "$ROOT_DIR")")" + fi + + # Remove existing container if it exists + if docker ps -a | grep -q hyperbridge-filler; then + echo -e "${YELLOW}Removing existing container...${NC}" + docker rm -f hyperbridge-filler + fi + + # Run the container + docker run -d \ + --name hyperbridge-filler \ + --restart unless-stopped \ + -v "$CONFIG_FILE:/app/packages/filler/config/config.toml:ro" \ + -e NODE_ENV=production \ + --log-driver json-file \ + --log-opt max-size=10m \ + --log-opt max-file=3 \ + polytopelabs/hyperbridge-filler:latest + + echo -e "${GREEN}✓ Container started!${NC}" + echo " View logs: docker logs -f hyperbridge-filler" + echo " Stop: docker stop hyperbridge-filler" + ;; + + up) + echo -e "${YELLOW}Starting with Docker Compose...${NC}" + + # Check if config file exists + if [ ! -f "$CONFIG_FILE" ]; then + echo -e "${RED}Error: Config file not found at $CONFIG_FILE${NC}" + exit 1 + fi + + # Ensure config file exists before starting + if [ ! -f "$CONFIG_FILE" ]; then + echo -e "${RED}Error: Config file not found at $CONFIG_FILE${NC}" + exit 1 + fi + + # Start with Docker Compose + CONFIG_PATH="$CONFIG_FILE" docker-compose -f "$COMPOSE_FILE" up -d + echo -e "${GREEN}✓ Services started!${NC}" + echo " View logs: $0 logs" + echo " Stop: $0 down" + ;; + + down) + echo -e "${YELLOW}Stopping Docker Compose services...${NC}" + docker-compose -f "$COMPOSE_FILE" down + echo -e "${GREEN}✓ Services stopped${NC}" + ;; + + logs) + echo -e "${YELLOW}Showing logs (Ctrl+C to exit)...${NC}" + docker-compose -f "$COMPOSE_FILE" logs -f + ;; + + help) + show_help + ;; + + *) + echo -e "${RED}Error: Unknown command $COMMAND${NC}" + show_help + exit 1 + ;; +esac diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/bin/filler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/bin/filler.ts new file mode 100644 index 00000000..b5088187 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/bin/filler.ts @@ -0,0 +1,245 @@ +#!/usr/bin/env node +import { Command } from "commander" +import { readFileSync } from "fs" +import { resolve, dirname } from "path" +import { fileURLToPath } from "url" +import { parse } from "toml" +import { IntentFiller } from "../core/filler.js" +import { BasicFiller } from "../strategies/basic.js" +import { ConfirmationPolicy } from "../config/confirmation-policy.js" +import { ChainConfig, FillerConfig, HexString } from "@hyperbridge/sdk" +import { + FillerConfigService, + UserProvidedChainConfig, + FillerConfig as FillerServiceConfig, + CoinGeckoConfig, + EtherscanConfig, + LoggingConfig, +} from "../services/FillerConfigService.js" +import { getLogger, configureLogger } from "../services/Logger.js" +import { Decimal } from "decimal.js" + +// ASCII art header +const ASCII_HEADER = ` +██╗███╗ ██╗████████╗███████╗███╗ ██╗████████╗ ██████╗ █████╗ ████████╗███████╗██╗ ██╗ █████╗ ██╗ ██╗ +██║████╗ ██║╚══██╔══╝██╔════╝████╗ ██║╚══██╔══╝██╔════╝ ██╔══██╗╚══██╔══╝██╔════╝██║ ██║██╔══██╗╚██╗ ██╔╝ +██║██╔██╗ ██║ ██║ █████╗ ██╔██╗ ██║ ██║ ██║ ███╗███████║ ██║ █████╗ ██║ █╗ ██║███████║ ╚████╔╝ +██║██║╚██╗██║ ██║ ██╔══╝ ██║╚██╗██║ ██║ ██║ ██║██╔══██║ ██║ ██╔══╝ ██║███╗██║██╔══██║ ╚██╔╝ +██║██║ ╚████║ ██║ ███████╗██║ ╚████║ ██║ ╚██████╔╝██║ ██║ ██║ ███████╗╚███╔███╔╝██║ ██║ ██║ +╚═╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚══╝╚══╝ ╚═╝ ╚═╝ ╚═╝ + +` + +// Get package.json path +const __filename = fileURLToPath(import.meta.url) +const __dirname = dirname(__filename) +const packageJsonPath = resolve(__dirname, "../../package.json") +const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8")) + +interface StrategyConfig { + type: "basic" | "stable-swap" + privateKey: string +} + +interface ChainConfirmationPolicy { + minAmount: string + maxAmount: string + minConfirmations: number + maxConfirmations: number +} + +interface PendingQueueConfig { + maxRechecks: number + recheckDelayMs: number +} + +interface FillerTomlConfig { + filler: { + privateKey: string + maxConcurrentOrders: number + pendingQueue: PendingQueueConfig + coingecko?: CoinGeckoConfig + etherscan?: EtherscanConfig + logging?: LoggingConfig + } + strategies: StrategyConfig[] + chains: UserProvidedChainConfig[] + confirmationPolicies: Record +} + +const program = new Command() + +program.name("filler").description("Hyperbridge IntentGateway Filler").version(packageJson.version) + +program + .command("run") + .description("Run the intent filler with the specified configuration") + .requiredOption("-c, --config ", "Path to TOML configuration file") + .action(async (options: { config: string }) => { + try { + // Display ASCII art header + process.stdout.write(ASCII_HEADER) + + const configPath = resolve(process.cwd(), options.config) + const tomlContent = readFileSync(configPath, "utf-8") + const config = parse(tomlContent) as FillerTomlConfig + + validateConfig(config) + + // Configure logger based on config BEFORE creating any services + if (config.filler.logging) { + configureLogger(config.filler.logging) + } + + const logger = getLogger("cli") + logger.info({ configPath }, "Loading configuration") + logger.info("Starting Hyperbridge IntentGateway Filler...") + + logger.info("Initializing services...") + + const fillerChainConfigs: UserProvidedChainConfig[] = config.chains.map((chain) => ({ + chainId: chain.chainId, + rpcUrl: chain.rpcUrl, + })) + + const fillerConfigForService: FillerServiceConfig | undefined = + config.filler.coingecko || config.filler.logging + ? { + privateKey: config.filler.privateKey, + maxConcurrentOrders: config.filler.maxConcurrentOrders, + coingecko: config.filler.coingecko, + etherscan: config.filler.etherscan, + logging: config.filler.logging, + } + : undefined + + const configService = new FillerConfigService(fillerChainConfigs, fillerConfigForService) + + const chainConfigs: ChainConfig[] = config.chains.map((chain) => { + // Get the chain name from chain ID for SDK compatibility + const chainName = `EVM-${chain.chainId}` + return configService.getChainConfig(chainName) + }) + + // Initialize confirmation policy + const confirmationPolicy = new ConfirmationPolicy(config.confirmationPolicies) + + // Create filler configuration + const fillerConfig: FillerConfig = { + confirmationPolicy: { + getConfirmationBlocks: (chainId: number, amount: number) => + confirmationPolicy.getConfirmationBlocks(chainId, new Decimal(amount)), + }, + maxConcurrentOrders: config.filler.maxConcurrentOrders, + pendingQueueConfig: config.filler.pendingQueue, + } + + // Initialize strategies + logger.info("Initializing strategies...") + const strategies = config.strategies.map((strategyConfig) => { + switch (strategyConfig.type) { + case "basic": + return new BasicFiller(strategyConfig.privateKey as HexString, configService) + default: + throw new Error(`Unknown strategy type: ${strategyConfig.type}`) + } + }) + + // Initialize and start the intent filler + logger.info("Starting intent filler...") + const intentFiller = new IntentFiller(chainConfigs, strategies, fillerConfig, configService) + // Start the filler + intentFiller.start() + + logger.info( + { + chains: config.chains.map((c) => c.chainId), + strategies: config.strategies.map((s) => s.type), + maxConcurrentOrders: config.filler.maxConcurrentOrders, + }, + "Intent filler is running", + ) + + // Handle graceful shutdown + process.on("SIGINT", () => { + logger.warn("Shutting down intent filler (SIGINT)...") + intentFiller.stop() + process.exit(0) + }) + + process.on("SIGTERM", () => { + logger.warn("Shutting down intent filler (SIGTERM)...") + intentFiller.stop() + process.exit(0) + }) + + // Keep the process running + process.stdin.resume() + } catch (error) { + // Use console.error for initial startup errors since logger might not be configured yet + console.error("Failed to start filler:", error) + process.exit(1) + } + }) + +function validateConfig(config: FillerTomlConfig): void { + // Validate required fields + if (!config.filler?.privateKey) { + throw new Error("Filler private key is required") + } + + if (!config.strategies || config.strategies.length === 0) { + throw new Error("At least one strategy must be configured") + } + + if (!config.chains || config.chains.length === 0) { + throw new Error("At least one chain must be configured") + } + + // Validate chain configurations + for (const chain of config.chains) { + if (!chain.chainId) { + throw new Error(`Chain configuration must have chainId`) + } + if (typeof chain.chainId !== "number") { + throw new Error(`Chain ${chain.chainId} chainId must be a number`) + } + if (!chain.rpcUrl) { + throw new Error(`Chain ${chain.chainId} must have rpcUrl`) + } + } + + // Validate strategies + for (const strategy of config.strategies) { + if (!strategy.type || !strategy.privateKey) { + throw new Error("Strategy type and private key are required") + } + + if (!["basic", "stable-swap"].includes(strategy.type)) { + throw new Error(`Invalid strategy type: ${strategy.type}`) + } + } + + // Validate confirmation policies + for (const [chainId, policy] of Object.entries(config.confirmationPolicies)) { + if (!policy.minAmount || !policy.maxAmount) { + throw new Error(`Confirmation policy for chain ${chainId} must have minAmount and maxAmount`) + } + + if (policy.minConfirmations === undefined || policy.maxConfirmations === undefined) { + throw new Error(`Confirmation policy for chain ${chainId} must have minConfirmations and maxConfirmations`) + } + + if (policy.minConfirmations > policy.maxConfirmations) { + throw new Error(`Invalid confirmation range for chain ${chainId}`) + } + } +} + +// Parse command line arguments +program.parse(process.argv) + +// Show help if no command is provided +if (!process.argv.slice(2).length) { + program.outputHelp() +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/ERC20.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/ERC20.ts new file mode 100644 index 00000000..1f5ab2c6 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/ERC20.ts @@ -0,0 +1,222 @@ +export const ERC20_ABI = [ + { + constant: true, + inputs: [], + name: "name", + outputs: [ + { + name: "", + type: "string", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: false, + inputs: [ + { + name: "_spender", + type: "address", + }, + { + name: "_value", + type: "uint256", + }, + ], + name: "approve", + outputs: [ + { + name: "", + type: "bool", + }, + ], + payable: false, + stateMutability: "nonpayable", + type: "function", + }, + { + constant: true, + inputs: [], + name: "totalSupply", + outputs: [ + { + name: "", + type: "uint256", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: false, + inputs: [ + { + name: "_from", + type: "address", + }, + { + name: "_to", + type: "address", + }, + { + name: "_value", + type: "uint256", + }, + ], + name: "transferFrom", + outputs: [ + { + name: "", + type: "bool", + }, + ], + payable: false, + stateMutability: "nonpayable", + type: "function", + }, + { + constant: true, + inputs: [], + name: "decimals", + outputs: [ + { + name: "", + type: "uint8", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: true, + inputs: [ + { + name: "_owner", + type: "address", + }, + ], + name: "balanceOf", + outputs: [ + { + name: "balance", + type: "uint256", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: true, + inputs: [], + name: "symbol", + outputs: [ + { + name: "", + type: "string", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + constant: false, + inputs: [ + { + name: "_to", + type: "address", + }, + { + name: "_value", + type: "uint256", + }, + ], + name: "transfer", + outputs: [ + { + name: "", + type: "bool", + }, + ], + payable: false, + stateMutability: "nonpayable", + type: "function", + }, + { + constant: true, + inputs: [ + { + name: "_owner", + type: "address", + }, + { + name: "_spender", + type: "address", + }, + ], + name: "allowance", + outputs: [ + { + name: "", + type: "uint256", + }, + ], + payable: false, + stateMutability: "view", + type: "function", + }, + { + payable: true, + stateMutability: "payable", + type: "fallback", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "owner", + type: "address", + }, + { + indexed: true, + name: "spender", + type: "address", + }, + { + indexed: false, + name: "value", + type: "uint256", + }, + ], + name: "Approval", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + name: "from", + type: "address", + }, + { + indexed: true, + name: "to", + type: "address", + }, + { + indexed: false, + name: "value", + type: "uint256", + }, + ], + name: "Transfer", + type: "event", + }, +] as const diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/EvmHost.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/EvmHost.ts new file mode 100644 index 00000000..7ee736ee --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/EvmHost.ts @@ -0,0 +1,2272 @@ +export const EVM_HOST = [ + { + inputs: [], + name: "CannotChangeFeeToken", + type: "error", + }, + { + inputs: [], + name: "DuplicateResponse", + type: "error", + }, + { + inputs: [], + name: "FrozenHost", + type: "error", + }, + { + inputs: [], + name: "InvalidAddressLength", + type: "error", + }, + { + inputs: [], + name: "InvalidConsensusClient", + type: "error", + }, + { + inputs: [], + name: "InvalidHandler", + type: "error", + }, + { + inputs: [], + name: "InvalidHostManager", + type: "error", + }, + { + inputs: [], + name: "InvalidHyperbridgeId", + type: "error", + }, + { + inputs: [], + name: "InvalidStateMachinesLength", + type: "error", + }, + { + inputs: [], + name: "InvalidUnstakingPeriod", + type: "error", + }, + { + inputs: [], + name: "UnauthorizedAccount", + type: "error", + }, + { + inputs: [], + name: "UnauthorizedAction", + type: "error", + }, + { + inputs: [], + name: "UnauthorizedResponse", + type: "error", + }, + { + inputs: [], + name: "UnknownRequest", + type: "error", + }, + { + inputs: [], + name: "UnknownResponse", + type: "error", + }, + { + inputs: [], + name: "WithdrawalFailed", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "source", + type: "string", + }, + { + indexed: false, + internalType: "string", + name: "dest", + type: "string", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + indexed: false, + internalType: "uint256", + name: "height", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "timeoutTimestamp", + type: "uint256", + }, + { + indexed: false, + internalType: "bytes", + name: "context", + type: "bytes", + }, + { + indexed: false, + internalType: "uint256", + name: "fee", + type: "uint256", + }, + ], + name: "GetRequestEvent", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "address", + name: "relayer", + type: "address", + }, + ], + name: "GetRequestHandled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "string", + name: "dest", + type: "string", + }, + ], + name: "GetRequestTimeoutHandled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "enum FrozenStatus", + name: "status", + type: "uint8", + }, + ], + name: "HostFrozen", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "defaultTimeout", + type: "uint256", + }, + { + internalType: "uint256", + name: "defaultPerByteFee", + type: "uint256", + }, + { + internalType: "uint256", + name: "stateCommitmentFee", + type: "uint256", + }, + { + internalType: "address", + name: "feeToken", + type: "address", + }, + { + internalType: "address", + name: "admin", + type: "address", + }, + { + internalType: "address", + name: "handler", + type: "address", + }, + { + internalType: "address", + name: "hostManager", + type: "address", + }, + { + internalType: "address", + name: "uniswapV2", + type: "address", + }, + { + internalType: "uint256", + name: "unStakingPeriod", + type: "uint256", + }, + { + internalType: "uint256", + name: "challengePeriod", + type: "uint256", + }, + { + internalType: "address", + name: "consensusClient", + type: "address", + }, + { + internalType: "uint256[]", + name: "stateMachines", + type: "uint256[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "stateIdHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "perByteFee", + type: "uint256", + }, + ], + internalType: "struct PerByteFee[]", + name: "perByteFees", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "hyperbridge", + type: "bytes", + }, + ], + indexed: false, + internalType: "struct HostParams", + name: "oldParams", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "defaultTimeout", + type: "uint256", + }, + { + internalType: "uint256", + name: "defaultPerByteFee", + type: "uint256", + }, + { + internalType: "uint256", + name: "stateCommitmentFee", + type: "uint256", + }, + { + internalType: "address", + name: "feeToken", + type: "address", + }, + { + internalType: "address", + name: "admin", + type: "address", + }, + { + internalType: "address", + name: "handler", + type: "address", + }, + { + internalType: "address", + name: "hostManager", + type: "address", + }, + { + internalType: "address", + name: "uniswapV2", + type: "address", + }, + { + internalType: "uint256", + name: "unStakingPeriod", + type: "uint256", + }, + { + internalType: "uint256", + name: "challengePeriod", + type: "uint256", + }, + { + internalType: "address", + name: "consensusClient", + type: "address", + }, + { + internalType: "uint256[]", + name: "stateMachines", + type: "uint256[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "stateIdHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "perByteFee", + type: "uint256", + }, + ], + internalType: "struct PerByteFee[]", + name: "perByteFees", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "hyperbridge", + type: "bytes", + }, + ], + indexed: false, + internalType: "struct HostParams", + name: "newParams", + type: "tuple", + }, + ], + name: "HostParamsUpdated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + indexed: false, + internalType: "address", + name: "beneficiary", + type: "address", + }, + { + indexed: false, + internalType: "bool", + name: "native", + type: "bool", + }, + ], + name: "HostWithdrawal", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "source", + type: "string", + }, + { + indexed: false, + internalType: "string", + name: "dest", + type: "string", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + indexed: false, + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "timeoutTimestamp", + type: "uint256", + }, + { + indexed: false, + internalType: "bytes", + name: "body", + type: "bytes", + }, + { + indexed: false, + internalType: "uint256", + name: "fee", + type: "uint256", + }, + ], + name: "PostRequestEvent", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "address", + name: "relayer", + type: "address", + }, + ], + name: "PostRequestHandled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "string", + name: "dest", + type: "string", + }, + ], + name: "PostRequestTimeoutHandled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "source", + type: "string", + }, + { + indexed: false, + internalType: "string", + name: "dest", + type: "string", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + indexed: false, + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "timeoutTimestamp", + type: "uint256", + }, + { + indexed: false, + internalType: "bytes", + name: "body", + type: "bytes", + }, + { + indexed: false, + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + indexed: false, + internalType: "uint256", + name: "responseTimeoutTimestamp", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "fee", + type: "uint256", + }, + ], + name: "PostResponseEvent", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "uint256", + name: "newFee", + type: "uint256", + }, + ], + name: "PostResponseFunded", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "address", + name: "relayer", + type: "address", + }, + ], + name: "PostResponseHandled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "string", + name: "dest", + type: "string", + }, + ], + name: "PostResponseTimeoutHandled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "uint256", + name: "newFee", + type: "uint256", + }, + ], + name: "RequestFunded", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "caller", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "fee", + type: "uint256", + }, + ], + name: "StateCommitmentRead", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "stateMachineId", + type: "string", + }, + { + indexed: false, + internalType: "uint256", + name: "height", + type: "uint256", + }, + { + components: [ + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "overlayRoot", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "stateRoot", + type: "bytes32", + }, + ], + indexed: false, + internalType: "struct StateCommitment", + name: "stateCommitment", + type: "tuple", + }, + { + indexed: true, + internalType: "address", + name: "fisherman", + type: "address", + }, + ], + name: "StateCommitmentVetoed", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "stateMachineId", + type: "string", + }, + { + indexed: false, + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + name: "StateMachineUpdated", + type: "event", + }, + { + inputs: [], + name: "admin", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "chainId", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "challengePeriod", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "consensusClient", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "consensusState", + outputs: [ + { + internalType: "bytes", + name: "", + type: "bytes", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "consensusUpdateTime", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "address", + name: "fisherman", + type: "address", + }, + ], + name: "deleteStateMachineCommitment", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "payer", + type: "address", + }, + ], + internalType: "struct DispatchPostResponse", + name: "post", + type: "tuple", + }, + ], + name: "dispatch", + outputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "payer", + type: "address", + }, + ], + internalType: "struct DispatchPost", + name: "post", + type: "tuple", + }, + ], + name: "dispatch", + outputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct DispatchGet", + name: "get", + type: "tuple", + }, + ], + name: "dispatch", + outputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse", + name: "response", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + name: "dispatchIncoming", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + name: "dispatchIncoming", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest", + name: "request", + type: "tuple", + }, + { + components: [ + { + internalType: "bytes", + name: "key", + type: "bytes", + }, + { + internalType: "bytes", + name: "value", + type: "bytes", + }, + ], + internalType: "struct StorageValue[]", + name: "values", + type: "tuple[]", + }, + ], + internalType: "struct GetResponse", + name: "response", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + name: "dispatchIncoming", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse", + name: "response", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + ], + internalType: "struct FeeMetadata", + name: "meta", + type: "tuple", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "dispatchTimeOut", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + ], + internalType: "struct FeeMetadata", + name: "meta", + type: "tuple", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "dispatchTimeOut", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest", + name: "request", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + ], + internalType: "struct FeeMetadata", + name: "meta", + type: "tuple", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "dispatchTimeOut", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "feeToken", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "frozen", + outputs: [ + { + internalType: "enum FrozenStatus", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "fundRequest", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "fundResponse", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [], + name: "host", + outputs: [ + { + internalType: "bytes", + name: "", + type: "bytes", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "hostParams", + outputs: [ + { + components: [ + { + internalType: "uint256", + name: "defaultTimeout", + type: "uint256", + }, + { + internalType: "uint256", + name: "defaultPerByteFee", + type: "uint256", + }, + { + internalType: "uint256", + name: "stateCommitmentFee", + type: "uint256", + }, + { + internalType: "address", + name: "feeToken", + type: "address", + }, + { + internalType: "address", + name: "admin", + type: "address", + }, + { + internalType: "address", + name: "handler", + type: "address", + }, + { + internalType: "address", + name: "hostManager", + type: "address", + }, + { + internalType: "address", + name: "uniswapV2", + type: "address", + }, + { + internalType: "uint256", + name: "unStakingPeriod", + type: "uint256", + }, + { + internalType: "uint256", + name: "challengePeriod", + type: "uint256", + }, + { + internalType: "address", + name: "consensusClient", + type: "address", + }, + { + internalType: "uint256[]", + name: "stateMachines", + type: "uint256[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "stateIdHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "perByteFee", + type: "uint256", + }, + ], + internalType: "struct PerByteFee[]", + name: "perByteFees", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "hyperbridge", + type: "bytes", + }, + ], + internalType: "struct HostParams", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "hyperbridge", + outputs: [ + { + internalType: "bytes", + name: "", + type: "bytes", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + ], + name: "latestStateMachineHeight", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "nonce", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "stateId", + type: "bytes", + }, + ], + name: "perByteFee", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "requestCommitments", + outputs: [ + { + components: [ + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + ], + internalType: "struct FeeMetadata", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "requestReceipts", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "responded", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "responseCommitments", + outputs: [ + { + components: [ + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + ], + internalType: "struct FeeMetadata", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "responseReceipts", + outputs: [ + { + components: [ + { + internalType: "bytes32", + name: "responseCommitment", + type: "bytes32", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + internalType: "struct ResponseReceipt", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "state", + type: "bytes", + }, + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "overlayRoot", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "stateRoot", + type: "bytes32", + }, + ], + internalType: "struct StateCommitment", + name: "commitment", + type: "tuple", + }, + ], + name: "setConsensusState", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "enum FrozenStatus", + name: "newState", + type: "uint8", + }, + ], + name: "setFrozenState", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "stateCommitmentFee", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + ], + name: "stateMachineCommitment", + outputs: [ + { + components: [ + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "overlayRoot", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "stateRoot", + type: "bytes32", + }, + ], + internalType: "struct StateCommitment", + name: "", + type: "tuple", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + ], + name: "stateMachineCommitmentUpdateTime", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "parachainId", + type: "bytes", + }, + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + ], + name: "stateMachineId", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "state", + type: "bytes", + }, + ], + name: "storeConsensusState", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "overlayRoot", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "stateRoot", + type: "bytes32", + }, + ], + internalType: "struct StateCommitment", + name: "commitment", + type: "tuple", + }, + ], + name: "storeStateMachineCommitment", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "timestamp", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "unStakingPeriod", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "uniswapV2Router", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "defaultTimeout", + type: "uint256", + }, + { + internalType: "uint256", + name: "defaultPerByteFee", + type: "uint256", + }, + { + internalType: "uint256", + name: "stateCommitmentFee", + type: "uint256", + }, + { + internalType: "address", + name: "feeToken", + type: "address", + }, + { + internalType: "address", + name: "admin", + type: "address", + }, + { + internalType: "address", + name: "handler", + type: "address", + }, + { + internalType: "address", + name: "hostManager", + type: "address", + }, + { + internalType: "address", + name: "uniswapV2", + type: "address", + }, + { + internalType: "uint256", + name: "unStakingPeriod", + type: "uint256", + }, + { + internalType: "uint256", + name: "challengePeriod", + type: "uint256", + }, + { + internalType: "address", + name: "consensusClient", + type: "address", + }, + { + internalType: "uint256[]", + name: "stateMachines", + type: "uint256[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "stateIdHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "perByteFee", + type: "uint256", + }, + ], + internalType: "struct PerByteFee[]", + name: "perByteFees", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "hyperbridge", + type: "bytes", + }, + ], + internalType: "struct HostParams", + name: "params", + type: "tuple", + }, + ], + name: "updateHostParams", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "paraId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + name: "vetoes", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "address", + name: "beneficiary", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + internalType: "bool", + name: "native", + type: "bool", + }, + ], + internalType: "struct WithdrawParams", + name: "params", + type: "tuple", + }, + ], + name: "withdraw", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + stateMutability: "payable", + type: "receive", + }, +] as const diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/HandlerV1.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/HandlerV1.ts new file mode 100644 index 00000000..26495464 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/HandlerV1.ts @@ -0,0 +1,748 @@ +export const HandlerV1_ABI = [ + { + inputs: [], + name: "ChallengePeriodNotElapsed", + type: "error", + }, + { + inputs: [], + name: "ConsensusClientExpired", + type: "error", + }, + { + inputs: [], + name: "DuplicateMessage", + type: "error", + }, + { + inputs: [], + name: "HostFrozen", + type: "error", + }, + { + inputs: [], + name: "InvalidMessageDestination", + type: "error", + }, + { + inputs: [], + name: "InvalidProof", + type: "error", + }, + { + inputs: [], + name: "MessageNotTimedOut", + type: "error", + }, + { + inputs: [], + name: "MessageTimedOut", + type: "error", + }, + { + inputs: [], + name: "StateCommitmentNotFound", + type: "error", + }, + { + inputs: [], + name: "UnknownMessage", + type: "error", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + internalType: "bytes", + name: "proof", + type: "bytes", + }, + ], + name: "handleConsensus", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest[]", + name: "timeouts", + type: "tuple[]", + }, + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "bytes[]", + name: "proof", + type: "bytes[]", + }, + ], + internalType: "struct GetTimeoutMessage", + name: "message", + type: "tuple", + }, + ], + name: "handleGetRequestTimeouts", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "bytes32[]", + name: "multiproof", + type: "bytes32[]", + }, + { + internalType: "uint256", + name: "leafCount", + type: "uint256", + }, + ], + internalType: "struct Proof", + name: "proof", + type: "tuple", + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest", + name: "request", + type: "tuple", + }, + { + components: [ + { + internalType: "bytes", + name: "key", + type: "bytes", + }, + { + internalType: "bytes", + name: "value", + type: "bytes", + }, + ], + internalType: "struct StorageValue[]", + name: "values", + type: "tuple[]", + }, + ], + internalType: "struct GetResponse", + name: "response", + type: "tuple", + }, + { + internalType: "uint256", + name: "index", + type: "uint256", + }, + { + internalType: "uint256", + name: "kIndex", + type: "uint256", + }, + ], + internalType: "struct GetResponseLeaf[]", + name: "responses", + type: "tuple[]", + }, + ], + internalType: "struct GetResponseMessage", + name: "message", + type: "tuple", + }, + ], + name: "handleGetResponses", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest[]", + name: "timeouts", + type: "tuple[]", + }, + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "bytes[]", + name: "proof", + type: "bytes[]", + }, + ], + internalType: "struct PostRequestTimeoutMessage", + name: "message", + type: "tuple", + }, + ], + name: "handlePostRequestTimeouts", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "bytes32[]", + name: "multiproof", + type: "bytes32[]", + }, + { + internalType: "uint256", + name: "leafCount", + type: "uint256", + }, + ], + internalType: "struct Proof", + name: "proof", + type: "tuple", + }, + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "uint256", + name: "index", + type: "uint256", + }, + { + internalType: "uint256", + name: "kIndex", + type: "uint256", + }, + ], + internalType: "struct PostRequestLeaf[]", + name: "requests", + type: "tuple[]", + }, + ], + internalType: "struct PostRequestMessage", + name: "request", + type: "tuple", + }, + ], + name: "handlePostRequests", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse[]", + name: "timeouts", + type: "tuple[]", + }, + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "bytes[]", + name: "proof", + type: "bytes[]", + }, + ], + internalType: "struct PostResponseTimeoutMessage", + name: "message", + type: "tuple", + }, + ], + name: "handlePostResponseTimeouts", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "bytes32[]", + name: "multiproof", + type: "bytes32[]", + }, + { + internalType: "uint256", + name: "leafCount", + type: "uint256", + }, + ], + internalType: "struct Proof", + name: "proof", + type: "tuple", + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse", + name: "response", + type: "tuple", + }, + { + internalType: "uint256", + name: "index", + type: "uint256", + }, + { + internalType: "uint256", + name: "kIndex", + type: "uint256", + }, + ], + internalType: "struct PostResponseLeaf[]", + name: "responses", + type: "tuple[]", + }, + ], + internalType: "struct PostResponseMessage", + name: "response", + type: "tuple", + }, + ], + name: "handlePostResponses", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes4", + name: "interfaceId", + type: "bytes4", + }, + ], + name: "supportsInterface", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, +] as const diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/IntentGateway.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/IntentGateway.ts new file mode 100644 index 00000000..3e1b9903 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/IntentGateway.ts @@ -0,0 +1,1440 @@ +export const INTENT_GATEWAY_ABI = [ + { + inputs: [ + { + internalType: "address", + name: "admin", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [], + name: "Expired", + type: "error", + }, + { + inputs: [], + name: "Filled", + type: "error", + }, + { + inputs: [], + name: "InsufficientNativeToken", + type: "error", + }, + { + inputs: [], + name: "InvalidInput", + type: "error", + }, + { + inputs: [], + name: "NotExpired", + type: "error", + }, + { + inputs: [], + name: "Unauthorized", + type: "error", + }, + { + inputs: [], + name: "UnauthorizedCall", + type: "error", + }, + { + inputs: [], + name: "UnexpectedCall", + type: "error", + }, + { + inputs: [], + name: "UnknownOrder", + type: "error", + }, + { + inputs: [], + name: "WrongChain", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "EscrowRefunded", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "EscrowReleased", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "bytes", + name: "stateMachineId", + type: "bytes", + }, + { + indexed: false, + internalType: "bytes32", + name: "gateway", + type: "bytes32", + }, + ], + name: "NewDeploymentAdded", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "address", + name: "filler", + type: "address", + }, + ], + name: "OrderFilled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "bytes32", + name: "user", + type: "bytes32", + }, + { + indexed: false, + internalType: "bytes", + name: "sourceChain", + type: "bytes", + }, + { + indexed: false, + internalType: "bytes", + name: "destChain", + type: "bytes", + }, + { + indexed: false, + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "fees", + type: "uint256", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + internalType: "bytes32", + name: "beneficiary", + type: "bytes32", + }, + ], + indexed: false, + internalType: "struct PaymentInfo[]", + name: "outputs", + type: "tuple[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + indexed: false, + internalType: "struct TokenInfo[]", + name: "inputs", + type: "tuple[]", + }, + { + indexed: false, + internalType: "bytes", + name: "callData", + type: "bytes", + }, + ], + name: "OrderPlaced", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + components: [ + { + internalType: "address", + name: "host", + type: "address", + }, + { + internalType: "address", + name: "dispatcher", + type: "address", + }, + ], + indexed: false, + internalType: "struct Params", + name: "previous", + type: "tuple", + }, + { + components: [ + { + internalType: "address", + name: "host", + type: "address", + }, + { + internalType: "address", + name: "dispatcher", + type: "address", + }, + ], + indexed: false, + internalType: "struct Params", + name: "current", + type: "tuple", + }, + ], + name: "ParamsUpdated", + type: "event", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "calculateCommitmentSlotHash", + outputs: [ + { + internalType: "bytes", + name: "", + type: "bytes", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes32", + name: "user", + type: "bytes32", + }, + { + internalType: "bytes", + name: "sourceChain", + type: "bytes", + }, + { + internalType: "bytes", + name: "destChain", + type: "bytes", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + internalType: "uint256", + name: "fees", + type: "uint256", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + internalType: "bytes32", + name: "beneficiary", + type: "bytes32", + }, + ], + internalType: "struct PaymentInfo[]", + name: "outputs", + type: "tuple[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct TokenInfo[]", + name: "inputs", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "callData", + type: "bytes", + }, + ], + internalType: "struct Order", + name: "order", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "relayerFee", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct CancelOptions", + name: "options", + type: "tuple", + }, + ], + name: "cancelOrder", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes32", + name: "user", + type: "bytes32", + }, + { + internalType: "bytes", + name: "sourceChain", + type: "bytes", + }, + { + internalType: "bytes", + name: "destChain", + type: "bytes", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + internalType: "uint256", + name: "fees", + type: "uint256", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + internalType: "bytes32", + name: "beneficiary", + type: "bytes32", + }, + ], + internalType: "struct PaymentInfo[]", + name: "outputs", + type: "tuple[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct TokenInfo[]", + name: "inputs", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "callData", + type: "bytes", + }, + ], + internalType: "struct Order", + name: "order", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "relayerFee", + type: "uint256", + }, + ], + internalType: "struct FillOptions", + name: "options", + type: "tuple", + }, + ], + name: "fillOrder", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [], + name: "host", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "stateMachineId", + type: "bytes", + }, + ], + name: "instance", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + internalType: "struct IncomingPostRequest", + name: "incoming", + type: "tuple", + }, + ], + name: "onAccept", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest", + name: "request", + type: "tuple", + }, + { + components: [ + { + internalType: "bytes", + name: "key", + type: "bytes", + }, + { + internalType: "bytes", + name: "value", + type: "bytes", + }, + ], + internalType: "struct StorageValue[]", + name: "values", + type: "tuple[]", + }, + ], + internalType: "struct GetResponse", + name: "response", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + internalType: "struct IncomingGetResponse", + name: "incoming", + type: "tuple", + }, + ], + name: "onGetResponse", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest", + name: "", + type: "tuple", + }, + ], + name: "onGetTimeout", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "", + type: "tuple", + }, + ], + name: "onPostRequestTimeout", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse", + name: "response", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + internalType: "struct IncomingPostResponse", + name: "", + type: "tuple", + }, + ], + name: "onPostResponse", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse", + name: "", + type: "tuple", + }, + ], + name: "onPostResponseTimeout", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "params", + outputs: [ + { + components: [ + { + internalType: "address", + name: "host", + type: "address", + }, + { + internalType: "address", + name: "dispatcher", + type: "address", + }, + ], + internalType: "struct Params", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes32", + name: "user", + type: "bytes32", + }, + { + internalType: "bytes", + name: "sourceChain", + type: "bytes", + }, + { + internalType: "bytes", + name: "destChain", + type: "bytes", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + internalType: "uint256", + name: "fees", + type: "uint256", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + internalType: "bytes32", + name: "beneficiary", + type: "bytes32", + }, + ], + internalType: "struct PaymentInfo[]", + name: "outputs", + type: "tuple[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct TokenInfo[]", + name: "inputs", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "callData", + type: "bytes", + }, + ], + internalType: "struct Order", + name: "order", + type: "tuple", + }, + { + internalType: "bytes32", + name: "graffiti", + type: "bytes32", + }, + ], + name: "placeOrder", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "payer", + type: "address", + }, + ], + internalType: "struct DispatchPost", + name: "request", + type: "tuple", + }, + ], + name: "quote", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct DispatchGet", + name: "request", + type: "tuple", + }, + ], + name: "quote", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "payer", + type: "address", + }, + ], + internalType: "struct DispatchPostResponse", + name: "response", + type: "tuple", + }, + ], + name: "quote", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "payer", + type: "address", + }, + ], + internalType: "struct DispatchPost", + name: "request", + type: "tuple", + }, + ], + name: "quoteNative", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "payer", + type: "address", + }, + ], + internalType: "struct DispatchPostResponse", + name: "request", + type: "tuple", + }, + ], + name: "quoteNative", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct DispatchGet", + name: "request", + type: "tuple", + }, + ], + name: "quoteNative", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "address", + name: "host", + type: "address", + }, + { + internalType: "address", + name: "dispatcher", + type: "address", + }, + ], + internalType: "struct Params", + name: "p", + type: "tuple", + }, + ], + name: "setParams", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + stateMutability: "payable", + type: "receive", + }, +] as const diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/UniswapRouterV2.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/UniswapRouterV2.ts new file mode 100644 index 00000000..d22ed2a9 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/abis/UniswapRouterV2.ts @@ -0,0 +1,953 @@ +export const UNISWAP_ROUTER_V2_ABI = [ + { + inputs: [], + name: "WETH", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "tokenA", + type: "address", + }, + { + internalType: "address", + name: "tokenB", + type: "address", + }, + { + internalType: "uint256", + name: "amountADesired", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountBDesired", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountAMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountBMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "addLiquidity", + outputs: [ + { + internalType: "uint256", + name: "amountA", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountB", + type: "uint256", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "token", + type: "address", + }, + { + internalType: "uint256", + name: "amountTokenDesired", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountTokenMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETHMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "addLiquidityETH", + outputs: [ + { + internalType: "uint256", + name: "amountToken", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [], + name: "factory", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + { + internalType: "uint256", + name: "reserveIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "reserveOut", + type: "uint256", + }, + ], + name: "getAmountIn", + outputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "reserveIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "reserveOut", + type: "uint256", + }, + ], + name: "getAmountOut", + outputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + ], + name: "getAmountsIn", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + ], + name: "getAmountsOut", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountA", + type: "uint256", + }, + { + internalType: "uint256", + name: "reserveA", + type: "uint256", + }, + { + internalType: "uint256", + name: "reserveB", + type: "uint256", + }, + ], + name: "quote", + outputs: [ + { + internalType: "uint256", + name: "amountB", + type: "uint256", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "tokenA", + type: "address", + }, + { + internalType: "address", + name: "tokenB", + type: "address", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountAMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountBMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "removeLiquidity", + outputs: [ + { + internalType: "uint256", + name: "amountA", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountB", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "token", + type: "address", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountTokenMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETHMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "removeLiquidityETH", + outputs: [ + { + internalType: "uint256", + name: "amountToken", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETH", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "token", + type: "address", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountTokenMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETHMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "removeLiquidityETHSupportingFeeOnTransferTokens", + outputs: [ + { + internalType: "uint256", + name: "amountETH", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "token", + type: "address", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountTokenMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETHMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + internalType: "bool", + name: "approveMax", + type: "bool", + }, + { + internalType: "uint8", + name: "v", + type: "uint8", + }, + { + internalType: "bytes32", + name: "r", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "s", + type: "bytes32", + }, + ], + name: "removeLiquidityETHWithPermit", + outputs: [ + { + internalType: "uint256", + name: "amountToken", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETH", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "token", + type: "address", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountTokenMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETHMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + internalType: "bool", + name: "approveMax", + type: "bool", + }, + { + internalType: "uint8", + name: "v", + type: "uint8", + }, + { + internalType: "bytes32", + name: "r", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "s", + type: "bytes32", + }, + ], + name: "removeLiquidityETHWithPermitSupportingFeeOnTransferTokens", + outputs: [ + { + internalType: "uint256", + name: "amountETH", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "tokenA", + type: "address", + }, + { + internalType: "address", + name: "tokenB", + type: "address", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountAMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountBMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + internalType: "bool", + name: "approveMax", + type: "bool", + }, + { + internalType: "uint8", + name: "v", + type: "uint8", + }, + { + internalType: "bytes32", + name: "r", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "s", + type: "bytes32", + }, + ], + name: "removeLiquidityWithPermit", + outputs: [ + { + internalType: "uint256", + name: "amountA", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountB", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapETHForExactTokens", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOutMin", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapExactETHForTokens", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOutMin", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapExactETHForTokensSupportingFeeOnTransferTokens", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountOutMin", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapExactTokensForETH", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountOutMin", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapExactTokensForETHSupportingFeeOnTransferTokens", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountOutMin", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapExactTokensForTokens", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountOutMin", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapExactTokensForTokensSupportingFeeOnTransferTokens", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountInMax", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapTokensForExactETH", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountInMax", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapTokensForExactTokens", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, +] as const diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/confirmation-policy.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/confirmation-policy.ts new file mode 100644 index 00000000..3a39408c --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/config/confirmation-policy.ts @@ -0,0 +1,58 @@ +import Decimal from "decimal.js" + +export class ConfirmationPolicy { + // Maps chainId -> policy configuration + private policies: Map< + number, + { + minAmount: number + maxAmount: number + minConfirmations: number + maxConfirmations: number + } + > + + constructor( + policyConfig: Record< + string, + { + minAmount: string + maxAmount: string + minConfirmations: number + maxConfirmations: number + } + >, + ) { + this.policies = new Map() + + Object.entries(policyConfig).forEach(([chainId, config]) => { + this.policies.set(Number(chainId), { + minAmount: parseFloat(config.minAmount), + maxAmount: parseFloat(config.maxAmount), + minConfirmations: config.minConfirmations, + maxConfirmations: config.maxConfirmations, + }) + }) + } + + getConfirmationBlocks(chainId: number, amountUsd: Decimal): number { + const chainPolicy = this.policies.get(chainId) + if (!chainPolicy) throw new Error(`No confirmation policy found for chainId ${chainId}`) + + if (amountUsd.lte(chainPolicy.minAmount)) { + return chainPolicy.minConfirmations + } + + if (amountUsd.gte(chainPolicy.maxAmount)) { + return chainPolicy.maxConfirmations + } + + const amountRange = chainPolicy.maxAmount - chainPolicy.minAmount + const confirmationRange = chainPolicy.maxConfirmations - chainPolicy.minConfirmations + const amountPosition = amountUsd.minus(chainPolicy.minAmount) + + const confirmationPosition = amountPosition.times(confirmationRange).div(amountRange) + + return chainPolicy.minConfirmations + Math.round(confirmationPosition.toNumber()) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/core/event-monitor.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/core/event-monitor.ts new file mode 100644 index 00000000..ce114f63 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/core/event-monitor.ts @@ -0,0 +1,191 @@ +import { EventEmitter } from "events" +import { ChainConfig, Order, orderCommitment, hexToString, DecodedOrderPlacedLog } from "@hyperbridge/sdk" +import { INTENT_GATEWAY_ABI } from "@/config/abis/IntentGateway" +import { PublicClient } from "viem" +import { ChainClientManager } from "@/services" +import { FillerConfigService } from "@/services/FillerConfigService" +import { getLogger } from "@/services/Logger" +import { Mutex } from "async-mutex" + +export class EventMonitor extends EventEmitter { + private clients: Map = new Map() + private listening: boolean = false + private clientManager: ChainClientManager + private configService: FillerConfigService + private logger = getLogger("event-monitor") + private lastScannedBlock: Map = new Map() + private blockScanIntervals: Map = new Map() + private scanningMutexes: Map = new Map() + + constructor(chainConfigs: ChainConfig[], configService: FillerConfigService, clientManager: ChainClientManager) { + super() + this.configService = configService + this.clientManager = clientManager + + chainConfigs.forEach((config) => { + const chainName = `EVM-${config.chainId}` + const client = this.clientManager.getPublicClient(chainName) + this.clients.set(config.chainId, client) + this.scanningMutexes.set(config.chainId, new Mutex()) + }) + } + + public async startListening(): Promise { + if (this.listening) return + this.listening = true + + for (const [chainId, client] of this.clients.entries()) { + try { + const orderPlacedEvent = INTENT_GATEWAY_ABI.find( + (item) => item.type === "event" && item.name === "OrderPlaced", + ) + const intentGatewayAddress = this.configService.getIntentGatewayAddress(`EVM-${chainId}`) + + const startBlock = await client.getBlockNumber() + this.lastScannedBlock.set(chainId, startBlock - 1n) + + this.logger.info({ chainId, startBlock }, "Initializing block scanner") + + const scanInterval = setInterval(async () => { + const mutex = this.scanningMutexes.get(chainId) + if (!mutex) return + + if (mutex.isLocked()) { + this.logger.warn({ chainId }, "Waiting for previous scan to complete") + return + } + + await mutex.runExclusive(async () => { + try { + await this.scanBlocks(chainId, client, intentGatewayAddress, orderPlacedEvent) + } catch (error) { + this.logger.error({ chainId, err: error }, "Error in block scanner") + } + }) + }, 1000) + + this.blockScanIntervals.set(chainId, scanInterval) + + this.logger.info({ chainId }, "Started monitoring for new orders") + } catch (error) { + this.logger.error({ chainId, err: error }, "Failed to start block scanner") + } + } + } + + private async scanBlocks( + chainId: number, + client: PublicClient, + intentGatewayAddress: `0x${string}`, + orderPlacedEvent: any, + ): Promise { + const lastScanned = this.lastScannedBlock.get(chainId) + if (!lastScanned) return + + const currentBlock = await client.getBlockNumber() + + if (currentBlock > lastScanned) { + const fromBlock = lastScanned + 1n + const toBlock = currentBlock + + const maxBlockRange = 1000n + const actualToBlock = fromBlock + maxBlockRange > toBlock ? toBlock : fromBlock + maxBlockRange + + this.logger.debug( + { chainId, fromBlock, toBlock: actualToBlock, gap: Number(actualToBlock - fromBlock) }, + "Scanning blocks", + ) + + const logs = await client.getLogs({ + address: intentGatewayAddress, + event: orderPlacedEvent, + fromBlock, + toBlock: actualToBlock, + }) + + if (logs.length > 0) { + this.logger.info( + { chainId, fromBlock, toBlock: actualToBlock, eventCount: logs.length }, + "Found events in block scan", + ) + this.processLogs(logs) + } + + // Update lastScannedBlock only after successful processing + // This is protected by the mutex, so no race condition + this.lastScannedBlock.set(chainId, actualToBlock) + } + } + + private processLogs(logs: any[]): void { + for (const log of logs) { + try { + const decodedLog = log as unknown as DecodedOrderPlacedLog + const order: Order = { + id: orderCommitment({ + id: "", + user: decodedLog.args.user, + sourceChain: hexToString(decodedLog.args.sourceChain), + destChain: hexToString(decodedLog.args.destChain), + deadline: decodedLog.args.deadline, + nonce: decodedLog.args.nonce, + fees: decodedLog.args.fees, + outputs: decodedLog.args.outputs.map((output) => ({ + token: output.token, + amount: output.amount, + beneficiary: output.beneficiary, + })), + inputs: decodedLog.args.inputs.map((input) => ({ + token: input.token, + amount: input.amount, + })), + callData: decodedLog.args.callData, + transactionHash: decodedLog.transactionHash, + }), + user: decodedLog.args.user, + sourceChain: hexToString(decodedLog.args.sourceChain), + destChain: hexToString(decodedLog.args.destChain), + deadline: decodedLog.args.deadline, + nonce: decodedLog.args.nonce, + fees: decodedLog.args.fees, + outputs: decodedLog.args.outputs.map((output) => ({ + token: output.token, + amount: output.amount, + beneficiary: output.beneficiary, + })), + inputs: decodedLog.args.inputs.map((input) => ({ + token: input.token, + amount: input.amount, + })), + callData: decodedLog.args.callData, + transactionHash: decodedLog.transactionHash, + } + + this.logger.info({ orderId: order.id, txHash: order.transactionHash }, "New order detected") + this.emit("newOrder", { order }) + } catch (error) { + this.logger.error({ err: error, log }, "Error parsing event log") + } + } + } + + public async stopListening(): Promise { + this.listening = false + + for (const [chainId, interval] of this.blockScanIntervals.entries()) { + clearInterval(interval) + this.logger.info({ chainId }, "Stopped block scanner") + } + this.blockScanIntervals.clear() + + const mutexPromises = Array.from(this.scanningMutexes.values()).map((mutex) => + mutex.runExclusive(async () => { + // Empty function - just wait for any ongoing operations to complete + }), + ) + await Promise.allSettled(mutexPromises) + + this.scanningMutexes.clear() + this.lastScannedBlock.clear() + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/core/filler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/core/filler.ts new file mode 100644 index 00000000..5d1742a7 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/core/filler.ts @@ -0,0 +1,170 @@ +import { chainIds } from "@hyperbridge/sdk" +import { EventMonitor } from "./event-monitor" +import { FillerStrategy } from "@/strategies/base" +import { Order, FillerConfig, ChainConfig, DUMMY_PRIVATE_KEY, ADDRESS_ZERO, bytes20ToBytes32 } from "@hyperbridge/sdk" +import pQueue from "p-queue" +import { ChainClientManager, ContractInteractionService } from "@/services" +import { FillerConfigService } from "@/services/FillerConfigService" +import { getLogger } from "@/services/Logger" + +import { PublicClient } from "viem" +import { generatePrivateKey } from "viem/accounts" + +export class IntentFiller { + public monitor: EventMonitor + private strategies: FillerStrategy[] + private chainQueues: Map + private globalQueue: pQueue + private chainClientManager: ChainClientManager + private contractService: ContractInteractionService + private config: FillerConfig + private configService: FillerConfigService + private logger = getLogger("intent-filler") + + constructor( + chainConfigs: ChainConfig[], + strategies: FillerStrategy[], + config: FillerConfig, + configService: FillerConfigService, + ) { + this.configService = configService + this.chainClientManager = new ChainClientManager(configService) + this.monitor = new EventMonitor(chainConfigs, configService, this.chainClientManager) + this.strategies = strategies + this.config = config + + this.contractService = new ContractInteractionService( + this.chainClientManager, + generatePrivateKey(), + configService, + ) + this.chainQueues = new Map() + chainConfigs.forEach((chainConfig) => { + // 1 order per chain at a time due to EVM constraints + this.chainQueues.set(chainConfig.chainId, new pQueue({ concurrency: 1 })) + }) + + this.globalQueue = new pQueue({ + concurrency: config.maxConcurrentOrders || 5, + }) + + // Set up event handlers + this.monitor.on("newOrder", ({ order }) => { + this.handleNewOrder(order) + }) + } + + public start(): void { + this.monitor.startListening() + } + + public stop(): void { + this.monitor.stopListening() + + // Wait for all queues to complete + const promises = [] + this.chainQueues.forEach((queue) => { + promises.push(queue.onIdle()) + }) + promises.push(this.globalQueue.onIdle()) + + Promise.all(promises).then(() => { + this.logger.info("All orders processed, filler stopped") + }) + } + + // Operations + + private handleNewOrder(order: Order): void { + // Use the global queue for the initial analysis + // This can happen in parallel for PublicClient orders + this.globalQueue.add(async () => { + this.logger.info({ orderId: order.id }, "New order detected") + try { + const sourceClient = this.chainClientManager.getPublicClient(order.sourceChain) + const orderValue = await this.contractService.getTokenUsdValue(order) + let currentConfirmations = await sourceClient.getTransactionConfirmations({ + hash: order.transactionHash!, + }) + const requiredConfirmations = this.config.confirmationPolicy.getConfirmationBlocks( + chainIds[order.sourceChain as keyof typeof chainIds], + orderValue.inputUsdValue.toNumber(), + ) + this.logger.info( + { orderId: order.id, requiredConfirmations, currentConfirmations }, + "Order confirmation requirements", + ) + + while (currentConfirmations < requiredConfirmations) { + await new Promise((resolve) => setTimeout(resolve, 300)) // Wait 300ms + currentConfirmations = await sourceClient.getTransactionConfirmations({ + hash: order.transactionHash!, + }) + this.logger.debug({ orderId: order.id, currentConfirmations }, "Order confirmation progress") + } + + this.logger.info({ orderId: order.id, currentConfirmations }, "Order confirmed on source chain") + + this.evaluateAndExecuteOrder(order) + } catch (error) { + this.logger.error({ orderId: order.id, err: error }, "Error processing order") + } + }) + } + + private evaluateAndExecuteOrder(order: Order): void { + this.globalQueue.add(async () => { + try { + const eligibleStrategies = await Promise.all( + this.strategies.map(async (strategy) => { + const canFill = await strategy.canFill(order) + if (!canFill) return null + + const profitability = await strategy.calculateProfitability(order) + return { strategy, profitability } + }), + ) + + const validStrategies = eligibleStrategies + .filter((s): s is NonNullable => s !== null && s.profitability > 0n) + .sort((a, b) => Number(b.profitability) - Number(a.profitability)) + + if (validStrategies.length === 0) { + this.logger.warn({ orderId: order.id }, "No profitable strategy found for order") + return + } + + // Get the chain-specific queue + const chainQueue = this.chainQueues.get(chainIds[order.destChain as keyof typeof chainIds]!) + if (!chainQueue) { + this.logger.error({ chain: order.destChain }, "No queue configured for chain") + return + } + + // Execute with the most profitable strategy using the chain-specific queue + // This ensures transactions for the same chain are processed sequentially + chainQueue.add(async () => { + const bestStrategy = validStrategies[0].strategy + this.logger.info( + { orderId: order.id, strategy: bestStrategy.name, chain: order.destChain }, + "Executing order", + ) + + try { + const result = await bestStrategy.executeOrder(order) + this.logger.info({ orderId: order.id, result }, "Order execution completed") + if (result.success) { + this.monitor.emit("orderFilled", { orderId: order.id, hash: result.txHash }) + } + return result + } catch (error) { + this.logger.error({ orderId: order.id, err: error }, "Order execution failed") + throw error + } + }) + } catch (error) { + this.logger.error({ orderId: order.id, err: error }, "Error processing order") + } + }) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/index.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/index.ts new file mode 100644 index 00000000..2ad2a662 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/index.ts @@ -0,0 +1,14 @@ +export const version = "0.1.0" + +// Core exports +export { IntentFiller } from "./core/filler" +export { EventMonitor } from "./core/event-monitor" + +// Strategy exports +export { BasicFiller } from "./strategies/basic" + +// Configuration exports +export { ConfirmationPolicy } from "./config/confirmation-policy" + +// Service exports +export { ChainClientManager, ContractInteractionService } from "./services" diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/CacheService.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/CacheService.ts new file mode 100644 index 00000000..865bd409 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/CacheService.ts @@ -0,0 +1,226 @@ +import { HexString } from "@hyperbridge/sdk" +import { getLogger } from "./Logger" + +interface GasEstimateCache { + fillGas: string + postGas: string + relayerFeeInFeeToken: string + relayerFeeInNativeToken: string + timestamp: number +} + +interface SwapCall { + to: string + data: string + value: string +} + +interface SwapOperationsCache { + calls: SwapCall[] + totalGasEstimate: string + timestamp: number +} + +interface CacheData { + gasEstimates: Record + swapOperations: Record + feeTokens: Record + perByteFees: Record> + tokenDecimals: Record> +} + +export class CacheService { + private cacheData: CacheData + private readonly CACHE_EXPIRY_MS = 1 * 60 * 1000 // 1 minute + private logger = getLogger("cache-service") + + constructor() { + this.cacheData = { gasEstimates: {}, swapOperations: {}, feeTokens: {}, perByteFees: {}, tokenDecimals: {} } + } + + private isCacheValid(timestamp: number): boolean { + return Date.now() - timestamp < this.CACHE_EXPIRY_MS + } + + private cleanupStaleData(): void { + // Clean up gas estimates + const staleGasEstimateIds = Object.entries(this.cacheData.gasEstimates) + .filter(([_, data]) => !this.isCacheValid(data.timestamp)) + .map(([orderId]) => orderId) + + staleGasEstimateIds.forEach((orderId) => { + delete this.cacheData.gasEstimates[orderId] + }) + + // Clean up swap operations + const staleSwapOperationIds = Object.entries(this.cacheData.swapOperations) + .filter(([_, data]) => !this.isCacheValid(data.timestamp)) + .map(([orderId]) => orderId) + + staleSwapOperationIds.forEach((orderId) => { + delete this.cacheData.swapOperations[orderId] + }) + } + + getGasEstimate( + orderId: string, + ): { fillGas: bigint; postGas: bigint; relayerFeeInFeeToken: bigint; relayerFeeInNativeToken: bigint } | null { + try { + const cache = this.cacheData.gasEstimates[orderId] + if (cache && this.isCacheValid(cache.timestamp)) { + return { + fillGas: BigInt(cache.fillGas), + postGas: BigInt(cache.postGas), + relayerFeeInFeeToken: BigInt(cache.relayerFeeInFeeToken), + relayerFeeInNativeToken: BigInt(cache.relayerFeeInNativeToken), + } + } + return null + } catch (error) { + this.logger.error({ err: error }, "Error getting gas estimate") + return null + } + } + + setGasEstimate( + orderId: string, + fillGas: bigint, + postGas: bigint, + relayerFeeInFeeToken: bigint, + relayerFeeInNativeToken: bigint, + ): void { + if (fillGas <= 0n || postGas <= 0n) { + throw new Error("Gas values must be positive") + } + try { + this.cleanupStaleData() + this.cacheData.gasEstimates[orderId] = { + fillGas: fillGas.toString(), + postGas: postGas.toString(), + relayerFeeInFeeToken: relayerFeeInFeeToken.toString(), + relayerFeeInNativeToken: relayerFeeInNativeToken.toString(), + timestamp: Date.now(), + } + } catch (error) { + this.logger.error({ err: error }, "Error setting gas estimate") + throw error + } + } + + getSwapOperations(orderId: string): { calls: SwapCall[]; totalGasEstimate: bigint } | null { + try { + const cache = this.cacheData.swapOperations[orderId] + if (cache && this.isCacheValid(cache.timestamp)) { + return { + calls: cache.calls, + totalGasEstimate: BigInt(cache.totalGasEstimate), + } + } + return null + } catch (error) { + this.logger.error({ err: error }, "Error getting swap operations") + return null + } + } + + setSwapOperations(orderId: string, calls: SwapCall[], totalGasEstimate: bigint): void { + try { + this.cleanupStaleData() + this.cacheData.swapOperations[orderId] = { + calls, + totalGasEstimate: totalGasEstimate.toString(), + timestamp: Date.now(), + } + } catch (error) { + this.logger.error({ err: error }, "Error setting swap operations") + throw error + } + } + + getFeeTokenWithDecimals(chain: string): { address: HexString; decimals: number } | null { + try { + const cache = this.cacheData.feeTokens[chain] + if (cache) { + return { + address: cache.address, + decimals: cache.decimals, + } + } + return null + } catch (error) { + this.logger.error({ err: error }, "Error getting fee token with decimals") + return null + } + } + + setFeeTokenWithDecimals(chain: string, address: HexString, decimals: number): void { + try { + this.cleanupStaleData() + + if (!this.cacheData.feeTokens[chain]) { + this.cacheData.feeTokens[chain] = { address, decimals } + } else { + this.cacheData.feeTokens[chain] = { address, decimals } + } + } catch (error) { + this.logger.error({ chain: chain, err: error }, "Error setting fee token with decimals") + throw error + } + } + + getPerByteFee(sourceChain: string, destChain: string): bigint | null { + try { + const sourceMap = this.cacheData.perByteFees[sourceChain] + if (sourceMap && sourceMap[destChain]) { + return sourceMap[destChain] + } + return null + } catch (error) { + this.logger.error({ err: error }, "Error getting per byte fee") + return null + } + } + + setPerByteFee(sourceChain: string, destChain: string, perByteFee: bigint): void { + try { + this.cleanupStaleData() + + if (!this.cacheData.perByteFees[sourceChain]) { + this.cacheData.perByteFees[sourceChain] = {} + } + this.cacheData.perByteFees[sourceChain][destChain] = perByteFee + } catch (error) { + this.logger.error( + { sourceChain: sourceChain, destChain: destChain, err: error }, + "Error setting per byte fee", + ) + throw error + } + } + + getTokenDecimals(chain: string, tokenAddress: HexString): number | null { + try { + const chainCache = this.cacheData.tokenDecimals[chain] + if (chainCache && chainCache[tokenAddress]) { + return chainCache[tokenAddress] + } + return null + } catch { + return null + } + } + + setTokenDecimals(chain: string, tokenAddress: HexString, decimals: number): void { + try { + this.cleanupStaleData() + // Ensure the chain object exists before setting the token decimals + if (!this.cacheData.tokenDecimals[chain]) { + this.cacheData.tokenDecimals[chain] = {} + } + this.cacheData.tokenDecimals[chain][tokenAddress] = decimals + } catch (error) { + this.logger.error({ chain: chain, tokenAddress: tokenAddress, err: error }, "Error setting token decimals") + throw error + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/ChainClientManager.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/ChainClientManager.ts new file mode 100644 index 00000000..3ffb17e5 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/ChainClientManager.ts @@ -0,0 +1,93 @@ +import { PublicClient, WalletClient, createPublicClient, createWalletClient, http, type Chain } from "viem" +import { generatePrivateKey, privateKeyToAccount } from "viem/accounts" +import { Order, HexString, ChainConfig } from "@hyperbridge/sdk" +import { viemChains } from "@hyperbridge/sdk" +import { FillerConfigService } from "./FillerConfigService" + +/** + * Factory for creating and managing Viem clients + */ +export class ViemClientFactory { + private publicClients: Map = new Map() + private walletClients: Map = new Map() + + public getPublicClient(chainConfig: ChainConfig): PublicClient { + if (!this.publicClients.has(chainConfig.chainId)) { + const chain = viemChains[chainConfig.chainId] as Chain + + const publicClient = createPublicClient({ + chain, + transport: http(chainConfig.rpcUrl, { + timeout: 30000, // 30 seconds + retryCount: 3, + retryDelay: 1000, + }), + }) + + this.publicClients.set(chainConfig.chainId, publicClient) + } + + return this.publicClients.get(chainConfig.chainId)! + } + + public getWalletClient(chainConfig: ChainConfig, privateKey: string): WalletClient { + if (!this.walletClients.has(chainConfig.chainId)) { + const chain = viemChains[chainConfig.chainId] as Chain + const account = privateKeyToAccount(privateKey as `0x${string}`) + + const walletClient = createWalletClient({ + chain, + account, + transport: http(chainConfig.rpcUrl, { + timeout: 30000, + retryCount: 3, + retryDelay: 1000, + }), + }) + + this.walletClients.set(chainConfig.chainId, walletClient) + } + + return this.walletClients.get(chainConfig.chainId)! + } +} + +// Create a singleton instance of the factory +export const viemClientFactory = new ViemClientFactory() + +/** + * Manages chain clients for different operations + */ +export class ChainClientManager { + private privateKey: HexString + private configService: FillerConfigService + private clientFactory: ViemClientFactory + + constructor(configService: FillerConfigService, privateKey?: HexString) { + this.privateKey = privateKey || generatePrivateKey() + this.configService = configService + this.clientFactory = viemClientFactory + } + + getPublicClient(chain: string): PublicClient { + const config = this.configService.getChainConfig(chain) + return this.clientFactory.getPublicClient(config) + } + + getWalletClient(chain: string): WalletClient { + const config = this.configService.getChainConfig(chain) + return this.clientFactory.getWalletClient(config, this.privateKey) + } + + getClientsForOrder(order: Order): { + destClient: PublicClient + sourceClient: PublicClient + walletClient: WalletClient + } { + return { + destClient: this.getPublicClient(order.destChain), + sourceClient: this.getPublicClient(order.sourceChain), + walletClient: this.getWalletClient(order.destChain), + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/ContractInteractionService.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/ContractInteractionService.ts new file mode 100644 index 00000000..74c16c34 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/ContractInteractionService.ts @@ -0,0 +1,936 @@ +import { getContract, toHex, encodePacked, keccak256, maxUint256, formatUnits, parseUnits } from "viem" +import { privateKeyToAccount, privateKeyToAddress } from "viem/accounts" +import { + ADDRESS_ZERO, + Order, + PaymentInfo, + HexString, + FillOptions, + DispatchPost, + bytes32ToBytes20, + bytes20ToBytes32, + estimateGasForPost, + constructRedeemEscrowRequestBody, + IPostRequest, + getStorageSlot, + ERC20Method, + fetchPrice, + maxBigInt, + getGasPriceFromEtherscan, + USE_ETHERSCAN_CHAINS, + retryPromise, +} from "@hyperbridge/sdk" +import { ERC20_ABI } from "@/config/abis/ERC20" +import { ChainClientManager } from "./ChainClientManager" +import { FillerConfigService } from "./FillerConfigService" +import { INTENT_GATEWAY_ABI } from "@/config/abis/IntentGateway" +import { EVM_HOST } from "@/config/abis/EvmHost" +import { orderCommitment } from "@hyperbridge/sdk" +import { ApiPromise, WsProvider } from "@polkadot/api" +import { keccakAsU8a } from "@polkadot/util-crypto" +import { CacheService } from "./CacheService" +import { UNISWAP_ROUTER_V2_ABI } from "@/config/abis/UniswapRouterV2" +import { getLogger } from "@/services/Logger" +import { Decimal } from "decimal.js" + +// Configure for financial precision +Decimal.config({ precision: 28, rounding: 4 }) +/** + * Handles contract interactions for tokens and other contracts + */ +export class ContractInteractionService { + private configService: FillerConfigService + private api: ApiPromise | null = null + public cacheService: CacheService + private logger = getLogger("contract-service") + + constructor( + private clientManager: ChainClientManager, + private privateKey: HexString, + configService: FillerConfigService, + ) { + this.configService = configService + this.cacheService = new CacheService() + this.initCache() + } + + async initCache(): Promise { + const chainIds = this.configService.getConfiguredChainIds() + const chainNames = chainIds.map((id) => `EVM-${id}`) + for (const chainName of chainNames) { + await this.getFeeTokenWithDecimals(chainName) + } + + for (const destChain of chainNames) { + const destClient = this.clientManager.getPublicClient(destChain) + const usdc = this.configService.getUsdcAsset(destChain) + const usdt = this.configService.getUsdtAsset(destChain) + await this.getTokenDecimals(usdc, destChain) + await this.getTokenDecimals(usdt, destChain) + for (const sourceChain of chainNames) { + if (sourceChain === destChain) continue + const perByteFee = await destClient.readContract({ + address: this.configService.getHostAddress(destChain), + abi: EVM_HOST, + functionName: "perByteFee", + args: [toHex(sourceChain)], + }) + this.cacheService.setPerByteFee(destChain, sourceChain, perByteFee) + } + } + } + + /** + * Gets the balance of a token for a wallet + */ + async getTokenBalance(tokenAddress: string, walletAddress: string, chain: string): Promise { + const client = this.clientManager.getPublicClient(chain) + + if (tokenAddress === ADDRESS_ZERO) { + return await client.getBalance({ address: walletAddress as HexString }) + } + + const tokenContract = getContract({ + address: tokenAddress as HexString, + abi: ERC20_ABI, + client, + }) + + const balance = await tokenContract.read.balanceOf([walletAddress as HexString]) + + return balance + } + + /** + * Gets the decimals for a token + */ + async getTokenDecimals(tokenAddress: string, chain: string): Promise { + const bytes20Address = tokenAddress.length === 66 ? bytes32ToBytes20(tokenAddress) : tokenAddress + + if (bytes20Address === ADDRESS_ZERO) { + return 18 // Native token (ETH, MATIC, etc.) + } + + const cachedTokenDecimals = this.cacheService.getTokenDecimals(chain, bytes20Address as HexString) + if (cachedTokenDecimals) { + return cachedTokenDecimals + } + + const client = this.clientManager.getPublicClient(chain) + + try { + const decimals = await client.readContract({ + address: bytes20Address as HexString, + abi: ERC20_ABI, + functionName: "decimals", + }) + + this.cacheService.setTokenDecimals(chain, bytes20Address as HexString, decimals) + return decimals + } catch (error) { + this.logger.warn({ err: error }, "Error getting token decimals, defaulting to 18") + return 18 // Default to 18 if we can't determine + } + } + + /** + * Checks if we have sufficient token balances to fill the order + */ + async checkTokenBalances(outputs: PaymentInfo[], destChain: string): Promise { + try { + let totalNativeTokenNeeded = BigInt(0) + const fillerWalletAddress = privateKeyToAddress(this.privateKey) + const destClient = this.clientManager.getPublicClient(destChain) + + // Check all token balances + for (const output of outputs) { + const tokenAddress = bytes32ToBytes20(output.token) + const amount = output.amount + + if (tokenAddress === ADDRESS_ZERO) { + // Native token + totalNativeTokenNeeded = totalNativeTokenNeeded + amount + } else { + // ERC20 token + const balance = await this.getTokenBalance(tokenAddress, fillerWalletAddress, destChain) + + if (balance < amount) { + this.logger.debug( + { tokenAddress, balance: balance.toString(), need: amount.toString() }, + "Insufficient token balance", + ) + return false + } + } + } + + // Check if we have enough native token + if (totalNativeTokenNeeded > 0n) { + const nativeBalance = await destClient.getBalance({ address: fillerWalletAddress }) + + if (BigInt(nativeBalance.toString()) < totalNativeTokenNeeded) { + this.logger.debug( + { have: nativeBalance.toString(), need: totalNativeTokenNeeded.toString() }, + "Insufficient native token balance", + ) + return false + } + } + + return true + } catch (error) { + this.logger.error({ err: error }, "Error checking token balances") + return false + } + } + + /** + * Approves ERC20 tokens for the contract if needed + */ + async approveTokensIfNeeded(order: Order): Promise { + const wallet = privateKeyToAccount(this.privateKey) + const destClient = this.clientManager.getPublicClient(order.destChain) + const walletClient = this.clientManager.getWalletClient(order.destChain) + const intentGateway = this.configService.getIntentGatewayAddress(order.destChain) + + const tokens = [ + ...new Set(order.outputs.map((o) => bytes32ToBytes20(o.token)).filter((addr) => addr !== ADDRESS_ZERO)), + (await this.getFeeTokenWithDecimals(order.destChain)).address, + ].map((address) => ({ + address, + amount: order.outputs.find((o) => bytes32ToBytes20(o.token) === address)?.amount || maxUint256 / 2n, + })) + + for (const token of tokens) { + const allowance = await destClient.readContract({ + abi: ERC20_ABI, + address: token.address as HexString, + functionName: "allowance", + args: [wallet.address, intentGateway], + }) + + if (allowance < token.amount) { + this.logger.info({ token: token.address }, "Approving token") + const etherscanApiKey = this.configService.getEtherscanApiKey() + const chain = order.destChain + const useEtherscan = USE_ETHERSCAN_CHAINS.has(chain) + const gasPrice = + useEtherscan && etherscanApiKey + ? await retryPromise(() => getGasPriceFromEtherscan(order.destChain, etherscanApiKey), { + maxRetries: 3, + backoffMs: 250, + }).catch(async () => { + this.logger.warn( + { chain: order.destChain }, + "Error getting gas price from etherscan, using client's gas price", + ) + return await destClient.getGasPrice() + }) + : await destClient.getGasPrice() + const tx = await walletClient.writeContract({ + abi: ERC20_ABI, + address: token.address as HexString, + functionName: "approve", + args: [intentGateway, maxUint256], + account: wallet, + chain: walletClient.chain, + gasPrice: gasPrice + (gasPrice * 2000n) / 10000n, + }) + + await destClient.waitForTransactionReceipt({ hash: tx }) + this.logger.info({ token: token.address }, "Approved token") + } + } + } + + /** + * Calculates the ETH value to send with the transaction + */ + calculateRequiredEthValue(outputs: PaymentInfo[]): bigint { + let totalEthValue = 0n + + for (const output of outputs) { + const bytes20Address = bytes32ToBytes20(output.token) + if (bytes20Address === ADDRESS_ZERO) { + // Native token output + totalEthValue = totalEthValue + output.amount + } + } + + return totalEthValue + } + + /** + * Transforms the order object to match the contract's expected format + */ + transformOrderForContract(order: Order) { + return { + sourceChain: toHex(order.sourceChain), + destChain: toHex(order.destChain), + fees: order.fees, + callData: order.callData, + deadline: order.deadline, + nonce: order.nonce, + inputs: order.inputs.map((input) => ({ + token: input.token, + amount: input.amount, + })), + outputs: order.outputs.map((output) => ({ + token: output.token, + amount: output.amount, + beneficiary: output.beneficiary, + })), + user: order.user, + } + } + + /** + * Checks if an order is already filled by querying contract storage + */ + async checkIfOrderFilled(order: Order): Promise { + try { + const commitment = orderCommitment(order) + const sourceClient = this.clientManager.getPublicClient(order.sourceChain) + const intentGatewayAddress = this.configService.getIntentGatewayAddress(order.sourceChain) + + const mappingSlot = 5n + + const filledSlot = keccak256(encodePacked(["bytes32", "uint256"], [commitment, mappingSlot])) + + const filledStatus = await sourceClient.getStorageAt({ + address: intentGatewayAddress, + slot: filledSlot, + }) + return filledStatus !== "0x0000000000000000000000000000000000000000000000000000000000000000" + } catch (error) { + this.logger.error({ err: error, orderId: order.id }, "Error checking if order filled") + // Default to assuming it's not filled if we can't check + return false + } + } + + /** + * Estimates gas for filling an order + */ + async estimateGasFillPost( + order: Order, + ): Promise<{ fillGas: bigint; postGas: bigint; relayerFeeInFeeToken: bigint; relayerFeeInNativeToken: bigint }> { + try { + // Check cache first + const cachedEstimate = this.cacheService.getGasEstimate(order.id!) + if (cachedEstimate) { + this.logger.debug({ orderId: order.id }, "Using cached gas estimate for order") + return cachedEstimate + } + + const { sourceClient, destClient } = this.clientManager.getClientsForOrder(order) + const postRequest: IPostRequest = { + source: order.destChain, + dest: order.sourceChain, + body: constructRedeemEscrowRequestBody(order, privateKeyToAddress(this.privateKey)), + timeoutTimestamp: 0n, + nonce: await this.getHostNonce(order.sourceChain), + from: this.configService.getIntentGatewayAddress(order.destChain), + to: this.configService.getIntentGatewayAddress(order.sourceChain), + } + + let { gas_fee: postGasEstimate } = await estimateGasForPost({ + postRequest: postRequest, + sourceClient: sourceClient as any, + hostLatestStateMachineHeight: 6291991n, + hostAddress: this.configService.getHostAddress(order.sourceChain), + }) + + const { decimals: destFeeTokenDecimals } = await this.getFeeTokenWithDecimals(order.destChain) + + let postGasEstimateInDestFeeToken = await this.convertGasToFeeToken( + postGasEstimate, + order.sourceChain, + destFeeTokenDecimals, + ) + + const minRelayerFee = 5n * 10n ** BigInt(destFeeTokenDecimals - 2) + const postGasWithIncentive = postGasEstimateInDestFeeToken + (postGasEstimateInDestFeeToken * 1n) / 100n + postGasEstimateInDestFeeToken = maxBigInt(postGasWithIncentive, minRelayerFee) + + this.logger.debug( + { + orderId: order.id, + postGasWei: postGasEstimate.toString(), + postGasInDestFeeToken: postGasEstimateInDestFeeToken.toString(), + destFeeTokenDecimals, + }, + "Relayer fee estimates", + ) + + const fillOptions: FillOptions = { + relayerFee: postGasEstimateInDestFeeToken, + } + + const ethValue = this.calculateRequiredEthValue(order.outputs) + const userAddress = privateKeyToAddress(this.privateKey) + const testValue = toHex(maxUint256 / 2n) + const intentGatewayAddress = this.configService.getIntentGatewayAddress(order.destChain) + + const overrides = ( + await Promise.all( + order.outputs.map(async (output) => { + const tokenAddress = bytes32ToBytes20(output.token) + if (tokenAddress === ADDRESS_ZERO) return null + + try { + const balanceData = ERC20Method.BALANCE_OF + bytes20ToBytes32(userAddress).slice(2) + const balanceSlot = await getStorageSlot( + destClient as any, + tokenAddress, + balanceData as HexString, + ) + const stateDiffs = [{ slot: balanceSlot as HexString, value: testValue }] + + try { + const allowanceData = + ERC20Method.ALLOWANCE + + bytes20ToBytes32(userAddress).slice(2) + + bytes20ToBytes32(intentGatewayAddress).slice(2) + const allowanceSlot = await getStorageSlot( + destClient as any, + tokenAddress, + allowanceData as HexString, + ) + stateDiffs.push({ slot: allowanceSlot as HexString, value: testValue }) + } catch (e) { + this.logger.warn({ tokenAddress, err: e }, "Could not find allowance slot for token") + } + + return { address: tokenAddress, stateDiff: stateDiffs } + } catch (e) { + this.logger.warn({ tokenAddress, err: e }, "Could not find balance slot for token") + return null + } + }), + ) + ).filter(Boolean) + + const stateOverride = [ + { + address: userAddress, + balance: maxUint256, + }, + ...overrides.map((override) => ({ + address: override!.address, + stateDiff: override!.stateDiff, + })), + ] + + let gas = 0n + let relayerFeeInNativeToken = 0n + + try { + let protocolFeeInNativeToken = await this.quoteNative( + postRequest, + postGasEstimateInDestFeeToken, + order.destChain, + ) + + // Add 0.5% markup + protocolFeeInNativeToken = protocolFeeInNativeToken + (protocolFeeInNativeToken * 50n) / 10000n + + gas = await destClient.estimateContractGas({ + abi: INTENT_GATEWAY_ABI, + address: this.configService.getIntentGatewayAddress(order.destChain), + functionName: "fillOrder", + args: [this.transformOrderForContract(order), fillOptions as any], + account: privateKeyToAccount(this.privateKey), + value: ethValue + protocolFeeInNativeToken, + stateOverride: stateOverride as any, + }) + this.logger.debug( + { orderId: order.id, fillGas: gas.toString(), feeMode: "native" }, + "Estimated fill gas", + ) + relayerFeeInNativeToken = protocolFeeInNativeToken + } catch { + this.logger.warn( + { chain: order.destChain }, + "Could not estimate gas with native token fees; trying fee token", + ) + const destChainFeeTokenAddress = (await this.getFeeTokenWithDecimals(order.destChain)).address + + // Check if fee token matches any order output + const feeTokenMatchesOrderOutput = order.outputs.some( + (output) => bytes32ToBytes20(output.token.toLowerCase()) === destChainFeeTokenAddress.toLowerCase(), + ) + + if (!feeTokenMatchesOrderOutput) { + // Only create fee token overrides if it doesn't match any order output + const destFeeTokenBalanceData = ERC20Method.BALANCE_OF + bytes20ToBytes32(userAddress).slice(2) + const destFeeTokenBalanceSlot = await getStorageSlot( + destClient as any, + destChainFeeTokenAddress, + destFeeTokenBalanceData as HexString, + ) + const destFeeTokenAllowanceData = + ERC20Method.ALLOWANCE + + bytes20ToBytes32(userAddress).slice(2) + + bytes20ToBytes32(intentGatewayAddress).slice(2) + const destFeeTokenAllowanceSlot = await getStorageSlot( + destClient as any, + destChainFeeTokenAddress, + destFeeTokenAllowanceData as HexString, + ) + const feeTokenStateDiffs = [ + { slot: destFeeTokenBalanceSlot, value: testValue }, + { slot: destFeeTokenAllowanceSlot, value: testValue }, + ] + + stateOverride.push({ + address: destChainFeeTokenAddress, + stateDiff: feeTokenStateDiffs as any, + }) + } + + gas = await destClient.estimateContractGas({ + abi: INTENT_GATEWAY_ABI, + address: this.configService.getIntentGatewayAddress(order.destChain), + functionName: "fillOrder", + args: [this.transformOrderForContract(order), fillOptions as any], + account: privateKeyToAccount(this.privateKey), + value: ethValue, + stateOverride: stateOverride as any, + }) + this.logger.debug( + { orderId: order.id, fillGas: gas.toString(), feeMode: "feeToken" }, + "Estimated fill gas", + ) + } + + // Cache the results + this.cacheService.setGasEstimate( + order.id!, + gas, + postGasEstimate, + postGasEstimateInDestFeeToken, + relayerFeeInNativeToken, + ) + + return { + fillGas: gas, + postGas: postGasEstimate, + relayerFeeInFeeToken: postGasEstimateInDestFeeToken, + relayerFeeInNativeToken, + } + } catch (error) { + this.logger.error({ err: error }, "Error estimating gas") + // Return a conservative estimate if we can't calculate precisely + return { fillGas: 3000000n, postGas: 270000n, relayerFeeInFeeToken: 10000000n, relayerFeeInNativeToken: 0n } + } + } + + /** + * Gets a quote for the native token cost of dispatching a post request. + * + * @param postRequest - The post request to quote + * @param fee - The fee amount in fee token + * @param chain - The chain identifier where the quote will be executed + * @returns The native token amount required + */ + async quoteNative(postRequest: IPostRequest, fee: bigint, chain: string): Promise { + const client = this.clientManager.getPublicClient(chain) + + const dispatchPost: DispatchPost = { + dest: toHex(postRequest.dest), + to: postRequest.to, + body: postRequest.body, + timeout: postRequest.timeoutTimestamp, + fee: fee, + payer: postRequest.from, + } + + const quoteNative = await client + .readContract({ + abi: INTENT_GATEWAY_ABI, + address: this.configService.getIntentGatewayAddress(postRequest.dest), + functionName: "quoteNative", + args: [dispatchPost] as any, + }) + .catch(async () => { + const quoteInFeeToken = await client.readContract({ + abi: INTENT_GATEWAY_ABI, + address: this.configService.getIntentGatewayAddress(postRequest.dest), + functionName: "quote", + args: [dispatchPost] as any, + }) + const feeToken = (await this.getFeeTokenWithDecimals(chain)).address + const routerAddr = this.configService.getUniswapRouterV2Address(chain) + const WETH = this.configService.getWrappedNativeAssetWithDecimals(chain).asset + const quote = await client.simulateContract({ + abi: UNISWAP_ROUTER_V2_ABI, + address: routerAddr, + // @ts-ignore + functionName: "getAmountsIn", + // @ts-ignore + args: [quoteInFeeToken, [WETH, feeToken]], + }) + + return quote.result[0] + }) + return quoteNative + } + + /** + * Gets the current native token price in USD with 18 decimal precision. + * + * @param chain - The chain identifier to get native token price for + * @returns The native token price in USD scaled to 18 decimals (e.g., $3000.50 becomes 3000500000000000000000n) + */ + async getNativeTokenPrice(chain: string): Promise { + let client = this.clientManager.getPublicClient(chain) + const nativeToken = client.chain?.nativeCurrency + const chainId = client.chain?.id + + if (!nativeToken?.symbol || !nativeToken?.decimals) { + throw new Error("Chain native currency information not available") + } + + const nativeTokenPriceUsd = await retryPromise( + () => fetchPrice(nativeToken.symbol, chainId, this.configService.getCoinGeckoApiKey()), + { + maxRetries: 3, + backoffMs: 250, + }, + ) + + return BigInt(Math.floor(nativeTokenPriceUsd * Math.pow(10, 18))) + } + + /** + * Converts gas costs to the equivalent amount in the fee token. + * Uses USD pricing to convert between native token gas costs and fee token amounts. + * + * @param gasEstimate - The estimated gas units + * @param chain - The chain identifier to get gas prices and native token info + * @param targetDecimals - The decimal places of the target fee token + * @returns The gas cost converted to fee token amount + */ + async convertGasToFeeToken(gasEstimate: bigint, chain: string, targetDecimals: number): Promise { + const client = this.clientManager.getPublicClient(chain) + const useEtherscan = USE_ETHERSCAN_CHAINS.has(chain) + const etherscanApiKey = this.configService.getEtherscanApiKey() + const gasPrice = + useEtherscan && etherscanApiKey + ? await retryPromise(() => getGasPriceFromEtherscan(chain, etherscanApiKey), { + maxRetries: 3, + backoffMs: 250, + }).catch(async () => { + this.logger.warn({ chain }, "Error getting gas price from etherscan, using client's gas price") + return await client.getGasPrice() + }) + : await client.getGasPrice() + const gasCostInWei = gasEstimate * gasPrice + const nativeToken = client.chain?.nativeCurrency + const chainId = client.chain?.id + + if (!nativeToken?.symbol || !nativeToken?.decimals) { + throw new Error("Chain native currency information not available") + } + + const gasCostInToken = new Decimal(formatUnits(gasCostInWei, nativeToken.decimals)) + const tokenPriceUsd = new Decimal( + await retryPromise(() => fetchPrice(nativeToken.symbol, chainId, this.configService.getCoinGeckoApiKey()), { + maxRetries: 3, + backoffMs: 250, + }), + ) + const gasCostUsd = gasCostInToken.times(tokenPriceUsd) + + const feeTokenPriceUsd = new Decimal(1) // DAI/USDC/USDT ≈ $1 (stable coin) + const gasCostInFeeToken = gasCostUsd.dividedBy(feeTokenPriceUsd) + + return parseUnits(gasCostInFeeToken.toFixed(targetDecimals), targetDecimals) + } + + /** + * Gets the fee token address and decimals for a given chain. + * + * @param chain - The chain identifier to get fee token info for + * @returns An object containing the fee token address and its decimal places + */ + async getFeeTokenWithDecimals(chain: string): Promise<{ address: HexString; decimals: number }> { + const cachedFeeToken = this.cacheService.getFeeTokenWithDecimals(chain) + if (cachedFeeToken) { + return cachedFeeToken + } + const client = this.clientManager.getPublicClient(chain) + const feeTokenAddress = await client.readContract({ + abi: EVM_HOST, + address: this.configService.getHostAddress(chain), + functionName: "feeToken", + }) + const feeTokenDecimals = await client.readContract({ + address: feeTokenAddress, + abi: ERC20_ABI, + functionName: "decimals", + }) + this.cacheService.setFeeTokenWithDecimals(chain, feeTokenAddress, feeTokenDecimals) + return { address: feeTokenAddress, decimals: feeTokenDecimals } + } + + /** + * Calculates the fee required to send a post request to the destination chain. + * The fee is calculated based on the per-byte fee for the destination chain + * multiplied by the size of the request body. + * + * @param order - The order to calculate the fee for + * @returns The total fee in fee token required to send the post request + */ + async quote(order: Order): Promise { + const cachedPerByteFee = this.cacheService.getPerByteFee(order.destChain, order.sourceChain) + if (cachedPerByteFee) { + return cachedPerByteFee + } + const { destClient } = this.clientManager.getClientsForOrder(order) + const postRequest: IPostRequest = { + source: order.destChain, + dest: order.sourceChain, + body: constructRedeemEscrowRequestBody(order, privateKeyToAddress(this.privateKey)), + timeoutTimestamp: 0n, + nonce: await this.getHostNonce(order.sourceChain), + from: this.configService.getIntentGatewayAddress(order.destChain), + to: this.configService.getIntentGatewayAddress(order.sourceChain), + } + const perByteFee = await destClient.readContract({ + address: this.configService.getHostAddress(order.destChain), + abi: EVM_HOST, + functionName: "perByteFee", + args: [toHex(order.sourceChain)], + }) + this.cacheService.setPerByteFee(order.destChain, order.sourceChain, perByteFee) + // Exclude 0x prefix from the body length, and get the byte length + const bodyByteLength = Math.floor((postRequest.body.length - 2) / 2) + const length = bodyByteLength < 32 ? 32 : bodyByteLength + + return perByteFee * BigInt(length) + } + + /** + * Gets the current nonce from the host contract. + * + * @param chain - The chain identifier to get the host nonce for + * @returns The current nonce value + */ + async getHostNonce(chain: string): Promise { + const client = this.clientManager.getPublicClient(chain) + const nonce = await client.readContract({ + abi: EVM_HOST, + address: this.configService.getHostAddress(chain), + functionName: "nonce", + }) + + return nonce + } + + /** + * Gets the latest state machine height from the host. + * If a chain is specified, gets the height for that chain's state machine. + * Otherwise, gets the current block number from the Hyperbridge API. + * + * @param chain - Optional chain identifier to get specific state machine height + * @returns The latest state machine height or current block number + */ + async getHostLatestStateMachineHeight(chain?: string): Promise { + if (!this.api) { + // Get hyperbridge RPC URL from config service + const hyperbridgeRpcUrl = this.configService.getHyperbridgeRpcUrl() + + this.api = await ApiPromise.create({ + provider: new WsProvider(hyperbridgeRpcUrl), + typesBundle: { + spec: { + gargantua: { + hasher: keccakAsU8a, + }, + }, + }, + }) + if (!(await this.api.isConnected)) { + await this.api.connect() + } + } + let latestHeight: any + + if (chain) { + latestHeight = await this.api.query.ismp.latestStateMachineHeight({ + stateId: { + Evm: this.configService.getChainId(chain), + }, + consensusStateId: this.configService.getConsensusStateId(chain), + }) + + return BigInt(latestHeight.toString()) + } + + latestHeight = await this.api.query.system.number() + + return BigInt(latestHeight.toString()) + } + + /** + * Calculates the total USD value of tokens in an order's inputs and outputs. + * + * @param order - The order to calculate token values for + * @returns An object containing the total USD values of outputs and inputs + */ + async getTokenUsdValue(order: Order): Promise<{ outputUsdValue: Decimal; inputUsdValue: Decimal }> { + const { destClient, sourceClient } = this.clientManager.getClientsForOrder(order) + let outputUsdValue = new Decimal(0) + let inputUsdValue = new Decimal(0) + const outputs = order.outputs + const inputs = order.inputs + + for (const output of outputs) { + let tokenAddress = bytes32ToBytes20(output.token) + let decimals = 18 + let amount = output.amount + let priceIdentifier: string + + if (tokenAddress === ADDRESS_ZERO) { + priceIdentifier = destClient.chain?.nativeCurrency?.symbol! + decimals = destClient.chain?.nativeCurrency?.decimals! + } else { + decimals = await this.getTokenDecimals(tokenAddress, order.destChain) + priceIdentifier = tokenAddress + } + + const pricePerToken = await retryPromise( + () => fetchPrice(priceIdentifier, destClient.chain?.id!, this.configService.getCoinGeckoApiKey()), + { + maxRetries: 3, + backoffMs: 250, + }, + ) + + // Use Decimal for precise calculations + const tokenAmount = new Decimal(formatUnits(amount, decimals)) + const tokenPrice = new Decimal(pricePerToken) + const tokenAmountValue = tokenAmount.times(tokenPrice) + outputUsdValue = outputUsdValue.plus(tokenAmountValue) + } + + for (const input of inputs) { + let tokenAddress = bytes32ToBytes20(input.token) + let decimals = 18 + let amount = input.amount + let priceIdentifier: string + + if (tokenAddress === ADDRESS_ZERO) { + priceIdentifier = sourceClient.chain?.nativeCurrency?.symbol! + decimals = sourceClient.chain?.nativeCurrency?.decimals! + } else { + decimals = await this.getTokenDecimals(tokenAddress, order.sourceChain) + priceIdentifier = tokenAddress + } + + const pricePerToken = await retryPromise( + () => fetchPrice(priceIdentifier, sourceClient.chain?.id!, this.configService.getCoinGeckoApiKey()), + { + maxRetries: 3, + backoffMs: 250, + }, + ) + + const tokenAmount = new Decimal(formatUnits(amount, decimals)) + const tokenPrice = new Decimal(pricePerToken) + const tokenAmountValue = tokenAmount.times(tokenPrice) + inputUsdValue = inputUsdValue.plus(tokenAmountValue) + } + + return { + outputUsdValue: outputUsdValue, + inputUsdValue: inputUsdValue, + } + } + + /** + * Gets the filler's token balances and their total USD value on a specific chain. + * Includes native token, DAI, USDT, and USDC balances. + * + * @param chain - The chain identifier to get balances for + * @returns An object containing individual token balances and total USD value + */ + async getFillerBalanceUSD(chain: string): Promise<{ + nativeTokenBalance: bigint + daiBalance: bigint + usdtBalance: bigint + usdcBalance: bigint + totalBalanceUsd: Decimal + }> { + const fillerWalletAddress = privateKeyToAddress(this.privateKey) + const destClient = this.clientManager.getPublicClient(chain) + const chainId = destClient.chain?.id! + + const nativeTokenBalance = await destClient.getBalance({ address: fillerWalletAddress }) + const nativeToken = destClient.chain?.nativeCurrency + if (!nativeToken?.symbol || !nativeToken?.decimals) { + throw new Error("Chain native currency information not available") + } + + const nativeTokenPriceUsd = await retryPromise( + () => fetchPrice(nativeToken.symbol, chainId, this.configService.getCoinGeckoApiKey()), + { + maxRetries: 3, + backoffMs: 250, + }, + ) + + // Use Decimal for precise calculations + const nativeTokenAmount = new Decimal(formatUnits(nativeTokenBalance, nativeToken.decimals)) + const nativeTokenPrice = new Decimal(nativeTokenPriceUsd) + const nativeTokenUsdValue = nativeTokenAmount.times(nativeTokenPrice) + + // DAI Balance + const daiAddress = this.configService.getDaiAsset(chain) + const daiBalance = await destClient.readContract({ + abi: ERC20_ABI, + address: daiAddress, + functionName: "balanceOf", + args: [fillerWalletAddress], + }) + const daiDecimals = await this.getTokenDecimals(daiAddress, chain) + const daiAmount = new Decimal(formatUnits(daiBalance, daiDecimals)) + const daiBalanceUsd = daiAmount // DAI ≈ $1 + + // USDT Balance + const usdtAddress = this.configService.getUsdtAsset(chain) + const usdtBalance = await destClient.readContract({ + abi: ERC20_ABI, + address: usdtAddress, + functionName: "balanceOf", + args: [fillerWalletAddress], + }) + const usdtDecimals = await this.getTokenDecimals(usdtAddress, chain) + const usdtAmount = new Decimal(formatUnits(usdtBalance, usdtDecimals)) + const usdtBalanceUsd = usdtAmount // USDT ≈ $1 + + // USDC Balance + const usdcAddress = this.configService.getUsdcAsset(chain) + const usdcBalance = await destClient.readContract({ + abi: ERC20_ABI, + address: usdcAddress, + functionName: "balanceOf", + args: [fillerWalletAddress], + }) + const usdcDecimals = await this.getTokenDecimals(usdcAddress, chain) + const usdcAmount = new Decimal(formatUnits(usdcBalance, usdcDecimals)) + const usdcBalanceUsd = usdcAmount // USDC ≈ $1 + + const totalBalanceUsd = nativeTokenUsdValue.plus(daiBalanceUsd).plus(usdtBalanceUsd).plus(usdcBalanceUsd) + + return { + nativeTokenBalance, + daiBalance, + usdtBalance, + usdcBalance, + totalBalanceUsd, + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/FillerConfigService.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/FillerConfigService.ts new file mode 100644 index 00000000..d80bea94 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/FillerConfigService.ts @@ -0,0 +1,166 @@ +import type { ChainConfig, HexString } from "@hyperbridge/sdk" +import { ChainConfigService } from "@hyperbridge/sdk" +import { LogLevel } from "./Logger" + +export interface UserProvidedChainConfig { + chainId: number + rpcUrl: string +} + +export interface CoinGeckoConfig { + apiKey?: string +} + +export interface EtherscanConfig { + apiKey?: string +} + +export interface LoggingConfig { + level?: LogLevel +} + +export interface FillerConfig { + privateKey: string + maxConcurrentOrders: number + coingecko?: CoinGeckoConfig + etherscan?: EtherscanConfig + logging?: LoggingConfig +} + +/** + * Simplified configuration service for the filler that wraps ChainConfigService + * and only requires minimal user configuration (RPC URLs, private keys, etc.) + */ +export class FillerConfigService { + private chainConfigService: ChainConfigService + private rpcOverrides: Map = new Map() + private fillerConfig?: FillerConfig + + constructor(chainConfigs: UserProvidedChainConfig[], fillerConfig?: FillerConfig) { + chainConfigs.forEach((config) => { + if (config.rpcUrl) { + this.rpcOverrides.set(config.chainId, config.rpcUrl) + } + }) + + this.chainConfigService = new ChainConfigService({}) + this.fillerConfig = fillerConfig + } + + getChainConfig(chain: string): ChainConfig { + const baseConfig = this.chainConfigService.getChainConfig(chain) + + // Override RPC URL if user provided a custom one + const customRpcUrl = this.getRpcUrl(chain) + + return { + ...baseConfig, + rpcUrl: customRpcUrl, + } + } + + getIntentGatewayAddress(chain: string): `0x${string}` { + return this.chainConfigService.getIntentGatewayAddress(chain) + } + + getHostAddress(chain: string): `0x${string}` { + return this.chainConfigService.getHostAddress(chain) + } + + getWrappedNativeAssetWithDecimals(chain: string): { asset: HexString; decimals: number } { + return this.chainConfigService.getWrappedNativeAssetWithDecimals(chain) + } + + getDaiAsset(chain: string): HexString { + return this.chainConfigService.getDaiAsset(chain) + } + + getUsdtAsset(chain: string): HexString { + return this.chainConfigService.getUsdtAsset(chain) + } + + getUsdcAsset(chain: string): HexString { + return this.chainConfigService.getUsdcAsset(chain) + } + + getChainId(chain: string): number { + return this.chainConfigService.getChainId(chain) + } + + getConsensusStateId(chain: string): HexString { + return this.chainConfigService.getConsensusStateId(chain) + } + + getHyperbridgeChainId(): number { + // Use SDK's default Hyperbridge chain ID + return this.chainConfigService.getHyperbridgeChainId() + } + + getHyperbridgeRpcUrl(): string { + // Use SDK's default Hyperbridge RPC URL + return this.chainConfigService.getRpcUrl("KUSAMA-4009") + } + + getRpcUrl(chain: string): string { + const chainId = this.getChainIdFromStateMachineId(chain) + const customRpcUrl = this.rpcOverrides.get(chainId) + if (customRpcUrl) { + return customRpcUrl + } + + // Fall back to SDK's default RPC URL + return this.chainConfigService.getRpcUrl(chain) + } + + private getChainIdFromStateMachineId(chain: string): number { + if (chain.includes("EVM")) { + return Number.parseInt(chain.slice(4)) + } + + return Number.parseInt(chain) + } + + getUniswapRouterV2Address(chain: string): HexString { + return this.chainConfigService.getUniswapRouterV2Address(chain) + } + + getUniswapV2FactoryAddress(chain: string): HexString { + return this.chainConfigService.getUniswapV2FactoryAddress(chain) + } + + getUniversalRouterAddress(chain: string): HexString { + return this.chainConfigService.getUniversalRouterAddress(chain) + } + + getUniswapV3QuoterAddress(chain: string): HexString { + return this.chainConfigService.getUniswapV3QuoterAddress(chain) + } + + getUniswapV4QuoterAddress(chain: string): HexString { + return this.chainConfigService.getUniswapV4QuoterAddress(chain) + } + + getPermit2Address(chain: string): HexString { + return this.chainConfigService.getPermit2Address(chain) + } + + getCoingeckoId(chain: string): string | undefined { + return this.chainConfigService.getCoingeckoId(chain) + } + + getCoinGeckoApiKey(): string | undefined { + return this.fillerConfig?.coingecko?.apiKey + } + + getEtherscanApiKey(): string | undefined { + return this.fillerConfig?.etherscan?.apiKey + } + + getConfiguredChainIds(): number[] { + return Array.from(this.rpcOverrides.keys()) + } + + getLoggingConfig(): LoggingConfig | undefined { + return this.fillerConfig?.logging + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/Logger.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/Logger.ts new file mode 100644 index 00000000..2c58f33a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/Logger.ts @@ -0,0 +1,49 @@ +import pino from "pino" +import { LoggingConfig } from "./FillerConfigService" + +type LoggerOptions = { + module?: string +} + +export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" + +let logLevel: LogLevel = "info" + +let baseLogger: pino.Logger + +// Initialize the logger with current config +function initializeLogger() { + baseLogger = pino({ + level: logLevel, + transport: { + target: "pino-pretty", + options: { + colorize: true, + singleLine: true, + ignore: "pid,hostname,moduleTag", + messageFormat: "{moduleTag}: {msg}", + }, + }, + }) +} + +initializeLogger() + +export function configureLogger(config: LoggingConfig) { + if (config.level) { + logLevel = config.level + initializeLogger() + } +} + +export function getLogger(moduleOrOptions?: string | LoggerOptions) { + console.log("Log level:", logLevel) + const options: LoggerOptions = + typeof moduleOrOptions === "string" ? { module: moduleOrOptions } : moduleOrOptions || {} + if (options.module) { + return baseLogger.child({ moduleTag: `[${options.module}]` }) + } + return baseLogger +} + +export type Logger = ReturnType diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/index.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/index.ts new file mode 100644 index 00000000..10c4b397 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/services/index.ts @@ -0,0 +1,4 @@ +export * from "./ChainClientManager" +export * from "./ContractInteractionService" +export * from "./FillerConfigService" +export * from "./Logger" diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/strategies/base.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/strategies/base.ts new file mode 100644 index 00000000..e807306f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/strategies/base.ts @@ -0,0 +1,10 @@ +import { Order, FillerConfig, ExecutionResult } from "@hyperbridge/sdk" +export interface FillerStrategy { + name: string + + canFill(order: Order): Promise + + calculateProfitability(order: Order): Promise + + executeOrder(order: Order): Promise +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/strategies/basic.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/strategies/basic.ts new file mode 100644 index 00000000..c1810f49 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/strategies/basic.ts @@ -0,0 +1,255 @@ +import { FillerStrategy } from "@/strategies/base" +import { + Order, + ExecutionResult, + HexString, + FillOptions, + adjustFeeDecimals, + bytes32ToBytes20, + TESTNET_CHAINS, +} from "@hyperbridge/sdk" +import { INTENT_GATEWAY_ABI } from "@/config/abis/IntentGateway" +import { privateKeyToAccount } from "viem/accounts" +import { ChainClientManager, ContractInteractionService } from "@/services" +import { FillerConfigService } from "@/services/FillerConfigService" +import { compareDecimalValues } from "@/utils" +import { formatUnits, parseUnits } from "viem" +import { getLogger } from "@/services/Logger" + +export class BasicFiller implements FillerStrategy { + name = "BasicFiller" + private privateKey: HexString + private clientManager: ChainClientManager + private contractService: ContractInteractionService + private configService: FillerConfigService + private logger = getLogger("basic-filler") + + constructor(privateKey: HexString, configService: FillerConfigService) { + this.privateKey = privateKey + this.configService = configService + this.clientManager = new ChainClientManager(configService, privateKey) + this.contractService = new ContractInteractionService(this.clientManager, privateKey, configService) + } + + /** + * Determines if this strategy can fill the given order + * @param order The order to check + * @param config The filler configuration + * @returns True if the strategy can fill the order + */ + async canFill(order: Order): Promise { + try { + return await this.validateOrderInputsOutputs(order) + } catch (error) { + this.logger.error({ err: error }, "Error in canFill") + return false + } + } + + /** + * Calculates the USD value of the order's inputs, outputs, fees and compares + * what will the filler receive and what will the filler pay + * @param order The order to calculate the USD value for + * @returns The profit in USD (Number) + */ + async calculateProfitability(order: Order): Promise { + try { + const { fillGas, relayerFeeInFeeToken } = await this.contractService.estimateGasFillPost(order) + + const protocolFeeInFeeToken = await this.contractService.quote(order) + + const { decimals: destFeeTokenDecimals } = await this.contractService.getFeeTokenWithDecimals( + order.destChain, + ) + const { decimals: sourceFeeTokenDecimals } = await this.contractService.getFeeTokenWithDecimals( + order.sourceChain, + ) + + let totalGasEstimateInFeeToken = + (await this.contractService.convertGasToFeeToken(fillGas, order.destChain, destFeeTokenDecimals)) + + protocolFeeInFeeToken + + relayerFeeInFeeToken + + totalGasEstimateInFeeToken = + TESTNET_CHAINS.has(order.destChain) || TESTNET_CHAINS.has(order.sourceChain) + ? parseUnits("0", 6) + : totalGasEstimateInFeeToken + + const orderFeeInDestFeeToken = adjustFeeDecimals(order.fees, sourceFeeTokenDecimals, destFeeTokenDecimals) + + const profit = + orderFeeInDestFeeToken > totalGasEstimateInFeeToken + ? orderFeeInDestFeeToken - totalGasEstimateInFeeToken + : BigInt(0) + + this.logger.info( + { + orderFeesUSD: formatUnits(orderFeeInDestFeeToken, destFeeTokenDecimals), + totalGasEstimateUSD: formatUnits(totalGasEstimateInFeeToken, destFeeTokenDecimals), + profitable: profit > 0, + profitUSD: formatUnits(profit, destFeeTokenDecimals), + }, + "Profitability evaluation", + ) + return parseFloat(formatUnits(profit, destFeeTokenDecimals)) + } catch (error) { + this.logger.error({ err: error }, "Error calculating profitability") + return 0 + } + } + + /** + * Executes the order fill + * @param order The order to fill + * @returns The execution result + */ + async executeOrder(order: Order): Promise { + const startTime = Date.now() + + try { + const { destClient, walletClient } = this.clientManager.getClientsForOrder(order) + + const { relayerFeeInFeeToken, relayerFeeInNativeToken, fillGas } = + await this.contractService.estimateGasFillPost(order) + + const fillOptions: FillOptions = { + relayerFee: relayerFeeInFeeToken, + } + + const ethValue = this.contractService.calculateRequiredEthValue(order.outputs) + + await this.contractService.approveTokensIfNeeded(order) + + const tx = await walletClient + .writeContract({ + abi: INTENT_GATEWAY_ABI, + address: this.configService.getIntentGatewayAddress(order.destChain), + functionName: "fillOrder", + args: [this.contractService.transformOrderForContract(order), fillOptions as any], + account: privateKeyToAccount(this.privateKey), + value: relayerFeeInFeeToken !== 0n ? ethValue + relayerFeeInNativeToken : ethValue, + chain: walletClient.chain, + gas: fillGas + (fillGas * 2500n) / 10000n, + }) + .catch(async () => { + return await walletClient.writeContract({ + abi: INTENT_GATEWAY_ABI, + address: this.configService.getIntentGatewayAddress(order.destChain), + functionName: "fillOrder", + args: [this.contractService.transformOrderForContract(order), fillOptions as any], + account: privateKeyToAccount(this.privateKey), + value: relayerFeeInFeeToken !== 0n ? ethValue + relayerFeeInNativeToken : ethValue, + chain: walletClient.chain, + }) + }) + + const endTime = Date.now() + const processingTimeMs = endTime - startTime + + const receipt = await destClient.waitForTransactionReceipt({ hash: tx, confirmations: 1 }) + + if (receipt.status !== "success") { + this.logger.error({ txHash: receipt.transactionHash, status: receipt.status }, "Could not fill order") + return { + success: false, + txHash: tx, + } + } + + return { + success: true, + txHash: receipt.transactionHash, + gasUsed: receipt.gasUsed.toString(), + gasPrice: receipt.effectiveGasPrice.toString(), + confirmedAtBlock: Number(receipt.blockNumber), + confirmedAt: new Date(), + strategyUsed: this.name, + processingTimeMs, + } + } catch (error) { + this.logger.error({ err: error }, "Error executing order") + + return { + success: false, + error: error instanceof Error ? error.message : "Unknown error", + } + } + } + + /** + * Validates that order inputs and outputs are valid for filling + * @param order The order to validate + * @returns True if the order inputs and outputs are valid + */ + async validateOrderInputsOutputs(order: Order): Promise { + try { + if (order.inputs.length !== order.outputs.length) { + this.logger.debug( + { inputs: order.inputs.length, outputs: order.outputs.length }, + "Order length mismatch", + ) + return false + } + + const getTokenType = (tokenAddress: string, chain: string): string | null => { + tokenAddress = bytes32ToBytes20(tokenAddress).toLowerCase() + const assets = { + DAI: this.configService.getDaiAsset(chain).toLowerCase(), + USDT: this.configService.getUsdtAsset(chain).toLowerCase(), + USDC: this.configService.getUsdcAsset(chain).toLowerCase(), + } + const result = + Object.keys(assets).find((type) => assets[type as keyof typeof assets] === tokenAddress) || null + + return result + } + + for (let i = 0; i < order.inputs.length; i++) { + const input = order.inputs[i] + const output = order.outputs[i] + + const inputType = getTokenType(input.token, order.sourceChain) + const outputType = getTokenType(output.token, order.destChain) + + if (!inputType) { + this.logger.debug({ index: i, token: input.token }, "Unsupported input token") + return false + } + + if (!outputType) { + this.logger.debug({ index: i, token: output.token }, "Unsupported output token") + return false + } + + if (inputType !== outputType) { + this.logger.debug({ index: i, inputType, outputType }, "Token mismatch") + return false + } + + const [inputDecimals, outputDecimals] = await Promise.all([ + this.contractService.getTokenDecimals(input.token, order.sourceChain), + this.contractService.getTokenDecimals(output.token, order.destChain), + ]) + + if (!compareDecimalValues(input.amount, inputDecimals, output.amount, outputDecimals)) { + this.logger.debug( + { + index: i, + inputAmount: input.amount.toString(), + inputDecimals, + outputAmount: output.amount.toString(), + outputDecimals, + }, + "Amount mismatch", + ) + return false + } + } + + return true + } catch (error) { + this.logger.error({ err: error }, "Order validation failed") + return false + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/filler.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/filler.test.ts new file mode 100644 index 00000000..944b7843 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/filler.test.ts @@ -0,0 +1,1156 @@ +import { IntentFiller } from "@/core/filler" +import { + ChainClientManager, + ContractInteractionService, + FillerConfigService, + UserProvidedChainConfig, +} from "@/services" +import { BasicFiller } from "@/strategies/basic" +import { + ChainConfig, + FillerConfig, + HexString, + Order, + PaymentInfo, + TokenInfo, + IndexerClient, + createQueryClient, + getRequestCommitment, + RequestStatus, + orderCommitment, + bytes20ToBytes32, + postRequestCommitment, + EvmChain, + IntentGateway, + DEFAULT_GRAFFITI, + getChain, +} from "@hyperbridge/sdk" +import { describe, it, expect } from "vitest" +import { ConfirmationPolicy } from "@/config/confirmation-policy" +import { + decodeFunctionData, + encodePacked, + getContract, + hexToString, + keccak256, + maxUint256, + parseAbi, + parseEventLogs, + parseUnits, + PublicClient, + WalletClient, +} from "viem" +import { INTENT_GATEWAY_ABI } from "@/config/abis/IntentGateway" +import { privateKeyToAccount, privateKeyToAddress } from "viem/accounts" +import { bscTestnet, gnosisChiado } from "viem/chains" +import "./setup" +import { EVM_HOST } from "@/config/abis/EvmHost" +import { ERC20_ABI } from "@/config/abis/ERC20" +import { HandlerV1_ABI } from "@/config/abis/HandlerV1" +import { UNISWAP_ROUTER_V2_ABI } from "@/config/abis/UniswapRouterV2" + +import { compareDecimalValues } from "@/utils" +import { readFileSync } from "fs" +import { resolve, dirname } from "path" +import { fileURLToPath } from "url" +import { parse } from "toml" +import { Decimal } from "decimal.js" + +// Helper function to load test configuration from TOML +function loadTestConfig() { + const __filename = fileURLToPath(import.meta.url) + const __dirname = dirname(__filename) + const configPath = resolve(__dirname, "test-config.toml") + let tomlContent = readFileSync(configPath, "utf-8") + + // Replace environment variable placeholders with actual values + tomlContent = tomlContent.replace( + /\$\{BSC_CHAPEL\}/g, + process.env.BSC_CHAPEL || "https://bnb-testnet.api.onfinality.io/public", + ) + tomlContent = tomlContent.replace( + /\$\{GNOSIS_CHIADO\}/g, + process.env.GNOSIS_CHIADO || "https://gnosis-chiado-rpc.publicnode.com", + ) + tomlContent = tomlContent.replace( + /\$\{ETH_MAINNET\}/g, + process.env.ETH_MAINNET || "https://eth-mainnet.g.alchemy.com/v2/demo", + ) + tomlContent = tomlContent.replace(/\$\{BSC_MAINNET\}/g, process.env.BSC_MAINNET || "https://binance.llamarpc.com") + tomlContent = tomlContent.replace( + /\$\{HYPERBRIDGE_GARGANTUA\}/g, + process.env.HYPERBRIDGE_GARGANTUA || "wss://gargantua.hyperbridge.xyz", + ) + + return parse(tomlContent) +} + +describe.sequential("Basic", () => { + let indexer: IndexerClient + + beforeAll(async () => { + const { bscIsmpHost, gnosisChiadoIsmpHost } = await setUp() + const queryClient = createQueryClient({ + url: process.env.INDEXER_URL!, + }) + + // Create chain instances + const sourceChain = await getChain({ + consensusStateId: "BSC0", + rpcUrl: process.env.BSC_CHAPEL!, + stateMachineId: "EVM-97", + host: bscIsmpHost.address, + }) + + const destChain = await getChain({ + consensusStateId: "GNO0", + rpcUrl: process.env.GNOSIS_CHIADO!, + stateMachineId: "EVM-10200", + host: gnosisChiadoIsmpHost.address, + }) + + const hyperbridgeChain = await getChain({ + consensusStateId: "PAS0", + stateMachineId: "KUSAMA-4009", + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + hasher: "Keccak" as const, + }) + + indexer = new IndexerClient({ + source: sourceChain, + dest: destChain, + hyperbridge: hyperbridgeChain, + queryClient: queryClient, + pollInterval: 1_000, + }) + }, 1_000_000) + + it.skip("Should listen, place order, fill order, and check if filled at the source chain", async () => { + const { + bscIntentGateway, + gnosisChiadoIntentGateway, + bscWalletClient, + bscPublicClient, + bscIsmpHost, + gnosisChiadoIsmpHost, + feeTokenBscAddress, + chainConfigs, + fillerConfig, + gnosisChiadoPublicClient, + bscEvmHelper, + gnosisChiadoEvmHelper, + chainConfigService, + bscChapelId, + } = await setUp() + + const intentGatewayHelper = new IntentGateway(bscEvmHelper, gnosisChiadoEvmHelper) + const strategies = [new BasicFiller(process.env.PRIVATE_KEY as HexString, chainConfigService)] + const intentFiller = new IntentFiller(chainConfigs, strategies, fillerConfig, chainConfigService) + intentFiller.start() + + const daiAsset = chainConfigService.getDaiAsset(bscChapelId) + const inputs: TokenInfo[] = [ + { + token: bytes20ToBytes32(daiAsset), + amount: 100n, + }, + ] + const outputs: PaymentInfo[] = [ + { + token: "0x0000000000000000000000000000000000000000000000000000000000000000", + amount: 100n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E", + }, + ] + + let order = { + user: "0x0000000000000000000000000000000000000000000000000000000000000000" as HexString, + sourceChain: await bscIsmpHost.read.host(), + destChain: await gnosisChiadoIsmpHost.read.host(), + deadline: 65337297n, + nonce: 0n, + fees: 0n, + outputs, + inputs, + callData: "0x" as HexString, + } + + const { order: orderWithFee } = await intentGatewayHelper.estimateFillOrder(order) + + await approveTokens(bscWalletClient, bscPublicClient, feeTokenBscAddress, bscIntentGateway.address) + + const orderDetectedPromise = new Promise((resolve) => { + const eventMonitor = intentFiller.monitor + if (!eventMonitor) { + console.error("Event monitor not found on intentFiller") + resolve({} as Order) + return + } + + eventMonitor.on("newOrder", (data: { order: Order }) => { + resolve(data.order) + }) + }) + + const hash = await bscIntentGateway.write.placeOrder([orderWithFee as any, DEFAULT_GRAFFITI], { + account: privateKeyToAccount(process.env.PRIVATE_KEY as HexString), + chain: bscTestnet, + }) + + const receipt = await bscPublicClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log("Order placed on BSC:", receipt.transactionHash) + + console.log("Waiting for event monitor to detect the order...") + const detectedOrder = await orderDetectedPromise + console.log("Order successfully detected by event monitor:", detectedOrder) + + const orderFilledPromise = new Promise<{ orderId: string; hash: string }>((resolve) => { + const eventMonitor = intentFiller.monitor + if (!eventMonitor) { + console.error("Event monitor not found on intentFiller") + resolve({ orderId: "", hash: "" }) + return + } + + eventMonitor.on("orderFilled", (data: { orderId: string; hash: string }) => { + console.log("Order filled by event monitor:", data.orderId, data.hash) + resolve(data) + }) + }) + + const { orderId, hash: filledHash } = await orderFilledPromise + console.log("Order filled:", orderId, filledHash) + + const filledReceipt = await gnosisChiadoPublicClient.waitForTransactionReceipt({ + hash: filledHash as `0x${string}`, + confirmations: 1, + }) + + let isFilled = await checkIfOrderFilled( + orderId as HexString, + gnosisChiadoPublicClient, + gnosisChiadoIntentGateway.address, + ) + + expect(isFilled).toBe(true) + + // parse EvmHost PostRequestEvent emitted in the transcation logs + const event = parseEventLogs({ abi: EVM_HOST, logs: filledReceipt.logs })[0] + + if (event.eventName !== "PostRequestEvent") { + throw new Error("Unexpected Event type") + } + + const request = event.args + console.log("PostRequestEvent", { request }) + const commitment = postRequestCommitment(request).commitment + + for await (const status of indexer.postRequestStatusStream(commitment)) { + console.log(JSON.stringify(status, null, 4)) + switch (status.status) { + case RequestStatus.SOURCE_FINALIZED: { + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${status.metadata.transactionHash}`, + ) + break + } + case RequestStatus.HYPERBRIDGE_DELIVERED: { + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${status.metadata.transactionHash}`, + ) + break + } + case RequestStatus.HYPERBRIDGE_FINALIZED: { + console.log( + `Status ${status.status}, Transaction: https://gnosis-chiado.blockscout.com/tx/${status.metadata.transactionHash}`, + ) + + break + } + case RequestStatus.DESTINATION: { + console.log( + `Status ${status.status}, Transaction: https://testnet.bscscan.com/tx/${status.metadata.transactionHash}`, + ) + + // Check if the order is filled at the source chain + const isFilled = await checkIfOrderFilled( + orderId as HexString, + bscPublicClient, + bscIntentGateway.address, + ) + expect(isFilled).toBe(true) + break + } + } + } + + intentFiller.stop() + }, 1_000_000) + + it("Should listen, place order, fill order at BSC Chapel, and check if filled at Gnosis Chiado", async () => { + const { + bscIntentGateway, + gnosisChiadoIntentGateway, + bscWalletClient, + bscPublicClient, + bscIsmpHost, + gnosisChiadoIsmpHost, + feeTokenGnosisChiadoAddress, + chainConfigs, + fillerConfig, + gnosisChiadoPublicClient, + bscEvmHelper, + gnosisChiadoEvmHelper, + chainConfigService, + bscChapelId, + gnosisChiadoId, + gnosisChiadoWalletClient, + } = await setUp() + + const intentGatewayHelper = new IntentGateway(gnosisChiadoEvmHelper, bscEvmHelper) + const strategies = [new BasicFiller(process.env.PRIVATE_KEY as HexString, chainConfigService)] + const intentFiller = new IntentFiller(chainConfigs, strategies, fillerConfig, chainConfigService) + intentFiller.start() + + const inputs: TokenInfo[] = [ + { + token: bytes20ToBytes32(chainConfigService.getDaiAsset(gnosisChiadoId)), + amount: 100n, + }, + ] + const outputs: PaymentInfo[] = [ + { + token: bytes20ToBytes32(chainConfigService.getDaiAsset(bscChapelId)), + amount: 100n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E", + }, + ] + + let order = { + user: "0x0000000000000000000000000000000000000000000000000000000000000000" as HexString, + sourceChain: await gnosisChiadoIsmpHost.read.host(), + destChain: await bscIsmpHost.read.host(), + deadline: 65337297000n, + nonce: 0n, + fees: 0n, + outputs, + inputs, + callData: "0x" as HexString, + } + + const { order: orderWithFee } = await intentGatewayHelper.estimateFillOrder(order) + + await approveTokens( + gnosisChiadoWalletClient, + gnosisChiadoPublicClient, + feeTokenGnosisChiadoAddress, + gnosisChiadoIntentGateway.address, + ) + + await approveTokens( + gnosisChiadoWalletClient, + gnosisChiadoPublicClient, + chainConfigService.getDaiAsset(gnosisChiadoId), + gnosisChiadoIntentGateway.address, + ) + + const orderDetectedPromise = new Promise((resolve) => { + const eventMonitor = intentFiller.monitor + if (!eventMonitor) { + console.error("Event monitor not found on intentFiller") + resolve({} as Order) + return + } + + eventMonitor.on("newOrder", (data: { order: Order }) => { + resolve(data.order) + }) + }) + + const hash = await gnosisChiadoIntentGateway.write.placeOrder( + [orderWithFee as any, bytes20ToBytes32("0x7f5f2cf1aec83bf0c74df566a41aa7ed65ea84ea")], + { + account: privateKeyToAccount(process.env.PRIVATE_KEY as HexString), + chain: gnosisChiado, + }, + ) + + const receipt = await gnosisChiadoPublicClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log("Order placed on Gnosis Chiado:", receipt.transactionHash) + + console.log("Waiting for event monitor to detect the order...") + const detectedOrder = await orderDetectedPromise + console.log("Order successfully detected by event monitor:", detectedOrder) + + const orderFilledPromise = new Promise<{ orderId: string; hash: string }>((resolve) => { + const eventMonitor = intentFiller.monitor + if (!eventMonitor) { + console.error("Event monitor not found on intentFiller") + resolve({ orderId: "", hash: "" }) + return + } + + eventMonitor.on("orderFilled", (data: { orderId: string; hash: string }) => { + console.log("Order filled by event monitor:", data.orderId, data.hash) + resolve(data) + }) + }) + + const { orderId, hash: filledHash } = await orderFilledPromise + console.log("Order filled:", orderId, filledHash) + + const filledReceipt = await bscPublicClient.waitForTransactionReceipt({ + hash: filledHash as `0x${string}`, + confirmations: 1, + }) + + let isFilled = await checkIfOrderFilled(orderId as HexString, bscPublicClient, bscIntentGateway.address) + + expect(isFilled).toBe(true) + + // parse EvmHost PostRequestEvent emitted in the transcation logs + const event = parseEventLogs({ abi: EVM_HOST, logs: filledReceipt.logs })[0] + + if (event.eventName !== "PostRequestEvent") { + throw new Error("Unexpected Event type") + } + + const request = event.args + console.log("PostRequestEvent", { request }) + const commitment = postRequestCommitment(request).commitment + + console.log("Post request commitment: ", commitment) + + for await (const status of indexer.postRequestStatusStream(commitment)) { + console.log(JSON.stringify(status, null, 4)) + switch (status.status) { + case RequestStatus.SOURCE_FINALIZED: { + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${status.metadata.transactionHash}`, + ) + break + } + case RequestStatus.HYPERBRIDGE_DELIVERED: { + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${status.metadata.transactionHash}`, + ) + break + } + case RequestStatus.HYPERBRIDGE_FINALIZED: { + console.log( + `Status ${status.status}, Transaction: https://gnosis-chiado.blockscout.com/tx/${status.metadata.transactionHash}`, + ) + + break + } + case RequestStatus.DESTINATION: { + console.log( + `Status ${status.status}, Transaction: https://testnet.bscscan.com/tx/${status.metadata.transactionHash}`, + ) + + // Check if the order is filled at the source chain + const isFilled = await checkIfOrderFilled( + orderId as HexString, + gnosisChiadoPublicClient, + gnosisChiadoIntentGateway.address, + ) + expect(isFilled).toBe(true) + break + } + } + } + + intentFiller.stop() + }, 1_000_000) + + it.skip("Should timeout if order deadline is reached", async () => { + const { + bscIntentGateway, + bscWalletClient, + bscPublicClient, + bscIsmpHost, + gnosisChiadoIsmpHost, + feeTokenBscAddress, + contractInteractionService, + gnosisChiadoIntentGateway, + bscHandler, + bscChapelId, + chainConfigService, + } = await setUp() + + const daiAsset = chainConfigService.getDaiAsset(bscChapelId) + + const inputs: TokenInfo[] = [ + { + token: bytes20ToBytes32(daiAsset), + amount: 100n, + }, + ] + const outputs: PaymentInfo[] = [ + { + token: "0x0000000000000000000000000000000000000000000000000000000000000000", + amount: 100n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E", + }, + ] + + const order = { + user: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + sourceChain: await bscIsmpHost.read.host(), + destChain: await gnosisChiadoIsmpHost.read.host(), + deadline: 0n, // Expired deadline + nonce: 0n, + fees: 1000000n, + outputs, + inputs, + callData: "0x" as HexString, + } + + await approveTokens(bscWalletClient, bscPublicClient, feeTokenBscAddress, bscIntentGateway.address) + + let hash = await bscIntentGateway.write.placeOrder([order, DEFAULT_GRAFFITI], { + account: privateKeyToAccount(process.env.PRIVATE_KEY as HexString), + chain: bscTestnet, + }) + + let receipt = await bscPublicClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + const orderPlaceEvent = parseEventLogs({ abi: INTENT_GATEWAY_ABI, logs: receipt.logs })[0] + + if (orderPlaceEvent.eventName !== "OrderPlaced") { + throw new Error("Unexpected Event type") + } + + const orderPlaced = orderPlaceEvent.args + + console.log("Order placed on BSC:", orderPlaced) + + // Now cancel the order + + const latestHeightDestChain = await contractInteractionService.getHostLatestStateMachineHeight( + hexToString(order.destChain), + ) + + const cancelOptions = { + relayerFee: 10000000000n, + height: latestHeightDestChain, + } + + hash = await bscIntentGateway.write.cancelOrder([orderPlaced, cancelOptions], { + account: privateKeyToAccount(process.env.PRIVATE_KEY as HexString), + chain: bscTestnet, + }) + + receipt = await bscPublicClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log("Order cancelled on BSC:", receipt.transactionHash) + + // parse EvmHost GetRequestEvent emitted in the transcation logs + const event = parseEventLogs({ abi: EVM_HOST, logs: receipt.logs })[0] + + if (event.eventName !== "GetRequestEvent") { + throw new Error("Unexpected Event type") + } + + const request = event.args + console.log("GetRequestEvent", { request }) + const commitment = getRequestCommitment({ ...request, keys: [...request.keys] }) + console.log("Get Request Commitment: ", commitment) + + for await (const status of indexer.getRequestStatusStream(commitment)) { + switch (status.status) { + case RequestStatus.SOURCE_FINALIZED: { + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${status.metadata.transactionHash}`, + ) + break + } + case RequestStatus.HYPERBRIDGE_DELIVERED: { + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${status.metadata.transactionHash}`, + ) + break + } + case RequestStatus.HYPERBRIDGE_FINALIZED: { + console.log( + `Status ${status.status}, Transaction: https://testnet.bscscan.com/tx/${status.metadata.transactionHash}`, + ) + const { args, functionName } = decodeFunctionData({ + abi: HandlerV1_ABI, + data: status.metadata.calldata, + }) + + expect(functionName).toBe("handleGetResponses") + + try { + const hash = await bscHandler.write.handleGetResponses(args as any, { + account: privateKeyToAccount(process.env.PRIVATE_KEY as HexString), + chain: bscTestnet, + }) + receipt = await bscPublicClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log(`Transaction submitted: https://testnet.bscscan.com/tx/${hash}`) + + // Check for the EscrowRefunded event + const escrowRefundedEvent = parseEventLogs({ abi: INTENT_GATEWAY_ABI, logs: receipt.logs })[0] + if (escrowRefundedEvent.eventName !== "EscrowRefunded") { + throw new Error("Unexpected Event type") + } + + expect(escrowRefundedEvent.args.commitment).toBe( + orderCommitment({ + ...orderPlaced, + sourceChain: hexToString(orderPlaced.sourceChain), + destChain: hexToString(orderPlaced.destChain), + outputs: orderPlaced.outputs as PaymentInfo[], + inputs: orderPlaced.inputs as TokenInfo[], + }), + ) + } catch (e) { + console.error("Error self-relaying: ", e) + } + break + } + case RequestStatus.DESTINATION: { + console.log( + `Status ${status.status}, Transaction: https://testnet.bscscan.com/tx/${status.metadata.transactionHash}`, + ) + break + } + } + } + }, 1_000_0000) + + it("Should validate order inputs and outputs correctly", async () => { + const { chainConfigService, bscChapelId, mainnetId } = await setUp() + + const basicFiller = new BasicFiller(process.env.PRIVATE_KEY as HexString, chainConfigService) + + // Get token assets for both chains + const sourceDaiAsset = chainConfigService.getDaiAsset(bscChapelId) + const sourceUsdtAsset = chainConfigService.getUsdtAsset(bscChapelId) + const sourceUsdcAsset = chainConfigService.getUsdcAsset(bscChapelId) + + const destDaiAsset = chainConfigService.getDaiAsset(mainnetId) + const destUsdtAsset = chainConfigService.getUsdtAsset(mainnetId) + const destUsdcAsset = chainConfigService.getUsdcAsset(mainnetId) + + // Test case 1: Valid order with matching USDC tokens + const validOrder: Order = { + user: "0x0000000000000000000000000000000000000000000000000000000000000000" as HexString, + sourceChain: bscChapelId, + destChain: mainnetId, + deadline: 65337297000n, + nonce: 0n, + fees: 1000000n, + inputs: [ + { + token: bytes20ToBytes32(sourceUsdcAsset), + amount: 1n * 10n ** 18n, // 1 USDC (6 decimals) + }, + ], + outputs: [ + { + token: bytes20ToBytes32(destUsdcAsset), + amount: 1n * 10n ** 6n, // 1 USDC (6 decimals) + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E", + }, + ], + callData: "0x" as HexString, + } + + // Test case 2: Invalid order with different array lengths + const invalidLengthOrder: Order = { + ...validOrder, + inputs: [ + { + token: bytes20ToBytes32(sourceUsdcAsset), + amount: 1000000n, + }, + { + token: bytes20ToBytes32(sourceUsdtAsset), + amount: 1000000000n, // 1 USDT (6 decimals) + }, + ], + outputs: [ + { + token: bytes20ToBytes32(destUsdcAsset), + amount: 1000000n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E", + }, + ], + } + + // Test case 3: Invalid order with token type mismatch + const invalidTokenTypeOrder: Order = { + ...validOrder, + inputs: [ + { + token: bytes20ToBytes32(sourceUsdcAsset), + amount: 1000000n, + }, + ], + outputs: [ + { + token: bytes20ToBytes32(destUsdtAsset), // USDC input but USDT output + amount: 1000000n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E", + }, + ], + } + + // Test case 4: Invalid order with unsupported token + const unsupportedTokenOrder: Order = { + ...validOrder, + inputs: [ + { + token: bytes20ToBytes32("0x1234567890123456789012345678901234567890" as HexString), // Unsupported token + amount: 1000000n, + }, + ], + outputs: [ + { + token: bytes20ToBytes32(destUsdcAsset), + amount: 1000000n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E", + }, + ], + } + + const canFillValid = await basicFiller.validateOrderInputsOutputs(validOrder) + expect(canFillValid).toBe(true) + + const canFillInvalidLength = await basicFiller.validateOrderInputsOutputs(invalidLengthOrder) + expect(canFillInvalidLength).toBe(false) + + // Invalid token type order should fail validation + const canFillInvalidTokenType = await basicFiller.validateOrderInputsOutputs(invalidTokenTypeOrder) + expect(canFillInvalidTokenType).toBe(false) + + // Unsupported token order should fail validation + const canFillUnsupportedToken = await basicFiller.validateOrderInputsOutputs(unsupportedTokenOrder) + expect(canFillUnsupportedToken).toBe(false) + + // Direct stress test for compare decimal values + + // Core precision tests that matter + let val1 = parseUnits("11245.123456789012345678", 18) // Full 18 decimal precision + let val2 = parseUnits("11245.123456", 6) // 6 decimal precision + expect(compareDecimalValues(val1, 18, val2, 6)).toBe(false) // Different due to precision loss + + let val3 = parseUnits("11245.123456000000000000", 18) // 18 decimals but only 6 significant + let val4 = parseUnits("11245.123456", 6) // Same logical value + expect(compareDecimalValues(val3, 18, val4, 6)).toBe(true) + + // Edge case: 1 wei difference (matters for exact comparisons) + let wei18 = BigInt("1000000000000000001") // 1 ETH + 1 wei + let eth6 = parseUnits("1", 6) // 1 token (6 decimals) + expect(compareDecimalValues(wei18, 18, eth6, 6)).toBe(false) // 1 wei makes them different + + // Zero values (should always match regardless of decimals) + let zero18 = parseUnits("0", 18) + let zero6 = parseUnits("0", 6) + expect(compareDecimalValues(zero18, 18, zero6, 6)).toBe(true) + + // Real stablecoin amounts (common use case) + let usdc = parseUnits("1234.567890", 6) // USDC amount + let dai = parseUnits("1234.567890", 18) // Same USD value in DAI + expect(compareDecimalValues(usdc, 6, dai, 18)).toBe(true) + + // Same decimals should work (sanity check) + let sameVal1 = parseUnits("100.5", 18) + let sameVal2 = parseUnits("100.5", 18) + expect(compareDecimalValues(sameVal1, 18, sameVal2, 18)).toBe(true) + + // Large numbers (stress test) + let large18 = parseUnits("999999999999.123456000000000000", 18) + let large6 = parseUnits("999999999999.123456", 6) + expect(compareDecimalValues(large18, 18, large6, 6)).toBe(true) + + // Fractional precision that gets truncated (common bug source) + let fraction18 = parseUnits("0.000000000000000123", 18) // 123 wei + zero6 = parseUnits("0", 6) // 0 in 6 decimals + expect(compareDecimalValues(fraction18, 18, zero6, 6)).toBe(false) + }, 300_000) +}) + +describe.sequential("ConfirmationPolicy", () => { + it("Should return correct confirmations for min, max, and interpolated amounts", () => { + const policyConfig = { + "1": { + minAmount: "100", + maxAmount: "1000", + minConfirmations: 2, + maxConfirmations: 12, + }, + } + + const policy = new ConfirmationPolicy(policyConfig) + + // Test boundaries + expect(policy.getConfirmationBlocks(1, new Decimal(50))).toBe(2) // Below min + expect(policy.getConfirmationBlocks(1, new Decimal(100))).toBe(2) // At min + expect(policy.getConfirmationBlocks(1, new Decimal(1000))).toBe(12) // At max + expect(policy.getConfirmationBlocks(1, new Decimal(1500))).toBe(12) // Above max + + // Test interpolation at midpoint + expect(policy.getConfirmationBlocks(1, new Decimal(550))).toBe(7) // Midpoint + }) + + it("Should handle multiple chains with different policies", () => { + const policyConfig = { + "1": { + minAmount: "1000", + maxAmount: "10000", + minConfirmations: 3, + maxConfirmations: 30, + }, + "97": { + minAmount: "10", + maxAmount: "100", + minConfirmations: 1, + maxConfirmations: 5, + }, + } + + const policy = new ConfirmationPolicy(policyConfig) + + expect(policy.getConfirmationBlocks(1, new Decimal(5500))).toBe(17) // Mainnet midpoint + expect(policy.getConfirmationBlocks(97, new Decimal(55))).toBe(3) // BSC Chapel midpoint + }) + + it("Should handle decimal/floating point amounts correctly", () => { + const policyConfig = { + "1": { + minAmount: "10.5", + maxAmount: "100.75", + minConfirmations: 2, + maxConfirmations: 20, + }, + } + + const policy = new ConfirmationPolicy(policyConfig) + + // Test boundaries with decimals + expect(policy.getConfirmationBlocks(1, new Decimal(5.0))).toBe(2) // Below min + expect(policy.getConfirmationBlocks(1, new Decimal(10.5))).toBe(2) // At min + expect(policy.getConfirmationBlocks(1, new Decimal(100.75))).toBe(20) // At max + expect(policy.getConfirmationBlocks(1, new Decimal(150.25))).toBe(20) // Above max + + // Test interpolation with decimals + expect(policy.getConfirmationBlocks(1, new Decimal(55.625))).toBe(11) + + // Test with very precise decimals + expect(policy.getConfirmationBlocks(1, new Decimal(33.1875))).toBe(7) // ~25% point + expect(policy.getConfirmationBlocks(1, new Decimal(78.0625))).toBe(15) // ~75% point + }) + + it("Should throw error for unknown chainId", () => { + const policyConfig = { + "1": { + minAmount: "100", + maxAmount: "1000", + minConfirmations: 2, + maxConfirmations: 12, + }, + } + + const policy = new ConfirmationPolicy(policyConfig) + + expect(() => policy.getConfirmationBlocks(999, new Decimal(500))).toThrow( + "No confirmation policy found for chainId 999", + ) + }) +}) + +async function setUp() { + const bscChapelId = "EVM-97" + const mainnetId = "EVM-1" + const gnosisChiadoId = "EVM-10200" + const bscMainnet = "EVM-56" + + const chains = [bscMainnet, mainnetId, gnosisChiadoId, bscChapelId] + + // Load test configuration from TOML file + const config = loadTestConfig() + + // Convert TOML chain configs to UserProvidedChainConfig format + const testChainConfigs: UserProvidedChainConfig[] = config.chains.map((chain: any) => ({ + chainId: chain.chainId, + rpcUrl: chain.rpcUrl, + })) + + // Convert TOML filler config including CoinGecko + const fillerConfigForService = config.filler.coingecko + ? { + privateKey: config.filler.privateKey, + maxConcurrentOrders: config.filler.maxConcurrentOrders, + coingecko: config.filler.coingecko, + } + : undefined + + // Create the custom config service + const chainConfigService = new FillerConfigService(testChainConfigs, fillerConfigForService) + let chainConfigs: ChainConfig[] = chains.map((chain) => chainConfigService.getChainConfig(chain)) + + // Use confirmation policies from TOML config + const confirmationPolicy = new ConfirmationPolicy(config.confirmationPolicies) + + const fillerConfig: FillerConfig = { + confirmationPolicy: { + getConfirmationBlocks: (chainId: number, amountUsd: number) => + confirmationPolicy.getConfirmationBlocks(chainId, new Decimal(amountUsd)), + }, + maxConcurrentOrders: config.filler.maxConcurrentOrders, + pendingQueueConfig: config.filler.pendingQueue, + } + + const chainClientManager = new ChainClientManager(chainConfigService, process.env.PRIVATE_KEY as HexString) + const contractInteractionService = new ContractInteractionService( + chainClientManager, + process.env.PRIVATE_KEY as HexString, + chainConfigService, + ) + const bscWalletClient = chainClientManager.getWalletClient(bscChapelId) + const gnosisChiadoWalletClient = chainClientManager.getWalletClient(gnosisChiadoId) + const bscPublicClient = chainClientManager.getPublicClient(bscChapelId) + const gnosisChiadoPublicClient = chainClientManager.getPublicClient(gnosisChiadoId) + const intentGatewayAddress = chainConfigService.getChainConfig(bscChapelId).intentGatewayAddress + const feeTokenBscAddress = (await contractInteractionService.getFeeTokenWithDecimals(bscChapelId)).address + const feeTokenGnosisChiadoAddress = (await contractInteractionService.getFeeTokenWithDecimals(gnosisChiadoId)) + .address + const bscIsmpHostAddress = "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7" as HexString + const gnosisChiadoIsmpHostAddress = "0x58a41b89f4871725e5d898d98ef4bf917601c5eb" as HexString + const bscHandlerAddress = "0x4638945E120846366cB7Abc08DB9c0766E3a663F" as HexString + const gnosisChiadoHandlerAddress = "0x4638945E120846366cB7Abc08DB9c0766E3a663F" as HexString + const bscIntentGateway = getContract({ + address: intentGatewayAddress as HexString, + abi: INTENT_GATEWAY_ABI, + client: { public: bscPublicClient, wallet: bscWalletClient }, + }) + + const gnosisChiadoIntentGateway = getContract({ + address: intentGatewayAddress as HexString, + abi: INTENT_GATEWAY_ABI, + client: { public: gnosisChiadoPublicClient, wallet: gnosisChiadoWalletClient }, + }) + + const bscIsmpHost = getContract({ + address: bscIsmpHostAddress, + abi: EVM_HOST, + client: { public: bscPublicClient, wallet: bscWalletClient }, + }) + + const gnosisChiadoIsmpHost = getContract({ + address: gnosisChiadoIsmpHostAddress, + abi: EVM_HOST, + client: { public: gnosisChiadoPublicClient, wallet: gnosisChiadoWalletClient }, + }) + + const bscHandler = getContract({ + address: bscHandlerAddress, + abi: HandlerV1_ABI, + client: { public: bscPublicClient, wallet: bscWalletClient }, + }) + + const gnosisChiadoHandler = getContract({ + address: gnosisChiadoHandlerAddress, + abi: HandlerV1_ABI, + client: { public: gnosisChiadoPublicClient, wallet: gnosisChiadoWalletClient }, + }) + + const bscEvmHelper = new EvmChain({ + chainId: 97, + host: bscIsmpHostAddress, + rpcUrl: process.env.BSC_CHAPEL!, + consensusStateId: "BSC0", + }) + const gnosisChiadoEvmHelper = new EvmChain({ + chainId: 10200, + host: gnosisChiadoIsmpHostAddress, + rpcUrl: process.env.GNOSIS_CHIADO!, + consensusStateId: "GNO0", + }) + + return { + chainClientManager, + bscWalletClient, + gnosisChiadoWalletClient, + bscPublicClient, + gnosisChiadoPublicClient, + bscIntentGateway, + gnosisChiadoIntentGateway, + bscIsmpHostAddress, + gnosisChiadoIsmpHostAddress, + bscIsmpHost, + gnosisChiadoIsmpHost, + feeTokenBscAddress, + feeTokenGnosisChiadoAddress, + contractInteractionService, + bscHandler, + bscChapelId, + gnosisChiadoId, + chainConfigService, + fillerConfig, + chainConfigs, + gnosisChiadoHandler, + bscEvmHelper, + gnosisChiadoEvmHelper, + mainnetId, + } +} + +async function approveTokens( + walletClient: WalletClient, + publicClient: PublicClient, + tokenAddress: HexString, + spender: HexString, +) { + const approval = await publicClient.readContract({ + abi: ERC20_ABI, + address: tokenAddress, + functionName: "allowance", + args: [walletClient.account?.address as HexString, spender], + account: walletClient.account, + }) + + if (approval == 0n) { + console.log("Approving tokens for test") + const tx = await walletClient.writeContract({ + abi: ERC20_ABI, + address: tokenAddress, + functionName: "approve", + args: [spender, maxUint256], + chain: walletClient.chain, + account: walletClient.account!, + }) + + console.log("Approved tokens for test:", tx) + // Wait for the 5 seconds, to make sure the transaction is mined + await new Promise((resolve) => setTimeout(resolve, 5000)) + } +} + +async function addLiquidity( + walletClient: WalletClient, + publicClient: PublicClient, + uniswapRouterAddress: HexString, + tokenA: HexString, + tokenB: HexString, + tokenAAmount: bigint, + tokenBAmount: bigint, + lpRecipient: HexString, +) { + await approveTokens(walletClient, publicClient, tokenA, uniswapRouterAddress) + await approveTokens(walletClient, publicClient, tokenB, uniswapRouterAddress) + try { + console.log("Adding liquidity to uniswap router:", uniswapRouterAddress) + const tx = await walletClient.writeContract({ + abi: UNISWAP_ROUTER_V2_ABI, + address: uniswapRouterAddress, + functionName: "addLiquidity", + args: [ + tokenA, + tokenB, + tokenAAmount, + tokenBAmount, + tokenAAmount - 1n, + tokenBAmount - 1n, + lpRecipient, + 6533729700n, + ], + chain: walletClient.chain, + account: walletClient.account!, + }) + + console.log("Added liquidity:", tx) + } catch (error) { + console.error("Error adding liquidity:", error) + throw error + } +} + +async function getPairAddress( + publicClient: PublicClient, + tokenA: HexString, + tokenB: HexString, + factoryAddress: HexString, +) { + const pairAddress = await publicClient.readContract({ + abi: parseAbi(["function getPair(address tokenA, address tokenB) view returns (address)"]), + address: factoryAddress, + functionName: "getPair", + args: [tokenA, tokenB], + }) + return pairAddress as HexString +} + +async function checkIfOrderFilled( + commitment: HexString, + client: PublicClient, + intentGatewayAddress: HexString, +): Promise { + try { + const mappingSlot = 5n + + const slot = keccak256(encodePacked(["bytes32", "uint256"], [commitment, mappingSlot])) + + const filledStatus = await client.getStorageAt({ + address: intentGatewayAddress, + slot: slot, + }) + + console.log("Filled status:", filledStatus) + return filledStatus !== "0x0000000000000000000000000000000000000000000000000000000000000000" + } catch (error) { + console.error(`Error checking if order filled:`, error) + return false + } +} + +async function clearOutputTokenBalance( + walletClient: WalletClient, + publicClient: PublicClient, + tokenAddresses: HexString[], + pairAddresses: HexString[], +) { + // Send each token to the pair address from user + for (const tokenAddress of tokenAddresses) { + // First check if the balance is greater than 0 + const balance = await publicClient.readContract({ + abi: ERC20_ABI, + address: tokenAddress, + functionName: "balanceOf", + args: [walletClient.account?.address as HexString], + }) + + if (balance > 0n) { + console.log("Clearing balance of", tokenAddress, "from", walletClient.account?.address) + const tx = await walletClient.writeContract({ + abi: ERC20_ABI, + address: tokenAddress, + functionName: "transfer", + args: [pairAddresses[0], balance], + chain: walletClient.chain, + account: walletClient.account!, + }) + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/sdk-imports.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/sdk-imports.test.ts new file mode 100644 index 00000000..d334254a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/sdk-imports.test.ts @@ -0,0 +1,5 @@ +import { __test } from '@hyperbridge/sdk'; + +it("should load test function and invoke without failure", async () => { + expect(await __test()).toMatchInlineSnapshot(`"{"root":"0x85835c4d5287fe023073eb733f4e4103935d61b4397f0f9d0fe627d434757fa5","proof":["0x894376e04f932deadc9ab212ac514f37b41e670be2f8002babde1faf20935461","0xf3ace1896f86f91627cc1c09eeaba2cd76d82a75be6f09b94c861524fa5e5289","0x0ffa0900c838d17341df2d00fa4832755de619e646137844700668ad544c8aae","0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","0x9c6b2c1b0d0b25a008e6c882cc7b415f309965c72ad2b944ac0931048ca31cd5","0xfadbd3c7f79fa2bdc4f24857709cd4a4e870623dc9e9abcdfd6e448033e35212"],"mmr_size":236,"leaf_positions":[232],"keccak_hash_calldata":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"}"`); +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/setup.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/setup.ts new file mode 100644 index 00000000..744bac8d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/setup.ts @@ -0,0 +1,5 @@ +import * as dotenv from "dotenv" +import * as path from "node:path" + +const root = process.cwd() +dotenv.config({ path: path.resolve(root, "../../.env.local") }) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/test-config.toml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/test-config.toml new file mode 100644 index 00000000..cc54c58a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/tests/test-config.toml @@ -0,0 +1,167 @@ +# Test configuration for Hyperbridge Intent Filler +# This file contains the configuration used for running tests + +# Filler configuration +[filler] +privateKey = "0x0000000000000000000000000000000000000000000000000000000000000000" # Dummy key for tests +maxConcurrentOrders = 5 + +# CoinGecko API configuration +[filler.coingecko] +apiKey = "" # Optional: Add your CoinGecko Pro API key for higher rate limits + +# Pending queue configuration +[filler.pendingQueue] +maxRechecks = 10 +recheckDelayMs = 30000 # 30 seconds + +# Strategy configuration +[[strategies]] +type = "basic" +privateKey = "0x0000000000000000000000000000000000000000000000000000000000000000" + +# BSC Chapel Testnet +[[chains]] +chainId = 97 +rpcUrl = "${BSC_CHAPEL}" +intentGatewayAddress = "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509" +hostAddress = "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7" +consensusStateId = "BSC0" +coingeckoId = "binance-smart-chain" +wrappedNativeDecimals = 18 + +# Asset addresses for BSC Chapel +[chains.assets] +WETH = "0xae13d989dac2f0debff460ac112a837c89baa7cd" +DAI = "0x1938165569A5463327fb206bE06d8D9253aa06b7" +USDC = "0xC625ec7D30A4b1AAEfb1304610CdAcD0d606aC92" +USDT = "0xc043f483373072f7f27420d6e7d7ad269c018e18" + +# Contract addresses for BSC Chapel +[chains.addresses] +UniswapRouter02 = "0x9639379819420704457B07A0C33B678D9E0F8Df0" +UniswapV2Factory = "0x12e036669DA18F4A2777853d6e2136b32AceEC86" +BatchExecutor = "0x4CC58B5D8FBf838d062E4b21F75C327835B5F0ef" +UniversalRouter = "0xcc6d5ece3d4a57245bf5a2f64f3ed9179b81f714" +UniswapV3Router = "0x0000000000000000000000000000000000000000" +UniswapV3Factory = "0x0000000000000000000000000000000000000000" +UniswapV3Quoter = "0x0000000000000000000000000000000000000000" +UniswapV4PoolManager = "0x0000000000000000000000000000000000000000" +UniswapV4Quoter = "0x0000000000000000000000000000000000000000" + +# Gnosis Chiado Testnet +[[chains]] +chainId = 10200 +rpcUrl = "${GNOSIS_CHIADO}" +intentGatewayAddress = "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509" +hostAddress = "0x58a41b89f4871725e5d898d98ef4bf917601c5eb" +consensusStateId = "GNO0" +coingeckoId = "gnosis" +wrappedNativeDecimals = 18 + +# Asset addresses for Gnosis Chiado +[chains.assets] +WETH = "0x0000000000000000000000000000000000000000" +DAI = "0x50B1d3c7c073c9caa1Ef207365A2c9C976bD70b9" +USDC = "0x0000000000000000000000000000000000000000" +USDT = "0x0000000000000000000000000000000000000000" + +# Contract addresses for Gnosis Chiado +[chains.addresses] +UniswapRouter02 = "0x0000000000000000000000000000000000000000" +UniswapV2Factory = "0x0000000000000000000000000000000000000000" +BatchExecutor = "0x0000000000000000000000000000000000000000" +UniversalRouter = "0x0000000000000000000000000000000000000000" +UniswapV3Router = "0x0000000000000000000000000000000000000000" +UniswapV3Factory = "0x0000000000000000000000000000000000000000" +UniswapV3Quoter = "0x0000000000000000000000000000000000000000" +UniswapV4PoolManager = "0x0000000000000000000000000000000000000000" +UniswapV4Quoter = "0x0000000000000000000000000000000000000000" + +# Ethereum Mainnet +[[chains]] +chainId = 1 +rpcUrl = "${ETH_MAINNET}" +intentGatewayAddress = "0x1a4ee689a004b10210a1df9f24a387ea13359acf" +hostAddress = "0x792A6236AF69787C40cF76b69B4c8c7B28c4cA20" +consensusStateId = "ETH0" +coingeckoId = "ethereum" +wrappedNativeDecimals = 18 + +# Asset addresses for Ethereum Mainnet +[chains.assets] +WETH = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" +DAI = "0x6B175474E89094C44Da98b954EedeAC495271d0F" +USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" +USDT = "0xdAC17F958D2ee523a2206206994597C13D831ec7" + +# Contract addresses for Ethereum Mainnet +[chains.addresses] +UniswapRouter02 = "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D" +UniswapV2Factory = "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f" +BatchExecutor = "0x0000000000000000000000000000000000000000" +UniversalRouter = "0x0000000000000000000000000000000000000000" +UniswapV3Router = "0x1F98431c8aD98523631AE4a59f267346ea31F984" +UniswapV3Factory = "0x1F98431c8aD98523631AE4a59f267346ea31F984" +UniswapV3Quoter = "0x61fFE014bA17989E743c5F6cB21bF9697530B21e" +UniswapV4PoolManager = "0x0000000000000000000000000000000000000000" +UniswapV4Quoter = "0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203" + +# BSC Mainnet +[[chains]] +chainId = 56 +rpcUrl = "${BSC_MAINNET}" +intentGatewayAddress = "0x1a4ee689a004b10210a1df9f24a387ea13359acf" +hostAddress = "0x24B5d421Ec373FcA57325dd2F0C074009Af021F7" +consensusStateId = "BSC0" +coingeckoId = "binance-smart-chain" +wrappedNativeDecimals = 18 + +# Asset addresses for BSC Mainnet +[chains.assets] +WETH = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c" +DAI = "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3" +USDC = "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d" +USDT = "0x55d398326f99059fF775485246999027B3197955" + +# Contract addresses for BSC Mainnet +[chains.addresses] +UniswapRouter02 = "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24" +UniswapV2Factory = "0x8909Dc15e40173Ff4699343b6eB8132c65e18eC6" +BatchExecutor = "0x0000000000000000000000000000000000000000" +UniversalRouter = "0x0000000000000000000000000000000000000000" +UniswapV3Router = "0x0000000000000000000000000000000000000000" +UniswapV3Factory = "0x0000000000000000000000000000000000000000" +UniswapV3Quoter = "0x0000000000000000000000000000000000000000" +UniswapV4PoolManager = "0x0000000000000000000000000000000000000000" +UniswapV4Quoter = "0x0000000000000000000000000000000000000000" + +# Hyperbridge configuration +[hyperbridge] +chainId = 4009 +rpcUrl = "${HYPERBRIDGE_GARGANTUA}" + +# Confirmation policies per chain +[confirmationPolicies."97"] # BSC Testnet +minAmount = "1000000000000000000" # 1 USD with 18 decimals +maxAmount = "1000000000000000000000" # 1000 USD with 18 decimals +minConfirmations = 1 +maxConfirmations = 5 + +[confirmationPolicies."10200"] # Gnosis Chiado +minAmount = "1000000000000000000" # 1 USD with 18 decimals +maxAmount = "1000000000000000000000" # 1000 USD with 18 decimals +minConfirmations = 1 +maxConfirmations = 5 + +[confirmationPolicies."1"] # Ethereum Mainnet +minAmount = "5000000000000000000" # 5 USD with 18 decimals +maxAmount = "10000000000000000000000" # 10000 USD with 18 decimals +minConfirmations = 3 +maxConfirmations = 12 + +[confirmationPolicies."56"] # BSC Mainnet +minAmount = "1000000000000000000" # 1 USD with 18 decimals +maxAmount = "5000000000000000000000" # 5000 USD with 18 decimals +minConfirmations = 3 +maxConfirmations = 15 diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/utils.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/utils.ts new file mode 100644 index 00000000..51a87f19 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/src/utils.ts @@ -0,0 +1,27 @@ +// Returns true if candidate <= reference * (1 + thresholdBps/10000) +export function isWithinThreshold(candidate: bigint, reference: bigint, thresholdBps: bigint): boolean { + const basisPoints = 10000n + return candidate * basisPoints <= reference * (basisPoints + thresholdBps) +} + +/** + * Compares two BigInt values that represent the same logical amount but with different decimal precisions + * @param value1 - First BigInt value + * @param decimals1 - Decimal places for first value + * @param value2 - Second BigInt value + * @param decimals2 - Decimal places for second value + * @returns true if the values represent the same amount, false otherwise + */ +export function compareDecimalValues(value1: bigint, decimals1: number, value2: bigint, decimals2: number): boolean { + if (decimals1 === decimals2) { + return value1 === value2 + } + + const maxDecimals = Math.max(decimals1, decimals2) + + const normalizedValue1 = decimals1 < maxDecimals ? value1 * 10n ** BigInt(maxDecimals - decimals1) : value1 + + const normalizedValue2 = decimals2 < maxDecimals ? value2 * 10n ** BigInt(maxDecimals - decimals2) : value2 + + return normalizedValue1 === normalizedValue2 +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/tsconfig.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/tsconfig.json new file mode 100644 index 00000000..750d7beb --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/tsconfig.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig.json", + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "module": "ESNext", + "moduleResolution": "node", + "outDir": "./dist", + "sourceMap": true, + "strictNullChecks": true, + "rootDir": "./src", + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + }, + "allowSyntheticDefaultImports": true, + "types": ["node", "vitest/globals"] + }, + "include": ["src/**/*", "tests/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/tsup.config.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/tsup.config.ts new file mode 100644 index 00000000..15fea01b --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/tsup.config.ts @@ -0,0 +1,33 @@ +import { defineConfig } from "tsup" + +export default defineConfig({ + entry: ["src/index.ts", "src/bin/filler.ts"], + format: ["esm", "cjs"], + dts: true, + splitting: false, + sourcemap: true, + clean: true, + shims: true, + onSuccess: async () => { + // Add shebang only to the CLI file after build + const fs = await import("fs/promises") + const cliPath = "./dist/bin/filler.js" + const cliCjsPath = "./dist/bin/filler.cjs" + + try { + // Add shebang to ESM version + const content = await fs.readFile(cliPath, "utf-8") + if (!content.startsWith("#!/usr/bin/env node")) { + await fs.writeFile(cliPath, `#!/usr/bin/env node\n${content}`) + } + + // Add shebang to CJS version + const cjsContent = await fs.readFile(cliCjsPath, "utf-8") + if (!cjsContent.startsWith("#!/usr/bin/env node")) { + await fs.writeFile(cliCjsPath, `#!/usr/bin/env node\n${cjsContent}`) + } + } catch (error) { + console.error("Failed to add shebang to CLI files:", error) + } + }, +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/vitest.config.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/vitest.config.ts new file mode 100644 index 00000000..e173b85a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/filler/vitest.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from "vitest/config" +import tsconfigPaths from "vite-tsconfig-paths" + +export default defineConfig({ + plugins: [tsconfigPaths()], + test: { + globals: true, + }, +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/.eslintrc.js b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/.eslintrc.js new file mode 100644 index 00000000..9dfe78dc --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/.eslintrc.js @@ -0,0 +1,9 @@ +module.exports = { + extends: ["../../.eslintrc.js"], + parserOptions: { + project: "./tsconfig.json", + }, + rules: { + // Any indexer-specific overrides + }, +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/README.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/README.md new file mode 100644 index 00000000..764ab7a6 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/README.md @@ -0,0 +1,26 @@ +# @hyperbridge/indexer + +A SubQuery-based indexer service for tracking and indexing cross-chain messages within the Hyperbridge ecosystem. + +## Features + +- Index post and get requests, transfers, relayer activities and state machine updates across different chains +- Track request statuses and timeouts +- Support for EVM and Substrate chains +- Real-time data processing + +## Installation + +This package is primarily for internal use, but you can install and run it locally: + +```bash +pnpm install +pnpm build +``` + +## Running the Indexer + +Start in development mode +```bash +pnpm local +``` diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/docker/docker-compose.local.yml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/docker/docker-compose.local.yml new file mode 100644 index 00000000..743bd6d8 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/docker/docker-compose.local.yml @@ -0,0 +1,198 @@ +services: + subquery-node-hyperbridge-gargantua-local: + image: subquerynetwork/subql-node-substrate:v5.9.1 + restart: unless-stopped + network_mode: host + environment: + DB_USER: ${DB_USER} + DB_PASS: ${DB_PASS} + DB_DATABASE: ${DB_DATABASE} + DB_HOST: 0.0.0.0 + DB_PORT: ${DB_PORT} + + depends_on: + postgres: + condition: service_healthy + + volumes: + - ../src/configs:/app + - ../dist:/app/dist + command: + - ${SUB_COMMAND:-} + - -f=/app/hyperbridge-gargantua.yaml + - --db-schema=app + - --workers=${SUBQL_WORKERS:-6} + - --batch-size=${SUBQL_BATCH_SIZE:-10} + - --multi-chain + - --unsafe + - --log-level=${LOG_LEVEL:-info} + - --block-confirmations=0 + - --store-cache-async=false + - --store-cache-threshold=1 + healthcheck: + test: ["CMD", "curl", "-f", "http://subquery-node-hyperbridge-gargantua-local:3000/ready"] + interval: 3s + timeout: 5s + retries: 10 + + # subquery-node-cere-local: + # image: subquerynetwork/subql-node-substrate:v5.9.1 + # restart: unless-stopped + # network_mode: host + # environment: + # DB_USER: ${DB_USER} + # DB_PASS: ${DB_PASS} + # DB_DATABASE: ${DB_DATABASE} + # DB_HOST: 0.0.0.0 + # DB_PORT: ${DB_PORT} + + # depends_on: + # postgres: + # condition: service_healthy + + # volumes: + # - ../src/configs:/app + # - ../dist:/app/dist + # command: + # - ${SUB_COMMAND:-} + # - -f=/app/cere-local.yaml + # - --db-schema=app + # - --workers=${SUBQL_WORKERS:-6} + # - --batch-size=${SUBQL_BATCH_SIZE:-10} + # - --multi-chain + # - --unsafe + # - --log-level=${LOG_LEVEL:-info} + # - --block-confirmations=0 + # - --store-cache-async=false + # - --store-cache-threshold=1 + # healthcheck: + # test: ["CMD", "curl", "-f", "http://subquery-node-cere-local:3000/ready"] + # interval: 3s + # timeout: 5s + # retries: 10 + + subquery-node-bsc-chapel-local: + image: subquerynetwork/subql-node-ethereum:v5.5.0 + restart: unless-stopped + environment: + DB_USER: ${DB_USER} + DB_PASS: ${DB_PASS} + DB_DATABASE: ${DB_DATABASE} + DB_HOST: ${DB_HOST} + DB_PORT: ${DB_PORT} + + depends_on: + postgres: + condition: service_healthy + + volumes: + - ../src/configs:/app + - ../dist:/app/dist + command: + - ${SUB_COMMAND:-} + - -f=/app/bsc-chapel.yaml + - --db-schema=app + - --workers=${SUBQL_WORKERS:-6} + - --batch-size=${SUBQL_BATCH_SIZE:-10} + - --multi-chain + - --unsafe + - --log-level=${LOG_LEVEL:-info} + - --historical=timestamp + - --unfinalized-blocks + - --block-confirmations=0 + - --store-cache-async=false + - --store-cache-threshold=1 + healthcheck: + test: ["CMD", "curl", "-f", "http://subquery-node-bsc-chapel-local:3000/ready"] + interval: 3s + timeout: 5s + retries: 10 + + subquery-node-gnosis-chiado-local: + image: subquerynetwork/subql-node-ethereum:v5.5.0 + restart: unless-stopped + environment: + DB_USER: ${DB_USER} + DB_PASS: ${DB_PASS} + DB_DATABASE: ${DB_DATABASE} + DB_HOST: ${DB_HOST} + DB_PORT: ${DB_PORT} + + depends_on: + postgres: + condition: service_healthy + + volumes: + - ../src/configs:/app + - ../dist:/app/dist + command: + - ${SUB_COMMAND:-} + - -f=/app/gnosis-chiado.yaml + - --db-schema=app + - --workers=${SUBQL_WORKERS:-6} + - --batch-size=${SUBQL_BATCH_SIZE:-10} + - --multi-chain + - --unsafe + - --log-level=${LOG_LEVEL:-info} + - --historical=timestamp + - --unfinalized-blocks + - --block-confirmations=0 + - --store-cache-async=false + - --store-cache-threshold=1 + healthcheck: + test: ["CMD", "curl", "-f", "http://subquery-node-gnosis-chiado-local:3000/ready"] + interval: 3s + timeout: 5s + retries: 10 + + graphql-engine: + image: subquerynetwork/subql-query:v2.21.0 + restart: always + ports: + - 3100:3000 + environment: + DB_USER: ${DB_USER} + DB_PASS: ${DB_PASS} + DB_DATABASE: ${DB_DATABASE} + DB_HOST: ${DB_HOST} + DB_PORT: ${DB_PORT} + command: + - --name=app + - --playground + - --query-timeout=0 + + postgres: + image: postgres:14-alpine + ports: + - 5432:5432 + volumes: + - ${DB_PATH}:/var/lib/postgresql/data + environment: + POSTGRES_PASSWORD: ${DB_PASS} + POSTGRES_USER: ${DB_USER} + POSTGRES_DB: ${DB_DATABASE} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_DATABASE}"] + interval: 10s + timeout: 5s + retries: 5 + command: | + bash -c ' + # Start PostgreSQL in the background + docker-entrypoint.sh postgres & + + sleep 5 + + # Wait for PostgreSQL to become available + until pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB; do + echo "Waiting for PostgreSQL to start..." + sleep 1 + done + + # Run our extension creation command - note we use localhost here + echo "Creating btree_gist extension..." + psql -v ON_ERROR_STOP=1 -U $$POSTGRES_USER -d $$POSTGRES_DB -c "CREATE EXTENSION IF NOT EXISTS btree_gist;" + + # Keep container running by waiting for the PostgreSQL process + wait + ' diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/docker/docker-compose.nexus-ci.yml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/docker/docker-compose.nexus-ci.yml new file mode 100644 index 00000000..7595aff0 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/docker/docker-compose.nexus-ci.yml @@ -0,0 +1,89 @@ +services: + subquery-node-hyperbridge-nexus-ci: + image: subquerynetwork/subql-node-substrate:v5.9.1 + restart: unless-stopped + network_mode: host + environment: + DB_USER: ${DB_USER} + DB_PASS: ${DB_PASS} + DB_DATABASE: ${DB_DATABASE} + DB_HOST: 0.0.0.0 + DB_PORT: ${DB_PORT} + + depends_on: + postgres: + condition: service_healthy + + volumes: + - ../src/configs:/app + - ../dist:/app/dist + command: + - ${SUB_COMMAND:-} + - -f=/app/hyperbridge-nexus.yaml + - --db-schema=app + - --workers=${SUBQL_WORKERS:-6} + - --batch-size=${SUBQL_BATCH_SIZE:-10} + - --multi-chain + - --unsafe + - --log-level=${LOG_LEVEL:-info} + - --block-confirmations=0 + - --store-cache-async=false + - --store-cache-threshold=1 + healthcheck: + test: ["CMD", "curl", "-f", "http://subquery-node-hyperbridge-nexus-ci:3000/ready"] + interval: 3s + timeout: 5s + retries: 10 + + + graphql-engine: + image: subquerynetwork/subql-query:v2.21.0 + restart: always + ports: + - 3100:3000 + environment: + DB_USER: ${DB_USER} + DB_PASS: ${DB_PASS} + DB_DATABASE: ${DB_DATABASE} + DB_HOST: ${DB_HOST} + DB_PORT: ${DB_PORT} + command: + - --name=app + - --playground + - --query-timeout=0 + + postgres: + image: postgres:14-alpine + ports: + - 5432:5432 + volumes: + - ${DB_PATH}:/var/lib/postgresql/data + environment: + POSTGRES_PASSWORD: ${DB_PASS} + POSTGRES_USER: ${DB_USER} + POSTGRES_DB: ${DB_DATABASE} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d ${DB_DATABASE}"] + interval: 10s + timeout: 5s + retries: 5 + command: | + bash -c ' + # Start PostgreSQL in the background + docker-entrypoint.sh postgres & + + sleep 5 + + # Wait for PostgreSQL to become available + until pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB; do + echo "Waiting for PostgreSQL to start..." + sleep 1 + done + + # Run our extension creation command - note we use localhost here + echo "Creating btree_gist extension..." + psql -v ON_ERROR_STOP=1 -U $$POSTGRES_USER -d $$POSTGRES_DB -c "CREATE EXTENSION IF NOT EXISTS btree_gist;" + + # Keep container running by waiting for the PostgreSQL process + wait + ' diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/jest.config.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/jest.config.ts new file mode 100644 index 00000000..f6314f20 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/jest.config.ts @@ -0,0 +1,19 @@ +export default { + preset: "ts-jest/presets/js-with-ts", + testEnvironment: "node", + transform: { + "^.+\\.(ts|tsx)$": [ + "ts-jest", + { + tsconfig: "tsconfig.json", + useESM: false, + }, + ], + }, + testMatch: ["**/__tests__/**/*.ts?(x)", "**/?(*.)+(test).ts?(x)", "**/test/**/*.ts?(x)"], + moduleNameMapper: { + "^@/(.*)$": "/src/$1", + }, + moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], + testTimeout: 30000, +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/package.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/package.json new file mode 100644 index 00000000..b092e1f0 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/package.json @@ -0,0 +1,102 @@ +{ + "name": "@hyperbridge/indexer", + "version": "1.0.0", + "description": "SubQuery indexer for the Hyperbridge network. Indexes data from connected rollups and Hyperbridge's messaging infrastructure", + "main": "dist/index.js", + "homepage": "https://hyperbridge.network/", + "repository": { + "type": "git", + "url": "https://github.com/polytope-labs/hyperbridge-sdk" + }, + "bugs": { + "url": "https://github.com/polytope-labs/hyperbridge-sdk/issues" + }, + "files": [ + "dist", + "src/configs/schema.graphql", + "src/configs/subquery-multichain.yaml" + ], + "author": "Polytope Labs", + "license": "MIT", + "keywords": [ + "hyperbridge", + "subquery", + "indexer", + "blockchain", + "graphql", + "cryptocurrency", + "interoperability" + ], + "type": "module", + "engines": { + "node": ">=22" + }, + "scripts": { + "prepack": "rm -rf dist && npm run build", + "test": "jest --runInBand --detectOpenHandles", + "format": "prettier --write \"**/*.ts\"", + "clean": "rm -rf dist node_modules", + "server": "docker run -d --name graphql-server -p 3000:3000 --restart always --env-file ../../.env.$ENV subquerynetwork/subql-query:latest --name=app --playground", + "codegen:l2-chains": "tsx scripts/generate-l2-chains.ts", + "codegen:subql": "subql codegen -f src/configs", + "codegen:yamls": "tsx scripts/generate-chain-yamls.ts && tsx scripts/generate-compose.ts", + "start": "./scripts/up.sh ./docker/$ENV", + "down": "./scripts/down.sh ./docker/$ENV", + "start:local": "ENV=local npm run build && docker-compose -f docker/docker-compose.local.yml --env-file ../../.env.local up --force-recreate --remove-orphans && docker-compose -f docker/docker-compose.local.yml --env-file ../../.env.local rm -fsv", + "start:nexus-ci": "ENV=nexus-ci npm run build && docker-compose -f docker/docker-compose.nexus-ci.yml --env-file ../../.env.nexus-ci up --force-recreate --remove-orphans && docker-compose -f docker/docker-compose.nexus-ci.yml --env-file ../../.env.nexus-ci rm -fsv", + "build": "npm run codegen:yamls && npm run codegen:l2-chains && npm run codegen:subql && ./node_modules/.bin/subql build" + }, + "dependencies": { + "@ethersproject/abi": "^5.7.0", + "@ethersproject/providers": "^5.7.2", + "@ethersproject/shims": "^5.7.0", + "@open-web3/orml-type-definitions": "^2.0.1", + "@polkadot/api": "latest", + "@polkadot/types": "latest", + "@polkadot/util": "latest", + "@polkadot/util-crypto": "latest", + "@subql/common": "latest", + "@subql/common-ethereum": "4.7.0", + "@subql/types-core": "latest", + "@subql/types-ethereum": "latest", + "@subql/validator": "latest", + "@types/node-fetch": "latest", + "assert": "^2.0.0", + "decimal.js": "^10.5.0", + "dotenv": "^16.4.7", + "fast-text-encoding": "^1.0.6", + "handlebars": "^4.7.8", + "node-fetch": "^2.7.0", + "safe-stable-stringify": "^2.5.0", + "scale-ts": "^1.6.1", + "viem": "^2.23.5", + "zod": "^3.25.32" + }, + "devDependencies": { + "@subql/cli": "5.7.1-0", + "@subql/node": "latest", + "@subql/node-core": "latest", + "@subql/node-ethereum": "latest", + "@subql/testing": "latest", + "@subql/types": "latest", + "@types/handlebars": "^4.1.0", + "@types/jest": "^29.5.14", + "@types/node": "^22.13.5", + "@types/pino": "^7.0.4", + "ethers": "^5.7.2", + "fs-extra": "^11.3.0", + "prettier": "^3.5.2", + "rpc-websocket-client": "^1.1.4", + "ts-jest": "^29.2.6", + "ts-node": "^10.9.2", + "tslib": "^2.8.1", + "tsx": "^4.19.4", + "typescript": "latest" + }, + "exports": { + "./substrate-chaintypes/hyperbridge": "./src/substrate-chaintypes/hyperbridge.ts" + }, + "publishConfig": { + "access": "public" + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/pnpm-lock.yaml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/pnpm-lock.yaml new file mode 100644 index 00000000..ff18c2dd --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/pnpm-lock.yaml @@ -0,0 +1,13920 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@ethersproject/abi': + specifier: ^5.7.0 + version: 5.8.0 + '@ethersproject/providers': + specifier: ^5.7.2 + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@ethersproject/shims': + specifier: ^5.7.0 + version: 5.8.0 + '@open-web3/orml-type-definitions': + specifier: ^2.0.1 + version: 2.0.1 + '@polkadot/api': + specifier: latest + version: 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/types': + specifier: latest + version: 16.4.7 + '@polkadot/util': + specifier: latest + version: 13.5.6 + '@polkadot/util-crypto': + specifier: latest + version: 13.5.6(@polkadot/util@13.5.6) + '@subql/common': + specifier: latest + version: 5.7.6 + '@subql/common-ethereum': + specifier: 4.7.0 + version: 4.7.0(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10) + '@subql/types-core': + specifier: latest + version: 2.1.1 + '@subql/types-ethereum': + specifier: latest + version: 4.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@subql/validator': + specifier: latest + version: 2.2.0(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/transactions@2.0.2(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2))(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))(algosdk@2.11.0)(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(ejs@3.1.10)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(node-fetch@2.7.0(encoding@0.1.13))(typescript@5.9.2)(utf-8-validate@5.0.10) + '@types/node-fetch': + specifier: latest + version: 2.6.13 + assert: + specifier: ^2.0.0 + version: 2.1.0 + decimal.js: + specifier: ^10.5.0 + version: 10.5.0 + dotenv: + specifier: ^16.4.7 + version: 16.4.7 + fast-text-encoding: + specifier: ^1.0.6 + version: 1.0.6 + handlebars: + specifier: ^4.7.8 + version: 4.7.8 + node-fetch: + specifier: ^2.7.0 + version: 2.7.0(encoding@0.1.13) + safe-stable-stringify: + specifier: ^2.5.0 + version: 2.5.0 + scale-ts: + specifier: ^1.6.1 + version: 1.6.1 + viem: + specifier: ^2.23.5 + version: 2.23.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.32) + zod: + specifier: ^3.25.32 + version: 3.25.32 + devDependencies: + '@subql/cli': + specifier: 5.7.1-0 + version: 5.7.1-0(@types/node@22.13.9)(encoding@0.1.13)(pg@8.13.3) + '@subql/node': + specifier: latest + version: 6.3.5(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)(graphql@15.10.1)(pg@8.13.3)(rxjs@7.8.2)(utf-8-validate@5.0.10) + '@subql/node-core': + specifier: latest + version: 18.4.0(@nestjs/core@11.0.11)(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@subql/node-ethereum': + specifier: latest + version: 6.2.1(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))(@subql/utils@2.21.2(pg@8.13.3))(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)(rxjs@7.8.2)(typescript@5.9.2)(utf-8-validate@5.0.10) + '@subql/testing': + specifier: latest + version: 2.3.0 + '@subql/types': + specifier: latest + version: 3.14.2(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@types/handlebars': + specifier: ^4.1.0 + version: 4.1.0 + '@types/jest': + specifier: ^29.5.14 + version: 29.5.14 + '@types/node': + specifier: ^22.13.5 + version: 22.13.9 + '@types/pino': + specifier: ^7.0.4 + version: 7.0.5 + ethers: + specifier: ^5.7.2 + version: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + fs-extra: + specifier: ^11.3.0 + version: 11.3.0 + prettier: + specifier: ^3.5.2 + version: 3.5.3 + rpc-websocket-client: + specifier: ^1.1.4 + version: 1.1.4(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ts-jest: + specifier: ^29.2.6 + version: 29.2.6(@babel/core@7.18.10)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.18.10))(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)))(typescript@5.9.2) + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@22.13.9)(typescript@5.9.2) + tslib: + specifier: ^2.8.1 + version: 2.8.1 + tsx: + specifier: ^4.19.4 + version: 4.19.4 + typescript: + specifier: latest + version: 5.9.2 + +packages: + + '@achingbrain/node-fetch@2.6.7': + resolution: {integrity: sha512-iTASGs+HTFK5E4ZqcMsHmeJ4zodyq8L38lZV33jwqcBJYoUt3HjN4+ot+O9/0b+ke8ddE7UgOtVuZN/OkV19/g==} + engines: {node: 4.x || >=6.0.0} + + '@adraffy/ens-normalize@1.11.0': + resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@apollo/client@3.14.0': + resolution: {integrity: sha512-0YQKKRIxiMlIou+SekQqdCo0ZTHxOcES+K8vKB53cIDpwABNR0P0yRzPgsbgcj3zRJniD93S/ontsnZsCLZrxQ==} + 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 + + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.26.8': + resolution: {integrity: sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.18.10': + resolution: {integrity: sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.26.9': + resolution: {integrity: sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.18.12': + resolution: {integrity: sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.24.4': + resolution: {integrity: sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.26.9': + resolution: {integrity: sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.25.9': + resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.26.5': + resolution: {integrity: sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.26.9': + resolution: {integrity: sha512-ubbUqCofvxPRurw5L8WTsCLSkQiVpov4Qx0WMA+jUN+nXBK8ADPlJO1grkFw5CWKC5+sZSOfuGMdX1aI1iT9Sg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.26.3': + resolution: {integrity: sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.3.3': + resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} + peerDependencies: + '@babel/core': ^7.4.0-0 + + '@babel/helper-environment-visitor@7.24.7': + resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-function-name@7.24.7': + resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-hoist-variables@7.24.7': + resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.25.9': + resolution: {integrity: sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.25.9': + resolution: {integrity: sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.25.9': + resolution: {integrity: sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.26.5': + resolution: {integrity: sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': + resolution: {integrity: sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-split-export-declaration@7.24.7': + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.25.9': + resolution: {integrity: sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.26.9': + resolution: {integrity: sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.18.11': + resolution: {integrity: sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@7.26.9': + resolution: {integrity: sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9': + resolution: {integrity: sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9': + resolution: {integrity: sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + + '@babel/plugin-proposal-async-generator-functions@7.20.7': + resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-async-generator-functions instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-class-properties@7.18.6': + resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-class-static-block@7.21.0': + resolution: {integrity: sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-static-block instead. + peerDependencies: + '@babel/core': ^7.12.0 + + '@babel/plugin-proposal-dynamic-import@7.18.6': + resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-dynamic-import instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-export-default-from@7.18.10': + resolution: {integrity: sha512-5H2N3R2aQFxkV4PIBUR/i7PUSwgTZjouJKzI8eKswfIjT0PhvzkPn0t0wIS5zn6maQuvtT0t1oHtMUz61LOuow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-export-namespace-from@7.18.9': + resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-export-namespace-from instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-json-strings@7.18.6': + resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-json-strings instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-logical-assignment-operators@7.20.7': + resolution: {integrity: sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-logical-assignment-operators instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-nullish-coalescing-operator@7.18.6': + resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-numeric-separator@7.18.6': + resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-numeric-separator instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-object-rest-spread@7.18.9': + resolution: {integrity: sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-optional-catch-binding@7.18.6': + resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-catch-binding instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-optional-chaining@7.21.0': + resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-private-methods@7.18.6': + resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-private-property-in-object@7.21.11': + resolution: {integrity: sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-unicode-property-regex@7.18.6': + resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} + engines: {node: '>=4'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-unicode-property-regex instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-export-default-from@7.25.9': + resolution: {integrity: sha512-9MhJ/SMTsVqsd69GyQg89lYR4o9T+oDGv5F6IsigxxqFVOyR/IflDLYP8WDI1l8fkhNGGktqkvL5qwNCtGEpgQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-export-namespace-from@7.8.3': + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-assertions@7.26.0': + resolution: {integrity: sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.27.1': + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.25.9': + resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.25.9': + resolution: {integrity: sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-arrow-functions@7.25.9': + resolution: {integrity: sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-to-generator@7.25.9': + resolution: {integrity: sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoped-functions@7.26.5': + resolution: {integrity: sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.25.9': + resolution: {integrity: sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-classes@7.25.9': + resolution: {integrity: sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.25.9': + resolution: {integrity: sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.25.9': + resolution: {integrity: sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-dotall-regex@7.25.9': + resolution: {integrity: sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-keys@7.25.9': + resolution: {integrity: sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-exponentiation-operator@7.26.3': + resolution: {integrity: sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.26.9': + resolution: {integrity: sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.25.9': + resolution: {integrity: sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.25.9': + resolution: {integrity: sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-member-expression-literals@7.25.9': + resolution: {integrity: sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-amd@7.25.9': + resolution: {integrity: sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.26.3': + resolution: {integrity: sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-systemjs@7.25.9': + resolution: {integrity: sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-umd@7.25.9': + resolution: {integrity: sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.25.9': + resolution: {integrity: sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-new-target@7.25.9': + resolution: {integrity: sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-super@7.25.9': + resolution: {integrity: sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.25.9': + resolution: {integrity: sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.25.9': + resolution: {integrity: sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-property-literals@7.25.9': + resolution: {integrity: sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regenerator@7.25.9': + resolution: {integrity: sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-reserved-words@7.25.9': + resolution: {integrity: sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-runtime@7.18.10': + resolution: {integrity: sha512-q5mMeYAdfEbpBAgzl7tBre/la3LeCxmDO1+wMXRdPWbcoMjR3GiXlCLk7JBZVVye0bqTGNMbt0yYVXX1B1jEWQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.25.9': + resolution: {integrity: sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.25.9': + resolution: {integrity: sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-sticky-regex@7.25.9': + resolution: {integrity: sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.26.8': + resolution: {integrity: sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typeof-symbol@7.26.7': + resolution: {integrity: sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.26.8': + resolution: {integrity: sha512-bME5J9AC8ChwA7aEPJ6zym3w7aObZULHhbNLU0bKUhKsAkylkzUdq+0kdymh9rzi8nlNFl2bmldFBCKNJBUpuw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-escapes@7.25.9': + resolution: {integrity: sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-regex@7.25.9': + resolution: {integrity: sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-env@7.18.10': + resolution: {integrity: sha512-wVxs1yjFdW3Z/XkNfXKoblxoHgbtUF7/l3PvvP4m02Qz9TZ6uZGxRVYjSQeR87oQmHco9zWitW5J82DJ7sCjvA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-modules@0.1.6': + resolution: {integrity: sha512-ID2yj6K/4lKfhuU3+EX4UvNbIt7eACFbHmNUjzA+ep+B5971CknnA/9DEWKbRokfbbtblxxxXFJJrH47UEAMVg==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + + '@babel/preset-typescript@7.26.0': + resolution: {integrity: sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.26.9': + resolution: {integrity: sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.26.9': + resolution: {integrity: sha512-qyRplbeIpNZhmzOysF/wFMuP9sctmh2cFzRAZOn1YapxBsE1i9bJIY586R/WBLfLcmcBlM8ROBiQURnnNy+zfA==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.18.11': + resolution: {integrity: sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.23.6': + resolution: {integrity: sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.24.1': + resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.26.9': + resolution: {integrity: sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.18.10': + resolution: {integrity: sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.23.6': + resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.24.0': + resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.28.2': + resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@borewit/text-codec@0.1.1': + resolution: {integrity: sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==} + + '@cosmjs/amino@0.36.0': + resolution: {integrity: sha512-PxK3+1smz5N1dxJjSSsvvZdHdSM2zuUAIP6ppYLGBcYmAKlK6hJ1vR1Ity+HLKusqo22bj0CY9m3QaeLNsSPww==} + + '@cosmjs/cosmwasm-stargate@0.36.0': + resolution: {integrity: sha512-hzzT4YRMt2cRdAILzGSNSmWr1IRpN3aWxL5ceMrZaaJyVa9nD4AUeR80yPB6mzkBpHuMwbSGWz8nus0psyonRQ==} + + '@cosmjs/crypto@0.36.0': + resolution: {integrity: sha512-IdzJETWBfMlJIpWmcAi4wiAa0sdHKZDbxKdhasrpSLvhwIItXBYMvApCFx6zr+V/Hby4KnsWduI7HomiRDFr+g==} + + '@cosmjs/encoding@0.36.0': + resolution: {integrity: sha512-xFJNd1096EqNxTsdOJN+DODC5HxKmqY0L2iWEnvPFq9UD/W2olYnv0bxV0S+XTs5tF/8/NAZHU3KXxeHTZ97DA==} + + '@cosmjs/json-rpc@0.36.0': + resolution: {integrity: sha512-7cGE8cBFGrtAHsadYWFOWv0bNaK0VPNzquzU/Naj+3twgnppaGbRBrTLw3iwhqrg+Cvb9KwSYPHzaUsavojUWQ==} + + '@cosmjs/math@0.36.0': + resolution: {integrity: sha512-vLXHInZA87QXgOxGJDc2nJa4/4oPFOdQtuxD6BL5xrYI1T0G/dk06hu4gXu4Tn3YuB8R5dWGS0u5AnlNv9LeYw==} + + '@cosmjs/proto-signing@0.36.0': + resolution: {integrity: sha512-RoZOQGG9njlzArNeAfYYQ136tdi5hNBleC/r7V8HPkROpMfSuQZF3yP6ukBvt5KkNzNge4YZKqFkwINBR/Vyew==} + + '@cosmjs/socket@0.36.0': + resolution: {integrity: sha512-rAeGDyQjIFWsP6DPSTJKUP9RDW6ZM5Cm074xKG/0Tdghn0kkOaQCzwJru4SSPWi7MOlOkoZHyEMATQiNA/cQ6Q==} + + '@cosmjs/stargate@0.36.0': + resolution: {integrity: sha512-FMRPF72WyLXGTU8qWpN2ZoxOY4gfRmg7vZoO99Ru8Gt21GS95JYO+RJFTfYlP9pT7Ni6S74rxCPNqkeHMqKp6w==} + + '@cosmjs/stream@0.36.0': + resolution: {integrity: sha512-gMezM+symoCWnJlrOJ5lxB+tVNUm9JUwFR3dpHzdccGTh1Sb7oVCf6VFias85O1j0fLkCIfQR2BI/RoX97+CGQ==} + + '@cosmjs/tendermint-rpc@0.36.0': + resolution: {integrity: sha512-dTh4L1RR22JszFbZqM3i0ITPTHhrs5mUqyyeP7lEebgtLrKgzCAqsWPnqfsC6ALFhMzbeApWebG2YR9W2W68zg==} + + '@cosmjs/utils@0.36.0': + resolution: {integrity: sha512-QXyHnxDHdkj+qZZDk+CSOeEXpkPRBvMPKQ7EiEO7wuJQpMIlF3F4CSuEBuYPQOPRDP6qsKS+rj47pXoE2Kr4dw==} + + '@cosmology/protobufjs@6.11.6': + resolution: {integrity: sha512-k1opGC9CTX5vD2447pUqLmleVv0Kb8RasBUxkZHudVOvuXs2qAAGONmMIEGRCROKTodhTY9fdTnGU2lCZqAwNw==} + hasBin: true + + '@cosmwasm/ts-codegen-ast@1.8.1': + resolution: {integrity: sha512-sRa0N/DiuudrjNUcmJDXtClrsIbooEBYUmBs0e2PNFLSjSqMGFFqSaT4cQjJU3az9Hgdlhv4yvhhdysHnY5h/g==} + + '@cosmwasm/ts-codegen-types@1.3.1': + resolution: {integrity: sha512-NI0hjBCtueN8WsME9rYym6r/R3m8rVJItQeqMpulQUk8MUPeK0SGJzQlhcWLopj/YF9R+fK+kBaFN5FA8zW1MA==} + + '@cosmwasm/ts-codegen@0.34.0': + resolution: {integrity: sha512-Mt/aYj0be9GnA51Arysqr9L8KQNWUJJHoJvtru7hkHmukPSewZDilwHCOJAaehk5gjsP7LFey2o2KEdfzkANhA==} + hasBin: true + + '@cosmwasm/ts-codegen@1.12.1': + resolution: {integrity: sha512-ZJTuC0XgZteB83ZBrSbIdRCPmY18LAHWZPBufficr8c1D9BIlD4/kfFg85dVECYpVrdOwI885a5orzpVumNLKA==} + hasBin: true + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@esbuild/aix-ppc64@0.25.5': + resolution: {integrity: sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.5': + resolution: {integrity: sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.5': + resolution: {integrity: sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.5': + resolution: {integrity: sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.5': + resolution: {integrity: sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.5': + resolution: {integrity: sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.5': + resolution: {integrity: sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.5': + resolution: {integrity: sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.5': + resolution: {integrity: sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.5': + resolution: {integrity: sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.5': + resolution: {integrity: sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.5': + resolution: {integrity: sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.5': + resolution: {integrity: sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.5': + resolution: {integrity: sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.5': + resolution: {integrity: sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.5': + resolution: {integrity: sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.5': + resolution: {integrity: sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.5': + resolution: {integrity: sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.5': + resolution: {integrity: sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.5': + resolution: {integrity: sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.5': + resolution: {integrity: sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.25.5': + resolution: {integrity: sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.5': + resolution: {integrity: sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.5': + resolution: {integrity: sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.5': + resolution: {integrity: sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@ethersproject/abi@5.8.0': + resolution: {integrity: sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==} + + '@ethersproject/abstract-provider@5.8.0': + resolution: {integrity: sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==} + + '@ethersproject/abstract-signer@5.8.0': + resolution: {integrity: sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==} + + '@ethersproject/address@5.8.0': + resolution: {integrity: sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==} + + '@ethersproject/base64@5.8.0': + resolution: {integrity: sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==} + + '@ethersproject/basex@5.8.0': + resolution: {integrity: sha512-PIgTszMlDRmNwW9nhS6iqtVfdTAKosA7llYXNmGPw4YAI1PUyMv28988wAb41/gHF/WqGdoLv0erHaRcHRKW2Q==} + + '@ethersproject/bignumber@5.8.0': + resolution: {integrity: sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==} + + '@ethersproject/bytes@5.8.0': + resolution: {integrity: sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==} + + '@ethersproject/constants@5.8.0': + resolution: {integrity: sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==} + + '@ethersproject/contracts@5.8.0': + resolution: {integrity: sha512-0eFjGz9GtuAi6MZwhb4uvUM216F38xiuR0yYCjKJpNfSEy4HUM8hvqqBj9Jmm0IUz8l0xKEhWwLIhPgxNY0yvQ==} + + '@ethersproject/hash@5.8.0': + resolution: {integrity: sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==} + + '@ethersproject/hdnode@5.8.0': + resolution: {integrity: sha512-4bK1VF6E83/3/Im0ERnnUeWOY3P1BZml4ZD3wcH8Ys0/d1h1xaFt6Zc+Dh9zXf9TapGro0T4wvO71UTCp3/uoA==} + + '@ethersproject/json-wallets@5.8.0': + resolution: {integrity: sha512-HxblNck8FVUtNxS3VTEYJAcwiKYsBIF77W15HufqlBF9gGfhmYOJtYZp8fSDZtn9y5EaXTE87zDwzxRoTFk11w==} + + '@ethersproject/keccak256@5.8.0': + resolution: {integrity: sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==} + + '@ethersproject/logger@5.8.0': + resolution: {integrity: sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==} + + '@ethersproject/networks@5.8.0': + resolution: {integrity: sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==} + + '@ethersproject/pbkdf2@5.8.0': + resolution: {integrity: sha512-wuHiv97BrzCmfEaPbUFpMjlVg/IDkZThp9Ri88BpjRleg4iePJaj2SW8AIyE8cXn5V1tuAaMj6lzvsGJkGWskg==} + + '@ethersproject/properties@5.8.0': + resolution: {integrity: sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==} + + '@ethersproject/providers@5.8.0': + resolution: {integrity: sha512-3Il3oTzEx3o6kzcg9ZzbE+oCZYyY+3Zh83sKkn4s1DZfTUjIegHnN2Cm0kbn9YFy45FDVcuCLLONhU7ny0SsCw==} + + '@ethersproject/random@5.8.0': + resolution: {integrity: sha512-E4I5TDl7SVqyg4/kkA/qTfuLWAQGXmSOgYyO01So8hLfwgKvYK5snIlzxJMk72IFdG/7oh8yuSqY2KX7MMwg+A==} + + '@ethersproject/rlp@5.8.0': + resolution: {integrity: sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==} + + '@ethersproject/sha2@5.8.0': + resolution: {integrity: sha512-dDOUrXr9wF/YFltgTBYS0tKslPEKr6AekjqDW2dbn1L1xmjGR+9GiKu4ajxovnrDbwxAKdHjW8jNcwfz8PAz4A==} + + '@ethersproject/shims@5.8.0': + resolution: {integrity: sha512-6yHbI6DHVaP1KjU0n9gKm8zrzU11EXwNG3VLetyIDBr2YRGpa0nrjk1QnZtLGiOqc+6iSiIoAzfAHf6iPdUunw==} + + '@ethersproject/signing-key@5.8.0': + resolution: {integrity: sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==} + + '@ethersproject/solidity@5.8.0': + resolution: {integrity: sha512-4CxFeCgmIWamOHwYN9d+QWGxye9qQLilpgTU0XhYs1OahkclF+ewO+3V1U0mvpiuQxm5EHHmv8f7ClVII8EHsA==} + + '@ethersproject/strings@5.8.0': + resolution: {integrity: sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==} + + '@ethersproject/transactions@5.8.0': + resolution: {integrity: sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==} + + '@ethersproject/units@5.8.0': + resolution: {integrity: sha512-lxq0CAnc5kMGIiWW4Mr041VT8IhNM+Pn5T3haO74XZWFulk7wH1Gv64HqE96hT4a7iiNMdOCFEBgaxWuk8ETKQ==} + + '@ethersproject/wallet@5.8.0': + resolution: {integrity: sha512-G+jnzmgg6UxurVKRKvw27h0kvG75YKXZKdlLYmAHeF32TGUzHkOFd7Zn6QHOTYRFWnfjtSSFjBowKo7vfrXzPA==} + + '@ethersproject/web@5.8.0': + resolution: {integrity: sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==} + + '@ethersproject/wordlists@5.8.0': + resolution: {integrity: sha512-2df9bbXicZws2Sb5S6ET493uJ0Z84Fjr3pC4tu/qlnZERibZCeUVuqdtt+7Tv9xxhUxHoIekIA7avrKUWHrezg==} + + '@graphql-typed-document-node/core@3.2.0': + resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} + 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 + + '@inquirer/checkbox@2.5.0': + resolution: {integrity: sha512-sMgdETOfi2dUHT8r7TT1BTKOwNvdDGFDXYWtQ2J69SvlYNntk9I/gJe7r5yvMwwsuKnYbuRs3pNhx4tgNck5aA==} + engines: {node: '>=18'} + + '@inquirer/confirm@3.2.0': + resolution: {integrity: sha512-oOIwPs0Dvq5220Z8lGL/6LHRTEr9TgLHmiI99Rj1PJ1p1czTys+olrgBqZk4E2qC0YTzeHprxSQmoHioVdJ7Lw==} + engines: {node: '>=18'} + + '@inquirer/core@9.2.1': + resolution: {integrity: sha512-F2VBt7W/mwqEU4bL0RnHNZmC/OxzNx9cOYxHqnXX3MP6ruYvZUZAW9imgN9+h/uBT/oP8Gh888J2OZSbjSeWcg==} + engines: {node: '>=18'} + + '@inquirer/editor@2.2.0': + resolution: {integrity: sha512-9KHOpJ+dIL5SZli8lJ6xdaYLPPzB8xB9GZItg39MBybzhxA16vxmszmQFrRwbOA918WA2rvu8xhDEg/p6LXKbw==} + engines: {node: '>=18'} + + '@inquirer/expand@2.3.0': + resolution: {integrity: sha512-qnJsUcOGCSG1e5DTOErmv2BPQqrtT6uzqn1vI/aYGiPKq+FgslGZmtdnXbhuI7IlT7OByDoEEqdnhUnVR2hhLw==} + engines: {node: '>=18'} + + '@inquirer/figures@1.0.10': + resolution: {integrity: sha512-Ey6176gZmeqZuY/W/nZiUyvmb1/qInjcpiZjXWi6nON+nxJpD1bxtSoBxNliGISae32n6OwbY+TSXPZ1CfS4bw==} + engines: {node: '>=18'} + + '@inquirer/input@2.3.0': + resolution: {integrity: sha512-XfnpCStx2xgh1LIRqPXrTNEEByqQWoxsWYzNRSEUxJ5c6EQlhMogJ3vHKu8aXuTacebtaZzMAHwEL0kAflKOBw==} + engines: {node: '>=18'} + + '@inquirer/number@1.1.0': + resolution: {integrity: sha512-ilUnia/GZUtfSZy3YEErXLJ2Sljo/mf9fiKc08n18DdwdmDbOzRcTv65H1jjDvlsAuvdFXf4Sa/aL7iw/NanVA==} + engines: {node: '>=18'} + + '@inquirer/password@2.2.0': + resolution: {integrity: sha512-5otqIpgsPYIshqhgtEwSspBQE40etouR8VIxzpJkv9i0dVHIpyhiivbkH9/dGiMLdyamT54YRdGJLfl8TFnLHg==} + engines: {node: '>=18'} + + '@inquirer/prompts@5.5.0': + resolution: {integrity: sha512-BHDeL0catgHdcHbSFFUddNzvx/imzJMft+tWDPwTm3hfu8/tApk1HrooNngB2Mb4qY+KaRWF+iZqoVUPeslEog==} + engines: {node: '>=18'} + + '@inquirer/rawlist@2.3.0': + resolution: {integrity: sha512-zzfNuINhFF7OLAtGHfhwOW2TlYJyli7lOUoJUXw/uyklcwalV6WRXBXtFIicN8rTRK1XTiPWB4UY+YuW8dsnLQ==} + engines: {node: '>=18'} + + '@inquirer/search@1.1.0': + resolution: {integrity: sha512-h+/5LSj51dx7hp5xOn4QFnUaKeARwUCLs6mIhtkJ0JYPBLmEYjdHSYh7I6GrLg9LwpJ3xeX0FZgAG1q0QdCpVQ==} + engines: {node: '>=18'} + + '@inquirer/select@2.5.0': + resolution: {integrity: sha512-YmDobTItPP3WcEI86GvPo+T2sRHkxxOq/kXmsBjHS5BVXUgvgZ5AfJjkvQvZr03T81NnI3KrrRuMzeuYUQRFOA==} + engines: {node: '>=18'} + + '@inquirer/type@1.5.5': + resolution: {integrity: sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==} + engines: {node: '>=18'} + + '@inquirer/type@2.0.0': + resolution: {integrity: sha512-XvJRx+2KR3YXyYtPUUy+qd9i7p+GO9Ko6VIIpWlBrpWwXDv8WLFeHTxz35CfQFUiBMLXlGHhGzys7lqit9gWag==} + engines: {node: '>=18'} + + '@ipld/dag-cbor@6.0.15': + resolution: {integrity: sha512-Vm3VTSTwlmGV92a3C5aeY+r2A18zbH2amehNhsX8PBa3muXICaWrN8Uri85A5hLH7D7ElhE8PdjxD6kNqUmTZA==} + + '@ipld/dag-cbor@7.0.3': + resolution: {integrity: sha512-1VVh2huHsuohdXC1bGJNE8WR72slZ9XE2T3wbBBq31dm7ZBatmKLLxrB+XAqafxfRFjv08RZmj/W/ZqaM13AuA==} + + '@ipld/dag-json@8.0.11': + resolution: {integrity: sha512-Pea7JXeYHTWXRTIhBqBlhw7G53PJ7yta3G/sizGEZyzdeEwhZRr0od5IQ0r2ZxOt1Do+2czddjeEPp+YTxDwCA==} + + '@ipld/dag-pb@2.1.18': + resolution: {integrity: sha512-ZBnf2fuX9y3KccADURG5vb9FaOeMjFkCrNysB0PtftME/4iCTjxfaLoNq/IAh5fTqUOMXvryN6Jyka4ZGuMLIg==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/schemas@28.1.3': + resolution: {integrity: sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@28.1.3': + resolution: {integrity: sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@28.1.3': + resolution: {integrity: sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.6': + resolution: {integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@jsdevtools/ono@7.1.3': + resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + + '@kwsites/file-exists@1.1.1': + resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} + + '@kwsites/promise-deferred@1.1.1': + resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} + + '@lukeed/csprng@1.1.0': + resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} + engines: {node: '>=8'} + + '@near-js/crypto@2.0.2': + resolution: {integrity: sha512-qmljQFYSYaEeeOA+yz2uDnWyeggyOjQ/7jMty8JVgoY1WdqOZphOmJfIJxl8WZxc7jlc0TU4pDnt7cfd0y5MuA==} + peerDependencies: + '@near-js/types': ^2.0.1 + '@near-js/utils': ^2.0.1 + + '@near-js/providers@2.0.2': + resolution: {integrity: sha512-iFzqlZAcHUqQwXwV/o5itsbk1YvV/A6e3NlGK8cSW9vXSlNbJwrBnrzdoh/81vwpknZbdWDg0mdYa8VRvFHgLg==} + peerDependencies: + '@near-js/crypto': ^2.0.1 + '@near-js/transactions': ^2.0.1 + '@near-js/types': ^2.0.1 + '@near-js/utils': ^2.0.1 + + '@near-js/transactions@2.0.2': + resolution: {integrity: sha512-QEPY9lHJR+W7fKYLpDXEi4JhyN26embvCx/YkG9KdfRmc+oHy6jxYGiL4eovrat1DcJgTcmiz4oyHznW35Ztvw==} + peerDependencies: + '@near-js/crypto': ^2.0.1 + '@near-js/types': ^2.0.1 + '@near-js/utils': ^2.0.1 + + '@near-js/types@2.0.2': + resolution: {integrity: sha512-NihtDMLOc/iKLbmE9yvY77HMXBA724Yj2X30b2glhFXxqBbBs7QRj5QpWT/O4ay4yovmnmlGKukQABeDNQI+qw==} + + '@near-js/utils@2.0.2': + resolution: {integrity: sha512-B1Ds7PdtAfxaUkYdu5i7OwihcUACAyKd9w4b/SJ9XXJSCCARSRvMnU8McffAlq7sGfgOE0V2SK85S0U0RGZQtg==} + peerDependencies: + '@near-js/types': ^2.0.1 + + '@nestjs/common@11.1.6': + resolution: {integrity: sha512-krKwLLcFmeuKDqngG2N/RuZHCs2ycsKcxWIDgcm7i1lf3sQ0iG03ci+DsP/r3FcT/eJDFsIHnKtNta2LIi7PzQ==} + peerDependencies: + class-transformer: '>=0.4.1' + class-validator: '>=0.13.2' + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + class-transformer: + optional: true + class-validator: + optional: true + + '@nestjs/core@11.0.11': + resolution: {integrity: sha512-jMH3jrjrPiaGrkQ5hANNcgDWN+j+hcM5GMQ3jSs4vOWNs3lmKHTVR11wJ9y5tTNnwKydzMogeju0VTUdfXDI5Q==} + engines: {node: '>= 20'} + peerDependencies: + '@nestjs/common': ^11.0.0 + '@nestjs/microservices': ^11.0.0 + '@nestjs/platform-express': ^11.0.0 + '@nestjs/websockets': ^11.0.0 + reflect-metadata: ^0.1.12 || ^0.2.0 + rxjs: ^7.1.0 + peerDependenciesMeta: + '@nestjs/microservices': + optional: true + '@nestjs/platform-express': + optional: true + '@nestjs/websockets': + optional: true + + '@nestjs/event-emitter@3.0.1': + resolution: {integrity: sha512-0Ln/x+7xkU6AJFOcQI9tIhUMXVF7D5itiaQGOyJbXtlAfAIt8gzDdJm+Im7cFzKoWkiW5nCXCPh6GSvdQd/3Dw==} + peerDependencies: + '@nestjs/common': ^10.0.0 || ^11.0.0 + '@nestjs/core': ^10.0.0 || ^11.0.0 + + '@nestjs/platform-express@11.0.11': + resolution: {integrity: sha512-iv6nH66i/RuRQufg5UUboQ4jQX4NuuePrYQpHB3ueiEIhJm2yLhhNYM6Y2l/76y9woW2eckbiqbzmW/JajAgeQ==} + peerDependencies: + '@nestjs/common': ^11.0.0 + '@nestjs/core': ^11.0.0 + + '@nestjs/schedule@5.0.1': + resolution: {integrity: sha512-kFoel84I4RyS2LNPH6yHYTKxB16tb3auAEciFuc788C3ph6nABkUfzX5IE+unjVaRX+3GuruJwurNepMlHXpQg==} + peerDependencies: + '@nestjs/common': ^10.0.0 || ^11.0.0 + '@nestjs/core': ^10.0.0 || ^11.0.0 + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.8.1': + resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.7': + resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.1': + resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nuxt/opencollective@0.4.1': + resolution: {integrity: sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==} + engines: {node: ^14.18.0 || >=16.10.0, npm: '>=5.10.0'} + hasBin: true + + '@oclif/core@2.16.0': + resolution: {integrity: sha512-dL6atBH0zCZl1A1IXCKJgLPrM/wR7K+Wi401E/IvqsK8m2iCHW+0TEOGrans/cuN3oTW+uxIyJFHJ8Im0k4qBw==} + engines: {node: '>=14.0.0'} + + '@open-web3/orml-type-definitions@2.0.1': + resolution: {integrity: sha512-wqeSBOKk8UU9CBqYhK2yQh9YqwaS7vai71WuOGFNJnzRT+6WnzY0leaLTionuzfE3M4Y/jTrc8BTL6+PVFCr6Q==} + + '@opentelemetry/api@1.9.0': + resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} + engines: {node: '>=8.0.0'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@polkadot-api/json-rpc-provider-proxy@0.1.0': + resolution: {integrity: sha512-8GSFE5+EF73MCuLQm8tjrbCqlgclcHBSRaswvXziJ0ZW7iw3UEMsKkkKvELayWyBuOPa2T5i1nj6gFOeIsqvrg==} + + '@polkadot-api/json-rpc-provider@0.0.1': + resolution: {integrity: sha512-/SMC/l7foRjpykLTUTacIH05H3mr9ip8b5xxfwXlVezXrNVLp3Cv0GX6uItkKd+ZjzVPf3PFrDF2B2/HLSNESA==} + + '@polkadot-api/metadata-builders@0.3.2': + resolution: {integrity: sha512-TKpfoT6vTb+513KDzMBTfCb/ORdgRnsS3TDFpOhAhZ08ikvK+hjHMt5plPiAX/OWkm1Wc9I3+K6W0hX5Ab7MVg==} + + '@polkadot-api/observable-client@0.3.2': + resolution: {integrity: sha512-HGgqWgEutVyOBXoGOPp4+IAq6CNdK/3MfQJmhCJb8YaJiaK4W6aRGrdQuQSTPHfERHCARt9BrOmEvTXAT257Ug==} + peerDependencies: + '@polkadot-api/substrate-client': 0.1.4 + rxjs: '>=7.8.0' + + '@polkadot-api/substrate-bindings@0.6.0': + resolution: {integrity: sha512-lGuhE74NA1/PqdN7fKFdE5C1gNYX357j1tWzdlPXI0kQ7h3kN0zfxNOpPUN7dIrPcOFZ6C0tRRVrBylXkI6xPw==} + + '@polkadot-api/substrate-client@0.1.4': + resolution: {integrity: sha512-MljrPobN0ZWTpn++da9vOvt+Ex+NlqTlr/XT7zi9sqPtDJiQcYl+d29hFAgpaeTqbeQKZwz3WDE9xcEfLE8c5A==} + + '@polkadot-api/utils@0.1.0': + resolution: {integrity: sha512-MXzWZeuGxKizPx2Xf/47wx9sr/uxKw39bVJUptTJdsaQn/TGq+z310mHzf1RCGvC1diHM8f593KrnDgc9oNbJA==} + + '@polkadot/api-augment@16.4.7': + resolution: {integrity: sha512-euQOOSxpozB2VEWf4H8RuEyjkMrL7ARcdYG95tkoBUbHDACublPmGcR/v5fYkfEEap8gWcXaMfXvdGFaKw7DQQ==} + engines: {node: '>=18'} + + '@polkadot/api-base@16.4.7': + resolution: {integrity: sha512-YTvPY9gu25HfnIURFmnejXGoqyEQkdGk7i9SG4a5wUxf6McKssNpUYZcyfhD13xjN8Tu3VBO19eSFY2xa7R13A==} + engines: {node: '>=18'} + + '@polkadot/api-derive@16.4.7': + resolution: {integrity: sha512-B5iephoFa7Hy+cCI4QxKgm9zYLQ93wMqKnd388DHuEsvCQ9exShtM3HdzTZUZAGl7GxWvustGOkConL4Ys0LKw==} + engines: {node: '>=18'} + + '@polkadot/api@16.4.7': + resolution: {integrity: sha512-aQypyQOmCUFmxmQ46jqLJYcptQ6xvceVrHuoUac4hFavejBjsGl2yM1uZo1ixpOTCCaK1/Dve8soF03YVedKLg==} + engines: {node: '>=18'} + + '@polkadot/keyring@13.5.6': + resolution: {integrity: sha512-Ybe6Mflrh96FKR5tfEaf/93RxJD7x9UigseNOJW6Yd8LF+GesdxrqmZD7zh+53Hb7smGQWf/0FCfwhoWZVgPUQ==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': 13.5.6 + '@polkadot/util-crypto': 13.5.6 + + '@polkadot/networks@13.5.6': + resolution: {integrity: sha512-9HqUIBOHnz9x/ssPb0aOD/7XcU8vGokEYpLoNgexFNIJzqDgrDHXR197iFpkbMqA/+98zagrvYUyPYj1yYs9Jw==} + engines: {node: '>=18'} + + '@polkadot/rpc-augment@16.4.7': + resolution: {integrity: sha512-CWrvtaYIOEB7Em8zGHuEq921WwVanWZomWudW1Sea3mHDuOvM46C6j5yQV8S9udLghqSNZjIemPyRPfyP/VgrA==} + engines: {node: '>=18'} + + '@polkadot/rpc-core@16.4.7': + resolution: {integrity: sha512-bm7WsbhHjrmKziRPQ7/2ua6BDl5f+7DCBqdMBbIMaOQtRtzA/hU2NkEnR71GsJ5A7awJBTNjnfaufvty9E4fnA==} + engines: {node: '>=18'} + + '@polkadot/rpc-provider@16.4.7': + resolution: {integrity: sha512-AW2eA+5/kJbCYPYcPZTmFyP4oedjcI+Qwu3mMtA42+rxVr67H8Rxm+rbooWd4MzwZB3LrKUo9fh40nKlQsc31w==} + engines: {node: '>=18'} + + '@polkadot/types-augment@16.4.7': + resolution: {integrity: sha512-MIuzMdrshbNtCJUR4QhVZUulAmcyXVkSo+6N9yMdMdhprKdfMt5WOlEt0iVEex39oDp2mlIqI8txMyYEK/GJcA==} + engines: {node: '>=18'} + + '@polkadot/types-codec@16.4.7': + resolution: {integrity: sha512-IA/KLpebFDcT/uwkXlt08BkpRdDeo29xLRt9+dTtNZjd5L+gJzph+W6VV/L/mOzRDhWUwz2C1a2VZJdqZQeWmQ==} + engines: {node: '>=18'} + + '@polkadot/types-create@16.4.7': + resolution: {integrity: sha512-KTqMikEr/Lef8J8ftrRQIz68xoG53I3mBbDMFk3QKURIQnbxSPo39tlJ7KFYdiJduyTO9E2wI3sYfbZic9jXxw==} + engines: {node: '>=18'} + + '@polkadot/types-known@16.4.7': + resolution: {integrity: sha512-L5n6Lc/J96p0sFh6TsiTMO1kKIdQQVYtafvqo4MQuoGCKzdpkeDiq9wujJYyegeeiVXqmUdezDyYGdNlbjbwUg==} + engines: {node: '>=18'} + + '@polkadot/types-support@16.4.7': + resolution: {integrity: sha512-/378JPqrIuMmw/ae845p295++w5//e8/4foRzms1Q5bK0RpsLqPFuh/b24iPEdzIpdRqSvdSJg9rJPGBeESfkw==} + engines: {node: '>=18'} + + '@polkadot/types@16.4.7': + resolution: {integrity: sha512-Z6EPaUuulGI1ohd3c9gCVhc4UeVE0/uNAUjlo0M5FTo+FDrLWLBL3fITuTHtKlLUwq+btwAT92cZUPderXaJjQ==} + engines: {node: '>=18'} + + '@polkadot/util-crypto@13.5.6': + resolution: {integrity: sha512-1l+t5lVc9UWxvbJe7/3V+QK8CwrDPuQjDK6FKtDZgZCU0JRrjySOxV0J4PeDIv8TgXZtbIcQFVUhIsJTyKZZJQ==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': 13.5.6 + + '@polkadot/util@13.5.6': + resolution: {integrity: sha512-V+CkW2VdhcMWvl7eXdmlCLGqLxrKvXZtXE76KBbPP5n0Z+8DqQ58IHNOE9xe2LOgqDwIzdLlOUwkyF9Zj19y+Q==} + engines: {node: '>=18'} + + '@polkadot/wasm-bridge@7.5.1': + resolution: {integrity: sha512-E+N3CSnX3YaXpAmfIQ+4bTyiAqJQKvVcMaXjkuL8Tp2zYffClWLG5e+RY15Uh+EWfUl9If4y6cLZi3D5NcpAGQ==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': '*' + '@polkadot/x-randomvalues': '*' + + '@polkadot/wasm-crypto-asmjs@7.5.1': + resolution: {integrity: sha512-jAg7Uusk+xeHQ+QHEH4c/N3b1kEGBqZb51cWe+yM61kKpQwVGZhNdlWetW6U23t/BMyZArIWMsZqmK/Ij0PHog==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': '*' + + '@polkadot/wasm-crypto-init@7.5.1': + resolution: {integrity: sha512-Obu4ZEo5jYO6sN31eqCNOXo88rPVkP9TrUOyynuFCnXnXr8V/HlmY/YkAd9F87chZnkTJRlzak17kIWr+i7w3A==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': '*' + '@polkadot/x-randomvalues': '*' + + '@polkadot/wasm-crypto-wasm@7.5.1': + resolution: {integrity: sha512-S2yQSGbOGTcaV6UdipFVyEGanJvG6uD6Tg7XubxpiGbNAblsyYKeFcxyH1qCosk/4qf+GIUwlOL4ydhosZflqg==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': '*' + + '@polkadot/wasm-crypto@7.5.1': + resolution: {integrity: sha512-acjt4VJ3w19v7b/SIPsV/5k9s6JsragHKPnwoZ0KTfBvAFXwzz80jUzVGxA06SKHacfCUe7vBRlz7M5oRby1Pw==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': '*' + '@polkadot/x-randomvalues': '*' + + '@polkadot/wasm-util@7.5.1': + resolution: {integrity: sha512-sbvu71isFhPXpvMVX+EkRnUg/+54Tx7Sf9BEMqxxoPj7cG1I/MKeDEwbQz6MaU4gm7xJqvEWCAemLFcXfHQ/2A==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': '*' + + '@polkadot/x-bigint@13.5.6': + resolution: {integrity: sha512-HpqZJ9ud94iK/+0Ofacw7QdtvzFp6SucBBml4XwWZTWoLaLOGDsO7FoWE7yCuwPbX8nLgIM6YmQBeUoZmBtVqQ==} + engines: {node: '>=18'} + + '@polkadot/x-fetch@13.5.6': + resolution: {integrity: sha512-gqx8c6lhnD7Qht+56J+4oeTA8YZ9bAPqzOt2cRJf9MTplMy44W6671T2p6hA3QMvzy4aBTxMie3uKc4tGpLu4A==} + engines: {node: '>=18'} + + '@polkadot/x-global@13.5.6': + resolution: {integrity: sha512-iw97n0Bnl2284WgAK732LYR4DW6w5+COfBfHzkhiHqs5xwPEwWMgWGrf2hM8WAQqNIz6Ni8w/jagucPyQBur3Q==} + engines: {node: '>=18'} + + '@polkadot/x-randomvalues@13.5.6': + resolution: {integrity: sha512-w1F9G7FxrJ7+hGC8bh9/VpPH4KN8xmyzgiQdR7+rVB2V8KsKQBQidG69pj5Kwsh3oODOz0yQYsTG6Rm6TAJbGA==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': 13.5.6 + '@polkadot/wasm-util': '*' + + '@polkadot/x-textdecoder@13.5.6': + resolution: {integrity: sha512-jTGeYCxFh89KRrP7bNj1CPqKO36Onsi0iA6A+5YtRS5wjdQU+/OFM/EHLTP2nvkvZo/tOkOewMR9sausisUvVQ==} + engines: {node: '>=18'} + + '@polkadot/x-textencoder@13.5.6': + resolution: {integrity: sha512-iVwz9+OrYCEF9QbNfr9M206mmWvY/AhDmGPfAIeTR4fRgKGVYqcP8RIF8iu/x0MVQWqiVO3vlhlUk7MfrmAnoQ==} + engines: {node: '>=18'} + + '@polkadot/x-ws@13.5.6': + resolution: {integrity: sha512-247ktVp/iE57NTXjFpHaoPoDcvoEPb8+16r2Eq0IBQ2umOV7P6KmxvdNx5eFUvRsgXvBpNwUXE1WVnXjK/eDtA==} + engines: {node: '>=18'} + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.4': + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.0': + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.0': + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + + '@protobufs/amino@0.0.11': + resolution: {integrity: sha512-JRIkW6/YGIUfbdDuASt3wsuxzC0Xj3U2sV0Arqa9iNwCvv4HtOpbqdWVVVgvQBnR0/ZkwQeXnt+GH7yT/DvsYQ==} + + '@protobufs/confio@0.0.6': + resolution: {integrity: sha512-abZ0ntTJBuB8q2aMBvOerAFk8CSzafB09YdttKFEqwxokZsLFZ3+o7YaH3RIk863oeM//8sonwTaxRV8r4rmSA==} + + '@protobufs/cosmos@0.1.0': + resolution: {integrity: sha512-L3NZ+z0kI6GMTiD2HASNe3WbopPhQlaQaKZNRue+8LiGEv/vbbxD1lox8cwOqes3AN5dHiT0i3+gvzIbKBb7gw==} + + '@protobufs/cosmos_proto@0.0.10': + resolution: {integrity: sha512-4nMopXxN23udy1HEe+vS49zD9dxrA7i0E3n15QUz1x0tbrowYLHzJKeyCUNlsh5PKpEIXGxHXpPZWXs7vVCwUw==} + + '@protobufs/cosmwasm@0.1.1': + resolution: {integrity: sha512-7rRkQVo7zWjTX+WKdtgM72KEnioGumA7ivYG+3ZGs/uuf8rwN8PmdWFYhLbMkSbPbyJf1bFSyjpP/+kxpH71ew==} + + '@protobufs/gogoproto@0.0.10': + resolution: {integrity: sha512-u3eK1aSO3KOuX4RVFpqKPTaT/WLV50GFLuIC3slVGfD7Z1CfZ5ivHbFYUib96gihu1Mq2OZpNVj3dNws9YsVoQ==} + + '@protobufs/google@0.0.10': + resolution: {integrity: sha512-3yo+liabFM1519smwwfzh1C535CntXVsS7zT98xmo21tZUX7vxeFpQDMx38EzMGYSy/Reo8wEMWJUHqZzYsCUw==} + + '@protobufs/ibc@0.1.0': + resolution: {integrity: sha512-GmGkX81yyd55Tm34SCOmcOiB0QRwFBHGmZpDRAsks33TBx4efAtT9rKAdtn/oPujx9sha1TqU2s3trnMPVvKyg==} + + '@protobufs/tendermint@0.0.10': + resolution: {integrity: sha512-hAAMLFhKdAovslKeWnLTp2gGn5bxSTDVcQLKs4C4cC91R/KfHOh+Klt4PqSGUv/APINAmREzsX2LDUbIQ2dCpg==} + + '@pyramation/json-schema-ref-parser@9.0.6': + resolution: {integrity: sha512-L5kToHAEc1Q87R8ZwWFaNa4tPHr8Hnm+U+DRdUVq3tUtk+EX4pCqSd34Z6EMxNi/bjTzt1syAG9J2Oo1YFlqSg==} + + '@pyramation/json-schema-to-typescript@11.0.4': + resolution: {integrity: sha512-+aSzXDLhMHOEdV2cJ7Tjg/9YenjHU5BCmClVygzwxJZ1R16NOfEn7lTAwVzb/2jivOSnhjHzMJbnSf8b6rd1zg==} + engines: {node: '>=12.0.0'} + hasBin: true + + '@scure/base@1.2.4': + resolution: {integrity: sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==} + + '@scure/bip32@1.6.2': + resolution: {integrity: sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==} + + '@scure/bip39@1.5.4': + resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==} + + '@sinclair/typebox@0.24.51': + resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sindresorhus/is@0.14.0': + resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==} + engines: {node: '>=6'} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@subql/cli@5.7.1-0': + resolution: {integrity: sha512-DEubqELTkJn+1wK6IheCtrc2ylLjTmm1nhbq4c2rr1IBB0IbRWckwLqCsv+ju0fqgTOCQlV7sqIASphEFbyD5g==} + engines: {node: '>=8.0.0'} + hasBin: true + + '@subql/common-algorand@4.4.3': + resolution: {integrity: sha512-hfQigcwdV1rRR84AbLNYP9jpGAEzrSuT54xj6fdHpWeiMxmioZHPaAkRxQ/JAEQFw/HaDcJMlA8kES3Pk+KhnA==} + peerDependencies: + algosdk: '*' + class-transformer: '*' + class-validator: '*' + js-yaml: '*' + + '@subql/common-cosmos@5.5.0': + resolution: {integrity: sha512-tuK3y4lgJp5yOMJJTQgwLwhakgqaI/72ccMIzDzJUE/C2UMWS6XLZIiE8gZOG4VnEHgyPBWUKi1IPTG1Q1s1kg==} + peerDependencies: + class-transformer: '*' + class-validator: '*' + ejs: '*' + + '@subql/common-ethereum@4.7.0': + resolution: {integrity: sha512-TSgNVxOkF58udoSCqK5WpXUbDjs7Jxj/78vgoczbxOn0RNFzPNjc+m5JxTBPNqDvGKOvBThgVK0EclByCHYfBw==} + peerDependencies: + class-transformer: '*' + class-validator: '*' + + '@subql/common-ethereum@4.9.3': + resolution: {integrity: sha512-JhrfSG5JUsOZpdI0/BoZJAGduoEW3U9RSw71rhgxxIcikn/0DHL9dhIaw03NikTyFfq2qmu0OO4mPYv/fKsbbw==} + peerDependencies: + class-transformer: '*' + class-validator: '*' + + '@subql/common-flare@3.8.3': + resolution: {integrity: sha512-j69Cq5VdH+IPDz7NJrGpDXA0gTO8IEFFeVgP2RWcVYomnTY1ur0bR6R2mmj7Xo8V8meOkJwWwhAjlMc3gzVAlQ==} + deprecated: '@subql/common-flare is not longer supported, please use @subql/common-ethereum instead' + peerDependencies: + class-transformer: '*' + class-validator: '*' + + '@subql/common-near@4.3.4': + resolution: {integrity: sha512-6D2QihcNZzTalKOUylH/geJ1/bMvZll87UdKRVY64B75sXRymeDNDI48YHFdGvFowKIr49s54LErXAZi0BooSA==} + peerDependencies: + class-transformer: '*' + class-validator: '*' + + '@subql/common-stellar@2.3.1': + resolution: {integrity: sha512-po36m7wJ99MsC8gRStix0IrcZATSidYPB6nSagfI9gxMOigxMkaatJoUZRDJ4j+p54YbVzW4RyGBGes+2XQ3Ew==} + peerDependencies: + class-transformer: '*' + class-validator: '*' + + '@subql/common-substrate@2.3.0': + resolution: {integrity: sha512-P56oKPZsjx5DJZZbJaSPvMvkMSz9SarjWQbx3dQHlsSNS6bF5ys9kLP3yUtL4osNHMpf5iKZa5FwWy/c9FF6Yw==} + peerDependencies: + class-transformer: '*' + class-validator: '*' + + '@subql/common-substrate@4.5.2': + resolution: {integrity: sha512-6ehMkqP7cmfEwEIi7Krpae/J6UpPier63DWRUyHz6GZ8I8QII6AlJItiD65sqk1QRhmb6SlPHfAREh5Nhqq8Hw==} + peerDependencies: + class-transformer: ^0.5.1 + class-validator: 0.14.1 + + '@subql/common@2.5.0': + resolution: {integrity: sha512-c35OSM8jSyIjipPSW6KUMf4jEtH/YN84tteoJrD4cUe35CxniIPC4FRA2YfzEaSgi85wHc02QNkO/uNYIX+WEA==} + + '@subql/common@2.6.0': + resolution: {integrity: sha512-yMABeCWU9QU4DfhZl1aO4FcMGbBc9Gp5IbjLXRXLg4VBs7lB2SVF4t9zAFmlgO8z8KY6TjIOT6+/idhgG9q3sQ==} + + '@subql/common@3.9.0': + resolution: {integrity: sha512-BeHvRlkOZdl8iRoKnZz9bTi7exq86kM+k+3AB88aRlcKaLllJmNKXMKEjwKKfob400O9Cv2JOgP3cdfcSUwftA==} + + '@subql/common@5.4.0': + resolution: {integrity: sha512-xCB13yE3mXXvdJhnsw+8epREDYnT17Lw9+2wL6ihXXWwbVqIkBMsVuEjyhMG+q4/KMj972rSD0dziy0OyxnDcA==} + + '@subql/common@5.7.6': + resolution: {integrity: sha512-g+lpTJviSn0YYZuWKS/CO1E07IqOuupZqWGdYXfJmiXaFs+mcf67DuXWCtbpM2IHMs2w32+M8iV6WanOU9VdAA==} + + '@subql/node-core@18.4.0': + resolution: {integrity: sha512-7htOEYQxbNeCoV9wvMRTYpY2ofJ0vxH8HIpq0lz5DVVkw4+wHnV3h6aO8QI+IBd4PydaRe74IzHV6URn59C0dA==} + + '@subql/node-ethereum@6.2.1': + resolution: {integrity: sha512-2xQ8MniVp07wlj9cSs6ymmu9+2jwr+Ahd6wOCI6fW44wUH5qAkJS03g/qLF1WhpXvNGvnTn+aD1zgWer7XX4GA==} + hasBin: true + peerDependencies: + '@subql/utils': '*' + + '@subql/node@6.3.5': + resolution: {integrity: sha512-/isw3kFE5SeS/voeIDExKFQ/rrrIxIWiUNNkSly1MUBehUEqRYqbv3WTn6jXvGOMEVzumfZhsAARFuio8dRkpg==} + hasBin: true + + '@subql/testing@2.3.0': + resolution: {integrity: sha512-kYH/ua/0ur6NMMacYPn5MgjXw5aHI0hGRwC5+Roju+zm/75NTBtyLNEratLC1RqBkqJxXJZDAT13BsNbpP7hWw==} + + '@subql/types-algorand@4.1.1': + resolution: {integrity: sha512-uVSMLf6ibx+01s5QRbvFJ8p2HQiy8Yjdr6Y7lLcDCVJIXBEjVNETXyViKMfWdzFs0zoQNmzPYdEVfyvThNepTg==} + peerDependencies: + algosdk: ^2.8.0 + + '@subql/types-core@0.7.0': + resolution: {integrity: sha512-/Is7bqy9x769N3BnRLUQJPx1q4QQZqYt9VwqYJguOEKmPLMFjChlr988hIDwvRCxN6SmemzZvFFnKH0Vmj7gEw==} + + '@subql/types-core@0.8.0': + resolution: {integrity: sha512-qoGS+DIiBCqam+HNZNHNEgiRkc97gwBNYcgdA3k3Qj4vTcdvfSsguLY5SQ/YYh5gn1oO0MwnRDoZei6T174YRA==} + + '@subql/types-core@2.0.1': + resolution: {integrity: sha512-y+QaxZYtJK1Pr3XXBVcPYtBQi/d/u5QHYiru5DxZG/lMCnqAjVmumI2dT98iKt4aDRlDAiMEBrrAiYQyxhXWhQ==} + + '@subql/types-core@2.1.1': + resolution: {integrity: sha512-O8nYq7ijodr8rkBqH1HY2OEAkmXh4+RtHnWiIcvL6Glq5uQCPV/XMfRODc0H1ceuaLYH5QjZYEHDfOD2dXaO0w==} + + '@subql/types-cosmos@4.2.0': + resolution: {integrity: sha512-vTO4N1QrRX9tKZ+RZm+G9g/XEjdPo5U/a122fPESpm5slZwZSLbnF89/JLnioTR9jzuupDR+mxQ4Ej4YNHYM0A==} + + '@subql/types-ethereum@4.1.0': + resolution: {integrity: sha512-Q8M0R3cHs09bdupIDMnXbmaAWMCH2SqcQ3BEtbVtozlZF2ta9712BMAIAK7mP2GdfXs1xnP7gpaap7Iq6wNihQ==} + + '@subql/types-ethereum@4.2.2': + resolution: {integrity: sha512-AFfR1uMx1u4aIxxDGFTXW+STUq/cVZefP69ls4J/BVgmgq4j4sLZ7DL3s3gHkqnAV7s3t3SJ4BNIinfg4KdHvQ==} + + '@subql/types-flare@3.6.1': + resolution: {integrity: sha512-ovCmQnylrFlk5X0ePCroQ23AypYBAGltU+6lYDlqayUbgQQO5QDBDCv1YvK7rljylE0vjP+mn9OR+TPb+n17ew==} + deprecated: '@subql/types-flare is not longer supported, please use @subql/types-ethereum instead' + + '@subql/types-near@5.0.1': + resolution: {integrity: sha512-W0NO7hMsOb0JUFMSUsVIjNkAiYFDcQkjBlvsRE36IKRvbkIIxCeCftWEolTeVN+6/Unzx6TZjhu6ogK9hH4rtg==} + + '@subql/types-stellar@2.3.0': + resolution: {integrity: sha512-O6bxDSAE/DRAW7lNsakZLQwuQb9VY7HUU52K3j/mwmANfOmppxcFY9/JXAstK+3b7mf2Kb6DdVOgSPEuRiAjbQ==} + + '@subql/types@2.1.3': + resolution: {integrity: sha512-YNnH3npZwogTe3zM/ET6CXX4ouY1fTxR8uMl2x7fdGLIhWRbxNCbZwRvQ8pHupreYxRREghSZwQ4gQmImTKNlw==} + peerDependencies: + '@polkadot/api': ^10 + + '@subql/types@3.14.2': + resolution: {integrity: sha512-vRzjs84Vqi2QAn3klQ0T6BP10Stvt2MJzGINetOpycdiFFF9UihQBRFQU6vMjEdHSBuz6SepjcZhbVLgZtpVtA==} + peerDependencies: + '@polkadot/api': ^16 + + '@subql/utils@2.18.0': + resolution: {integrity: sha512-cDK7lGvdLmw4EaTb6MhpgeqZxopNgc/1I+fo7xvIcY8zX2wVvLdp9kX0tLA0imUuQgKwNDYRc6nvKJN7imWz5Q==} + + '@subql/utils@2.21.2': + resolution: {integrity: sha512-4hl2B4PaZ53BajpBdjNG+jMomYNHTr7UQbZzEvuPIIGJWX7oYBpkW2qJtvFb5a+2XXxggxoJxenjkV3uVz7dEA==} + + '@subql/validator@2.2.0': + resolution: {integrity: sha512-1A/JyLfDFaIgoRQ5vZZZi+kYmoQ3a3Kcz6i9KAceZh8zC/QNOO6cxycMmk2ADb55OyeCQZiDTk7h6/IU+iAVZg==} + + '@subql/x-cosmology-ast@1.4.10': + resolution: {integrity: sha512-oXIDzneQJy9IzwjRwrLONDx6Q4tyJnX5ELUZqoHf8YXQExTdNO73ufcQah52Curq0Y465mxcdptil1urmEe4zg==} + + '@subql/x-cosmology-proto-parser@1.4.6': + resolution: {integrity: sha512-8xYLuTvo1KlsSoprZGA0MHzG3eoLSUUWZT1gKL9TII9TlUHFO7HvXsaot8VutkxmqdfkrsenzyNFI9KLngZg6w==} + + '@subql/x-cosmology-telescope@1.4.14': + resolution: {integrity: sha512-vyt8Hs/HTCaEO4JAeU5XD8ZqUHx/aWBxKmBRHt+UX+X3FnhHSxsj9WjV2MPvP/dkvM1f5YH0Gds8SyasK2XymA==} + hasBin: true + + '@subql/x-cosmology-types@1.4.4': + resolution: {integrity: sha512-t/5hpflOrc1+Q13Ob5+xXesPM/6+V9qaRmUBkXbo4TlwVSWuKZT5kVAt6w9YUnbx3g9UECE+v7Mht2X4PmyL5A==} + + '@subql/x-cosmology-utils@1.4.4': + resolution: {integrity: sha512-7nTz2L8UwbhjSm+KMVGV5bPVYj/uM2M5poxdnp671J6H8oxamcTO9lSqAQJzIRWC4eZ4fH9kqW8u8mCKOChoOw==} + + '@subql/x-sequelize@6.32.0-0.0.4': + resolution: {integrity: sha512-J4ffdh2OwNSGBHzRHIudbmLrV/sJnh1eQ9heV3DVXb406KxmjUTVGfIAp//ObOImW3C3P3RY9/WyAE5AklaGBg==} + engines: {node: '>=10.0.0'} + peerDependencies: + ibm_db: '*' + mariadb: '*' + mysql2: '*' + oracledb: '*' + pg: '*' + pg-hstore: '*' + snowflake-sdk: '*' + sqlite3: '*' + tedious: '*' + peerDependenciesMeta: + ibm_db: + optional: true + mariadb: + optional: true + mysql2: + optional: true + oracledb: + optional: true + pg: + optional: true + pg-hstore: + optional: true + snowflake-sdk: + optional: true + sqlite3: + optional: true + tedious: + optional: true + + '@substrate/connect-extension-protocol@2.2.2': + resolution: {integrity: sha512-t66jwrXA0s5Goq82ZtjagLNd7DPGCNjHeehRlE/gcJmJ+G56C0W+2plqOMRicJ8XGR1/YFnUSEqUFiSNbjGrAA==} + + '@substrate/connect-known-chains@1.9.2': + resolution: {integrity: sha512-uEmm+rKJQQhhbforvmcg74TsDHKFVBkstjPwblGT1RdHMxUKR7Gq7F8vbkGnr5ce9tMK2Ylil760Z7vtX013hw==} + + '@substrate/connect@0.8.11': + resolution: {integrity: sha512-ofLs1PAO9AtDdPbdyTYj217Pe+lBfTLltdHDs3ds8no0BseoLeAGxpz1mHfi7zB4IxI3YyAiLjH6U8cw4pj4Nw==} + deprecated: versions below 1.x are no longer maintained + + '@substrate/light-client-extension-helpers@1.0.0': + resolution: {integrity: sha512-TdKlni1mBBZptOaeVrKnusMg/UBpWUORNDv5fdCaJklP4RJiFOzBCrzC+CyVI5kQzsXBisZ+2pXm+rIjS38kHg==} + peerDependencies: + smoldot: 2.x + + '@substrate/ss58-registry@1.51.0': + resolution: {integrity: sha512-TWDurLiPxndFgKjVavCniytBIw+t4ViOi7TYp9h/D0NMmkEc9klFTo+827eyEJ0lELpqO207Ey7uGxUa+BS1jQ==} + + '@szmarczak/http-timer@1.1.2': + resolution: {integrity: sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==} + engines: {node: '>=6'} + + '@tokenizer/inflate@0.2.7': + resolution: {integrity: sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==} + engines: {node: '>=18'} + + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@typechain/ethers-v5@11.1.2': + resolution: {integrity: sha512-ID6pqWkao54EuUQa0P5RgjvfA3MYqxUQKpbGKERbsjBW5Ra7EIXvbMlPp2pcP5IAdUkyMCFYsP2SN5q7mPdLDQ==} + peerDependencies: + '@ethersproject/abi': ^5.0.0 + '@ethersproject/providers': ^5.0.0 + ethers: ^5.1.3 + typechain: ^8.3.2 + typescript: '>=4.3.0' + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/bn.js@5.1.6': + resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} + + '@types/cli-progress@3.11.6': + resolution: {integrity: sha512-cE3+jb9WRlu+uOSAugewNpITJDt1VF8dHOopPO4IABFc3SXYL5WE/+PTz/FCdZRRfIujiWW3n3aMbv1eIGVRWA==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/eslint-scope@3.7.7': + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/eventsource@1.1.15': + resolution: {integrity: sha512-XQmGcbnxUNa06HR3VBVkc9+A2Vpi9ZyLJcdS5dwaQQ/4ZMWFO+5c90FnMUpbtMZwB/FChoYHwuVg8TvkECacTA==} + + '@types/glob@7.2.0': + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + + '@types/glob@8.1.0': + resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/handlebars@4.1.0': + resolution: {integrity: sha512-gq9YweFKNNB1uFK71eRqsd4niVkXrxHugqWFQkeLRJvGjnxsLr16bYtcsG4tOFwmYi0Bax+wCkbf1reUfdl4kA==} + deprecated: This is a stub types definition. handlebars provides its own type definitions, so you do not need this installed. + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@29.5.14': + resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/keyv@3.1.4': + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + + '@types/lodash@4.17.16': + resolution: {integrity: sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==} + + '@types/long@4.0.2': + resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} + + '@types/luxon@3.4.2': + resolution: {integrity: sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA==} + + '@types/minimatch@3.0.5': + resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} + + '@types/minimatch@5.1.2': + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/mute-stream@0.0.4': + resolution: {integrity: sha512-CPM9nzrCPPJHQNA9keH9CVkVI+WR5kMa+7XEs5jcGQ0VoAGnLv242w8lIVgwAEfmE4oufJRaTc9PNLQl0ioAow==} + + '@types/node-fetch@2.6.13': + resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} + + '@types/node@22.13.9': + resolution: {integrity: sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==} + + '@types/parse-package-name@0.1.0': + resolution: {integrity: sha512-+vF4M3Cd3Ec22Uwb+OKhDrSAcXQ5I6evRx+1letx4KzfzycU+AOEDHnCifus8In11i8iYNFXPfzg9HWTcC1h+Q==} + + '@types/pino@7.0.5': + resolution: {integrity: sha512-wKoab31pknvILkxAF8ss+v9iNyhw5Iu/0jLtRkUD74cNfOOLJNnqfFKAv0r7wVaTQxRZtWrMpGfShwwBjOcgcg==} + deprecated: This is a stub types definition. pino provides its own type definitions, so you do not need this installed. + + '@types/prettier@2.7.3': + resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} + + '@types/randombytes@2.0.3': + resolution: {integrity: sha512-+NRgihTfuURllWCiIAhm1wsJqzsocnqXM77V/CalsdJIYSRGEHMnritxh+6EsBklshC+clo1KgnN14qgSGeQdw==} + + '@types/responselike@1.0.3': + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + + '@types/rimraf@3.0.2': + resolution: {integrity: sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==} + + '@types/shelljs@0.8.15': + resolution: {integrity: sha512-vzmnCHl6hViPu9GNLQJ+DZFd6BQI2DBTUeOvYHqkWQLMfKAAQYMb/xAmZkTogZI/vqXHCWkqDRymDI5p0QTi5Q==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/tough-cookie@4.0.5': + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + + '@types/urijs@1.19.25': + resolution: {integrity: sha512-XOfUup9r3Y06nFAZh3WvO0rBU4OtlfPB/vgxpjg+NRdGU6CN6djdc6OEiH+PcqHCY6eFLo9Ista73uarf4gnBg==} + + '@types/validator@13.12.2': + resolution: {integrity: sha512-6SlHBzUW8Jhf3liqrGGXyTJSIFe4nqlJ5A5KaMZ2l/vbM3Wh3KSybots/wfWVzNLK4D1NZluDlSQIbIEPx6oyA==} + + '@types/wrap-ansi@3.0.0': + resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + + '@willsoto/nestjs-prometheus@6.0.2': + resolution: {integrity: sha512-ePyLZYdIrOOdlOWovzzMisIgviXqhPVzFpSMKNNhn6xajhRHeBsjAzSdpxZTc6pnjR9hw1lNAHyKnKl7lAPaVg==} + peerDependencies: + '@nestjs/common': ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 + prom-client: ^15.0.0 + + '@wry/caches@1.0.1': + resolution: {integrity: sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA==} + engines: {node: '>=8'} + + '@wry/context@0.7.4': + resolution: {integrity: sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ==} + engines: {node: '>=8'} + + '@wry/equality@0.5.7': + resolution: {integrity: sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw==} + engines: {node: '>=8'} + + '@wry/trie@0.5.0': + resolution: {integrity: sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA==} + engines: {node: '>=8'} + + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + '@zilliqa-js/crypto@3.5.0': + resolution: {integrity: sha512-KMTY4hREh706k0oqCJ7KTFCEgPvgWuckv7z1SkOc9UDjJnnfOD8KxGWrleaKMZOw+EjKJRybxgewPUvSZ+o7Mw==} + + '@zilliqa-js/util@3.5.0': + resolution: {integrity: sha512-YT8OhYAv2nCIrRTMMwXLDEqyV/O0jbtfc5Uvlb0qkIx56a4OeneebIJtBlTwf9ld7MZlU5LvvDOEJyljQErz6w==} + + abitype@1.0.8: + resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abort-controller@3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.14.1: + resolution: {integrity: sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==} + engines: {node: '>=0.4.0'} + hasBin: true + + address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} + + aes-js@3.0.0: + resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} + + aes-js@3.1.2: + resolution: {integrity: sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==} + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + algo-msgpack-with-bigint@2.1.1: + resolution: {integrity: sha512-F1tGh056XczEaEAqu7s+hlZUDWwOBT70Eq0lfMpBP2YguSQVyxRbprLq5rELXKQOyOaixTWYhMeMQMzP0U5FoQ==} + engines: {node: '>= 10'} + + algosdk@2.11.0: + resolution: {integrity: sha512-MJ9xrjBKqG6ItCAR0Z974DG7nvifXsQxlj7HbWkBat4+h/IygwKPEH/v0dQPOYWdTcf5/5lfu+OyEVOsjxvyRQ==} + engines: {node: '>=18.0.0'} + + already@2.2.1: + resolution: {integrity: sha512-qk6RIVMS/R1yTvBzfIL1T76PsIL7DIVCINoLuFw2YXKLpLtsTobqdChMs8m3OhuPS3CEE3+Ra5ibYiqdyogbsQ==} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-escapes@2.0.0: + resolution: {integrity: sha512-tH/fSoQp4DrEodDK3QpdiWiZTSe7sBJ9eOqcQBZ0o9HTM+5M/viSEn+sPMoTuPjQQ8n++w3QJoPEjt8LVPcrCg==} + engines: {node: '>=4'} + + ansi-escapes@3.2.0: + resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==} + engines: {node: '>=4'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@2.1.1: + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} + engines: {node: '>=0.10.0'} + + ansi-regex@3.0.1: + resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} + engines: {node: '>=4'} + + ansi-regex@4.1.1: + resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@2.2.1: + resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} + engines: {node: '>=0.10.0'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + ansicolors@0.3.2: + resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + any-signal@2.1.2: + resolution: {integrity: sha512-B+rDnWasMi/eWcajPcCWSlYc7muXOrcYrqgyzcdKisl2H/WTlQ0gip1KyQfr0ZlxJdsuWCj/LWwQm7fhyhRfIQ==} + + any-signal@3.0.1: + resolution: {integrity: sha512-xgZgJtKEa9YmDqXodIgl7Fl1C8yNXr8w6gXjqK3LW4GcEiYT+6AQfJSE/8SPsEpLLmcvbv8YU+qet94UewHxqg==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + append-field@1.0.0: + resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-back@3.1.0: + resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} + engines: {node: '>=6'} + + array-back@4.0.2: + resolution: {integrity: sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==} + engines: {node: '>=8'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + asn1.js@4.10.1: + resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} + + assert@2.1.0: + resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} + + ast-stringify@0.1.0: + resolution: {integrity: sha512-J1PgFYV3RG6r37+M6ySZJH406hR82okwGvFM9hLXpOvdx4WC4GEW8/qiw6pi1hKTrqcRvoHP8a7mp87egYr6iA==} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + async-mutex@0.5.0: + resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axios@0.24.0: + resolution: {integrity: sha512-Q6cWsys88HoPgAaFAVUb0WpPk0O8iTeisR9IMqy9G8AbO4NlpVknrnQS03zzF9PGAWgO3cgletO3VjV/P7VztA==} + + axios@0.25.0: + resolution: {integrity: sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==} + + axios@0.27.2: + resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} + + axios@0.28.1: + resolution: {integrity: sha512-iUcGA5a7p0mVb4Gm/sy+FSECNkPFT4y7wt6OM/CDpO/OnNCvSs3PoMG8ibrC9jRoGYU0gUK5pXVC4NPXq6lHRQ==} + + axios@1.12.1: + resolution: {integrity: sha512-Kn4kbSXpkFHCGE6rBFNwIv0GQs4AvDT80jlveJDKFxjbTYMUeB4QtsdPCv6H8Cm19Je7IU6VFtRl2zWZI0rudQ==} + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + babel-plugin-polyfill-corejs2@0.3.3: + resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + babel-plugin-polyfill-corejs3@0.5.3: + resolution: {integrity: sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + babel-plugin-polyfill-regenerator@0.4.1: + resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + babel-preset-current-node-syntax@1.2.0: + resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} + peerDependencies: + '@babel/core': ^7.0.0 || ^8.0.0-0 + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + bare-addon-resolve@1.9.3: + resolution: {integrity: sha512-0W343p8kVy9KimDMrxJtJct/ILWL8gzC0Wwg/Fn/GgQplHvrllyz4fPobUVG5+gx9BokWttzg8FYypQP7V5nrA==} + peerDependencies: + bare-url: '*' + peerDependenciesMeta: + bare-url: + optional: true + + bare-module-resolve@1.10.2: + resolution: {integrity: sha512-C9COe/GhWfVXKytW3DElTkiBU+Gb2OXeaVkdGdRB/lp26TVLESHkTGS876iceAGdvtPgohfp9nX8vXHGvN3++Q==} + peerDependencies: + bare-url: '*' + peerDependenciesMeta: + bare-url: + optional: true + + bare-os@3.5.1: + resolution: {integrity: sha512-LvfVNDcWLw2AnIw5f2mWUgumW3I3N/WYGiWeimhQC1Ybt71n2FjlS9GJKeCnFeg1MKZHxzIFmpFnBXDI+sBeFg==} + engines: {bare: '>=1.14.0'} + + bare-path@3.0.0: + resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} + + bare-semver@1.0.1: + resolution: {integrity: sha512-UtggzHLiTrmFOC/ogQ+Hy7VfoKoIwrP1UFcYtTxoCUdLtsIErT8+SWtOC2DH/snT9h+xDrcBEPcwKei1mzemgg==} + + bare-url@2.1.3: + resolution: {integrity: sha512-c02+eKvn/4esh5E2lSYQFwHL1WoTIL3u3NeFqb9e7ahBVENXw13MWx4/4/wdPyI557GqqB2Cm0bBbOXD0I0qgA==} + + base32.js@0.1.0: + resolution: {integrity: sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==} + engines: {node: '>=0.12.0'} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bech32@1.1.4: + resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} + + big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + + bignumber.js@4.1.0: + resolution: {integrity: sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==} + + bignumber.js@9.1.2: + resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + + bintrees@1.0.2: + resolution: {integrity: sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + blob-to-it@1.0.4: + resolution: {integrity: sha512-iCmk0W4NdbrWgRRuxOriU8aM5ijeVLI61Zulsmg/lUHNr7pYjoj+U77opLefNagevtrrbMt3JQ5Qip7ar178kA==} + + bn.js@4.12.1: + resolution: {integrity: sha512-k8TVBiPkPJT9uHLdOKfFpqcfprwBFOAAXXozRubr7R7PfIuKvQlzcI4M0pALeqXN09vdaMbUdUj+pass+uULAg==} + + bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + + body-parser@2.1.0: + resolution: {integrity: sha512-/hPxh61E+ll0Ujp24Ilm64cykicul1ypfwjVttduAiEdtnJFvLePSrIPk+HMImtNv5270wOGCb1Tns2rybMkoQ==} + engines: {node: '>=18'} + + borsh@1.0.0: + resolution: {integrity: sha512-fSVWzzemnyfF89EPwlUNsrS5swF5CrtiN4e+h0/lLf4dz2he4L3ndM20PS9wj7ICSkXJe/TQUHdaPTq15b1mNQ==} + + boxen@5.1.2: + resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} + engines: {node: '>=10'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + + browser-readablestream-to-it@1.0.3: + resolution: {integrity: sha512-+12sHB+Br8HIh6VAMVEG5r3UXCyESIgDW7kzk3BjIXa43DVqVwL7GC5TW3jeh+72dtcH99pPVpw0X8i0jt+/kw==} + + browserify-aes@1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + + browserify-cipher@1.0.1: + resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} + + browserify-des@1.0.2: + resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} + + browserify-rsa@4.1.1: + resolution: {integrity: sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==} + engines: {node: '>= 0.10'} + + browserify-sign@4.2.3: + resolution: {integrity: sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==} + engines: {node: '>= 0.12'} + + browserslist@4.24.4: + resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bs-logger@0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-xor@1.0.3: + resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bufferutil@4.0.9: + resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} + engines: {node: '>=6.14.2'} + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cacheable-lookup@6.1.0: + resolution: {integrity: sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==} + engines: {node: '>=10.6.0'} + + cacheable-request@6.1.0: + resolution: {integrity: sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.8: + resolution: {integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + call-me-maybe@1.0.2: + resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + + callguard@2.0.0: + resolution: {integrity: sha512-I3nd+fuj20FK1qu00ImrbH+II+8ULS6ioYr9igqR1xyqySoqc3DiHEyUM0mkoAdKeLGg2CtGnO8R3VRQX5krpQ==} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-lite@1.0.30001702: + resolution: {integrity: sha512-LoPe/D7zioC0REI5W73PeR1e1MLCipRGq/VkovJnd6Df+QVqT+vT33OXCp8QUd7kA7RZrHWxb1B36OQKI/0gOA==} + + cardinal@2.1.1: + resolution: {integrity: sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==} + hasBin: true + + case@1.6.3: + resolution: {integrity: sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==} + engines: {node: '>= 0.8.0'} + + cborg@1.10.2: + resolution: {integrity: sha512-b3tFPA9pUr2zCUiCfRd2+wok2/LBSNUMKOuRRok+WlvvAgEt/PlbgPTsZUcwCOs53IJvLgTp0eotwtosE6njug==} + hasBin: true + + chalk@1.1.3: + resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} + engines: {node: '>=0.10.0'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + chardet@0.4.2: + resolution: {integrity: sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==} + + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + ci-info@2.0.0: + resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + cipher-base@1.0.6: + resolution: {integrity: sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==} + engines: {node: '>= 0.10'} + + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + + class-transformer@0.5.1: + resolution: {integrity: sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==} + + class-validator@0.14.1: + resolution: {integrity: sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ==} + + clean-stack@3.0.1: + resolution: {integrity: sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==} + engines: {node: '>=10'} + + cli-boxes@2.2.1: + resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} + engines: {node: '>=6'} + + cli-color@2.0.4: + resolution: {integrity: sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==} + engines: {node: '>=0.10'} + + cli-cursor@2.1.0: + resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==} + engines: {node: '>=4'} + + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + cli-progress@3.12.0: + resolution: {integrity: sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==} + engines: {node: '>=4'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-width@2.2.1: + resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==} + + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colors@1.4.0: + resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} + engines: {node: '>=0.1.90'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + command-line-args@5.2.1: + resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} + engines: {node: '>=4.0.0'} + + command-line-usage@6.1.3: + resolution: {integrity: sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==} + engines: {node: '>=8.0.0'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + + configstore@5.0.1: + resolution: {integrity: sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==} + engines: {node: '>=8'} + + consola@3.4.0: + resolution: {integrity: sha512-EiPU8G6dQG0GFHNR8ljnZFki/8a+cQwEQ+7wpxdChl02Q8HXlwEZWD5lqAF8vC2sEC3Tehr8hy7vErz88LHyUA==} + engines: {node: ^14.18.0 || >=16.10.0} + + content-disposition@1.0.0: + resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + + core-js-compat@3.41.0: + resolution: {integrity: sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + cosmjs-types@0.10.1: + resolution: {integrity: sha512-CENXb4O5GN+VyB68HYXFT2SOhv126Z59631rZC56m8uMWa6/cSlFeai8BwZGT1NMepw0Ecf+U8XSOnBzZUWh9Q==} + + crc@3.8.0: + resolution: {integrity: sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==} + + crc@4.3.2: + resolution: {integrity: sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A==} + engines: {node: '>=12'} + peerDependencies: + buffer: '>=6.0.3' + peerDependenciesMeta: + buffer: + optional: true + + create-ecdh@4.0.4: + resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} + + create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + + create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cron-converter@2.1.0: + resolution: {integrity: sha512-BmrrSldZxI2kYRhy85DH7wbPlq3BebDCEMtVEmpDuFAVPi7tzLsoPYthIVubvMoJzmXM83jlV0FaXgxOyv2/AA==} + + cron@3.5.0: + resolution: {integrity: sha512-0eYZqCnapmxYcV06uktql93wNWdlTmmBFP2iYz+JPVcQqlyFYcn1lFuIk4R54pkOmE7mcldTAPZv6X5XA4Q46A==} + + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crypto-browserify@3.12.1: + resolution: {integrity: sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==} + engines: {node: '>= 0.10'} + + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + + crypto-random-string@2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} + + csv-stringify@6.5.2: + resolution: {integrity: sha512-RFPahj0sXcmUyjrObAK+DOWtMvMIFV328n4qZJhgX3x2RqkQgOTU2mCUmiFR0CzM6AzChlRSUErjiJeEt8BaQA==} + + d@1.0.2: + resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} + engines: {node: '>=0.12'} + + dag-jose@1.0.0: + resolution: {integrity: sha512-U0b/YsIPBp6YZNTFrVjwLZAlY3qGRxZTIEcM/CcQmrVrCWq9MWQq9pheXVSPLIhF4SNwzp2SikPva4/BIrJY+g==} + + dargs@7.0.0: + resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} + engines: {node: '>=8'} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.6: + resolution: {integrity: sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.5.0: + resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} + + decompress-response@3.3.0: + resolution: {integrity: sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==} + engines: {node: '>=4'} + + dedent@1.6.0: + resolution: {integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deepmerge@4.2.2: + resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} + engines: {node: '>=0.10.0'} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + defer-to-connect@1.1.3: + resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + des.js@1.1.0: + resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + + detect-port@1.6.1: + resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} + engines: {node: '>= 4.0.0'} + hasBin: true + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + diffie-hellman@5.0.3: + resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dns-over-http-resolver@1.2.3: + resolution: {integrity: sha512-miDiVSI6KSNbi4SVifzO/reD8rMnxgrlnkrlkugOLQpWQTe2qMdHsZp5DmfKjxNE+/T3VAAYLQUZMv9SMr6+AA==} + + dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + + dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + engines: {node: '>=12'} + + dottie@2.0.6: + resolution: {integrity: sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA==} + + dotty@0.1.2: + resolution: {integrity: sha512-V0EWmKeH3DEhMwAZ+8ZB2Ao4OK6p++Z0hsDtZq3N0+0ZMVqkzrcEGROvOnZpLnvBg5PTNG23JEDLAm64gPaotQ==} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexer3@0.1.5: + resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + electron-fetch@1.9.1: + resolution: {integrity: sha512-M9qw6oUILGVrcENMSRRefE1MbHPIz0h79EKIeJWK9v563aT9Qkh8aEHPO1H5vi970wPirNY+jO9OpFoLiMsMGA==} + engines: {node: '>=6'} + + electron-to-chromium@1.5.112: + resolution: {integrity: sha512-oen93kVyqSb3l+ziUgzIOlWt/oOuy4zRmpwestMn4rhFWAoFJeFuCVte9F2fASjeZZo7l/Cif9TiyrdW4CwEMA==} + + elliptic@6.6.1: + resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} + + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + enhanced-resolve@5.18.1: + resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} + engines: {node: '>=10.13.0'} + + err-code@3.0.1: + resolution: {integrity: sha512-GiaH0KJUewYok+eeY05IIgjtAe4Yltygk9Wqp1V5yVWLdhf0hYZchRjNIT9bb0mSwRcIusT3cx7PJUf3zEIfUA==} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.6.0: + resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es5-ext@0.10.64: + resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} + engines: {node: '>=0.10'} + + es6-iterator@2.0.3: + resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + + es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + + es6-symbol@3.1.4: + resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} + engines: {node: '>=0.12'} + + es6-weak-map@2.0.3: + resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} + + esbuild@0.25.5: + resolution: {integrity: sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-goat@2.1.1: + resolution: {integrity: sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==} + engines: {node: '>=8'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + esniff@2.0.1: + resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} + engines: {node: '>=0.10'} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + ethers@5.8.0: + resolution: {integrity: sha512-DUq+7fHrCg1aPDFCHx6UIPb3nmt2XMpM7Y/g2gLhsl3lIBqeAfOJIl1qEvRf2uq3BiKxmh6Fh5pfp2ieyek7Kg==} + + event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + + event-target-shim@5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + + eventemitter2@6.4.9: + resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + eventsource@1.1.2: + resolution: {integrity: sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA==} + engines: {node: '>=0.12.0'} + + eventsource@2.0.2: + resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==} + engines: {node: '>=12.0.0'} + + evp_bytestokey@1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + exponential-backoff@3.1.2: + resolution: {integrity: sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==} + + express@5.0.1: + resolution: {integrity: sha512-ORF7g6qGnD+YtUG9yx4DFoqCShNMmUKiXuT5oWMHiOvt/4WFbHC6yCwQMTSBMno7AqntNCAzzcnnjowRkTL9eQ==} + engines: {node: '>= 18'} + + ext@1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + + external-editor@2.2.0: + resolution: {integrity: sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==} + engines: {node: '>=0.12'} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-fifo@1.3.2: + resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fast-text-encoding@1.0.6: + resolution: {integrity: sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==} + + fast-uri@3.0.6: + resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + fetch-h2@3.0.2: + resolution: {integrity: sha512-Lo6UPdMKKc9Ond7yjG2vq0mnocspOLh1oV6+XZdtfdexacvMSz5xm3WoQhTAdoR2+UqPlyMNqcqfecipoD+l/A==} + engines: {node: '>=12'} + + fflate@0.8.2: + resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + + figures@2.0.0: + resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} + engines: {node: '>=4'} + + file-type@21.0.0: + resolution: {integrity: sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==} + engines: {node: '>=20'} + + filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@2.0.0: + resolution: {integrity: sha512-MX6Zo2adDViYh+GcxxB1dpO43eypOGUOL12rLCOTMQv/DfIbpSJUy4oQIIZhVZkH9e+bZWKMon0XHFEju16tkQ==} + engines: {node: '>= 0.8'} + + find-replace@3.0.0: + resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} + engines: {node: '>=4.0.0'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + flatstr@1.0.12: + resolution: {integrity: sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw==} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + form-data@4.0.4: + resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + engines: {node: '>= 6'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-extra@11.3.0: + resolution: {integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==} + engines: {node: '>=14.14'} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + fuzzy@0.1.3: + resolution: {integrity: sha512-/gZffu4ykarLrCiP3Ygsa86UAo1E5vEVlvTrpkKywXSbP9Xhln3oSp9QSV57gEq3JFFpGJ4GZ+5zdEp3FcUh4w==} + engines: {node: '>= 0.6.0'} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-iterator@1.0.2: + resolution: {integrity: sha512-v+dm9bNVfOYsY1OrhaCrmyOcYoSeVvbt+hHZ0Au+T+p1y+0Uyj9aMaGIeUTT6xdpRbWzDeYKvfOslPhggQMcsg==} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stdin@8.0.0: + resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} + engines: {node: '>=10'} + + get-stream@4.1.0: + resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} + engines: {node: '>=6'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-tsconfig@4.10.1: + resolution: {integrity: sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-promise@4.2.2: + resolution: {integrity: sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==} + engines: {node: '>=12'} + peerDependencies: + glob: ^7.1.6 + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.1.7: + resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@8.0.3: + resolution: {integrity: sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + + global-dirs@3.0.1: + resolution: {integrity: sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==} + engines: {node: '>=10'} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + got@9.6.0: + resolution: {integrity: sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==} + engines: {node: '>=8.6'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphql-tag@2.12.6: + resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==} + 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 + + graphql@15.10.1: + resolution: {integrity: sha512-BL/Xd/T9baO6NFzoMpiMD7YUZ62R6viR5tp/MULVEnbYJXZA//kRNW7J0j1w/wXArgL0sCxhDfK5dczSKn3+cg==} + engines: {node: '>= 10.x'} + + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + has-ansi@2.0.0: + resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} + engines: {node: '>=0.10.0'} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has-yarn@2.1.0: + resolution: {integrity: sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==} + engines: {node: '>=8'} + + hash-base@3.0.5: + resolution: {integrity: sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==} + engines: {node: '>= 0.10'} + + hash-wasm@4.12.0: + resolution: {integrity: sha512-+/2B2rYLb48I/evdOIhP+K/DD2ca2fgBjp6O+GBEnCDk2e4rpeXIK8GvIyRPjTezgmWn9gmKwkQjjx6BtqDHVQ==} + + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + hi-base32@0.5.1: + resolution: {integrity: sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA==} + + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + hyperlinker@1.0.0: + resolution: {integrity: sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==} + engines: {node: '>=4'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.5.2: + resolution: {integrity: sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-lazy@2.1.0: + resolution: {integrity: sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==} + engines: {node: '>=4'} + + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflection@1.13.4: + resolution: {integrity: sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==} + engines: {'0': node >= 0.4.0} + + inflight@1.0.6: + resolution: {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. + + inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + ini@2.0.0: + resolution: {integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==} + engines: {node: '>=10'} + + inquirer-autocomplete-prompt@0.11.1: + resolution: {integrity: sha512-VM4eNiyRD4CeUc2cyKni+F8qgHwL9WC4LdOr+mEC85qP/QNsDV+ysVqUrJYhw1TmDQu1QVhc8hbaL7wfk8SJxw==} + + inquirer@3.1.1: + resolution: {integrity: sha512-H50sHQwgvvaTBd3HpKMVtL/u6LoHDvYym51gd7bGQe/+9HkCE+J0/3N5FJLfd6O6oz44hHewC2Pc2LodzWVafQ==} + + inquirer@6.5.2: + resolution: {integrity: sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==} + engines: {node: '>=6.0.0'} + + inquirerer@0.1.3: + resolution: {integrity: sha512-yGgLUOqPxTsINBjZNZeLi3cv2zgxXtw9feaAOSJf2j6AqIT5Uxs5ZOqOrfAf+xP65Sicla1FD3iDxa3D6TsCAQ==} + + interface-datastore@5.2.0: + resolution: {integrity: sha512-nthO4C4BMJM2j9x/mT2KFa/g/sbcY8yf9j/kOBgli3u5mq9ZdPvQyDxi0OhKzr4JmoM81OYh5xcFjyebquqwvA==} + + interface-datastore@6.1.1: + resolution: {integrity: sha512-AmCS+9CT34pp2u0QQVXjKztkuq3y5T+BIciuiHDDtDZucZD8VudosnSdUyXJV6IsRkN5jc4RFDhCk1O6Q3Gxjg==} + + interface-store@1.0.2: + resolution: {integrity: sha512-rUBLYsgoWwxuUpnQoSUr+DR/3dH3reVeIu5aOHFZK31lAexmb++kR6ZECNRgrx6WvoaM3Akdo0A7TDrqgCzZaQ==} + + interface-store@2.0.2: + resolution: {integrity: sha512-rScRlhDcz6k199EkHqT8NpM87ebN89ICOzILoBHgaG36/WX50N32BnU/kpZgCGPLhARRAWUUX5/cyaIjt7Kipg==} + + interpret@1.4.0: + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} + engines: {node: '>= 0.10'} + + ip-regex@4.3.0: + resolution: {integrity: sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==} + engines: {node: '>=8'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + ipfs-core-types@0.10.3: + resolution: {integrity: sha512-GNid2lRBjR5qgScCglgk7w9Hk3TZAwPHQXxOLQx72wgyc0jF2U5NXRoKW0GRvX8NPbHmsrFszForIqxd23I1Gw==} + deprecated: js-IPFS has been deprecated in favour of Helia - please see https://github.com/ipfs/js-ipfs/issues/4336 for details + + ipfs-core-types@0.7.3: + resolution: {integrity: sha512-FkmOlqhEf3yG0K8Qt7We7kqA0xKjj8pe0dmNK593I3cgMP0MQS/xjMj1CXVdGeZc5Nn5CJ+TsuQydPbJ+7Y8eQ==} + deprecated: js-IPFS has been deprecated in favour of Helia - please see https://github.com/ipfs/js-ipfs/issues/4336 for details + + ipfs-core-utils@0.10.5: + resolution: {integrity: sha512-WPRbMkbn/99pKMF3h8x1/c19+eTXVWOZu1+cmlc3NLR6gMlCd8KNpcq9OCAvs9G1JHx3w/FbEWHnqJm0TJMvrw==} + deprecated: js-IPFS has been deprecated in favour of Helia - please see https://github.com/ipfs/js-ipfs/issues/4336 for details + + ipfs-core-utils@0.14.3: + resolution: {integrity: sha512-aBkewVhgAj3NWXPwu6imj0wADGiGVZmJzqKzODOJsibDjkx6FGdMv8kvvqtLnK8LS/dvSk9yk32IDtuDyYoV7Q==} + deprecated: js-IPFS has been deprecated in favour of Helia - please see https://github.com/ipfs/js-ipfs/issues/4336 for details + + ipfs-http-client@52.0.5: + resolution: {integrity: sha512-vQ2z6JdBcIJvf6N1Bh/ZdpYBa7fgl0jFV8Rn3HaADhHnIZ/dou8e6nSxHkBPpw2OUyR4ljjjsDvmy2SIIQXohA==} + engines: {node: '>=14.0.0', npm: '>=3.0.0'} + deprecated: js-IPFS has been deprecated in favour of Helia - please see https://github.com/ipfs/js-ipfs/issues/4336 for details + + ipfs-http-client@56.0.3: + resolution: {integrity: sha512-E3L5ylVl6BjyRUsNehvfuRBYp1hj8vQ8in4zskVPMNzXs6JiCFUbif5a6BtcAlSK4xPQyJCeLNNAWLUeFQTLNA==} + engines: {node: '>=15.0.0', npm: '>=3.0.0'} + deprecated: js-IPFS has been deprecated in favour of Helia - please see https://github.com/ipfs/js-ipfs/issues/4336 for details + + ipfs-unixfs@6.0.9: + resolution: {integrity: sha512-0DQ7p0/9dRB6XCb0mVCTli33GzIzSVx5udpJuVM47tGcD+W+Bl4LsnoLswd3ggNnNEakMv1FdoFITiEnchXDqQ==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + + ipfs-utils@8.1.6: + resolution: {integrity: sha512-V/cwb6113DrDhrjDTWImA6+zmJbpdbUkxdxmEQO7it8ykV76bBmzU1ZXSM0QR0qxGy9VW8dkUlPAC2K10VgSmw==} + + ipfs-utils@9.0.14: + resolution: {integrity: sha512-zIaiEGX18QATxgaS0/EOQNoo33W0islREABAcxXE8n7y2MGAlB+hdsxXn4J0hGZge8IqVQhW8sWIb+oJz2yEvg==} + engines: {node: '>=16.0.0', npm: '>=7.0.0'} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-ci@2.0.0: + resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==} + hasBin: true + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-electron@2.2.2: + resolution: {integrity: sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + is-generator-function@1.1.0: + resolution: {integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-installed-globally@0.4.0: + resolution: {integrity: sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ==} + engines: {node: '>=10'} + + is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + + is-ip@3.1.0: + resolution: {integrity: sha512-35vd5necO7IitFPjd/YBeqwWnyDWbuLH9ZXQdMfDA8TEo7pv5X8yfrvVO3xbJbLUlERCMvf6X0hTUamQxCYJ9Q==} + engines: {node: '>=8'} + + is-nan@1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + engines: {node: '>= 0.4'} + + is-npm@5.0.0: + resolution: {integrity: sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA==} + engines: {node: '>=10'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + is-yarn-global@0.3.0: + resolution: {integrity: sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + iso-url@1.2.1: + resolution: {integrity: sha512-9JPDgCN4B7QPkLtYAAOrEuAWvP9rWvR5offAr0/SeF046wIkglqH3VXgYYP6NcsKslH80UIVgmPqNe3j7tG2ng==} + engines: {node: '>=12'} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + + isows@1.0.6: + resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} + peerDependencies: + ws: '*' + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + + it-all@1.0.6: + resolution: {integrity: sha512-3cmCc6Heqe3uWi3CVM/k51fa/XbMFpQVzFoDsV0IZNHSQDyAXl3c4MjHkFX5kF3922OGj7Myv1nSEUgRtcuM1A==} + + it-drain@1.0.5: + resolution: {integrity: sha512-r/GjkiW1bZswC04TNmUnLxa6uovme7KKwPhc+cb1hHU65E3AByypHH6Pm91WHuvqfFsm+9ws0kPtDBV3/8vmIg==} + + it-filter@1.0.3: + resolution: {integrity: sha512-EI3HpzUrKjTH01miLHWmhNWy3Xpbx4OXMXltgrNprL5lDpF3giVpHIouFpr5l+evXw6aOfxhnt01BIB+4VQA+w==} + + it-first@1.0.7: + resolution: {integrity: sha512-nvJKZoBpZD/6Rtde6FXqwDqDZGF1sCADmr2Zoc0hZsIvnE449gRFnGctxDf09Bzc/FWnHXAdaHVIetY6lrE0/g==} + + it-glob@0.0.14: + resolution: {integrity: sha512-TKKzs9CglbsihSpcwJPXN5DBUssu4akRzPlp8QJRCoLrKoaOpyY2V1qDlxx+UMivn0i114YyTd4AawWl7eqIdw==} + + it-glob@1.0.2: + resolution: {integrity: sha512-Ch2Dzhw4URfB9L/0ZHyY+uqOnKvBNeS/SMcRiPmJfpHiM0TsUZn+GkpcZxAoF3dJVdPm/PuIk3A4wlV7SUo23Q==} + + it-last@1.0.6: + resolution: {integrity: sha512-aFGeibeiX/lM4bX3JY0OkVCFkAw8+n9lkukkLNivbJRvNz8lI3YXv5xcqhFUV2lDJiraEK3OXRDbGuevnnR67Q==} + + it-map@1.0.6: + resolution: {integrity: sha512-XT4/RM6UHIFG9IobGlQPFQUrlEKkU4eBUFG3qhWhfAdh1JfF2x11ShCrKCdmZ0OiZppPfoLuzcfA4cey6q3UAQ==} + + it-peekable@1.0.3: + resolution: {integrity: sha512-5+8zemFS+wSfIkSZyf0Zh5kNN+iGyccN02914BY4w/Dj+uoFEoPSvj5vaWn8pNZJNSxzjW0zHRxC3LUb2KWJTQ==} + + it-take@1.0.2: + resolution: {integrity: sha512-u7I6qhhxH7pSevcYNaMECtkvZW365ARqAIt9K+xjdK1B2WUDEjQSfETkOCT8bxFq/59LqrN3cMLUtTgmDBaygw==} + + it-to-stream@1.0.0: + resolution: {integrity: sha512-pLULMZMAB/+vbdvbZtebC0nWBTbG581lk6w8P7DfIIIKUfa8FbY7Oi0FxZcFPbxvISs7A9E+cMpLDBc1XhpAOA==} + + iterare@1.2.1: + resolution: {integrity: sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==} + engines: {node: '>=6'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jake@10.9.2: + resolution: {integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==} + engines: {node: '>=10'} + hasBin: true + + javascript-stringify@2.1.0: + resolution: {integrity: sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==} + + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@28.1.3: + resolution: {integrity: sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@28.0.2: + resolution: {integrity: sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@28.1.3: + resolution: {integrity: sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + jest-worker@28.1.3: + resolution: {integrity: sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + js-sha256@0.9.0: + resolution: {integrity: sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==} + + js-sha3@0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + + js-sha512@0.8.0: + resolution: {integrity: sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-xdr@1.3.0: + resolution: {integrity: sha512-fjLTm2uBtFvWsE3l2J14VjTuuB8vJfeTtYuNS7LiLHDWIX2kt0l1pqq9334F8kODUkKPMuULjEcbGbkFFwhx5g==} + deprecated: ⚠️ This package has moved to @stellar/js-xdr! 🚚 + + js-xdr@3.1.2: + resolution: {integrity: sha512-jyAZSw6mD5AKKGNEv+HW2ce+MJNTgzkpvYCydt2wPIhWYfFKx2jcn2cwOmBG1APXNDlPL6tYCVxO/v+FOnXYzA==} + deprecated: ⚠️ This package has moved to @stellar/js-xdr! 🚚 + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-bigint@1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + + json-buffer@3.0.0: + resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + keyv@3.1.0: + resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + latest-version@5.1.0: + resolution: {integrity: sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==} + engines: {node: '>=8'} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + libphonenumber-js@1.12.5: + resolution: {integrity: sha512-DOjiaVjjSmap12ztyb4QgoFmUe/GbgnEXHu+R7iowk0lzDIjScvPAm8cK9RYTEobbRb0OPlwlZUGTTJPJg13Kw==} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-esm@1.0.2: + resolution: {integrity: sha512-nVAvWk/jeyrWyXEAs84mpQCYccxRqgKY4OznLuJhJCa0XsPSfdOIr2zvBZEj3IHEHbX97jjscKRRV539bW0Gpw==} + engines: {node: '>=13.2.0'} + + loader-runner@4.3.0: + resolution: {integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==} + engines: {node: '>=6.11.5'} + + loader-utils@2.0.4: + resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} + engines: {node: '>=8.9.0'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + long@2.4.0: + resolution: {integrity: sha512-ijUtjmO/n2A5PaosNG9ZGDsQ3vxJg7ZW8vsY8Kp0f2yIZWhSJvjmegV7t+9RPQKxKrvj8yKGehhS+po14hPLGQ==} + engines: {node: '>=0.6'} + + long@4.0.0: + resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} + + long@5.3.1: + resolution: {integrity: sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lowercase-keys@1.0.1: + resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} + engines: {node: '>=0.10.0'} + + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + + lru-cache@10.1.0: + resolution: {integrity: sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==} + engines: {node: 14 || >=16.14} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-queue@0.1.0: + resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} + + luxon@3.5.0: + resolution: {integrity: sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==} + engines: {node: '>=12'} + + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + media-typer@1.1.0: + resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} + engines: {node: '>= 0.8'} + + memoizee@0.4.17: + resolution: {integrity: sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==} + engines: {node: '>=0.12'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + merge-options@3.0.4: + resolution: {integrity: sha512-2Sug1+knBjkaMsMgf1ctR1Ujx+Ayku4EdJN4Z+C2+JzoeF7A3OZ9KM2GY0CpQS51NR61LTurMJrRKPhSs3ZRTQ==} + engines: {node: '>=10'} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + merkle-tools@1.4.1: + resolution: {integrity: sha512-QhO1/eDvAnyn0oXgRWlydVWYVMrVJwrdNICYvQXYhBU1Bjj1LoxsQxdAKJ5ttN3L6pkKhjcK6O4k927kgTMdqw==} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + miller-rabin@4.0.1: + resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} + hasBin: true + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.53.0: + resolution: {integrity: sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.0: + resolution: {integrity: sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==} + engines: {node: '>= 0.6'} + + mimic-fn@1.2.0: + resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} + engines: {node: '>=4'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@5.1.0: + resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==} + engines: {node: '>=10'} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.6: + resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mkdirp@3.0.0: + resolution: {integrity: sha512-7+JDnNsyCvZXoUJdkMR0oUE2AmAdsNXGTmRbiOjYIwQ6q+bL6NwrozGQdPcmYaNcrhH37F50HHBUzoaBV6FITQ==} + engines: {node: '>=10'} + hasBin: true + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + mock-socket@9.3.1: + resolution: {integrity: sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==} + engines: {node: '>= 8'} + + moment-timezone@0.5.47: + resolution: {integrity: sha512-UbNt/JAWS0m/NJOebR0QMRHBk0hu03r5dx9GK8Cs0AS3I81yDcOc9k+DytPItgVvBP7J6Mf6U2n3BPAacAV9oA==} + + moment@2.30.1: + resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multer@1.4.5-lts.1: + resolution: {integrity: sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==} + engines: {node: '>= 6.0.0'} + + multiaddr-to-uri@8.0.0: + resolution: {integrity: sha512-dq4p/vsOOUdVEd1J1gl+R2GFrXJQH8yjLtz4hodqdVbieg39LvBOdMQRdQnfbg5LSM/q1BYNVf5CBbwZFFqBgA==} + deprecated: This module is deprecated, please upgrade to @multiformats/multiaddr-to-uri + + multiaddr@10.0.1: + resolution: {integrity: sha512-G5upNcGzEGuTHkzxezPrrD6CaIHR9uo+7MwqhNVcXTs33IInon4y7nMiGxl2CY5hG7chvYQUQhz5V52/Qe3cbg==} + deprecated: This module is deprecated, please upgrade to @multiformats/multiaddr + + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + + mustache@4.0.0: + resolution: {integrity: sha512-FJgjyX/IVkbXBXYUwH+OYwQKqWpFPLaLVESd70yHjSDunwzV2hZOoTBvPf4KLoxesUzzyfTH6F784Uqd7Wm5yA==} + engines: {npm: '>=1.4.0'} + hasBin: true + + mute-stream@0.0.7: + resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==} + + mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + native-abort-controller@1.0.4: + resolution: {integrity: sha512-zp8yev7nxczDJMoP6pDxyD20IU0T22eX8VwN2ztDccKvSZhRaV33yP1BGwKSZfXuqWUzsXopVFjBdau9OOAwMQ==} + peerDependencies: + abort-controller: '*' + + native-fetch@3.0.0: + resolution: {integrity: sha512-G3Z7vx0IFb/FQ4JxvtqGABsOTIqRWvgQz6e+erkB+JJD6LrszQtMozEHI4EkmgZQvnGHrpLVzUWk7t4sJCIkVw==} + peerDependencies: + node-fetch: '*' + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + natural-orderby@2.0.3: + resolution: {integrity: sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==} + + negotiator@1.0.0: + resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + nested-obj@0.0.1: + resolution: {integrity: sha512-kB1WKTng+IePQhZVs1UXtFaHBx4QEM5a0XKGAzYfCKvdx5DhNjCytNDWMUGpNNpHLotln+tiwcA52kWCIgGq1Q==} + + next-tick@1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + + nock@13.5.6: + resolution: {integrity: sha512-o2zOYiCpzRqSzPj0Zt/dQ/DqZeYoaQ7TUonc/xUPjCGl9WeHpNbxgVvOquXYAaJzI0M9BXV3HTzG0p8IUAbBTQ==} + engines: {node: '>= 10.13'} + + node-addon-api@5.1.0: + resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@4.5.1: + resolution: {integrity: sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==} + engines: {node: '>=8'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object-treeify@1.1.33: + resolution: {integrity: sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==} + engines: {node: '>= 10'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + on-exit-leak-free@2.1.2: + resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} + engines: {node: '>=14.0.0'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@2.0.1: + resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==} + engines: {node: '>=4'} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + optimism@0.18.1: + resolution: {integrity: sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ==} + + ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + ox@0.6.7: + resolution: {integrity: sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + p-cancelable@1.1.0: + resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==} + engines: {node: '>=6'} + + p-defer@3.0.0: + resolution: {integrity: sha512-ugZxsxmtTln604yeYd29EGrNhazN2lywetzpKhfmQjW/VJmhpDmWbiX+h0zL8V91R0UXkhb3KtPmyq9PZw3aYw==} + engines: {node: '>=8'} + + p-fifo@1.0.0: + resolution: {integrity: sha512-IjoCxXW48tqdtDFz6fqo5q1UfFVjjVZe8TC1QRflvNUJtNfCUhxOUw6MOVZhDPjqhSzc26xKdugsO17gmzd5+A==} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + package-json-type@1.0.3: + resolution: {integrity: sha512-Bey4gdRuOwDbS8Fj1qA3/pTq5r8pqiI5E3tjSqCdhaLSsyGG364VFzXLTIexN5AaNGe/vgdBzLfoKdr7EVg2KQ==} + + package-json@6.5.0: + resolution: {integrity: sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==} + engines: {node: '>=8'} + + pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + + parse-asn1@5.1.7: + resolution: {integrity: sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==} + engines: {node: '>= 0.10'} + + parse-duration@1.1.2: + resolution: {integrity: sha512-p8EIONG8L0u7f8GFgfVlL4n8rnChTt8O5FSxgxMz2tjc9FMP199wxVKVB6IbKx11uTbKHACSvaLVIKNnoeNR/A==} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-package-name@1.0.0: + resolution: {integrity: sha512-kBeTUtcj+SkyfaW4+KBe0HtsloBJ/mKTPoxpVdA57GZiPerREsUWJOhVj9anXweFiJkm5y8FG1sxFZkZ0SN6wg==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + password-prompt@1.1.3: + resolution: {integrity: sha512-HkrjG2aJlvF0t2BMH0e2LB/EHf3Lcq3fNMzy4GYHcQblAvOl+QQji1Lx7WRBMqpVK8p+KR7bCg7oqAMXtdgqyw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-to-regexp@8.2.0: + resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} + engines: {node: '>=16'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pbkdf2@3.1.2: + resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} + engines: {node: '>=0.12'} + + pg-cloudflare@1.1.1: + resolution: {integrity: sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==} + + pg-connection-string@2.7.0: + resolution: {integrity: sha512-PI2W9mv53rXJQEOb8xNR8lH7Hr+EKa6oJa38zsK0S/ky2er16ios1wLKhZyxzD7jUReiWokc9WK5nxSnC7W1TA==} + + pg-int8@1.0.1: + resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} + engines: {node: '>=4.0.0'} + + pg-pool@3.7.1: + resolution: {integrity: sha512-xIOsFoh7Vdhojas6q3596mXFsR8nwBQBXX5JiV7p9buEVAGqYL4yFzclON5P9vFrpu1u7Zwl2oriyDa89n0wbw==} + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.7.1: + resolution: {integrity: sha512-gjTHWGYWsEgy9MsY0Gp6ZJxV24IjDqdpTW7Eh0x+WfJLFsm/TJx1MzL6T0D88mBvkpxotCQ6TwW6N+Kko7lhgQ==} + + pg-types@2.2.0: + resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} + engines: {node: '>=4'} + + pg@8.13.3: + resolution: {integrity: sha512-P6tPt9jXbL9HVu/SSRERNYaYG++MjnscnegFh9pPHihfoBSujsrka0hyuymMzeJKFWrcG8wvCKy8rCe8e5nDUQ==} + engines: {node: '>= 8.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pino-abstract-transport@2.0.0: + resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + + pino-std-serializers@3.2.0: + resolution: {integrity: sha512-EqX4pwDPrt3MuOAAUBMU0Tk5kR/YcCM5fNPEzgCO2zJ5HfX0vbiH9HbJglnyeQsN96Kznae6MWD47pZB5avTrg==} + + pino-std-serializers@7.0.0: + resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} + + pino@6.14.0: + resolution: {integrity: sha512-iuhEDel3Z3hF9Jfe44DPXR8l07bhjuFY3GMHIXbjnY9XcafbyDDwl2sN2vw2GjMPf5Nkoe+OFao7ffn9SXaKDg==} + hasBin: true + + pino@9.6.0: + resolution: {integrity: sha512-i85pKRCt4qMjZ1+L7sy2Ag4t1atFcdbEt76+7iRJn1g2BvsnRMGu9p8pivl9fs63M2kF/A0OacFZhTub+m/qMg==} + hasBin: true + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postgres-array@2.0.0: + resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} + engines: {node: '>=4'} + + postgres-bytea@1.0.0: + resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} + engines: {node: '>=0.10.0'} + + postgres-date@1.0.7: + resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} + engines: {node: '>=0.10.0'} + + postgres-interval@1.2.0: + resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} + engines: {node: '>=0.10.0'} + + prepend-http@2.0.0: + resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==} + engines: {node: '>=4'} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + prettier@3.5.3: + resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + + process-warning@4.0.1: + resolution: {integrity: sha512-3c2LzQ3rY9d0hc1emcsHhfT9Jwz0cChib/QN89oME2R451w5fy3f0afAhERFZAwrbDU43wk12d0ORBpDVME50Q==} + + prom-client@15.1.3: + resolution: {integrity: sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==} + engines: {node: ^16 || ^18 || >=20} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + propagate@2.0.1: + resolution: {integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==} + engines: {node: '>= 8'} + + protobufjs@6.11.4: + resolution: {integrity: sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw==} + hasBin: true + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + psl@1.15.0: + resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + + public-encrypt@4.0.3: + resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} + + pump@3.0.2: + resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pupa@2.1.1: + resolution: {integrity: sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==} + engines: {node: '>=8'} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + + qs@6.14.0: + resolution: {integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==} + engines: {node: '>=0.6'} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + randomfill@1.0.4: + resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@3.0.0: + resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} + engines: {node: '>= 0.8'} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react-native-fetch-api@2.0.0: + resolution: {integrity: sha512-GOA8tc1EVYLnHvma/TU9VTgLOyralO7eATRuCDchQveXW9Fr9vXygyq9iwqmM7YRZ8qRJfEt9xOS7OYMdJvRFw==} + + react-native-fetch-api@3.0.0: + resolution: {integrity: sha512-g2rtqPjdroaboDKTsJCTlcmtw54E25OjyaunUP0anOZn4Fuo2IKs8BVfe02zVggA/UysbmfSnRJIqtNkAgggNA==} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readonly-date@1.0.0: + resolution: {integrity: sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==} + + real-require@0.2.0: + resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} + engines: {node: '>= 12.13.0'} + + receptacle@1.3.2: + resolution: {integrity: sha512-HrsFvqZZheusncQRiEE7GatOAETrARKV/lnfYicIm8lbvp/JQOdADOfhjBd2DajvoszEyxSM6RlAAIZgEoeu/A==} + + rechoir@0.6.2: + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} + engines: {node: '>= 0.10'} + + redeyed@2.1.1: + resolution: {integrity: sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==} + + reduce-flatten@2.0.0: + resolution: {integrity: sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==} + engines: {node: '>=6'} + + reflect-metadata@0.1.14: + resolution: {integrity: sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + + regenerate-unicode-properties@10.2.0: + resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regenerator-transform@0.15.2: + resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==} + + regexpu-core@6.2.0: + resolution: {integrity: sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==} + engines: {node: '>=4'} + + registry-auth-token@4.2.2: + resolution: {integrity: sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==} + engines: {node: '>=6.0.0'} + + registry-url@5.1.0: + resolution: {integrity: sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==} + engines: {node: '>=8'} + + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.12.0: + resolution: {integrity: sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==} + hasBin: true + + rehackt@0.1.0: + resolution: {integrity: sha512-7kRDOuLHB87D/JESKxQoRwv4DzbIdwkAGQ7p6QKGdVlY1IZheUnVhlk/4UZlNUVxdAXpyxikE3URsG067ybVzw==} + peerDependencies: + '@types/react': '*' + react: '*' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + + require-addon@1.1.0: + resolution: {integrity: sha512-KbXAD5q2+v1GJnkzd8zzbOxchTkStSyJZ9QwoCq3QwEXAaIlG3wDYRZGzVD357jmwaGY7hr5VaoEAL0BkF0Kvg==} + engines: {bare: '>=1.10.0'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} + engines: {node: '>=10'} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + responselike@1.0.2: + resolution: {integrity: sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==} + + restore-cursor@2.0.0: + resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==} + engines: {node: '>=4'} + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + + retimer@2.0.0: + resolution: {integrity: sha512-KLXY85WkEq2V2bKex/LOO1ViXVn2KGYe4PYysAdYdjmraYIUsVkXu8O4am+8+5UbaaGl1qho4aqAAPHNQ4GSbg==} + + retimer@3.0.0: + resolution: {integrity: sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA==} + + retry-as-promised@7.1.1: + resolution: {integrity: sha512-hMD7odLOt3LkTjcif8aRZqi/hybjpLNgSk5oF5FCowfCjok6LukpN2bDX7R5wDmbgBQFn7YoBxSagmtXHaJYJw==} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@5.0.0: + resolution: {integrity: sha512-Jf9llaP+RvaEVS5nPShYFhtXIrb3LRKP281ib3So0KkeZKo2wIKyq0Re7TOSwanasA423PSr6CCIL4bP6T040g==} + engines: {node: '>=14'} + hasBin: true + + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + ripemd160@2.0.2: + resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + + rotating-file-stream@3.2.6: + resolution: {integrity: sha512-r8yShzMWUvWXkRzbOXDM1fEaMpc3qo2PzK7bBH/0p0Nl/uz8Mud/Y+0XTQxe3kbSnDF7qBH2tSe83WDKA7o3ww==} + engines: {node: '>=14.0'} + + router@2.1.0: + resolution: {integrity: sha512-/m/NSLxeYEgWNtyC+WtNHCF7jbGxOibVWKnn+1Psff4dJGOfoXP+MuC/f2CwSmyiHdOIzYnYFp4W6GxWfekaLA==} + engines: {node: '>= 18'} + + rpc-websocket-client@1.1.4: + resolution: {integrity: sha512-UDMVcsNDJ3WET+0EFdmseYX+60MOCA3BpgpZ5dbtiGsqHo+9uWfgNbPZ4iGDtNcX+EUhCt/Y7C0fTmUU3CkkWA==} + engines: {node: '>=6.0.0'} + + run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rx-lite-aggregates@4.0.8: + resolution: {integrity: sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==} + + rx-lite@4.0.8: + resolution: {integrity: sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==} + + rxjs@6.6.7: + resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} + engines: {npm: '>=2.0.0'} + + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + scale-ts@1.6.1: + resolution: {integrity: sha512-PBMc2AWc6wSEqJYBDPcyCLUj9/tMKnLX70jLOSndMtcUoLQucP/DM0vnQo1wJAYjTrQiq8iG9rD0q6wFzgjH7g==} + + schema-utils@4.3.0: + resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==} + engines: {node: '>= 10.13.0'} + + scrypt-js@3.0.1: + resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} + + scryptsy@2.1.0: + resolution: {integrity: sha512-1CdSqHQowJBnMAFyPEBRfqag/YP9OF394FV+4YREIJX4ljD7OxvQRDayyoyyCk+senRjSkP6VnUNQmVQqB6g7w==} + + secp256k1@5.0.1: + resolution: {integrity: sha512-lDFs9AAIaWP9UCdtWrotXWWF9t8PWgQDcxqgAnpM9rMqxb3Oaq2J0thzPVSxBwdJgyQtkU/sYtFtbM1RSt/iYA==} + engines: {node: '>=18.0.0'} + + semver-diff@3.1.1: + resolution: {integrity: sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==} + engines: {node: '>=8'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + + send@1.1.0: + resolution: {integrity: sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==} + engines: {node: '>= 18'} + + sequelize-pool@7.1.0: + resolution: {integrity: sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==} + engines: {node: '>= 10.0.0'} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-static@2.1.0: + resolution: {integrity: sha512-A3We5UfEjG8Z7VkDv6uItWw6HY2bBSBJT1KtVESn6EOoOr2jAxNhxWCLY3jDE2WcuHXByWju74ck3ZgLwL8xmA==} + engines: {node: '>= 18'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + + shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shelljs@0.8.5: + resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} + engines: {node: '>=4'} + hasBin: true + + side-channel-list@1.0.0: + resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-git@3.27.0: + resolution: {integrity: sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + smoldot@2.0.26: + resolution: {integrity: sha512-F+qYmH4z2s2FK+CxGj8moYcd1ekSIKH8ywkdqlOz88Dat35iB1DIYL11aILN46YSGMzQW/lbJNS307zBSDN5Ig==} + + sodium-native@3.4.1: + resolution: {integrity: sha512-PaNN/roiFWzVVTL6OqjzYct38NSXewdl2wz8SRB51Br/MLIJPrbM3XexhVWkq7D3UWMysfrhKVf1v1phZq6MeQ==} + + sodium-native@4.3.3: + resolution: {integrity: sha512-OnxSlN3uyY8D0EsLHpmm2HOFmKddQVvEMmsakCrXUzSd8kjjbzL413t4ZNF3n0UxSwNgwTyUvkmZHTfuCeiYSw==} + + sonic-boom@1.4.1: + resolution: {integrity: sha512-LRHh/A8tpW7ru89lrlkU4AszXt1dbwSjVWguGrmlxE7tawVmDBlI1PILMkXAxJTwqhgsEeTHzj36D5CmHgQmNg==} + + sonic-boom@4.2.0: + resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} + + soroban-client@0.9.2: + resolution: {integrity: sha512-PPQLvAQTF/y56ev9V9wdMze/K49u1Cj6F9rkiUlRy++wCpSAVjiRYG+duolYvjkzUFPon56xlgAc7tuP4EolWA==} + deprecated: '⚠️ This package is now deprecated: transition to @stellar/stellar-sdk@latest, instead! 🚚 All future updates and bug fixes will happen there. Please refer to the migration guide for details on porting your codebase: https://github.com/stellar/js-soroban-client/tree/main/docs/migration.md' + + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + stellar-base@10.0.0-soroban.4: + resolution: {integrity: sha512-Afl2Mlh+aXokIHhy2x67Df5ofbss83oAOHV7pHLI0fsPlxAgs7YtbClzkNxvpnXyxQI77PMIWFJbT17Y3dR/+A==} + deprecated: ⚠️ This package has moved to @stellar/stellar-base! 🚚 + + stellar-base@8.2.2: + resolution: {integrity: sha512-YVCIuJXU1bPn+vU0ded+g0D99DcpYXH9CEXfpYEDc4Gf04h65YjOVhGojQBm1hqVHq3rKT7m1tgfNACkU84FTA==} + deprecated: ⚠️ This package has moved to @stellar/stellar-base! 🚚 + + stellar-sdk@10.4.1: + resolution: {integrity: sha512-Wdm2UoLuN9SNrSEHO0R/I+iZuRwUkfny1xg4akhGCpO8LQZw8QzuMTJvbEoMT3sHT4/eWYiteVLp7ND21xZf5A==} + deprecated: ⚠️ This package has moved to @stellar/stellar-sdk! 🚚 + + stream-to-it@0.2.4: + resolution: {integrity: sha512-4vEbkSs83OahpmBybNJXlJd7d6/RxzkkSdT3I0mnGt79Xd2Kk+e1JqbvAvsQfCeKj3aKb0QIWkyK3/n0j506vQ==} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + string-format@2.0.0: + resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} + + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + + string-width@2.1.1: + resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} + engines: {node: '>=4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@3.0.1: + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} + engines: {node: '>=0.10.0'} + + strip-ansi@4.0.0: + resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} + engines: {node: '>=4'} + + strip-ansi@5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strtok3@10.3.4: + resolution: {integrity: sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg==} + engines: {node: '>=18'} + + supports-color@2.0.0: + resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} + engines: {node: '>=0.8.0'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-hyperlinks@2.3.0: + resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + symbol-observable@2.0.3: + resolution: {integrity: sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==} + engines: {node: '>=0.10'} + + symbol-observable@4.0.0: + resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} + engines: {node: '>=0.10'} + + table-layout@1.0.2: + resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} + engines: {node: '>=8.0.0'} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + + tdigest@0.1.2: + resolution: {integrity: sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==} + + terser-webpack-plugin@5.3.12: + resolution: {integrity: sha512-jDLYqo7oF8tJIttjXO6jBY5Hk8p3A8W4ttih7cCEq64fQFWmgJ4VqAQjKr7WwIDlmXKEc6QeoRb5ecjZ+2afcg==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + + terser@5.39.0: + resolution: {integrity: sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==} + engines: {node: '>=10'} + hasBin: true + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + thread-stream@3.1.0: + resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + + through2@4.0.2: + resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + timeout-abort-controller@1.1.1: + resolution: {integrity: sha512-BsF9i3NAJag6T0ZEjki9j654zoafI2X6ayuNd6Tp8+Ul6Tr5s4jo973qFeiWrRSweqvskC+AHDKUmIW4b7pdhQ==} + + timeout-abort-controller@3.0.0: + resolution: {integrity: sha512-O3e+2B8BKrQxU2YRyEjC/2yFdb33slI22WRdUaDx6rvysfi9anloNZyR2q0l6LnePo5qH7gSM7uZtvvwZbc2yA==} + + timers-ext@0.1.8: + resolution: {integrity: sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==} + engines: {node: '>=0.12'} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-arraybuffer@1.0.1: + resolution: {integrity: sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==} + + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + to-readable-stream@1.0.0: + resolution: {integrity: sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==} + engines: {node: '>=6'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + token-types@6.1.1: + resolution: {integrity: sha512-kh9LVIWH5CnL63Ipf0jhlBIy0UsrMj/NJDfpsy1SqOXlLKEVyXXYrnFxFT1yOOYVGBSApeVnjPw/sBz5BfEjAQ==} + engines: {node: '>=14.16'} + + toml@2.3.6: + resolution: {integrity: sha512-gVweAectJU3ebq//Ferr2JUY4WKSDe5N+z0FvjDncLGyHmIDoxgY/2Ie4qfEIDm4IS7OA6Rmdm7pdEEdMcV/xQ==} + + toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + + toposort-class@1.0.1: + resolution: {integrity: sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==} + + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + ts-command-line-args@2.5.1: + resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} + hasBin: true + + ts-essentials@7.0.3: + resolution: {integrity: sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==} + peerDependencies: + typescript: '>=3.7.0' + + ts-invariant@0.10.3: + resolution: {integrity: sha512-uivwYcQaxAucv1CzRp2n/QdYPo4ILf9VXgH19zEIjFx2EJufV16P0JtJVpYHy89DItG6Kwj2oIUjrcK5au+4tQ==} + engines: {node: '>=8'} + + ts-jest@29.2.6: + resolution: {integrity: sha512-yTNZVZqc8lSixm+QGVFcPe6+yj7+TWZwIesuOWvfcn4B9bz5x4NDzVCQQjOs7Hfouu36aEqfEbo9Qpo+gq8dDg==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 + '@jest/types': ^29.0.0 + babel-jest: ^29.0.0 + esbuild: '*' + jest: ^29.0.0 + typescript: '>=4.3 <6' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/transform': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + + ts-loader@9.5.2: + resolution: {integrity: sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==} + engines: {node: '>=12.0.0'} + peerDependencies: + typescript: '*' + webpack: ^5.0.0 + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tsconfig-paths-webpack-plugin@4.2.0: + resolution: {integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==} + engines: {node: '>=10.13.0'} + + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.3.1: + resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsx@4.19.4: + resolution: {integrity: sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==} + engines: {node: '>=18.0.0'} + hasBin: true + + tweetnacl@1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + type-is@2.0.0: + resolution: {integrity: sha512-gd0sGezQYCbWSbkZr75mln4YBidWUN60+devscpLF5mtRDUpiaTvKpBNrdaCvel1NdR2k6vclXybU5fBd2i+nw==} + engines: {node: '>= 0.6'} + + type@2.7.3: + resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} + + typechain@8.3.2: + resolution: {integrity: sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==} + hasBin: true + peerDependencies: + typescript: '>=4.3.0' + + typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + typescript@5.9.2: + resolution: {integrity: sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==} + engines: {node: '>=14.17'} + hasBin: true + + typical@4.0.0: + resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} + engines: {node: '>=8'} + + typical@5.2.0: + resolution: {integrity: sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==} + engines: {node: '>=8'} + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + uid@2.0.2: + resolution: {integrity: sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==} + engines: {node: '>=8'} + + uint8array-extras@1.5.0: + resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} + engines: {node: '>=18'} + + uint8arrays@3.1.1: + resolution: {integrity: sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==} + + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.2.0: + resolution: {integrity: sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + + unique-string@2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + update-notifier@5.1.0: + resolution: {integrity: sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw==} + engines: {node: '>=10'} + + urijs@1.19.11: + resolution: {integrity: sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==} + + url-parse-lax@3.0.0: + resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==} + engines: {node: '>=4'} + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util@0.10.4: + resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + utility-types@3.11.0: + resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==} + engines: {node: '>= 4'} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} + + validator@13.12.0: + resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} + engines: {node: '>= 0.10'} + + varint@6.0.0: + resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + viem@2.23.6: + resolution: {integrity: sha512-+yUeK8rktbGFQaLIvY4Tki22HUjian9Z4eKGAUT72RF9bcfkYgK8CJZz9P83tgoeLpiTyX3xcBM4xJZrJyKmsA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + vlq@2.0.4: + resolution: {integrity: sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==} + + vm2@3.9.19: + resolution: {integrity: sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==} + engines: {node: '>=6.0'} + deprecated: The library contains critical security issues and should not be used for production! The maintenance of the project has been discontinued. Consider migrating your code to isolated-vm. + hasBin: true + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + wasm-ast-types@0.25.0: + resolution: {integrity: sha512-ZTjXuBqRf3ntxXmskO1TyTTr8UbmAZGr72JGGctizzpdokMtuLsk5q8jHaFUv/qgQni1KuBxZnHIyaj1lnZegQ==} + + watchpack@2.4.2: + resolution: {integrity: sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==} + engines: {node: '>=10.13.0'} + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webpack-merge@6.0.1: + resolution: {integrity: sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==} + engines: {node: '>=18.0.0'} + + webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + + webpack@5.98.0: + resolution: {integrity: sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + websocket@1.0.35: + resolution: {integrity: sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q==} + engines: {node: '>=4.0.0'} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-typed-array@1.1.18: + resolution: {integrity: sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + widest-line@3.1.0: + resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} + engines: {node: '>=8'} + + wildcard@2.0.1: + resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} + + wkx@0.5.0: + resolution: {integrity: sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + wordwrapjs@4.0.1: + resolution: {integrity: sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==} + engines: {node: '>=8.0.0'} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + 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 + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + 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 + + ws@8.18.1: + resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} + 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 + + xdg-basedir@4.0.0: + resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==} + engines: {node: '>=8'} + + xstream@11.14.0: + resolution: {integrity: sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaeti@0.0.6: + resolution: {integrity: sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==} + engines: {node: '>=0.10.32'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml-loader@0.8.1: + resolution: {integrity: sha512-BCEndnUoi3BaZmePkwGGe93txRxLgMhBa/gE725v1/GHnura8QvNs7c4+4C1yyhhKoj3Dg63M7IqhA++15j6ww==} + engines: {node: '>= 14'} + + yaml@2.7.0: + resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} + engines: {node: '>= 14'} + hasBin: true + + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yoctocolors-cjs@2.1.2: + resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} + engines: {node: '>=18'} + + zen-observable-ts@1.2.5: + resolution: {integrity: sha512-QZWQekv6iB72Naeake9hS1KxHlotfRpe+WGNbNx5/ta+R3DNjVO2bswf63gXlWDcs+EMd7XY8HfVQyP1X6T4Zg==} + + zen-observable@0.8.15: + resolution: {integrity: sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==} + + zod@3.25.32: + resolution: {integrity: sha512-OSm2xTIRfW8CV5/QKgngwmQW/8aPfGdaQFlrGoErlgg/Epm7cjb6K6VEyExfe65a3VybUOnu381edLb0dfJl0g==} + +snapshots: + + '@achingbrain/node-fetch@2.6.7': {} + + '@adraffy/ens-normalize@1.11.0': {} + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@apollo/client@3.14.0(graphql@15.10.1)': + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@15.10.1) + '@wry/caches': 1.0.1 + '@wry/equality': 0.5.7 + '@wry/trie': 0.5.0 + graphql: 15.10.1 + graphql-tag: 2.12.6(graphql@15.10.1) + hoist-non-react-statics: 3.3.2 + optimism: 0.18.1 + prop-types: 15.8.1 + rehackt: 0.1.0 + symbol-observable: 4.0.0 + ts-invariant: 0.10.3 + tslib: 2.8.1 + zen-observable-ts: 1.2.5 + transitivePeerDependencies: + - '@types/react' + + '@babel/code-frame@7.26.2': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.26.8': {} + + '@babel/core@7.18.10': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.18.10) + '@babel/helpers': 7.26.9 + '@babel/parser': 7.26.9 + '@babel/template': 7.26.9 + '@babel/traverse': 7.26.9 + '@babel/types': 7.28.2 + convert-source-map: 1.9.0 + debug: 4.4.0(supports-color@8.1.1) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/core@7.26.9': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.9) + '@babel/helpers': 7.26.9 + '@babel/parser': 7.26.9 + '@babel/template': 7.26.9 + '@babel/traverse': 7.26.9 + '@babel/types': 7.28.2 + convert-source-map: 2.0.0 + debug: 4.4.0(supports-color@8.1.1) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.18.12': + dependencies: + '@babel/types': 7.28.2 + '@jridgewell/gen-mapping': 0.3.8 + jsesc: 2.5.2 + + '@babel/generator@7.24.4': + dependencies: + '@babel/types': 7.28.2 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 2.5.2 + + '@babel/generator@7.26.9': + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.28.2 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.25.9': + dependencies: + '@babel/types': 7.28.2 + + '@babel/helper-compilation-targets@7.26.5': + dependencies: + '@babel/compat-data': 7.26.8 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.4 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.26.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-member-expression-to-functions': 7.25.9 + '@babel/helper-optimise-call-expression': 7.25.9 + '@babel/helper-replace-supers': 7.26.5(@babel/core@7.18.10) + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/traverse': 7.26.9 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.26.3(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-annotate-as-pure': 7.25.9 + regexpu-core: 6.2.0 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.3.3(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.27.1 + debug: 4.4.0(supports-color@8.1.1) + lodash.debounce: 4.0.8 + resolve: 1.22.10 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-environment-visitor@7.24.7': + dependencies: + '@babel/types': 7.28.2 + + '@babel/helper-function-name@7.24.7': + dependencies: + '@babel/template': 7.26.9 + '@babel/types': 7.28.2 + + '@babel/helper-hoist-variables@7.24.7': + dependencies: + '@babel/types': 7.28.2 + + '@babel/helper-member-expression-to-functions@7.25.9': + dependencies: + '@babel/traverse': 7.26.9 + '@babel/types': 7.28.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.25.9': + dependencies: + '@babel/traverse': 7.26.9 + '@babel/types': 7.28.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.26.0(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.25.9': + dependencies: + '@babel/types': 7.28.2 + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-remap-async-to-generator@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-wrap-function': 7.25.9 + '@babel/traverse': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.26.5(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-member-expression-to-functions': 7.25.9 + '@babel/helper-optimise-call-expression': 7.25.9 + '@babel/traverse': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.25.9': + dependencies: + '@babel/traverse': 7.26.9 + '@babel/types': 7.28.2 + transitivePeerDependencies: + - supports-color + + '@babel/helper-split-export-declaration@7.24.7': + dependencies: + '@babel/types': 7.28.2 + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/helper-validator-option@7.25.9': {} + + '@babel/helper-wrap-function@7.25.9': + dependencies: + '@babel/template': 7.26.9 + '@babel/traverse': 7.26.9 + '@babel/types': 7.28.2 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.26.9': + dependencies: + '@babel/template': 7.26.9 + '@babel/types': 7.28.2 + + '@babel/parser@7.18.11': + dependencies: + '@babel/types': 7.28.2 + + '@babel/parser@7.26.9': + dependencies: + '@babel/types': 7.28.2 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/plugin-transform-optional-chaining': 7.25.9(@babel/core@7.18.10) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-async-generator-functions@7.20.7(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.18.10) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-create-class-features-plugin': 7.26.9(@babel/core@7.18.10) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-class-static-block@7.21.0(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-create-class-features-plugin': 7.26.9(@babel/core@7.18.10) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.18.10) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-dynamic-import@7.18.6(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.18.10) + + '@babel/plugin-proposal-export-default-from@7.18.10(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-export-default-from': 7.25.9(@babel/core@7.18.10) + + '@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.18.10) + + '@babel/plugin-proposal-json-strings@7.18.6(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.18.10) + + '@babel/plugin-proposal-logical-assignment-operators@7.20.7(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.18.10) + + '@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.18.10) + + '@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.18.10) + + '@babel/plugin-proposal-object-rest-spread@7.18.9(@babel/core@7.18.10)': + dependencies: + '@babel/compat-data': 7.26.8 + '@babel/core': 7.18.10 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.18.10) + + '@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.18.10) + + '@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.18.10) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-create-class-features-plugin': 7.26.9(@babel/core@7.18.10) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.11(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-create-class-features-plugin': 7.26.9(@babel/core@7.18.10) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.18.10) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.18.10) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-export-default-from@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + optional: true + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.25.9(@babel/core@7.26.9)': + dependencies: + '@babel/core': 7.26.9 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-arrow-functions@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-async-to-generator@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.18.10) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.26.5(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-block-scoping@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-classes@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.26.5(@babel/core@7.18.10) + '@babel/traverse': 7.26.9 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/template': 7.26.9 + + '@babel/plugin-transform-destructuring@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-dotall-regex@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.18.10) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-duplicate-keys@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-exponentiation-operator@7.26.3(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-for-of@7.26.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/traverse': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-literals@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-member-expression-literals@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-modules-amd@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.18.10) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.26.3(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.18.10) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.18.10) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.26.9 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.18.10) + '@babel/helper-plugin-utils': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.18.10) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-new-target@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-object-super@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-replace-supers': 7.26.5(@babel/core@7.18.10) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-chaining@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-property-literals@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-regenerator@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + regenerator-transform: 0.15.2 + + '@babel/plugin-transform-reserved-words@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-runtime@7.18.10(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-plugin-utils': 7.27.1 + babel-plugin-polyfill-corejs2: 0.3.3(@babel/core@7.18.10) + babel-plugin-polyfill-corejs3: 0.5.3(@babel/core@7.18.10) + babel-plugin-polyfill-regenerator: 0.4.1(@babel/core@7.18.10) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-shorthand-properties@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-spread@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-template-literals@7.26.8(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-typeof-symbol@7.26.7(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-typescript@7.26.8(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-create-class-features-plugin': 7.26.9(@babel/core@7.18.10) + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-skip-transparent-expression-wrappers': 7.25.9 + '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.18.10) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-unicode-escapes@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-transform-unicode-regex@7.25.9(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-create-regexp-features-plugin': 7.26.3(@babel/core@7.18.10) + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/preset-env@7.18.10(@babel/core@7.18.10)': + dependencies: + '@babel/compat-data': 7.26.8 + '@babel/core': 7.18.10 + '@babel/helper-compilation-targets': 7.26.5 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.25.9 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-proposal-async-generator-functions': 7.20.7(@babel/core@7.18.10) + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.18.10) + '@babel/plugin-proposal-class-static-block': 7.21.0(@babel/core@7.18.10) + '@babel/plugin-proposal-dynamic-import': 7.18.6(@babel/core@7.18.10) + '@babel/plugin-proposal-export-namespace-from': 7.18.9(@babel/core@7.18.10) + '@babel/plugin-proposal-json-strings': 7.18.6(@babel/core@7.18.10) + '@babel/plugin-proposal-logical-assignment-operators': 7.20.7(@babel/core@7.18.10) + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.18.10) + '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.18.10) + '@babel/plugin-proposal-object-rest-spread': 7.18.9(@babel/core@7.18.10) + '@babel/plugin-proposal-optional-catch-binding': 7.18.6(@babel/core@7.18.10) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.18.10) + '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.18.10) + '@babel/plugin-proposal-private-property-in-object': 7.21.11(@babel/core@7.18.10) + '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.18.10) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.18.10) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.18.10) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.18.10) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-syntax-import-assertions': 7.26.0(@babel/core@7.18.10) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.18.10) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.18.10) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.18.10) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.18.10) + '@babel/plugin-transform-arrow-functions': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-async-to-generator': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-block-scoped-functions': 7.26.5(@babel/core@7.18.10) + '@babel/plugin-transform-block-scoping': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-classes': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-computed-properties': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-destructuring': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-dotall-regex': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-duplicate-keys': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-exponentiation-operator': 7.26.3(@babel/core@7.18.10) + '@babel/plugin-transform-for-of': 7.26.9(@babel/core@7.18.10) + '@babel/plugin-transform-function-name': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-literals': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-member-expression-literals': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-modules-amd': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-modules-commonjs': 7.26.3(@babel/core@7.18.10) + '@babel/plugin-transform-modules-systemjs': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-modules-umd': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-named-capturing-groups-regex': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-new-target': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-object-super': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-property-literals': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-regenerator': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-reserved-words': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-shorthand-properties': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-spread': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-sticky-regex': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-template-literals': 7.26.8(@babel/core@7.18.10) + '@babel/plugin-transform-typeof-symbol': 7.26.7(@babel/core@7.18.10) + '@babel/plugin-transform-unicode-escapes': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-unicode-regex': 7.25.9(@babel/core@7.18.10) + '@babel/preset-modules': 0.1.6(@babel/core@7.18.10) + '@babel/types': 7.28.2 + babel-plugin-polyfill-corejs2: 0.3.3(@babel/core@7.18.10) + babel-plugin-polyfill-corejs3: 0.5.3(@babel/core@7.18.10) + babel-plugin-polyfill-regenerator: 0.4.1(@babel/core@7.18.10) + core-js-compat: 3.41.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-modules@0.1.6(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.18.10) + '@babel/plugin-transform-dotall-regex': 7.25.9(@babel/core@7.18.10) + '@babel/types': 7.28.2 + esutils: 2.0.3 + + '@babel/preset-typescript@7.26.0(@babel/core@7.18.10)': + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-validator-option': 7.25.9 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.18.10) + '@babel/plugin-transform-modules-commonjs': 7.26.3(@babel/core@7.18.10) + '@babel/plugin-transform-typescript': 7.26.8(@babel/core@7.18.10) + transitivePeerDependencies: + - supports-color + + '@babel/runtime@7.26.9': + dependencies: + regenerator-runtime: 0.14.1 + + '@babel/template@7.26.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.9 + '@babel/types': 7.28.2 + + '@babel/traverse@7.18.11': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/parser': 7.26.9 + '@babel/types': 7.28.2 + debug: 4.4.0(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/traverse@7.23.6': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/parser': 7.26.9 + '@babel/types': 7.28.2 + debug: 4.4.0(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/traverse@7.24.1': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/parser': 7.26.9 + '@babel/types': 7.28.2 + debug: 4.4.0(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/traverse@7.26.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.9 + '@babel/parser': 7.26.9 + '@babel/template': 7.26.9 + '@babel/types': 7.28.2 + debug: 4.4.0(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.18.10': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + to-fast-properties: 2.0.0 + + '@babel/types@7.23.6': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + to-fast-properties: 2.0.0 + + '@babel/types@7.24.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + to-fast-properties: 2.0.0 + + '@babel/types@7.28.2': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@bcoe/v8-coverage@0.2.3': {} + + '@borewit/text-codec@0.1.1': {} + + '@cosmjs/amino@0.36.0': + dependencies: + '@cosmjs/crypto': 0.36.0 + '@cosmjs/encoding': 0.36.0 + '@cosmjs/math': 0.36.0 + '@cosmjs/utils': 0.36.0 + + '@cosmjs/cosmwasm-stargate@0.36.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@cosmjs/amino': 0.36.0 + '@cosmjs/crypto': 0.36.0 + '@cosmjs/encoding': 0.36.0 + '@cosmjs/math': 0.36.0 + '@cosmjs/proto-signing': 0.36.0 + '@cosmjs/stargate': 0.36.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@cosmjs/tendermint-rpc': 0.36.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@cosmjs/utils': 0.36.0 + cosmjs-types: 0.10.1 + pako: 2.1.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@cosmjs/crypto@0.36.0': + dependencies: + '@cosmjs/encoding': 0.36.0 + '@cosmjs/math': 0.36.0 + '@cosmjs/utils': 0.36.0 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + hash-wasm: 4.12.0 + + '@cosmjs/encoding@0.36.0': + dependencies: + base64-js: 1.5.1 + bech32: 1.1.4 + readonly-date: 1.0.0 + + '@cosmjs/json-rpc@0.36.0': + dependencies: + '@cosmjs/stream': 0.36.0 + xstream: 11.14.0 + + '@cosmjs/math@0.36.0': {} + + '@cosmjs/proto-signing@0.36.0': + dependencies: + '@cosmjs/amino': 0.36.0 + '@cosmjs/crypto': 0.36.0 + '@cosmjs/encoding': 0.36.0 + '@cosmjs/math': 0.36.0 + '@cosmjs/utils': 0.36.0 + cosmjs-types: 0.10.1 + + '@cosmjs/socket@0.36.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@cosmjs/stream': 0.36.0 + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@cosmjs/stargate@0.36.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@cosmjs/amino': 0.36.0 + '@cosmjs/encoding': 0.36.0 + '@cosmjs/math': 0.36.0 + '@cosmjs/proto-signing': 0.36.0 + '@cosmjs/stream': 0.36.0 + '@cosmjs/tendermint-rpc': 0.36.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@cosmjs/utils': 0.36.0 + cosmjs-types: 0.10.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@cosmjs/stream@0.36.0': + dependencies: + xstream: 11.14.0 + + '@cosmjs/tendermint-rpc@0.36.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@cosmjs/crypto': 0.36.0 + '@cosmjs/encoding': 0.36.0 + '@cosmjs/json-rpc': 0.36.0 + '@cosmjs/math': 0.36.0 + '@cosmjs/socket': 0.36.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@cosmjs/stream': 0.36.0 + '@cosmjs/utils': 0.36.0 + readonly-date: 1.0.0 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@cosmjs/utils@0.36.0': {} + + '@cosmology/protobufjs@6.11.6': + 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.2 + '@types/node': 22.13.9 + long: 4.0.0 + + '@cosmwasm/ts-codegen-ast@1.8.1': + dependencies: + '@babel/types': 7.24.0 + '@cosmwasm/ts-codegen-types': 1.3.1 + ast-stringify: 0.1.0 + case: 1.6.3 + deepmerge: 4.2.2 + + '@cosmwasm/ts-codegen-types@1.3.1': {} + + '@cosmwasm/ts-codegen@0.34.0': + dependencies: + '@babel/core': 7.18.10 + '@babel/generator': 7.18.12 + '@babel/parser': 7.18.11 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.18.10) + '@babel/plugin-proposal-export-default-from': 7.18.10(@babel/core@7.18.10) + '@babel/plugin-proposal-object-rest-spread': 7.18.9(@babel/core@7.18.10) + '@babel/plugin-transform-runtime': 7.18.10(@babel/core@7.18.10) + '@babel/preset-env': 7.18.10(@babel/core@7.18.10) + '@babel/preset-typescript': 7.26.0(@babel/core@7.18.10) + '@babel/runtime': 7.26.9 + '@babel/traverse': 7.18.11 + '@babel/types': 7.18.10 + '@pyramation/json-schema-to-typescript': 11.0.4 + case: 1.6.3 + dargs: 7.0.0 + deepmerge: 4.2.2 + dotty: 0.1.2 + fuzzy: 0.1.3 + glob: 8.0.3 + inquirerer: 0.1.3 + long: 5.3.1 + minimist: 1.2.6 + mkdirp: 1.0.4 + parse-package-name: 1.0.0 + rimraf: 3.0.2 + shelljs: 0.8.5 + wasm-ast-types: 0.25.0 + transitivePeerDependencies: + - supports-color + + '@cosmwasm/ts-codegen@1.12.1': + dependencies: + '@babel/generator': 7.24.4 + '@babel/traverse': 7.24.1 + '@babel/types': 7.24.0 + '@cosmwasm/ts-codegen-ast': 1.8.1 + '@cosmwasm/ts-codegen-types': 1.3.1 + '@pyramation/json-schema-to-typescript': 11.0.4 + '@types/rimraf': 3.0.2 + '@types/shelljs': 0.8.15 + case: 1.6.3 + dargs: 7.0.0 + deepmerge: 4.2.2 + fuzzy: 0.1.3 + glob: 8.0.3 + inquirerer: 0.1.3 + minimist: 1.2.6 + mkdirp: 1.0.4 + nested-obj: 0.0.1 + parse-package-name: 1.0.0 + rimraf: 3.0.2 + shelljs: 0.8.5 + transitivePeerDependencies: + - supports-color + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@esbuild/aix-ppc64@0.25.5': + optional: true + + '@esbuild/android-arm64@0.25.5': + optional: true + + '@esbuild/android-arm@0.25.5': + optional: true + + '@esbuild/android-x64@0.25.5': + optional: true + + '@esbuild/darwin-arm64@0.25.5': + optional: true + + '@esbuild/darwin-x64@0.25.5': + optional: true + + '@esbuild/freebsd-arm64@0.25.5': + optional: true + + '@esbuild/freebsd-x64@0.25.5': + optional: true + + '@esbuild/linux-arm64@0.25.5': + optional: true + + '@esbuild/linux-arm@0.25.5': + optional: true + + '@esbuild/linux-ia32@0.25.5': + optional: true + + '@esbuild/linux-loong64@0.25.5': + optional: true + + '@esbuild/linux-mips64el@0.25.5': + optional: true + + '@esbuild/linux-ppc64@0.25.5': + optional: true + + '@esbuild/linux-riscv64@0.25.5': + optional: true + + '@esbuild/linux-s390x@0.25.5': + optional: true + + '@esbuild/linux-x64@0.25.5': + optional: true + + '@esbuild/netbsd-arm64@0.25.5': + optional: true + + '@esbuild/netbsd-x64@0.25.5': + optional: true + + '@esbuild/openbsd-arm64@0.25.5': + optional: true + + '@esbuild/openbsd-x64@0.25.5': + optional: true + + '@esbuild/sunos-x64@0.25.5': + optional: true + + '@esbuild/win32-arm64@0.25.5': + optional: true + + '@esbuild/win32-ia32@0.25.5': + optional: true + + '@esbuild/win32-x64@0.25.5': + optional: true + + '@ethersproject/abi@5.8.0': + dependencies: + '@ethersproject/address': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/hash': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/strings': 5.8.0 + + '@ethersproject/abstract-provider@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/networks': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/transactions': 5.8.0 + '@ethersproject/web': 5.8.0 + + '@ethersproject/abstract-signer@5.8.0': + dependencies: + '@ethersproject/abstract-provider': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + + '@ethersproject/address@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/rlp': 5.8.0 + + '@ethersproject/base64@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + + '@ethersproject/basex@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/properties': 5.8.0 + + '@ethersproject/bignumber@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + bn.js: 5.2.1 + + '@ethersproject/bytes@5.8.0': + dependencies: + '@ethersproject/logger': 5.8.0 + + '@ethersproject/constants@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + + '@ethersproject/contracts@5.8.0': + 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 + + '@ethersproject/hash@5.8.0': + dependencies: + '@ethersproject/abstract-signer': 5.8.0 + '@ethersproject/address': 5.8.0 + '@ethersproject/base64': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/strings': 5.8.0 + + '@ethersproject/hdnode@5.8.0': + 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 + + '@ethersproject/json-wallets@5.8.0': + 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 + + '@ethersproject/keccak256@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + js-sha3: 0.8.0 + + '@ethersproject/logger@5.8.0': {} + + '@ethersproject/networks@5.8.0': + dependencies: + '@ethersproject/logger': 5.8.0 + + '@ethersproject/pbkdf2@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/sha2': 5.8.0 + + '@ethersproject/properties@5.8.0': + dependencies: + '@ethersproject/logger': 5.8.0 + + '@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + 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(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@ethersproject/random@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@ethersproject/rlp@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@ethersproject/sha2@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + hash.js: 1.1.7 + + '@ethersproject/shims@5.8.0': {} + + '@ethersproject/signing-key@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + bn.js: 5.2.1 + elliptic: 6.6.1 + hash.js: 1.1.7 + + '@ethersproject/solidity@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/sha2': 5.8.0 + '@ethersproject/strings': 5.8.0 + + '@ethersproject/strings@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@ethersproject/transactions@5.8.0': + dependencies: + '@ethersproject/address': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/rlp': 5.8.0 + '@ethersproject/signing-key': 5.8.0 + + '@ethersproject/units@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@ethersproject/wallet@5.8.0': + 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 + + '@ethersproject/web@5.8.0': + dependencies: + '@ethersproject/base64': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/strings': 5.8.0 + + '@ethersproject/wordlists@5.8.0': + 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 + + '@graphql-typed-document-node/core@3.2.0(graphql@15.10.1)': + dependencies: + graphql: 15.10.1 + + '@inquirer/checkbox@2.5.0': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/figures': 1.0.10 + '@inquirer/type': 1.5.5 + ansi-escapes: 4.3.2 + yoctocolors-cjs: 2.1.2 + + '@inquirer/confirm@3.2.0': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 1.5.5 + + '@inquirer/core@9.2.1': + dependencies: + '@inquirer/figures': 1.0.10 + '@inquirer/type': 2.0.0 + '@types/mute-stream': 0.0.4 + '@types/node': 22.13.9 + '@types/wrap-ansi': 3.0.0 + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 1.0.0 + signal-exit: 4.1.0 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + + '@inquirer/editor@2.2.0': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 1.5.5 + external-editor: 3.1.0 + + '@inquirer/expand@2.3.0': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 1.5.5 + yoctocolors-cjs: 2.1.2 + + '@inquirer/figures@1.0.10': {} + + '@inquirer/input@2.3.0': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 1.5.5 + + '@inquirer/number@1.1.0': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 1.5.5 + + '@inquirer/password@2.2.0': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 1.5.5 + ansi-escapes: 4.3.2 + + '@inquirer/prompts@5.5.0': + dependencies: + '@inquirer/checkbox': 2.5.0 + '@inquirer/confirm': 3.2.0 + '@inquirer/editor': 2.2.0 + '@inquirer/expand': 2.3.0 + '@inquirer/input': 2.3.0 + '@inquirer/number': 1.1.0 + '@inquirer/password': 2.2.0 + '@inquirer/rawlist': 2.3.0 + '@inquirer/search': 1.1.0 + '@inquirer/select': 2.5.0 + + '@inquirer/rawlist@2.3.0': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/type': 1.5.5 + yoctocolors-cjs: 2.1.2 + + '@inquirer/search@1.1.0': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/figures': 1.0.10 + '@inquirer/type': 1.5.5 + yoctocolors-cjs: 2.1.2 + + '@inquirer/select@2.5.0': + dependencies: + '@inquirer/core': 9.2.1 + '@inquirer/figures': 1.0.10 + '@inquirer/type': 1.5.5 + ansi-escapes: 4.3.2 + yoctocolors-cjs: 2.1.2 + + '@inquirer/type@1.5.5': + dependencies: + mute-stream: 1.0.0 + + '@inquirer/type@2.0.0': + dependencies: + mute-stream: 1.0.0 + + '@ipld/dag-cbor@6.0.15': + dependencies: + cborg: 1.10.2 + multiformats: 9.9.0 + + '@ipld/dag-cbor@7.0.3': + dependencies: + cborg: 1.10.2 + multiformats: 9.9.0 + + '@ipld/dag-json@8.0.11': + dependencies: + cborg: 1.10.2 + multiformats: 9.9.0 + + '@ipld/dag-pb@2.1.18': + dependencies: + multiformats: 9.9.0 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.13.9 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.13.9 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.13.9 + jest-mock: 29.7.0 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 22.13.9 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + '@types/node': 22.13.9 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.2.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + + '@jest/schemas@28.1.3': + dependencies: + '@sinclair/typebox': 0.24.51 + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/transform@28.1.3': + dependencies: + '@babel/core': 7.26.9 + '@jest/types': 28.1.3 + '@jridgewell/trace-mapping': 0.3.25 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 1.9.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 28.1.3 + jest-regex-util: 28.0.2 + jest-util: 28.1.3 + micromatch: 4.0.8 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.26.9 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.6 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@28.1.3': + dependencies: + '@jest/schemas': 28.1.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 22.13.9 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 22.13.9 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/source-map@0.3.6': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jsdevtools/ono@7.1.3': {} + + '@kwsites/file-exists@1.1.1': + dependencies: + debug: 4.4.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@kwsites/promise-deferred@1.1.1': {} + + '@lukeed/csprng@1.1.0': {} + + '@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2))': + dependencies: + '@near-js/types': 2.0.2 + '@near-js/utils': 2.0.2(@near-js/types@2.0.2) + '@noble/curves': 1.8.1 + borsh: 1.0.0 + randombytes: 2.1.0 + secp256k1: 5.0.1 + + '@near-js/providers@2.0.2(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/transactions@2.0.2(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2))(encoding@0.1.13)': + dependencies: + '@near-js/crypto': 2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)) + '@near-js/transactions': 2.0.2(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)) + '@near-js/types': 2.0.2 + '@near-js/utils': 2.0.2(@near-js/types@2.0.2) + borsh: 1.0.0 + exponential-backoff: 3.1.2 + optionalDependencies: + node-fetch: 2.6.7(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + '@near-js/transactions@2.0.2(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2))': + dependencies: + '@near-js/crypto': 2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)) + '@near-js/types': 2.0.2 + '@near-js/utils': 2.0.2(@near-js/types@2.0.2) + '@noble/hashes': 1.7.1 + borsh: 1.0.0 + + '@near-js/types@2.0.2': {} + + '@near-js/utils@2.0.2(@near-js/types@2.0.2)': + dependencies: + '@near-js/types': 2.0.2 + '@scure/base': 1.2.4 + depd: 2.0.0 + mustache: 4.0.0 + + '@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2)': + dependencies: + file-type: 21.0.0 + iterare: 1.2.1 + load-esm: 1.0.2 + reflect-metadata: 0.1.14 + rxjs: 7.8.2 + tslib: 2.8.1 + uid: 2.0.2 + optionalDependencies: + class-transformer: 0.5.1 + class-validator: 0.14.1 + transitivePeerDependencies: + - supports-color + + '@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + file-type: 21.0.0 + iterare: 1.2.1 + load-esm: 1.0.2 + reflect-metadata: 0.2.2 + rxjs: 7.8.2 + tslib: 2.8.1 + uid: 2.0.2 + optionalDependencies: + class-transformer: 0.5.1 + class-validator: 0.14.1 + transitivePeerDependencies: + - supports-color + + '@nestjs/core@11.0.11(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/platform-express@11.0.11)(reflect-metadata@0.1.14)(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nuxt/opencollective': 0.4.1 + fast-safe-stringify: 2.1.1 + iterare: 1.2.1 + path-to-regexp: 8.2.0 + reflect-metadata: 0.1.14 + rxjs: 7.8.2 + tslib: 2.8.1 + uid: 2.0.2 + optionalDependencies: + '@nestjs/platform-express': 11.0.11(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11) + + '@nestjs/core@11.0.11(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/platform-express@11.0.11)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + '@nestjs/common': 11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nuxt/opencollective': 0.4.1 + fast-safe-stringify: 2.1.1 + iterare: 1.2.1 + path-to-regexp: 8.2.0 + reflect-metadata: 0.2.2 + rxjs: 7.8.2 + tslib: 2.8.1 + uid: 2.0.2 + optionalDependencies: + '@nestjs/platform-express': 11.0.11(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11) + + '@nestjs/event-emitter@3.0.1(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11)': + dependencies: + '@nestjs/common': 11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/core': 11.0.11(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/platform-express@11.0.11)(reflect-metadata@0.1.14)(rxjs@7.8.2) + eventemitter2: 6.4.9 + + '@nestjs/platform-express@11.0.11(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11)': + dependencies: + '@nestjs/common': 11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/core': 11.0.11(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/platform-express@11.0.11)(reflect-metadata@0.1.14)(rxjs@7.8.2) + cors: 2.8.5 + express: 5.0.1 + multer: 1.4.5-lts.1 + path-to-regexp: 8.2.0 + tslib: 2.8.1 + transitivePeerDependencies: + - supports-color + + '@nestjs/schedule@5.0.1(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11)': + dependencies: + '@nestjs/common': 11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/core': 11.0.11(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/platform-express@11.0.11)(reflect-metadata@0.1.14)(rxjs@7.8.2) + cron: 3.5.0 + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.8.1': + dependencies: + '@noble/hashes': 1.7.1 + + '@noble/curves@1.9.7': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.7.1': {} + + '@noble/hashes@1.8.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@nuxt/opencollective@0.4.1': + dependencies: + consola: 3.4.0 + + '@oclif/core@2.16.0(@types/node@22.13.9)(typescript@5.9.2)': + dependencies: + '@types/cli-progress': 3.11.6 + ansi-escapes: 4.3.2 + ansi-styles: 4.3.0 + cardinal: 2.1.1 + chalk: 4.1.2 + clean-stack: 3.0.1 + cli-progress: 3.12.0 + debug: 4.4.0(supports-color@8.1.1) + ejs: 3.1.10 + get-package-type: 0.1.0 + globby: 11.1.0 + hyperlinker: 1.0.0 + indent-string: 4.0.0 + is-wsl: 2.2.0 + js-yaml: 3.14.1 + natural-orderby: 2.0.3 + object-treeify: 1.1.33 + password-prompt: 1.1.3 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + supports-color: 8.1.1 + supports-hyperlinks: 2.3.0 + ts-node: 10.9.2(@types/node@22.13.9)(typescript@5.9.2) + tslib: 2.8.1 + widest-line: 3.1.0 + wordwrap: 1.0.0 + wrap-ansi: 7.0.0 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - '@types/node' + - typescript + + '@open-web3/orml-type-definitions@2.0.1': + dependencies: + lodash.merge: 4.6.2 + + '@opentelemetry/api@1.9.0': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@polkadot-api/json-rpc-provider-proxy@0.1.0': + optional: true + + '@polkadot-api/json-rpc-provider@0.0.1': + optional: true + + '@polkadot-api/metadata-builders@0.3.2': + dependencies: + '@polkadot-api/substrate-bindings': 0.6.0 + '@polkadot-api/utils': 0.1.0 + optional: true + + '@polkadot-api/observable-client@0.3.2(@polkadot-api/substrate-client@0.1.4)(rxjs@7.8.2)': + dependencies: + '@polkadot-api/metadata-builders': 0.3.2 + '@polkadot-api/substrate-bindings': 0.6.0 + '@polkadot-api/substrate-client': 0.1.4 + '@polkadot-api/utils': 0.1.0 + rxjs: 7.8.2 + optional: true + + '@polkadot-api/substrate-bindings@0.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@polkadot-api/utils': 0.1.0 + '@scure/base': 1.2.4 + scale-ts: 1.6.1 + optional: true + + '@polkadot-api/substrate-client@0.1.4': + dependencies: + '@polkadot-api/json-rpc-provider': 0.0.1 + '@polkadot-api/utils': 0.1.0 + optional: true + + '@polkadot-api/utils@0.1.0': + optional: true + + '@polkadot/api-augment@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@polkadot/api-base': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/rpc-augment': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/types': 16.4.7 + '@polkadot/types-augment': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/api-base@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@polkadot/rpc-core': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/types': 16.4.7 + '@polkadot/util': 13.5.6 + rxjs: 7.8.2 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/api-derive@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@polkadot/api': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/api-augment': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/api-base': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/rpc-core': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/types': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/util': 13.5.6 + '@polkadot/util-crypto': 13.5.6(@polkadot/util@13.5.6) + rxjs: 7.8.2 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@polkadot/api-augment': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/api-base': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/api-derive': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/keyring': 13.5.6(@polkadot/util-crypto@13.5.6(@polkadot/util@13.5.6))(@polkadot/util@13.5.6) + '@polkadot/rpc-augment': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/rpc-core': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/rpc-provider': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/types': 16.4.7 + '@polkadot/types-augment': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/types-create': 16.4.7 + '@polkadot/types-known': 16.4.7 + '@polkadot/util': 13.5.6 + '@polkadot/util-crypto': 13.5.6(@polkadot/util@13.5.6) + eventemitter3: 5.0.1 + rxjs: 7.8.2 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/keyring@13.5.6(@polkadot/util-crypto@13.5.6(@polkadot/util@13.5.6))(@polkadot/util@13.5.6)': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/util-crypto': 13.5.6(@polkadot/util@13.5.6) + tslib: 2.8.1 + + '@polkadot/networks@13.5.6': + dependencies: + '@polkadot/util': 13.5.6 + '@substrate/ss58-registry': 1.51.0 + tslib: 2.8.1 + + '@polkadot/rpc-augment@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@polkadot/rpc-core': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/types': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/rpc-core@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@polkadot/rpc-augment': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/rpc-provider': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@polkadot/types': 16.4.7 + '@polkadot/util': 13.5.6 + rxjs: 7.8.2 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/rpc-provider@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@polkadot/keyring': 13.5.6(@polkadot/util-crypto@13.5.6(@polkadot/util@13.5.6))(@polkadot/util@13.5.6) + '@polkadot/types': 16.4.7 + '@polkadot/types-support': 16.4.7 + '@polkadot/util': 13.5.6 + '@polkadot/util-crypto': 13.5.6(@polkadot/util@13.5.6) + '@polkadot/x-fetch': 13.5.6 + '@polkadot/x-global': 13.5.6 + '@polkadot/x-ws': 13.5.6(bufferutil@4.0.9)(utf-8-validate@5.0.10) + eventemitter3: 5.0.1 + mock-socket: 9.3.1 + nock: 13.5.6 + tslib: 2.8.1 + optionalDependencies: + '@substrate/connect': 0.8.11(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/types-augment@16.4.7': + dependencies: + '@polkadot/types': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + + '@polkadot/types-codec@16.4.7': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/x-bigint': 13.5.6 + tslib: 2.8.1 + + '@polkadot/types-create@16.4.7': + dependencies: + '@polkadot/types-codec': 16.4.7 + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + + '@polkadot/types-known@16.4.7': + dependencies: + '@polkadot/networks': 13.5.6 + '@polkadot/types': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/types-create': 16.4.7 + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + + '@polkadot/types-support@16.4.7': + dependencies: + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + + '@polkadot/types@16.4.7': + dependencies: + '@polkadot/keyring': 13.5.6(@polkadot/util-crypto@13.5.6(@polkadot/util@13.5.6))(@polkadot/util@13.5.6) + '@polkadot/types-augment': 16.4.7 + '@polkadot/types-codec': 16.4.7 + '@polkadot/types-create': 16.4.7 + '@polkadot/util': 13.5.6 + '@polkadot/util-crypto': 13.5.6(@polkadot/util@13.5.6) + rxjs: 7.8.2 + tslib: 2.8.1 + + '@polkadot/util-crypto@13.5.6(@polkadot/util@13.5.6)': + dependencies: + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@polkadot/networks': 13.5.6 + '@polkadot/util': 13.5.6 + '@polkadot/wasm-crypto': 7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6))) + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/x-bigint': 13.5.6 + '@polkadot/x-randomvalues': 13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)) + '@scure/base': 1.2.4 + tslib: 2.8.1 + + '@polkadot/util@13.5.6': + dependencies: + '@polkadot/x-bigint': 13.5.6 + '@polkadot/x-global': 13.5.6 + '@polkadot/x-textdecoder': 13.5.6 + '@polkadot/x-textencoder': 13.5.6 + '@types/bn.js': 5.1.6 + bn.js: 5.2.1 + tslib: 2.8.1 + + '@polkadot/wasm-bridge@7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)))': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/x-randomvalues': 13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)) + tslib: 2.8.1 + + '@polkadot/wasm-crypto-asmjs@7.5.1(@polkadot/util@13.5.6)': + dependencies: + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + + '@polkadot/wasm-crypto-init@7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)))': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/wasm-bridge': 7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6))) + '@polkadot/wasm-crypto-asmjs': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/wasm-crypto-wasm': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/x-randomvalues': 13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)) + tslib: 2.8.1 + + '@polkadot/wasm-crypto-wasm@7.5.1(@polkadot/util@13.5.6)': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.6) + tslib: 2.8.1 + + '@polkadot/wasm-crypto@7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)))': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/wasm-bridge': 7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6))) + '@polkadot/wasm-crypto-asmjs': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/wasm-crypto-init': 7.5.1(@polkadot/util@13.5.6)(@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6))) + '@polkadot/wasm-crypto-wasm': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/x-randomvalues': 13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)) + tslib: 2.8.1 + + '@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6)': + dependencies: + '@polkadot/util': 13.5.6 + tslib: 2.8.1 + + '@polkadot/x-bigint@13.5.6': + dependencies: + '@polkadot/x-global': 13.5.6 + tslib: 2.8.1 + + '@polkadot/x-fetch@13.5.6': + dependencies: + '@polkadot/x-global': 13.5.6 + node-fetch: 3.3.2 + tslib: 2.8.1 + + '@polkadot/x-global@13.5.6': + dependencies: + tslib: 2.8.1 + + '@polkadot/x-randomvalues@13.5.6(@polkadot/util@13.5.6)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.6))': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.6) + '@polkadot/x-global': 13.5.6 + tslib: 2.8.1 + + '@polkadot/x-textdecoder@13.5.6': + dependencies: + '@polkadot/x-global': 13.5.6 + tslib: 2.8.1 + + '@polkadot/x-textencoder@13.5.6': + dependencies: + '@polkadot/x-global': 13.5.6 + tslib: 2.8.1 + + '@polkadot/x-ws@13.5.6(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@polkadot/x-global': 13.5.6 + tslib: 2.8.1 + ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@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': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 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': {} + + '@protobufs/amino@0.0.11': + dependencies: + '@protobufs/google': 0.0.10 + + '@protobufs/confio@0.0.6': {} + + '@protobufs/cosmos@0.1.0': + dependencies: + '@protobufs/amino': 0.0.11 + '@protobufs/cosmos_proto': 0.0.10 + '@protobufs/gogoproto': 0.0.10 + '@protobufs/google': 0.0.10 + '@protobufs/tendermint': 0.0.10 + + '@protobufs/cosmos_proto@0.0.10': + dependencies: + '@protobufs/google': 0.0.10 + + '@protobufs/cosmwasm@0.1.1': + dependencies: + '@protobufs/cosmos': 0.1.0 + '@protobufs/cosmos_proto': 0.0.10 + '@protobufs/gogoproto': 0.0.10 + '@protobufs/google': 0.0.10 + + '@protobufs/gogoproto@0.0.10': + dependencies: + '@protobufs/google': 0.0.10 + + '@protobufs/google@0.0.10': {} + + '@protobufs/ibc@0.1.0': + dependencies: + '@protobufs/amino': 0.0.11 + '@protobufs/confio': 0.0.6 + '@protobufs/cosmos': 0.1.0 + '@protobufs/gogoproto': 0.0.10 + '@protobufs/google': 0.0.10 + '@protobufs/tendermint': 0.0.10 + + '@protobufs/tendermint@0.0.10': + dependencies: + '@protobufs/gogoproto': 0.0.10 + '@protobufs/google': 0.0.10 + + '@pyramation/json-schema-ref-parser@9.0.6': + dependencies: + '@jsdevtools/ono': 7.1.3 + call-me-maybe: 1.0.2 + js-yaml: 3.14.1 + + '@pyramation/json-schema-to-typescript@11.0.4': + dependencies: + '@pyramation/json-schema-ref-parser': 9.0.6 + '@types/json-schema': 7.0.15 + '@types/lodash': 4.17.16 + '@types/prettier': 2.7.3 + cli-color: 2.0.4 + get-stdin: 8.0.0 + glob: 7.2.3 + glob-promise: 4.2.2(glob@7.2.3) + is-glob: 4.0.3 + lodash: 4.17.21 + minimist: 1.2.8 + mkdirp: 1.0.4 + mz: 2.7.0 + prettier: 2.8.8 + + '@scure/base@1.2.4': {} + + '@scure/bip32@1.6.2': + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/base': 1.2.4 + + '@scure/bip39@1.5.4': + dependencies: + '@noble/hashes': 1.7.1 + '@scure/base': 1.2.4 + + '@sinclair/typebox@0.24.51': {} + + '@sinclair/typebox@0.27.8': {} + + '@sindresorhus/is@0.14.0': {} + + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@subql/cli@5.7.1-0(@types/node@22.13.9)(encoding@0.1.13)(pg@8.13.3)': + dependencies: + '@inquirer/prompts': 5.5.0 + '@oclif/core': 2.16.0(@types/node@22.13.9)(typescript@5.9.2) + '@subql/common': 5.4.0 + '@subql/utils': 2.18.0(pg@8.13.3) + boxen: 5.1.2 + chalk: 4.1.2 + ejs: 3.1.10 + fs-extra: 11.3.0 + fuzzy: 0.1.3 + glob: 10.4.5 + json5: 2.2.3 + node-fetch: 2.7.0(encoding@0.1.13) + ora: 5.4.1 + rimraf: 5.0.10 + semver: 7.7.1 + simple-git: 3.27.0 + terser-webpack-plugin: 5.3.12(webpack@5.98.0) + ts-loader: 9.5.2(typescript@5.9.2)(webpack@5.98.0) + ts-node: 10.9.2(@types/node@22.13.9)(typescript@5.9.2) + tsconfig-paths-webpack-plugin: 4.2.0 + tslib: 2.8.1 + typescript: 5.9.2 + update-notifier: 5.1.0 + webpack: 5.98.0 + webpack-merge: 6.0.1 + websocket: 1.0.35 + yaml: 2.7.0 + yaml-loader: 0.8.1 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - '@types/node' + - debug + - encoding + - esbuild + - ibm_db + - mariadb + - mysql2 + - oracledb + - pg + - pg-hstore + - snowflake-sdk + - sqlite3 + - supports-color + - tedious + - uglify-js + - webpack-cli + + '@subql/common-algorand@4.4.3(algosdk@2.11.0)(class-transformer@0.5.1)(class-validator@0.14.1)(js-yaml@4.1.0)': + dependencies: + '@subql/common': 5.7.6 + '@subql/types-algorand': 4.1.1(algosdk@2.11.0) + algosdk: 2.11.0 + class-transformer: 0.5.1 + class-validator: 0.14.1 + js-yaml: 4.1.0 + transitivePeerDependencies: + - debug + + '@subql/common-cosmos@5.5.0(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(ejs@3.1.10)(utf-8-validate@5.0.10)': + dependencies: + '@cosmwasm/ts-codegen': 1.12.1 + '@protobufs/cosmos': 0.1.0 + '@protobufs/cosmos_proto': 0.0.10 + '@protobufs/cosmwasm': 0.1.1 + '@protobufs/gogoproto': 0.0.10 + '@protobufs/google': 0.0.10 + '@protobufs/ibc': 0.1.0 + '@protobufs/tendermint': 0.0.10 + '@subql/common': 5.7.6 + '@subql/types-cosmos': 4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@subql/x-cosmology-telescope': 1.4.14 + class-transformer: 0.5.1 + class-validator: 0.14.1 + ejs: 3.1.10 + fs-extra: 11.3.0 + js-yaml: 4.1.0 + reflect-metadata: 0.1.14 + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + + '@subql/common-ethereum@4.7.0(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)': + dependencies: + '@subql/common': 5.7.6 + '@subql/types-ethereum': 4.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@typechain/ethers-v5': 11.1.2(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.2))(typescript@5.9.2) + '@zilliqa-js/crypto': 3.5.0 + class-transformer: 0.5.1 + class-validator: 0.14.1 + js-yaml: 4.1.0 + pino: 6.14.0 + reflect-metadata: 0.1.14 + typechain: 8.3.2(typescript@5.9.2) + transitivePeerDependencies: + - '@ethersproject/abi' + - '@ethersproject/providers' + - bufferutil + - debug + - ethers + - supports-color + - typescript + - utf-8-validate + + '@subql/common-ethereum@4.9.3(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)': + dependencies: + '@subql/common': 5.7.6 + '@subql/types-ethereum': 4.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@typechain/ethers-v5': 11.1.2(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.2))(typescript@5.9.2) + '@zilliqa-js/crypto': 3.5.0 + class-transformer: 0.5.1 + class-validator: 0.14.1 + js-yaml: 4.1.0 + pino: 6.14.0 + reflect-metadata: 0.1.14 + typechain: 8.3.2(typescript@5.9.2) + transitivePeerDependencies: + - '@ethersproject/abi' + - '@ethersproject/providers' + - bufferutil + - debug + - ethers + - supports-color + - typescript + - utf-8-validate + + '@subql/common-flare@3.8.3(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(node-fetch@2.7.0(encoding@0.1.13))(typescript@5.9.2)(utf-8-validate@5.0.10)': + dependencies: + '@subql/common': 3.9.0(encoding@0.1.13)(node-fetch@2.7.0(encoding@0.1.13)) + '@subql/types-flare': 3.6.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@typechain/ethers-v5': 11.1.2(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.2))(typescript@5.9.2) + '@zilliqa-js/crypto': 3.5.0 + class-transformer: 0.5.1 + class-validator: 0.14.1 + js-yaml: 4.1.0 + pino: 6.14.0 + reflect-metadata: 0.1.14 + typechain: 8.3.2(typescript@5.9.2) + transitivePeerDependencies: + - '@ethersproject/abi' + - '@ethersproject/providers' + - bufferutil + - debug + - encoding + - ethers + - node-fetch + - supports-color + - typescript + - utf-8-validate + + '@subql/common-near@4.3.4(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/transactions@2.0.2(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2))(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)': + dependencies: + '@subql/common': 5.7.6 + '@subql/types-near': 5.0.1(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/transactions@2.0.2(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2))(encoding@0.1.13) + class-transformer: 0.5.1 + class-validator: 0.14.1 + js-yaml: 4.1.0 + reflect-metadata: 0.1.14 + transitivePeerDependencies: + - '@near-js/crypto' + - '@near-js/transactions' + - '@near-js/types' + - '@near-js/utils' + - debug + - encoding + + '@subql/common-stellar@2.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)(node-fetch@2.7.0(encoding@0.1.13))': + dependencies: + '@subql/common': 2.6.0(encoding@0.1.13)(node-fetch@2.7.0(encoding@0.1.13)) + '@subql/types-stellar': 2.3.0 + class-transformer: 0.5.1 + class-validator: 0.14.1 + js-yaml: 4.1.0 + pino: 6.14.0 + reflect-metadata: 0.1.14 + stellar-sdk: 10.4.1 + transitivePeerDependencies: + - debug + - encoding + - node-fetch + - supports-color + + '@subql/common-substrate@2.3.0(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))(class-transformer@0.5.1)(class-validator@0.14.1)(node-fetch@2.7.0(encoding@0.1.13))': + dependencies: + '@subql/common': 2.5.0(node-fetch@2.7.0(encoding@0.1.13)) + '@subql/types': 2.1.3(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + class-transformer: 0.5.1 + class-validator: 0.14.1 + js-yaml: 4.1.0 + reflect-metadata: 0.1.14 + transitivePeerDependencies: + - '@polkadot/api' + - debug + - node-fetch + - supports-color + + '@subql/common-substrate@4.5.2(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))(class-transformer@0.5.1)(class-validator@0.14.1)': + dependencies: + '@subql/common': 5.7.6 + '@subql/types': 3.14.2(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + class-transformer: 0.5.1 + class-validator: 0.14.1 + transitivePeerDependencies: + - '@polkadot/api' + - debug + + '@subql/common@2.5.0(node-fetch@2.7.0(encoding@0.1.13))': + dependencies: + axios: 0.27.2 + class-transformer: 0.5.1 + class-validator: 0.14.1 + fs-extra: 10.1.0 + ipfs-http-client: 52.0.5(node-fetch@2.7.0(encoding@0.1.13)) + js-yaml: 4.1.0 + reflect-metadata: 0.1.14 + semver: 7.7.1 + update-notifier: 5.1.0 + transitivePeerDependencies: + - debug + - node-fetch + - supports-color + + '@subql/common@2.6.0(encoding@0.1.13)(node-fetch@2.7.0(encoding@0.1.13))': + dependencies: + axios: 0.27.2 + class-transformer: 0.5.1 + class-validator: 0.14.1 + fs-extra: 10.1.0 + ipfs-http-client: 56.0.3(encoding@0.1.13)(node-fetch@2.7.0(encoding@0.1.13)) + js-yaml: 4.1.0 + reflect-metadata: 0.1.14 + semver: 7.7.1 + update-notifier: 5.1.0 + transitivePeerDependencies: + - debug + - encoding + - node-fetch + - supports-color + + '@subql/common@3.9.0(encoding@0.1.13)(node-fetch@2.7.0(encoding@0.1.13))': + dependencies: + '@subql/types-core': 0.8.0 + axios: 0.28.1 + class-transformer: 0.5.1 + class-validator: 0.14.1 + fs-extra: 10.1.0 + ipfs-http-client: 56.0.3(encoding@0.1.13)(node-fetch@2.7.0(encoding@0.1.13)) + js-yaml: 4.1.0 + reflect-metadata: 0.1.14 + semver: 7.7.1 + update-notifier: 5.1.0 + transitivePeerDependencies: + - debug + - encoding + - node-fetch + - supports-color + + '@subql/common@5.4.0': + dependencies: + '@subql/types-core': 2.0.1 + axios: 0.28.1 + class-transformer: 0.5.1 + class-validator: 0.14.1 + form-data: 4.0.4 + js-yaml: 4.1.0 + reflect-metadata: 0.1.14 + semver: 7.7.1 + update-notifier: 5.1.0 + transitivePeerDependencies: + - debug + + '@subql/common@5.7.6': + dependencies: + '@subql/types-core': 2.1.1 + axios: 1.12.1 + class-transformer: 0.5.1 + class-validator: 0.14.1 + form-data: 4.0.4 + js-yaml: 4.1.0 + reflect-metadata: 0.2.2 + semver: 7.7.1 + update-notifier: 5.1.0 + transitivePeerDependencies: + - debug + + '@subql/node-core@18.4.0(@nestjs/core@11.0.11)(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)(reflect-metadata@0.1.14)(rxjs@7.8.2)': + dependencies: + '@apollo/client': 3.14.0(graphql@15.10.1) + '@nestjs/common': 11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/event-emitter': 3.0.1(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11) + '@nestjs/schedule': 5.0.1(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11) + '@subql/common': 5.7.6 + '@subql/testing': 2.3.0 + '@subql/types': 3.14.2(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@subql/utils': 2.21.2(pg@8.13.3) + '@willsoto/nestjs-prometheus': 6.0.2(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(prom-client@15.1.3) + async-mutex: 0.5.0 + cron-converter: 2.1.0 + cross-fetch: 3.2.0(encoding@0.1.13) + csv-stringify: 6.5.2 + dayjs: 1.11.13 + dotenv: 16.4.7 + graphql: 15.10.1 + lodash: 4.17.21 + lru-cache: 10.1.0 + merkle-tools: 1.4.1 + pg: 8.13.3 + prom-client: 15.1.3 + source-map: 0.7.4 + tar: 7.4.3 + toposort-class: 1.0.1 + vm2: 3.9.19 + yargs: 16.2.0 + transitivePeerDependencies: + - '@nestjs/core' + - '@polkadot/api' + - '@types/react' + - class-transformer + - class-validator + - debug + - encoding + - graphql-ws + - ibm_db + - mariadb + - mysql2 + - oracledb + - pg-hstore + - pg-native + - react + - react-dom + - reflect-metadata + - rxjs + - snowflake-sdk + - sqlite3 + - subscriptions-transport-ws + - supports-color + - tedious + + '@subql/node-core@18.4.0(@nestjs/core@11.0.11)(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2)': + dependencies: + '@apollo/client': 3.14.0(graphql@15.10.1) + '@nestjs/common': 11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/event-emitter': 3.0.1(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11) + '@nestjs/schedule': 5.0.1(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11) + '@subql/common': 5.7.6 + '@subql/testing': 2.3.0 + '@subql/types': 3.14.2(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@subql/utils': 2.21.2(pg@8.13.3) + '@willsoto/nestjs-prometheus': 6.0.2(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(prom-client@15.1.3) + async-mutex: 0.5.0 + cron-converter: 2.1.0 + cross-fetch: 3.2.0(encoding@0.1.13) + csv-stringify: 6.5.2 + dayjs: 1.11.13 + dotenv: 16.4.7 + graphql: 15.10.1 + lodash: 4.17.21 + lru-cache: 10.1.0 + merkle-tools: 1.4.1 + pg: 8.13.3 + prom-client: 15.1.3 + source-map: 0.7.4 + tar: 7.4.3 + toposort-class: 1.0.1 + vm2: 3.9.19 + yargs: 16.2.0 + transitivePeerDependencies: + - '@nestjs/core' + - '@polkadot/api' + - '@types/react' + - class-transformer + - class-validator + - debug + - encoding + - graphql-ws + - ibm_db + - mariadb + - mysql2 + - oracledb + - pg-hstore + - pg-native + - react + - react-dom + - reflect-metadata + - rxjs + - snowflake-sdk + - sqlite3 + - subscriptions-transport-ws + - supports-color + - tedious + + '@subql/node-ethereum@6.2.1(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))(@subql/utils@2.21.2(pg@8.13.3))(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)(rxjs@7.8.2)(typescript@5.9.2)(utf-8-validate@5.0.10)': + dependencies: + '@nestjs/common': 11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/core': 11.0.11(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/platform-express@11.0.11)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@nestjs/event-emitter': 3.0.1(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11) + '@nestjs/platform-express': 11.0.11(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11) + '@nestjs/schedule': 5.0.1(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11) + '@subql/common': 5.7.6 + '@subql/common-ethereum': 4.9.3(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10) + '@subql/node-core': 18.4.0(@nestjs/core@11.0.11)(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)(reflect-metadata@0.1.14)(rxjs@7.8.2) + '@subql/testing': 2.3.0 + '@subql/types-ethereum': 4.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@subql/utils': 2.21.2(pg@8.13.3) + cacheable-lookup: 6.1.0 + ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + eventemitter2: 6.4.9 + json5: 2.2.3 + lodash: 4.17.21 + reflect-metadata: 0.1.14 + rimraf: 3.0.2 + yargs: 16.2.0 + transitivePeerDependencies: + - '@ethersproject/abi' + - '@ethersproject/providers' + - '@nestjs/microservices' + - '@nestjs/websockets' + - '@polkadot/api' + - '@types/react' + - bufferutil + - class-transformer + - class-validator + - debug + - encoding + - graphql-ws + - ibm_db + - mariadb + - mysql2 + - oracledb + - pg-hstore + - pg-native + - react + - react-dom + - rxjs + - snowflake-sdk + - sqlite3 + - subscriptions-transport-ws + - supports-color + - tedious + - typescript + - utf-8-validate + + '@subql/node@6.3.5(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)(graphql@15.10.1)(pg@8.13.3)(rxjs@7.8.2)(utf-8-validate@5.0.10)': + dependencies: + '@apollo/client': 3.14.0(graphql@15.10.1) + '@nestjs/common': 11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/core': 11.0.11(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/platform-express@11.0.11)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@nestjs/event-emitter': 3.0.1(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11) + '@nestjs/platform-express': 11.0.11(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11) + '@nestjs/schedule': 5.0.1(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(@nestjs/core@11.0.11) + '@polkadot/api': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@subql/common-substrate': 4.5.2(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))(class-transformer@0.5.1)(class-validator@0.14.1) + '@subql/node-core': 18.4.0(@nestjs/core@11.0.11)(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)(reflect-metadata@0.2.2)(rxjs@7.8.2) + '@subql/types': 3.14.2(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@subql/utils': 2.21.2(pg@8.13.3) + fetch-h2: 3.0.2 + lodash: 4.17.21 + reflect-metadata: 0.2.2 + transitivePeerDependencies: + - '@nestjs/microservices' + - '@nestjs/websockets' + - '@types/react' + - bufferutil + - class-transformer + - class-validator + - debug + - encoding + - graphql + - graphql-ws + - ibm_db + - mariadb + - mysql2 + - oracledb + - pg + - pg-hstore + - pg-native + - react + - react-dom + - rxjs + - snowflake-sdk + - sqlite3 + - subscriptions-transport-ws + - supports-color + - tedious + - utf-8-validate + + '@subql/testing@2.3.0': + dependencies: + '@subql/types-core': 2.1.1 + + '@subql/types-algorand@4.1.1(algosdk@2.11.0)': + dependencies: + '@subql/types-core': 2.1.1 + algosdk: 2.11.0 + + '@subql/types-core@0.7.0': + dependencies: + package-json-type: 1.0.3 + + '@subql/types-core@0.8.0': + dependencies: + package-json-type: 1.0.3 + + '@subql/types-core@2.0.1': {} + + '@subql/types-core@2.1.1': + dependencies: + package-json-type: 1.0.3 + pino: 6.14.0 + + '@subql/types-cosmos@4.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@cosmjs/cosmwasm-stargate': 0.36.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@cosmjs/proto-signing': 0.36.0 + '@cosmjs/stargate': 0.36.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@subql/types-core': 2.1.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@subql/types-ethereum@4.1.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@ethersproject/abstract-provider': 5.8.0 + '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@subql/types-core': 2.1.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@subql/types-ethereum@4.2.2(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@ethersproject/abstract-provider': 5.8.0 + '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@subql/types-core': 2.1.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@subql/types-flare@3.6.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@ethersproject/abstract-provider': 5.8.0 + '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@subql/types-core': 0.7.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@subql/types-near@5.0.1(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/transactions@2.0.2(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2))(encoding@0.1.13)': + dependencies: + '@near-js/providers': 2.0.2(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/transactions@2.0.2(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2))(encoding@0.1.13) + '@subql/types-core': 2.1.1 + transitivePeerDependencies: + - '@near-js/crypto' + - '@near-js/transactions' + - '@near-js/types' + - '@near-js/utils' + - encoding + + '@subql/types-stellar@2.3.0': + dependencies: + soroban-client: 0.9.2 + stellar-sdk: 10.4.1 + transitivePeerDependencies: + - debug + + '@subql/types@2.1.3(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@polkadot/api': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + '@subql/types@3.14.2(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@polkadot/api': 16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@subql/types-core': 2.1.1 + + '@subql/utils@2.18.0(pg@8.13.3)': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/util-crypto': 13.5.6(@polkadot/util@13.5.6) + '@subql/x-sequelize': 6.32.0-0.0.4(pg@8.13.3) + chalk: 4.1.2 + detect-port: 1.6.1 + flatted: 3.3.3 + graphql: 15.10.1 + graphql-tag: 2.12.6(graphql@15.10.1) + lodash: 4.17.21 + pino: 6.14.0 + rotating-file-stream: 3.2.6 + transitivePeerDependencies: + - ibm_db + - mariadb + - mysql2 + - oracledb + - pg + - pg-hstore + - snowflake-sdk + - sqlite3 + - supports-color + - tedious + + '@subql/utils@2.21.2(pg@8.13.3)': + dependencies: + '@polkadot/util': 13.5.6 + '@polkadot/util-crypto': 13.5.6(@polkadot/util@13.5.6) + '@subql/x-sequelize': 6.32.0-0.0.4(pg@8.13.3) + chalk: 4.1.2 + detect-port: 1.6.1 + flatted: 3.3.3 + graphql: 15.10.1 + graphql-tag: 2.12.6(graphql@15.10.1) + lodash: 4.17.21 + pino: 6.14.0 + rotating-file-stream: 3.2.6 + transitivePeerDependencies: + - ibm_db + - mariadb + - mysql2 + - oracledb + - pg + - pg-hstore + - snowflake-sdk + - sqlite3 + - supports-color + - tedious + + '@subql/validator@2.2.0(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/transactions@2.0.2(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2))(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))(algosdk@2.11.0)(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(ejs@3.1.10)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(node-fetch@2.7.0(encoding@0.1.13))(typescript@5.9.2)(utf-8-validate@5.0.10)': + dependencies: + '@subql/common': 2.5.0(node-fetch@2.7.0(encoding@0.1.13)) + '@subql/common-algorand': 4.4.3(algosdk@2.11.0)(class-transformer@0.5.1)(class-validator@0.14.1)(js-yaml@4.1.0) + '@subql/common-cosmos': 5.5.0(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(ejs@3.1.10)(utf-8-validate@5.0.10) + '@subql/common-ethereum': 4.9.3(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10) + '@subql/common-flare': 3.8.3(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(node-fetch@2.7.0(encoding@0.1.13))(typescript@5.9.2)(utf-8-validate@5.0.10) + '@subql/common-near': 4.3.4(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/transactions@2.0.2(@near-js/crypto@2.0.2(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2)))(@near-js/types@2.0.2)(@near-js/utils@2.0.2(@near-js/types@2.0.2))(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13) + '@subql/common-stellar': 2.3.1(class-transformer@0.5.1)(class-validator@0.14.1)(encoding@0.1.13)(node-fetch@2.7.0(encoding@0.1.13)) + '@subql/common-substrate': 2.3.0(@polkadot/api@16.4.7(bufferutil@4.0.9)(utf-8-validate@5.0.10))(class-transformer@0.5.1)(class-validator@0.14.1)(node-fetch@2.7.0(encoding@0.1.13)) + axios: 0.24.0 + js-yaml: 4.1.0 + package-json-type: 1.0.3 + transitivePeerDependencies: + - '@ethersproject/abi' + - '@ethersproject/providers' + - '@near-js/crypto' + - '@near-js/transactions' + - '@near-js/types' + - '@near-js/utils' + - '@polkadot/api' + - algosdk + - bufferutil + - class-transformer + - class-validator + - debug + - ejs + - encoding + - ethers + - node-fetch + - supports-color + - typescript + - utf-8-validate + + '@subql/x-cosmology-ast@1.4.10': + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.23.6 + '@subql/x-cosmology-types': 1.4.4 + '@subql/x-cosmology-utils': 1.4.4 + case: 1.6.3 + dotty: 0.1.2 + + '@subql/x-cosmology-proto-parser@1.4.6': + dependencies: + '@cosmology/protobufjs': 6.11.6 + '@subql/x-cosmology-types': 1.4.4 + '@subql/x-cosmology-utils': 1.4.4 + dotty: 0.1.2 + glob: 8.0.3 + minimatch: 5.1.0 + mkdirp: 3.0.0 + + '@subql/x-cosmology-telescope@1.4.14': + dependencies: + '@babel/generator': 7.26.9 + '@babel/parser': 7.26.9 + '@babel/traverse': 7.23.6 + '@babel/types': 7.23.6 + '@cosmwasm/ts-codegen': 0.34.0 + '@subql/x-cosmology-ast': 1.4.10 + '@subql/x-cosmology-proto-parser': 1.4.6 + '@subql/x-cosmology-types': 1.4.4 + '@subql/x-cosmology-utils': 1.4.4 + '@types/parse-package-name': 0.1.0 + case: 1.6.3 + dargs: 7.0.0 + deepmerge: 4.3.1 + dotty: 0.1.2 + fuzzy: 0.1.3 + glob: 8.0.3 + inquirerer: 0.1.3 + long: 5.3.1 + minimatch: 5.1.0 + minimist: 1.2.8 + mkdirp: 3.0.0 + parse-package-name: 1.0.0 + rimraf: 5.0.0 + shelljs: 0.8.5 + transitivePeerDependencies: + - supports-color + + '@subql/x-cosmology-types@1.4.4': + dependencies: + case: 1.6.3 + + '@subql/x-cosmology-utils@1.4.4': + dependencies: + '@subql/x-cosmology-types': 1.4.4 + dotty: 0.1.2 + + '@subql/x-sequelize@6.32.0-0.0.4(pg@8.13.3)': + dependencies: + '@types/debug': 4.1.12 + '@types/validator': 13.12.2 + debug: 4.4.0(supports-color@8.1.1) + dottie: 2.0.6 + inflection: 1.13.4 + lodash: 4.17.21 + moment: 2.30.1 + moment-timezone: 0.5.47 + pg-connection-string: 2.7.0 + retry-as-promised: 7.1.1 + semver: 7.7.1 + sequelize-pool: 7.1.0 + toposort-class: 1.0.1 + uuid: 8.3.2 + validator: 13.12.0 + wkx: 0.5.0 + optionalDependencies: + pg: 8.13.3 + transitivePeerDependencies: + - supports-color + + '@substrate/connect-extension-protocol@2.2.2': + optional: true + + '@substrate/connect-known-chains@1.9.2': + optional: true + + '@substrate/connect@0.8.11(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@substrate/connect-extension-protocol': 2.2.2 + '@substrate/connect-known-chains': 1.9.2 + '@substrate/light-client-extension-helpers': 1.0.0(smoldot@2.0.26(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + smoldot: 2.0.26(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + optional: true + + '@substrate/light-client-extension-helpers@1.0.0(smoldot@2.0.26(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@polkadot-api/json-rpc-provider': 0.0.1 + '@polkadot-api/json-rpc-provider-proxy': 0.1.0 + '@polkadot-api/observable-client': 0.3.2(@polkadot-api/substrate-client@0.1.4)(rxjs@7.8.2) + '@polkadot-api/substrate-client': 0.1.4 + '@substrate/connect-extension-protocol': 2.2.2 + '@substrate/connect-known-chains': 1.9.2 + rxjs: 7.8.2 + smoldot: 2.0.26(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optional: true + + '@substrate/ss58-registry@1.51.0': {} + + '@szmarczak/http-timer@1.1.2': + dependencies: + defer-to-connect: 1.1.3 + + '@tokenizer/inflate@0.2.7': + dependencies: + debug: 4.4.0(supports-color@8.1.1) + fflate: 0.8.2 + token-types: 6.1.1 + transitivePeerDependencies: + - supports-color + + '@tokenizer/token@0.3.0': {} + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@typechain/ethers-v5@11.1.2(@ethersproject/abi@5.8.0)(@ethersproject/providers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.9.2))(typescript@5.9.2)': + dependencies: + '@ethersproject/abi': 5.8.0 + '@ethersproject/providers': 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ethers: 5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + lodash: 4.17.21 + ts-essentials: 7.0.3(typescript@5.9.2) + typechain: 8.3.2(typescript@5.9.2) + typescript: 5.9.2 + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.28.2 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.28.2 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.28.2 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.28.2 + + '@types/bn.js@5.1.6': + dependencies: + '@types/node': 22.13.9 + + '@types/cli-progress@3.11.6': + dependencies: + '@types/node': 22.13.9 + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 2.1.0 + + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.6 + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + + '@types/estree@1.0.6': {} + + '@types/eventsource@1.1.15': {} + + '@types/glob@7.2.0': + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 22.13.9 + + '@types/glob@8.1.0': + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 22.13.9 + + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 22.13.9 + + '@types/handlebars@4.1.0': + dependencies: + handlebars: 4.7.8 + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/jest@29.5.14': + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + + '@types/json-schema@7.0.15': {} + + '@types/keyv@3.1.4': + dependencies: + '@types/node': 22.13.9 + + '@types/lodash@4.17.16': {} + + '@types/long@4.0.2': {} + + '@types/luxon@3.4.2': {} + + '@types/minimatch@3.0.5': {} + + '@types/minimatch@5.1.2': {} + + '@types/ms@2.1.0': {} + + '@types/mute-stream@0.0.4': + dependencies: + '@types/node': 22.13.9 + + '@types/node-fetch@2.6.13': + dependencies: + '@types/node': 22.13.9 + form-data: 4.0.4 + + '@types/node@22.13.9': + dependencies: + undici-types: 6.20.0 + + '@types/parse-package-name@0.1.0': {} + + '@types/pino@7.0.5': + dependencies: + pino: 9.6.0 + + '@types/prettier@2.7.3': {} + + '@types/randombytes@2.0.3': + dependencies: + '@types/node': 22.13.9 + + '@types/responselike@1.0.3': + dependencies: + '@types/node': 22.13.9 + + '@types/rimraf@3.0.2': + dependencies: + '@types/glob': 8.1.0 + '@types/node': 22.13.9 + + '@types/shelljs@0.8.15': + dependencies: + '@types/glob': 7.2.0 + '@types/node': 22.13.9 + + '@types/stack-utils@2.0.3': {} + + '@types/tough-cookie@4.0.5': {} + + '@types/urijs@1.19.25': {} + + '@types/validator@13.12.2': {} + + '@types/wrap-ansi@3.0.0': {} + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.33': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@webassemblyjs/ast@1.14.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + + '@webassemblyjs/helper-api-error@1.13.2': {} + + '@webassemblyjs/helper-buffer@1.14.1': {} + + '@webassemblyjs/helper-numbers@1.13.2': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + + '@webassemblyjs/helper-wasm-section@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + + '@webassemblyjs/ieee754@1.13.2': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.13.2': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.13.2': {} + + '@webassemblyjs/wasm-edit@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + + '@webassemblyjs/wasm-gen@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wasm-opt@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + + '@webassemblyjs/wasm-parser@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wast-printer@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + + '@willsoto/nestjs-prometheus@6.0.2(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2))(prom-client@15.1.3)': + dependencies: + '@nestjs/common': 11.1.6(class-transformer@0.5.1)(class-validator@0.14.1)(reflect-metadata@0.1.14)(rxjs@7.8.2) + prom-client: 15.1.3 + + '@wry/caches@1.0.1': + dependencies: + tslib: 2.8.1 + + '@wry/context@0.7.4': + dependencies: + tslib: 2.8.1 + + '@wry/equality@0.5.7': + dependencies: + tslib: 2.8.1 + + '@wry/trie@0.5.0': + dependencies: + tslib: 2.8.1 + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + '@zilliqa-js/crypto@3.5.0': + dependencies: + '@zilliqa-js/util': 3.5.0 + aes-js: 3.1.2 + buffer: 6.0.3 + crypto-js: 4.2.0 + elliptic: 6.6.1 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + pbkdf2: 3.1.2 + scrypt-js: 3.0.1 + scryptsy: 2.1.0 + tslib: 2.3.1 + uuid: 8.3.2 + + '@zilliqa-js/util@3.5.0': + dependencies: + bn.js: 4.12.1 + camelcase: 5.3.1 + long: 4.0.0 + tslib: 2.3.1 + + abitype@1.0.8(typescript@5.9.2)(zod@3.25.32): + optionalDependencies: + typescript: 5.9.2 + zod: 3.25.32 + + abort-controller@3.0.0: + dependencies: + event-target-shim: 5.0.1 + + accepts@2.0.0: + dependencies: + mime-types: 3.0.0 + negotiator: 1.0.0 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.14.1 + + acorn@8.14.1: {} + + address@1.2.2: {} + + aes-js@3.0.0: {} + + aes-js@3.1.2: {} + + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv-keywords@5.1.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.6 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + algo-msgpack-with-bigint@2.1.1: {} + + algosdk@2.11.0: + 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 + + already@2.2.1: {} + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-escapes@2.0.0: {} + + ansi-escapes@3.2.0: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@2.1.1: {} + + ansi-regex@3.0.1: {} + + ansi-regex@4.1.1: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@2.2.1: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + ansicolors@0.3.2: {} + + any-promise@1.3.0: {} + + any-signal@2.1.2: + dependencies: + abort-controller: 3.0.0 + native-abort-controller: 1.0.4(abort-controller@3.0.0) + + any-signal@3.0.1: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + append-field@1.0.0: {} + + arg@4.1.3: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-back@3.1.0: {} + + array-back@4.0.2: {} + + array-union@2.1.0: {} + + asn1.js@4.10.1: + dependencies: + bn.js: 4.12.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + assert@2.1.0: + dependencies: + call-bind: 1.0.8 + is-nan: 1.3.2 + object-is: 1.1.6 + object.assign: 4.1.7 + util: 0.12.5 + + ast-stringify@0.1.0: + dependencies: + '@babel/runtime': 7.26.9 + + astral-regex@2.0.0: {} + + async-mutex@0.5.0: + dependencies: + tslib: 2.8.1 + + async@3.2.6: {} + + asynckit@0.4.0: {} + + atomic-sleep@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axios@0.24.0: + dependencies: + follow-redirects: 1.15.9 + transitivePeerDependencies: + - debug + + axios@0.25.0: + dependencies: + follow-redirects: 1.15.9 + transitivePeerDependencies: + - debug + + axios@0.27.2: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.4 + transitivePeerDependencies: + - debug + + axios@0.28.1: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.4 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + axios@1.12.1: + dependencies: + follow-redirects: 1.15.9 + form-data: 4.0.4 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + babel-jest@29.7.0(@babel/core@7.18.10): + dependencies: + '@babel/core': 7.18.10 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.18.10) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + optional: true + + babel-jest@29.7.0(@babel/core@7.26.9): + dependencies: + '@babel/core': 7.26.9 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.26.9) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-istanbul@6.1.1: + dependencies: + '@babel/helper-plugin-utils': 7.27.1 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.26.9 + '@babel/types': 7.28.2 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + + babel-plugin-polyfill-corejs2@0.3.3(@babel/core@7.18.10): + dependencies: + '@babel/compat-data': 7.26.8 + '@babel/core': 7.18.10 + '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.18.10) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.5.3(@babel/core@7.18.10): + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.18.10) + core-js-compat: 3.41.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.4.1(@babel/core@7.18.10): + dependencies: + '@babel/core': 7.18.10 + '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.18.10) + transitivePeerDependencies: + - supports-color + + babel-preset-current-node-syntax@1.2.0(@babel/core@7.18.10): + dependencies: + '@babel/core': 7.18.10 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.18.10) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.18.10) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.18.10) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.18.10) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.18.10) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.18.10) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.18.10) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.18.10) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.18.10) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.18.10) + optional: true + + babel-preset-current-node-syntax@1.2.0(@babel/core@7.26.9): + dependencies: + '@babel/core': 7.26.9 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.26.9) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.26.9) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.26.9) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.26.9) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.26.9) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.26.9) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.26.9) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.26.9) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.26.9) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.26.9) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.26.9) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.26.9) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.26.9) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.26.9) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.26.9) + + babel-preset-jest@29.6.3(@babel/core@7.18.10): + dependencies: + '@babel/core': 7.18.10 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.18.10) + optional: true + + babel-preset-jest@29.6.3(@babel/core@7.26.9): + dependencies: + '@babel/core': 7.26.9 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.26.9) + + balanced-match@1.0.2: {} + + bare-addon-resolve@1.9.3(bare-url@2.1.3): + dependencies: + bare-module-resolve: 1.10.2(bare-url@2.1.3) + bare-semver: 1.0.1 + optionalDependencies: + bare-url: 2.1.3 + optional: true + + bare-module-resolve@1.10.2(bare-url@2.1.3): + dependencies: + bare-semver: 1.0.1 + optionalDependencies: + bare-url: 2.1.3 + optional: true + + bare-os@3.5.1: + optional: true + + bare-path@3.0.0: + dependencies: + bare-os: 3.5.1 + optional: true + + bare-semver@1.0.1: + optional: true + + bare-url@2.1.3: + dependencies: + bare-path: 3.0.0 + optional: true + + base32.js@0.1.0: {} + + base64-js@1.5.1: {} + + bech32@1.1.4: {} + + big.js@5.2.2: {} + + bignumber.js@4.1.0: {} + + bignumber.js@9.1.2: {} + + bintrees@1.0.2: {} + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + blob-to-it@1.0.4: + dependencies: + browser-readablestream-to-it: 1.0.3 + + bn.js@4.12.1: {} + + bn.js@5.2.1: {} + + body-parser@2.1.0: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.0(supports-color@8.1.1) + http-errors: 2.0.0 + iconv-lite: 0.5.2 + on-finished: 2.4.1 + qs: 6.14.0 + raw-body: 3.0.0 + type-is: 2.0.0 + transitivePeerDependencies: + - supports-color + + borsh@1.0.0: {} + + boxen@5.1.2: + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 2.2.1 + string-width: 4.2.3 + type-fest: 0.20.2 + widest-line: 3.1.0 + wrap-ansi: 7.0.0 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + brorand@1.1.0: {} + + browser-readablestream-to-it@1.0.3: {} + + browserify-aes@1.2.0: + dependencies: + buffer-xor: 1.0.3 + cipher-base: 1.0.6 + create-hash: 1.2.0 + evp_bytestokey: 1.0.3 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + browserify-cipher@1.0.1: + dependencies: + browserify-aes: 1.2.0 + browserify-des: 1.0.2 + evp_bytestokey: 1.0.3 + + browserify-des@1.0.2: + dependencies: + cipher-base: 1.0.6 + des.js: 1.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + browserify-rsa@4.1.1: + dependencies: + bn.js: 5.2.1 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + + browserify-sign@4.2.3: + dependencies: + bn.js: 5.2.1 + browserify-rsa: 4.1.1 + create-hash: 1.2.0 + create-hmac: 1.1.7 + elliptic: 6.6.1 + hash-base: 3.0.5 + inherits: 2.0.4 + parse-asn1: 5.1.7 + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + + browserslist@4.24.4: + dependencies: + caniuse-lite: 1.0.30001702 + electron-to-chromium: 1.5.112 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.24.4) + + bs-logger@0.2.6: + dependencies: + fast-json-stable-stringify: 2.1.0 + + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + + buffer-from@1.1.2: {} + + buffer-xor@1.0.3: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bufferutil@4.0.9: + dependencies: + node-gyp-build: 4.8.4 + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + bytes@3.1.2: {} + + cacheable-lookup@6.1.0: {} + + cacheable-request@6.1.0: + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.1.1 + keyv: 3.1.0 + lowercase-keys: 2.0.0 + normalize-url: 4.5.1 + responselike: 1.0.2 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.8: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + call-me-maybe@1.0.2: {} + + callguard@2.0.0: {} + + callsites@3.1.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-lite@1.0.30001702: {} + + cardinal@2.1.1: + dependencies: + ansicolors: 0.3.2 + redeyed: 2.1.1 + + case@1.6.3: {} + + cborg@1.10.2: {} + + chalk@1.1.3: + dependencies: + ansi-styles: 2.2.1 + escape-string-regexp: 1.0.5 + has-ansi: 2.0.0 + strip-ansi: 3.0.1 + supports-color: 2.0.0 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + char-regex@1.0.2: {} + + chardet@0.4.2: {} + + chardet@0.7.0: {} + + chownr@3.0.0: {} + + chrome-trace-event@1.0.4: {} + + ci-info@2.0.0: {} + + ci-info@3.9.0: {} + + cipher-base@1.0.6: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + cjs-module-lexer@1.4.3: {} + + class-transformer@0.5.1: {} + + class-validator@0.14.1: + dependencies: + '@types/validator': 13.12.2 + libphonenumber-js: 1.12.5 + validator: 13.12.0 + + clean-stack@3.0.1: + dependencies: + escape-string-regexp: 4.0.0 + + cli-boxes@2.2.1: {} + + cli-color@2.0.4: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-iterator: 2.0.3 + memoizee: 0.4.17 + timers-ext: 0.1.8 + + cli-cursor@2.1.0: + dependencies: + restore-cursor: 2.0.0 + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-progress@3.12.0: + dependencies: + string-width: 4.2.3 + + cli-spinners@2.9.2: {} + + cli-width@2.2.1: {} + + cli-width@4.1.0: {} + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone-deep@4.0.1: + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + + clone-response@1.0.3: + dependencies: + mimic-response: 1.0.1 + + clone@1.0.4: {} + + co@4.6.0: {} + + collect-v8-coverage@1.0.2: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + colors@1.4.0: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + command-line-args@5.2.1: + dependencies: + array-back: 3.1.0 + find-replace: 3.0.0 + lodash.camelcase: 4.3.0 + typical: 4.0.0 + + command-line-usage@6.1.3: + dependencies: + array-back: 4.0.2 + chalk: 2.4.2 + table-layout: 1.0.2 + typical: 5.2.0 + + commander@2.20.3: {} + + concat-map@0.0.1: {} + + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + + configstore@5.0.1: + dependencies: + dot-prop: 5.3.0 + graceful-fs: 4.2.11 + make-dir: 3.1.0 + unique-string: 2.0.0 + write-file-atomic: 3.0.3 + xdg-basedir: 4.0.0 + + consola@3.4.0: {} + + content-disposition@1.0.0: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + convert-source-map@1.9.0: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.1: {} + + core-js-compat@3.41.0: + dependencies: + browserslist: 4.24.4 + + core-util-is@1.0.3: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cosmjs-types@0.10.1: {} + + crc@3.8.0: + dependencies: + buffer: 5.7.1 + + crc@4.3.2(buffer@6.0.3): + optionalDependencies: + buffer: 6.0.3 + + create-ecdh@4.0.4: + dependencies: + bn.js: 4.12.1 + elliptic: 6.6.1 + + create-hash@1.2.0: + dependencies: + cipher-base: 1.0.6 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.2 + sha.js: 2.4.11 + + create-hmac@1.1.7: + dependencies: + cipher-base: 1.0.6 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + create-jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + create-require@1.1.1: {} + + cron-converter@2.1.0: + dependencies: + luxon: 3.5.0 + + cron@3.5.0: + dependencies: + '@types/luxon': 3.4.2 + luxon: 3.5.0 + + cross-fetch@3.2.0(encoding@0.1.13): + dependencies: + node-fetch: 2.7.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypto-browserify@3.12.1: + dependencies: + browserify-cipher: 1.0.1 + browserify-sign: 4.2.3 + create-ecdh: 4.0.4 + create-hash: 1.2.0 + create-hmac: 1.1.7 + diffie-hellman: 5.0.3 + hash-base: 3.0.5 + inherits: 2.0.4 + pbkdf2: 3.1.2 + public-encrypt: 4.0.3 + randombytes: 2.1.0 + randomfill: 1.0.4 + + crypto-js@4.2.0: {} + + crypto-random-string@2.0.0: {} + + csv-stringify@6.5.2: {} + + d@1.0.2: + dependencies: + es5-ext: 0.10.64 + type: 2.7.3 + + dag-jose@1.0.0: + dependencies: + '@ipld/dag-cbor': 6.0.15 + multiformats: 9.9.0 + + dargs@7.0.0: {} + + data-uri-to-buffer@4.0.1: {} + + dayjs@1.11.13: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.3.6: + dependencies: + ms: 2.1.2 + + debug@4.4.0(supports-color@8.1.1): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 8.1.1 + + decimal.js@10.5.0: {} + + decompress-response@3.3.0: + dependencies: + mimic-response: 1.0.1 + + dedent@1.6.0: {} + + deep-extend@0.6.0: {} + + deepmerge@4.2.2: {} + + deepmerge@4.3.1: {} + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + defer-to-connect@1.1.3: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + des.js@1.1.0: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + destroy@1.2.0: {} + + detect-newline@3.1.0: {} + + detect-node@2.1.0: {} + + detect-port@1.6.1: + dependencies: + address: 1.2.2 + debug: 4.4.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + diff-sequences@29.6.3: {} + + diff@4.0.2: {} + + diffie-hellman@5.0.3: + dependencies: + bn.js: 4.12.1 + miller-rabin: 4.0.1 + randombytes: 2.1.0 + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dns-over-http-resolver@1.2.3(node-fetch@2.7.0(encoding@0.1.13)): + dependencies: + debug: 4.4.0(supports-color@8.1.1) + native-fetch: 3.0.0(node-fetch@2.7.0(encoding@0.1.13)) + receptacle: 1.3.2 + transitivePeerDependencies: + - node-fetch + - supports-color + + dot-prop@5.3.0: + dependencies: + is-obj: 2.0.0 + + dotenv@16.4.7: {} + + dottie@2.0.6: {} + + dotty@0.1.2: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer3@0.1.5: {} + + eastasianwidth@0.2.0: {} + + ee-first@1.1.1: {} + + ejs@3.1.10: + dependencies: + jake: 10.9.2 + + electron-fetch@1.9.1: + dependencies: + encoding: 0.1.13 + + electron-to-chromium@1.5.112: {} + + elliptic@6.6.1: + dependencies: + bn.js: 4.12.1 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + emittery@0.13.1: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + emojis-list@3.0.0: {} + + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + enhanced-resolve@5.18.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + err-code@3.0.1: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.6.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es5-ext@0.10.64: + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + esniff: 2.0.1 + next-tick: 1.1.0 + + es6-iterator@2.0.3: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-symbol: 3.1.4 + + es6-promise@4.2.8: {} + + es6-symbol@3.1.4: + dependencies: + d: 1.0.2 + ext: 1.7.0 + + es6-weak-map@2.0.3: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + + esbuild@0.25.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.5 + '@esbuild/android-arm': 0.25.5 + '@esbuild/android-arm64': 0.25.5 + '@esbuild/android-x64': 0.25.5 + '@esbuild/darwin-arm64': 0.25.5 + '@esbuild/darwin-x64': 0.25.5 + '@esbuild/freebsd-arm64': 0.25.5 + '@esbuild/freebsd-x64': 0.25.5 + '@esbuild/linux-arm': 0.25.5 + '@esbuild/linux-arm64': 0.25.5 + '@esbuild/linux-ia32': 0.25.5 + '@esbuild/linux-loong64': 0.25.5 + '@esbuild/linux-mips64el': 0.25.5 + '@esbuild/linux-ppc64': 0.25.5 + '@esbuild/linux-riscv64': 0.25.5 + '@esbuild/linux-s390x': 0.25.5 + '@esbuild/linux-x64': 0.25.5 + '@esbuild/netbsd-arm64': 0.25.5 + '@esbuild/netbsd-x64': 0.25.5 + '@esbuild/openbsd-arm64': 0.25.5 + '@esbuild/openbsd-x64': 0.25.5 + '@esbuild/sunos-x64': 0.25.5 + '@esbuild/win32-arm64': 0.25.5 + '@esbuild/win32-ia32': 0.25.5 + '@esbuild/win32-x64': 0.25.5 + + escalade@3.2.0: {} + + escape-goat@2.1.1: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@2.0.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + esniff@2.0.1: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + event-emitter: 0.3.5 + type: 2.7.3 + + esprima@4.0.1: {} + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + ethers@5.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + 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(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@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 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + event-emitter@0.3.5: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + + event-target-shim@5.0.1: {} + + eventemitter2@6.4.9: {} + + eventemitter3@5.0.1: {} + + events@3.3.0: {} + + eventsource@1.1.2: {} + + eventsource@2.0.2: {} + + evp_bytestokey@1.0.3: + dependencies: + md5.js: 1.3.5 + safe-buffer: 5.2.1 + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + exit@0.1.2: {} + + expect@29.7.0: + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + + exponential-backoff@3.1.2: {} + + express@5.0.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.1.0 + content-disposition: 1.0.0 + content-type: 1.0.5 + cookie: 0.7.1 + cookie-signature: 1.2.2 + debug: 4.3.6 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.0.0 + fresh: 2.0.0 + http-errors: 2.0.0 + merge-descriptors: 2.0.0 + methods: 1.1.2 + mime-types: 3.0.0 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.7 + qs: 6.13.0 + range-parser: 1.2.1 + router: 2.1.0 + safe-buffer: 5.2.1 + send: 1.1.0 + serve-static: 2.1.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 2.0.0 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + ext@1.7.0: + dependencies: + type: 2.7.3 + + external-editor@2.2.0: + dependencies: + chardet: 0.4.2 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + fast-deep-equal@3.1.3: {} + + fast-fifo@1.3.2: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-redact@3.5.0: {} + + fast-safe-stringify@2.1.1: {} + + fast-text-encoding@1.0.6: {} + + fast-uri@3.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fb-watchman@2.0.2: + dependencies: + bser: 2.1.1 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + fetch-h2@3.0.2: + dependencies: + '@types/tough-cookie': 4.0.5 + already: 2.2.1 + callguard: 2.0.0 + get-stream: 6.0.1 + through2: 4.0.2 + to-arraybuffer: 1.0.1 + tough-cookie: 4.1.4 + + fflate@0.8.2: {} + + figures@2.0.0: + dependencies: + escape-string-regexp: 1.0.5 + + file-type@21.0.0: + dependencies: + '@tokenizer/inflate': 0.2.7 + strtok3: 10.3.4 + token-types: 6.1.1 + uint8array-extras: 1.5.0 + transitivePeerDependencies: + - supports-color + + filelist@1.0.4: + dependencies: + minimatch: 5.1.6 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@2.0.0: + dependencies: + debug: 2.6.9 + encodeurl: 1.0.2 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-replace@3.0.0: + dependencies: + array-back: 3.1.0 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + flat@5.0.2: {} + + flatstr@1.0.12: {} + + flatted@3.3.3: {} + + follow-redirects@1.15.9: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + form-data@4.0.4: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.2 + mime-types: 2.1.35 + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + forwarded@0.2.0: {} + + fresh@0.5.2: {} + + fresh@2.0.0: {} + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-extra@11.3.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + fuzzy@0.1.3: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + 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 + + get-iterator@1.0.2: {} + + get-package-type@0.1.0: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stdin@8.0.0: {} + + get-stream@4.1.0: + dependencies: + pump: 3.0.2 + + get-stream@5.2.0: + dependencies: + pump: 3.0.2 + + get-stream@6.0.1: {} + + get-tsconfig@4.10.1: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-promise@4.2.2(glob@7.2.3): + dependencies: + '@types/glob': 7.2.0 + glob: 7.2.3 + + glob-to-regexp@0.4.1: {} + + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.1.7: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.0.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + + global-dirs@3.0.1: + dependencies: + ini: 2.0.0 + + globals@11.12.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.2.0: {} + + got@9.6.0: + dependencies: + '@sindresorhus/is': 0.14.0 + '@szmarczak/http-timer': 1.1.2 + '@types/keyv': 3.1.4 + '@types/responselike': 1.0.3 + cacheable-request: 6.1.0 + decompress-response: 3.3.0 + duplexer3: 0.1.5 + get-stream: 4.1.0 + lowercase-keys: 1.0.1 + mimic-response: 1.0.1 + p-cancelable: 1.1.0 + to-readable-stream: 1.0.0 + url-parse-lax: 3.0.0 + + graceful-fs@4.2.11: {} + + graphql-tag@2.12.6(graphql@15.10.1): + dependencies: + graphql: 15.10.1 + tslib: 2.8.1 + + graphql@15.10.1: {} + + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + + has-ansi@2.0.0: + dependencies: + ansi-regex: 2.1.1 + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + has-yarn@2.1.0: {} + + hash-base@3.0.5: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + hash-wasm@4.12.0: {} + + hash.js@1.1.7: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + hi-base32@0.5.1: {} + + hmac-drbg@1.0.1: + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + html-escaper@2.0.2: {} + + http-cache-semantics@4.1.1: {} + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + human-signals@2.1.0: {} + + hyperlinker@1.0.0: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.5.2: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + import-lazy@2.1.0: {} + + import-local@3.2.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + inflection@1.13.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.3: {} + + inherits@2.0.4: {} + + ini@1.3.8: {} + + ini@2.0.0: {} + + inquirer-autocomplete-prompt@0.11.1: + dependencies: + ansi-escapes: 2.0.0 + chalk: 1.1.3 + figures: 2.0.0 + inquirer: 3.1.1 + lodash: 4.17.21 + run-async: 2.4.1 + util: 0.10.4 + + inquirer@3.1.1: + dependencies: + ansi-escapes: 2.0.0 + chalk: 1.1.3 + cli-cursor: 2.1.0 + cli-width: 2.2.1 + external-editor: 2.2.0 + figures: 2.0.0 + lodash: 4.17.21 + mute-stream: 0.0.7 + run-async: 2.4.1 + rx-lite: 4.0.8 + rx-lite-aggregates: 4.0.8 + string-width: 2.1.1 + strip-ansi: 3.0.1 + through: 2.3.8 + + inquirer@6.5.2: + dependencies: + ansi-escapes: 3.2.0 + chalk: 2.4.2 + cli-cursor: 2.1.0 + cli-width: 2.2.1 + external-editor: 3.1.0 + figures: 2.0.0 + lodash: 4.17.21 + mute-stream: 0.0.7 + run-async: 2.4.1 + rxjs: 6.6.7 + string-width: 2.1.1 + strip-ansi: 5.2.0 + through: 2.3.8 + + inquirerer@0.1.3: + dependencies: + colors: 1.4.0 + inquirer: 6.5.2 + inquirer-autocomplete-prompt: 0.11.1 + + interface-datastore@5.2.0: + dependencies: + err-code: 3.0.1 + interface-store: 1.0.2 + ipfs-utils: 8.1.6 + it-all: 1.0.6 + it-drain: 1.0.5 + it-filter: 1.0.3 + it-take: 1.0.2 + nanoid: 3.3.8 + uint8arrays: 3.1.1 + + interface-datastore@6.1.1: + dependencies: + interface-store: 2.0.2 + nanoid: 3.3.8 + uint8arrays: 3.1.1 + + interface-store@1.0.2: {} + + interface-store@2.0.2: {} + + interpret@1.4.0: {} + + ip-regex@4.3.0: {} + + ipaddr.js@1.9.1: {} + + ipfs-core-types@0.10.3(node-fetch@2.7.0(encoding@0.1.13)): + dependencies: + '@ipld/dag-pb': 2.1.18 + interface-datastore: 6.1.1 + ipfs-unixfs: 6.0.9 + multiaddr: 10.0.1(node-fetch@2.7.0(encoding@0.1.13)) + multiformats: 9.9.0 + transitivePeerDependencies: + - node-fetch + - supports-color + + ipfs-core-types@0.7.3(node-fetch@2.7.0(encoding@0.1.13)): + dependencies: + interface-datastore: 5.2.0 + multiaddr: 10.0.1(node-fetch@2.7.0(encoding@0.1.13)) + multiformats: 9.9.0 + transitivePeerDependencies: + - node-fetch + - supports-color + + ipfs-core-utils@0.10.5(node-fetch@2.7.0(encoding@0.1.13)): + dependencies: + any-signal: 2.1.2 + blob-to-it: 1.0.4 + browser-readablestream-to-it: 1.0.3 + err-code: 3.0.1 + ipfs-core-types: 0.7.3(node-fetch@2.7.0(encoding@0.1.13)) + ipfs-unixfs: 6.0.9 + ipfs-utils: 8.1.6 + it-all: 1.0.6 + it-map: 1.0.6 + it-peekable: 1.0.3 + multiaddr: 10.0.1(node-fetch@2.7.0(encoding@0.1.13)) + multiaddr-to-uri: 8.0.0(node-fetch@2.7.0(encoding@0.1.13)) + multiformats: 9.9.0 + parse-duration: 1.1.2 + timeout-abort-controller: 1.1.1 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - node-fetch + - supports-color + + ipfs-core-utils@0.14.3(encoding@0.1.13)(node-fetch@2.7.0(encoding@0.1.13)): + dependencies: + any-signal: 3.0.1 + blob-to-it: 1.0.4 + browser-readablestream-to-it: 1.0.3 + debug: 4.4.0(supports-color@8.1.1) + err-code: 3.0.1 + ipfs-core-types: 0.10.3(node-fetch@2.7.0(encoding@0.1.13)) + ipfs-unixfs: 6.0.9 + ipfs-utils: 9.0.14(encoding@0.1.13) + it-all: 1.0.6 + it-map: 1.0.6 + it-peekable: 1.0.3 + it-to-stream: 1.0.0 + merge-options: 3.0.4 + multiaddr: 10.0.1(node-fetch@2.7.0(encoding@0.1.13)) + multiaddr-to-uri: 8.0.0(node-fetch@2.7.0(encoding@0.1.13)) + multiformats: 9.9.0 + nanoid: 3.3.8 + parse-duration: 1.1.2 + timeout-abort-controller: 3.0.0 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - encoding + - node-fetch + - supports-color + + ipfs-http-client@52.0.5(node-fetch@2.7.0(encoding@0.1.13)): + dependencies: + '@ipld/dag-cbor': 6.0.15 + '@ipld/dag-pb': 2.1.18 + abort-controller: 3.0.0 + any-signal: 2.1.2 + debug: 4.4.0(supports-color@8.1.1) + err-code: 3.0.1 + form-data: 4.0.4 + ipfs-core-types: 0.7.3(node-fetch@2.7.0(encoding@0.1.13)) + ipfs-core-utils: 0.10.5(node-fetch@2.7.0(encoding@0.1.13)) + ipfs-utils: 8.1.6 + it-first: 1.0.7 + it-last: 1.0.6 + it-to-stream: 1.0.0 + merge-options: 3.0.4 + multiaddr: 10.0.1(node-fetch@2.7.0(encoding@0.1.13)) + multiformats: 9.9.0 + nanoid: 3.3.8 + native-abort-controller: 1.0.4(abort-controller@3.0.0) + parse-duration: 1.1.2 + stream-to-it: 0.2.4 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - node-fetch + - supports-color + + ipfs-http-client@56.0.3(encoding@0.1.13)(node-fetch@2.7.0(encoding@0.1.13)): + dependencies: + '@ipld/dag-cbor': 7.0.3 + '@ipld/dag-json': 8.0.11 + '@ipld/dag-pb': 2.1.18 + any-signal: 3.0.1 + dag-jose: 1.0.0 + debug: 4.4.0(supports-color@8.1.1) + err-code: 3.0.1 + ipfs-core-types: 0.10.3(node-fetch@2.7.0(encoding@0.1.13)) + ipfs-core-utils: 0.14.3(encoding@0.1.13)(node-fetch@2.7.0(encoding@0.1.13)) + ipfs-utils: 9.0.14(encoding@0.1.13) + it-first: 1.0.7 + it-last: 1.0.6 + merge-options: 3.0.4 + multiaddr: 10.0.1(node-fetch@2.7.0(encoding@0.1.13)) + multiformats: 9.9.0 + parse-duration: 1.1.2 + stream-to-it: 0.2.4 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - encoding + - node-fetch + - supports-color + + ipfs-unixfs@6.0.9: + dependencies: + err-code: 3.0.1 + protobufjs: 6.11.4 + + ipfs-utils@8.1.6: + dependencies: + abort-controller: 3.0.0 + any-signal: 2.1.2 + buffer: 6.0.3 + electron-fetch: 1.9.1 + err-code: 3.0.1 + is-electron: 2.2.2 + iso-url: 1.2.1 + it-glob: 0.0.14 + it-to-stream: 1.0.0 + merge-options: 3.0.4 + nanoid: 3.3.8 + native-abort-controller: 1.0.4(abort-controller@3.0.0) + native-fetch: 3.0.0(@achingbrain/node-fetch@2.6.7) + node-fetch: '@achingbrain/node-fetch@2.6.7' + react-native-fetch-api: 2.0.0 + stream-to-it: 0.2.4 + + ipfs-utils@9.0.14(encoding@0.1.13): + dependencies: + any-signal: 3.0.1 + browser-readablestream-to-it: 1.0.3 + buffer: 6.0.3 + electron-fetch: 1.9.1 + err-code: 3.0.1 + is-electron: 2.2.2 + iso-url: 1.2.1 + it-all: 1.0.6 + it-glob: 1.0.2 + it-to-stream: 1.0.0 + merge-options: 3.0.4 + nanoid: 3.3.8 + native-fetch: 3.0.0(node-fetch@2.7.0(encoding@0.1.13)) + node-fetch: 2.7.0(encoding@0.1.13) + react-native-fetch-api: 3.0.0 + stream-to-it: 0.2.4 + transitivePeerDependencies: + - encoding + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-arrayish@0.2.1: {} + + is-callable@1.2.7: {} + + is-ci@2.0.0: + dependencies: + ci-info: 2.0.0 + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-docker@2.2.1: {} + + is-electron@2.2.2: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@2.0.0: {} + + is-fullwidth-code-point@3.0.0: {} + + is-generator-fn@2.1.0: {} + + is-generator-function@1.1.0: + dependencies: + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-installed-globally@0.4.0: + dependencies: + global-dirs: 3.0.1 + is-path-inside: 3.0.3 + + is-interactive@1.0.0: {} + + is-ip@3.1.0: + dependencies: + ip-regex: 4.3.0 + + is-nan@1.3.2: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + + is-npm@5.0.0: {} + + is-number@7.0.0: {} + + is-obj@2.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-obj@2.1.0: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-promise@2.2.2: {} + + is-promise@4.0.0: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + is-stream@2.0.1: {} + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.18 + + is-typedarray@1.0.0: {} + + is-unicode-supported@0.1.0: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + is-yarn-global@0.3.0: {} + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + iso-url@1.2.1: {} + + isobject@3.0.1: {} + + isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + isows@1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@5.2.1: + dependencies: + '@babel/core': 7.26.9 + '@babel/parser': 7.26.9 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.26.9 + '@babel/parser': 7.26.9 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.7.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@4.0.1: + dependencies: + debug: 4.4.0(supports-color@8.1.1) + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + it-all@1.0.6: {} + + it-drain@1.0.5: {} + + it-filter@1.0.3: {} + + it-first@1.0.7: {} + + it-glob@0.0.14: + dependencies: + '@types/minimatch': 3.0.5 + minimatch: 3.1.2 + + it-glob@1.0.2: + dependencies: + '@types/minimatch': 3.0.5 + minimatch: 3.1.2 + + it-last@1.0.6: {} + + it-map@1.0.6: {} + + it-peekable@1.0.3: {} + + it-take@1.0.2: {} + + it-to-stream@1.0.0: + dependencies: + buffer: 6.0.3 + fast-fifo: 1.3.2 + get-iterator: 1.0.2 + p-defer: 3.0.0 + p-fifo: 1.0.0 + readable-stream: 3.6.2 + + iterare@1.2.1: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jake@10.9.2: + dependencies: + async: 3.2.6 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + + javascript-stringify@2.1.0: {} + + jest-changed-files@29.7.0: + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + + jest-circus@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.13.9 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.6.0 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-cli@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest-config@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)): + dependencies: + '@babel/core': 7.26.9 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.26.9) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.13.9 + ts-node: 10.9.2(@types/node@22.13.9)(typescript@5.9.2) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-docblock@29.7.0: + dependencies: + detect-newline: 3.1.0 + + jest-each@29.7.0: + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.13.9 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + jest-get-type@29.6.3: {} + + jest-haste-map@28.1.3: + dependencies: + '@jest/types': 28.1.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 22.13.9 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 28.0.2 + jest-util: 28.1.3 + jest-worker: 28.1.3 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-haste-map@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 22.13.9 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-leak-detector@29.7.0: + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-matcher-utils@29.7.0: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-message-util@29.7.0: + dependencies: + '@babel/code-frame': 7.26.2 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.13.9 + jest-util: 29.7.0 + + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 + + jest-regex-util@28.0.2: {} + + jest-regex-util@29.6.3: {} + + jest-resolve-dependencies@29.7.0: + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + jest-resolve@29.7.0: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.10 + resolve.exports: 2.0.3 + slash: 3.0.0 + + jest-runner@29.7.0: + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.13.9 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + + jest-runtime@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.13.9 + chalk: 4.1.2 + cjs-module-lexer: 1.4.3 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + + jest-snapshot@29.7.0: + dependencies: + '@babel/core': 7.26.9 + '@babel/generator': 7.26.9 + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.9) + '@babel/plugin-syntax-typescript': 7.25.9(@babel/core@7.26.9) + '@babel/types': 7.28.2 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.26.9) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.7.1 + transitivePeerDependencies: + - supports-color + + jest-util@28.1.3: + dependencies: + '@jest/types': 28.1.3 + '@types/node': 22.13.9 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.13.9 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + jest-validate@29.7.0: + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + + jest-watcher@29.7.0: + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.13.9 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + + jest-worker@27.5.1: + dependencies: + '@types/node': 22.13.9 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest-worker@28.1.3: + dependencies: + '@types/node': 22.13.9 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest-worker@29.7.0: + dependencies: + '@types/node': 22.13.9 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + js-sha256@0.9.0: {} + + js-sha3@0.8.0: {} + + js-sha512@0.8.0: {} + + js-tokens@4.0.0: {} + + js-xdr@1.3.0: + dependencies: + lodash: 4.17.21 + long: 2.4.0 + + js-xdr@3.1.2: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@2.5.2: {} + + jsesc@3.0.2: {} + + jsesc@3.1.0: {} + + json-bigint@1.0.0: + dependencies: + bignumber.js: 9.1.2 + + json-buffer@3.0.0: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@1.0.0: {} + + json-stringify-safe@5.0.1: {} + + json5@2.2.3: {} + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + keyv@3.1.0: + dependencies: + json-buffer: 3.0.0 + + kind-of@6.0.3: {} + + kleur@3.0.3: {} + + latest-version@5.1.0: + dependencies: + package-json: 6.5.0 + + leven@3.1.0: {} + + libphonenumber-js@1.12.5: {} + + lines-and-columns@1.2.4: {} + + load-esm@1.0.2: {} + + loader-runner@4.3.0: {} + + loader-utils@2.0.4: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 2.2.3 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + lodash.camelcase@4.3.0: {} + + lodash.debounce@4.0.8: {} + + lodash.memoize@4.1.2: {} + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + long@2.4.0: {} + + long@4.0.0: {} + + long@5.3.1: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lowercase-keys@1.0.1: {} + + lowercase-keys@2.0.0: {} + + lru-cache@10.1.0: {} + + lru-cache@10.4.3: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-queue@0.1.0: + dependencies: + es5-ext: 0.10.64 + + luxon@3.5.0: {} + + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + + make-dir@4.0.0: + dependencies: + semver: 7.7.1 + + make-error@1.3.6: {} + + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + + math-intrinsics@1.1.0: {} + + md5.js@1.3.5: + dependencies: + hash-base: 3.0.5 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + media-typer@0.3.0: {} + + media-typer@1.1.0: {} + + memoizee@0.4.17: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-weak-map: 2.0.3 + event-emitter: 0.3.5 + is-promise: 2.2.2 + lru-queue: 0.1.0 + next-tick: 1.1.0 + timers-ext: 0.1.8 + + merge-descriptors@2.0.0: {} + + merge-options@3.0.4: + dependencies: + is-plain-obj: 2.1.0 + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + merkle-tools@1.4.1: + dependencies: + js-sha3: 0.8.0 + + methods@1.1.2: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + miller-rabin@4.0.1: + dependencies: + bn.js: 4.12.1 + brorand: 1.1.0 + + mime-db@1.52.0: {} + + mime-db@1.53.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime-types@3.0.0: + dependencies: + mime-db: 1.53.0 + + mimic-fn@1.2.0: {} + + mimic-fn@2.1.0: {} + + mimic-response@1.0.1: {} + + minimalistic-assert@1.0.1: {} + + minimalistic-crypto-utils@1.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.1.0: + dependencies: + brace-expansion: 2.0.1 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.6: {} + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + minizlib@3.0.1: + dependencies: + minipass: 7.1.2 + rimraf: 5.0.10 + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mkdirp@1.0.4: {} + + mkdirp@3.0.0: {} + + mkdirp@3.0.1: {} + + mock-socket@9.3.1: {} + + moment-timezone@0.5.47: + dependencies: + moment: 2.30.1 + + moment@2.30.1: {} + + ms@2.0.0: {} + + ms@2.1.2: {} + + ms@2.1.3: {} + + multer@1.4.5-lts.1: + dependencies: + append-field: 1.0.0 + busboy: 1.6.0 + concat-stream: 1.6.2 + mkdirp: 0.5.6 + object-assign: 4.1.1 + type-is: 1.6.18 + xtend: 4.0.2 + + multiaddr-to-uri@8.0.0(node-fetch@2.7.0(encoding@0.1.13)): + dependencies: + multiaddr: 10.0.1(node-fetch@2.7.0(encoding@0.1.13)) + transitivePeerDependencies: + - node-fetch + - supports-color + + multiaddr@10.0.1(node-fetch@2.7.0(encoding@0.1.13)): + dependencies: + dns-over-http-resolver: 1.2.3(node-fetch@2.7.0(encoding@0.1.13)) + err-code: 3.0.1 + is-ip: 3.1.0 + multiformats: 9.9.0 + uint8arrays: 3.1.1 + varint: 6.0.0 + transitivePeerDependencies: + - node-fetch + - supports-color + + multiformats@9.9.0: {} + + mustache@4.0.0: {} + + mute-stream@0.0.7: {} + + mute-stream@1.0.0: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.8: {} + + native-abort-controller@1.0.4(abort-controller@3.0.0): + dependencies: + abort-controller: 3.0.0 + + native-fetch@3.0.0(@achingbrain/node-fetch@2.6.7): + dependencies: + node-fetch: '@achingbrain/node-fetch@2.6.7' + + native-fetch@3.0.0(node-fetch@2.7.0(encoding@0.1.13)): + dependencies: + node-fetch: 2.7.0(encoding@0.1.13) + + natural-compare@1.4.0: {} + + natural-orderby@2.0.3: {} + + negotiator@1.0.0: {} + + neo-async@2.6.2: {} + + nested-obj@0.0.1: {} + + next-tick@1.1.0: {} + + nock@13.5.6: + dependencies: + debug: 4.4.0(supports-color@8.1.1) + json-stringify-safe: 5.0.1 + propagate: 2.0.1 + transitivePeerDependencies: + - supports-color + + node-addon-api@5.1.0: {} + + node-domexception@1.0.0: {} + + node-fetch@2.6.7(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + optional: true + + node-fetch@2.7.0(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + node-gyp-build@4.8.4: {} + + node-int64@0.4.0: {} + + node-releases@2.0.19: {} + + normalize-path@3.0.0: {} + + normalize-url@4.5.1: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.8 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + object-treeify@1.1.33: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.8 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + on-exit-leak-free@2.1.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@2.0.1: + dependencies: + mimic-fn: 1.2.0 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + optimism@0.18.1: + dependencies: + '@wry/caches': 1.0.1 + '@wry/context': 0.7.4 + '@wry/trie': 0.5.0 + tslib: 2.8.1 + + ora@5.4.1: + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + + os-tmpdir@1.0.2: {} + + ox@0.6.7(typescript@5.9.2)(zod@3.25.32): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.9.2)(zod@3.25.32) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.2 + transitivePeerDependencies: + - zod + + p-cancelable@1.1.0: {} + + p-defer@3.0.0: {} + + p-fifo@1.0.0: + dependencies: + fast-fifo: 1.3.2 + p-defer: 3.0.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-try@2.2.0: {} + + package-json-from-dist@1.0.1: {} + + package-json-type@1.0.3: {} + + package-json@6.5.0: + dependencies: + got: 9.6.0 + registry-auth-token: 4.2.2 + registry-url: 5.1.0 + semver: 6.3.1 + + pako@2.1.0: {} + + parse-asn1@5.1.7: + dependencies: + asn1.js: 4.10.1 + browserify-aes: 1.2.0 + evp_bytestokey: 1.0.3 + hash-base: 3.0.5 + pbkdf2: 3.1.2 + safe-buffer: 5.2.1 + + parse-duration@1.1.2: {} + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.26.2 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse-package-name@1.0.0: {} + + parseurl@1.3.3: {} + + password-prompt@1.1.3: + dependencies: + ansi-escapes: 4.3.2 + cross-spawn: 7.0.6 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-to-regexp@8.2.0: {} + + path-type@4.0.0: {} + + pbkdf2@3.1.2: + dependencies: + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + pg-cloudflare@1.1.1: + optional: true + + pg-connection-string@2.7.0: {} + + pg-int8@1.0.1: {} + + pg-pool@3.7.1(pg@8.13.3): + dependencies: + pg: 8.13.3 + + pg-protocol@1.7.1: {} + + pg-types@2.2.0: + dependencies: + pg-int8: 1.0.1 + postgres-array: 2.0.0 + postgres-bytea: 1.0.0 + postgres-date: 1.0.7 + postgres-interval: 1.2.0 + + pg@8.13.3: + dependencies: + pg-connection-string: 2.7.0 + pg-pool: 3.7.1(pg@8.13.3) + pg-protocol: 1.7.1 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.1.1 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + pino-abstract-transport@2.0.0: + dependencies: + split2: 4.2.0 + + pino-std-serializers@3.2.0: {} + + pino-std-serializers@7.0.0: {} + + pino@6.14.0: + dependencies: + fast-redact: 3.5.0 + fast-safe-stringify: 2.1.1 + flatstr: 1.0.12 + pino-std-serializers: 3.2.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + sonic-boom: 1.4.1 + + pino@9.6.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 2.0.0 + pino-std-serializers: 7.0.0 + process-warning: 4.0.1 + quick-format-unescaped: 4.0.4 + real-require: 0.2.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 4.2.0 + thread-stream: 3.1.0 + + pirates@4.0.6: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + possible-typed-array-names@1.1.0: {} + + postgres-array@2.0.0: {} + + postgres-bytea@1.0.0: {} + + postgres-date@1.0.7: {} + + postgres-interval@1.2.0: + dependencies: + xtend: 4.0.2 + + prepend-http@2.0.0: {} + + prettier@2.8.8: {} + + prettier@3.5.3: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + process-nextick-args@2.0.1: {} + + process-warning@1.0.0: {} + + process-warning@4.0.1: {} + + prom-client@15.1.3: + dependencies: + '@opentelemetry/api': 1.9.0 + tdigest: 0.1.2 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + propagate@2.0.1: {} + + protobufjs@6.11.4: + 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.2 + '@types/node': 22.13.9 + long: 4.0.0 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + proxy-from-env@1.1.0: {} + + psl@1.15.0: + dependencies: + punycode: 2.3.1 + + public-encrypt@4.0.3: + dependencies: + bn.js: 4.12.1 + browserify-rsa: 4.1.1 + create-hash: 1.2.0 + parse-asn1: 5.1.7 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + + pump@3.0.2: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + punycode@2.3.1: {} + + pupa@2.1.1: + dependencies: + escape-goat: 2.1.1 + + pure-rand@6.1.0: {} + + qs@6.13.0: + dependencies: + side-channel: 1.1.0 + + qs@6.14.0: + dependencies: + side-channel: 1.1.0 + + querystringify@2.2.0: {} + + queue-microtask@1.2.3: {} + + quick-format-unescaped@4.0.4: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + randomfill@1.0.4: + dependencies: + randombytes: 2.1.0 + safe-buffer: 5.2.1 + + range-parser@1.2.1: {} + + raw-body@3.0.0: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.6.3 + unpipe: 1.0.0 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + react-is@16.13.1: {} + + react-is@18.3.1: {} + + react-native-fetch-api@2.0.0: + dependencies: + p-defer: 3.0.0 + + react-native-fetch-api@3.0.0: + dependencies: + p-defer: 3.0.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readonly-date@1.0.0: {} + + real-require@0.2.0: {} + + receptacle@1.3.2: + dependencies: + ms: 2.1.3 + + rechoir@0.6.2: + dependencies: + resolve: 1.22.10 + + redeyed@2.1.1: + dependencies: + esprima: 4.0.1 + + reduce-flatten@2.0.0: {} + + reflect-metadata@0.1.14: {} + + reflect-metadata@0.2.2: {} + + regenerate-unicode-properties@10.2.0: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regenerator-runtime@0.14.1: {} + + regenerator-transform@0.15.2: + dependencies: + '@babel/runtime': 7.26.9 + + regexpu-core@6.2.0: + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.2.0 + regjsgen: 0.8.0 + regjsparser: 0.12.0 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.2.0 + + registry-auth-token@4.2.2: + dependencies: + rc: 1.2.8 + + registry-url@5.1.0: + dependencies: + rc: 1.2.8 + + regjsgen@0.8.0: {} + + regjsparser@0.12.0: + dependencies: + jsesc: 3.0.2 + + rehackt@0.1.0: {} + + require-addon@1.1.0: + dependencies: + bare-addon-resolve: 1.9.3(bare-url@2.1.3) + bare-url: 2.1.3 + optional: true + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + requires-port@1.0.0: {} + + resolve-cwd@3.0.0: + dependencies: + resolve-from: 5.0.0 + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve.exports@2.0.3: {} + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + responselike@1.0.2: + dependencies: + lowercase-keys: 1.0.1 + + restore-cursor@2.0.0: + dependencies: + onetime: 2.0.1 + signal-exit: 3.0.7 + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + retimer@2.0.0: {} + + retimer@3.0.0: {} + + retry-as-promised@7.1.1: {} + + reusify@1.1.0: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rimraf@5.0.0: + dependencies: + glob: 10.4.5 + + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + + ripemd160@2.0.2: + dependencies: + hash-base: 3.0.5 + inherits: 2.0.4 + + rotating-file-stream@3.2.6: {} + + router@2.1.0: + dependencies: + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.2.0 + + rpc-websocket-client@1.1.4(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + uuid: 3.4.0 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + run-async@2.4.1: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rx-lite-aggregates@4.0.8: + dependencies: + rx-lite: 4.0.8 + + rx-lite@4.0.8: {} + + rxjs@6.6.7: + dependencies: + tslib: 1.14.1 + + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safe-stable-stringify@2.5.0: {} + + safer-buffer@2.1.2: {} + + scale-ts@1.6.1: {} + + schema-utils@4.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + + scrypt-js@3.0.1: {} + + scryptsy@2.1.0: {} + + secp256k1@5.0.1: + dependencies: + elliptic: 6.6.1 + node-addon-api: 5.1.0 + node-gyp-build: 4.8.4 + + semver-diff@3.1.1: + dependencies: + semver: 6.3.1 + + semver@6.3.1: {} + + semver@7.7.1: {} + + send@1.1.0: + dependencies: + debug: 4.4.0(supports-color@8.1.1) + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime-types: 2.1.35 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + sequelize-pool@7.1.0: {} + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serve-static@2.1.0: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.1.0 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + sha.js@2.4.11: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + shallow-clone@3.0.1: + dependencies: + kind-of: 6.0.3 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shelljs@0.8.5: + dependencies: + glob: 7.2.3 + interpret: 1.4.0 + rechoir: 0.6.2 + + side-channel-list@1.0.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.0 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + simple-git@3.27.0: + dependencies: + '@kwsites/file-exists': 1.1.1 + '@kwsites/promise-deferred': 1.1.1 + debug: 4.4.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + smoldot@2.0.26(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + optional: true + + sodium-native@3.4.1: + dependencies: + node-gyp-build: 4.8.4 + optional: true + + sodium-native@4.3.3: + dependencies: + require-addon: 1.1.0 + optional: true + + sonic-boom@1.4.1: + dependencies: + atomic-sleep: 1.0.0 + flatstr: 1.0.12 + + sonic-boom@4.2.0: + dependencies: + atomic-sleep: 1.0.0 + + soroban-client@0.9.2: + dependencies: + axios: 1.12.1 + bignumber.js: 9.1.2 + buffer: 6.0.3 + detect-node: 2.1.0 + es6-promise: 4.2.8 + eventsource: 2.0.2 + lodash: 4.17.21 + randombytes: 2.1.0 + stellar-base: 10.0.0-soroban.4 + toml: 3.0.0 + urijs: 1.19.11 + transitivePeerDependencies: + - debug + + source-map-support@0.5.13: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.4: {} + + split2@4.2.0: {} + + sprintf-js@1.0.3: {} + + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + + statuses@2.0.1: {} + + stellar-base@10.0.0-soroban.4: + dependencies: + base32.js: 0.1.0 + bignumber.js: 9.1.2 + buffer: 6.0.3 + crc: 4.3.2(buffer@6.0.3) + crypto-browserify: 3.12.1 + js-xdr: 3.1.2 + sha.js: 2.4.11 + tweetnacl: 1.0.3 + optionalDependencies: + sodium-native: 4.3.3 + + stellar-base@8.2.2: + dependencies: + base32.js: 0.1.0 + bignumber.js: 4.1.0 + crc: 3.8.0 + js-xdr: 1.3.0 + lodash: 4.17.21 + sha.js: 2.4.11 + tweetnacl: 1.0.3 + optionalDependencies: + sodium-native: 3.4.1 + + stellar-sdk@10.4.1: + dependencies: + '@types/eventsource': 1.1.15 + '@types/node': 22.13.9 + '@types/randombytes': 2.0.3 + '@types/urijs': 1.19.25 + axios: 0.25.0 + bignumber.js: 4.1.0 + detect-node: 2.1.0 + es6-promise: 4.2.8 + eventsource: 1.1.2 + lodash: 4.17.21 + randombytes: 2.1.0 + stellar-base: 8.2.2 + toml: 2.3.6 + tslib: 1.14.1 + urijs: 1.19.11 + utility-types: 3.11.0 + transitivePeerDependencies: + - debug + + stream-to-it@0.2.4: + dependencies: + get-iterator: 1.0.2 + + streamsearch@1.1.0: {} + + string-format@2.0.0: {} + + string-length@4.0.2: + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + + string-width@2.1.1: + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 4.0.0 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@3.0.1: + dependencies: + ansi-regex: 2.1.1 + + strip-ansi@4.0.0: + dependencies: + ansi-regex: 3.0.1 + + strip-ansi@5.2.0: + dependencies: + ansi-regex: 4.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-bom@3.0.0: {} + + strip-bom@4.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-json-comments@2.0.1: {} + + strip-json-comments@3.1.1: {} + + strtok3@10.3.4: + dependencies: + '@tokenizer/token': 0.3.0 + + supports-color@2.0.0: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-hyperlinks@2.3.0: + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + symbol-observable@2.0.3: {} + + symbol-observable@4.0.0: {} + + table-layout@1.0.2: + dependencies: + array-back: 4.0.2 + deep-extend: 0.6.0 + typical: 5.2.0 + wordwrapjs: 4.0.1 + + tapable@2.2.1: {} + + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.1 + mkdirp: 3.0.1 + yallist: 5.0.0 + + tdigest@0.1.2: + dependencies: + bintrees: 1.0.2 + + terser-webpack-plugin@5.3.12(webpack@5.98.0): + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + jest-worker: 27.5.1 + schema-utils: 4.3.0 + serialize-javascript: 6.0.2 + terser: 5.39.0 + webpack: 5.98.0 + + terser@5.39.0: + dependencies: + '@jridgewell/source-map': 0.3.6 + acorn: 8.14.1 + commander: 2.20.3 + source-map-support: 0.5.21 + + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + thread-stream@3.1.0: + dependencies: + real-require: 0.2.0 + + through2@4.0.2: + dependencies: + readable-stream: 3.6.2 + + through@2.3.8: {} + + timeout-abort-controller@1.1.1: + dependencies: + abort-controller: 3.0.0 + retimer: 2.0.0 + + timeout-abort-controller@3.0.0: + dependencies: + retimer: 3.0.0 + + timers-ext@0.1.8: + dependencies: + es5-ext: 0.10.64 + next-tick: 1.1.0 + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + tmpl@1.0.5: {} + + to-arraybuffer@1.0.1: {} + + to-fast-properties@2.0.0: {} + + to-readable-stream@1.0.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + token-types@6.1.1: + dependencies: + '@borewit/text-codec': 0.1.1 + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + + toml@2.3.6: {} + + toml@3.0.0: {} + + toposort-class@1.0.1: {} + + tough-cookie@4.1.4: + dependencies: + psl: 1.15.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + + tr46@0.0.3: {} + + ts-command-line-args@2.5.1: + dependencies: + chalk: 4.1.2 + command-line-args: 5.2.1 + command-line-usage: 6.1.3 + string-format: 2.0.0 + + ts-essentials@7.0.3(typescript@5.9.2): + dependencies: + typescript: 5.9.2 + + ts-invariant@0.10.3: + dependencies: + tslib: 2.8.1 + + ts-jest@29.2.6(@babel/core@7.18.10)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.18.10))(jest@29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)))(typescript@5.9.2): + dependencies: + bs-logger: 0.2.6 + ejs: 3.1.10 + fast-json-stable-stringify: 2.1.0 + jest: 29.7.0(@types/node@22.13.9)(ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2)) + jest-util: 29.7.0 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.7.1 + typescript: 5.9.2 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.18.10 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.18.10) + + ts-loader@9.5.2(typescript@5.9.2)(webpack@5.98.0): + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.18.1 + micromatch: 4.0.8 + semver: 7.7.1 + source-map: 0.7.4 + typescript: 5.9.2 + webpack: 5.98.0 + + ts-node@10.9.2(@types/node@22.13.9)(typescript@5.9.2): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.13.9 + acorn: 8.14.1 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.9.2 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tsconfig-paths-webpack-plugin@4.2.0: + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.18.1 + tapable: 2.2.1 + tsconfig-paths: 4.2.0 + + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@1.14.1: {} + + tslib@2.3.1: {} + + tslib@2.8.1: {} + + tsx@4.19.4: + dependencies: + esbuild: 0.25.5 + get-tsconfig: 4.10.1 + optionalDependencies: + fsevents: 2.3.3 + + tweetnacl@1.0.3: {} + + type-detect@4.0.8: {} + + type-fest@0.20.2: {} + + type-fest@0.21.3: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + type-is@2.0.0: + dependencies: + content-type: 1.0.5 + media-typer: 1.1.0 + mime-types: 3.0.0 + + type@2.7.3: {} + + typechain@8.3.2(typescript@5.9.2): + dependencies: + '@types/prettier': 2.7.3 + debug: 4.4.0(supports-color@8.1.1) + fs-extra: 7.0.1 + glob: 7.1.7 + js-sha3: 0.8.0 + lodash: 4.17.21 + mkdirp: 1.0.4 + prettier: 2.8.8 + ts-command-line-args: 2.5.1 + ts-essentials: 7.0.3(typescript@5.9.2) + typescript: 5.9.2 + transitivePeerDependencies: + - supports-color + + typedarray-to-buffer@3.1.5: + dependencies: + is-typedarray: 1.0.0 + + typedarray@0.0.6: {} + + typescript@5.9.2: {} + + typical@4.0.0: {} + + typical@5.2.0: {} + + uglify-js@3.19.3: + optional: true + + uid@2.0.2: + dependencies: + '@lukeed/csprng': 1.1.0 + + uint8array-extras@1.5.0: {} + + uint8arrays@3.1.1: + dependencies: + multiformats: 9.9.0 + + undici-types@6.20.0: {} + + unicode-canonical-property-names-ecmascript@2.0.1: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.1 + unicode-property-aliases-ecmascript: 2.1.0 + + unicode-match-property-value-ecmascript@2.2.0: {} + + unicode-property-aliases-ecmascript@2.1.0: {} + + unique-string@2.0.0: + dependencies: + crypto-random-string: 2.0.0 + + universalify@0.1.2: {} + + universalify@0.2.0: {} + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + update-browserslist-db@1.1.3(browserslist@4.24.4): + dependencies: + browserslist: 4.24.4 + escalade: 3.2.0 + picocolors: 1.1.1 + + update-notifier@5.1.0: + dependencies: + boxen: 5.1.2 + chalk: 4.1.2 + configstore: 5.0.1 + has-yarn: 2.1.0 + import-lazy: 2.1.0 + is-ci: 2.0.0 + is-installed-globally: 0.4.0 + is-npm: 5.0.0 + is-yarn-global: 0.3.0 + latest-version: 5.1.0 + pupa: 2.1.1 + semver: 7.7.1 + semver-diff: 3.1.1 + xdg-basedir: 4.0.0 + + urijs@1.19.11: {} + + url-parse-lax@3.0.0: + dependencies: + prepend-http: 2.0.0 + + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + + utf-8-validate@5.0.10: + dependencies: + node-gyp-build: 4.8.4 + + util-deprecate@1.0.2: {} + + util@0.10.4: + dependencies: + inherits: 2.0.3 + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.1.0 + is-typed-array: 1.1.15 + which-typed-array: 1.1.18 + + utility-types@3.11.0: {} + + utils-merge@1.0.1: {} + + uuid@3.4.0: {} + + uuid@8.3.2: {} + + v8-compile-cache-lib@3.0.1: {} + + v8-to-istanbul@9.3.0: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + + validator@13.12.0: {} + + varint@6.0.0: {} + + vary@1.1.2: {} + + viem@2.23.6(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.25.32): + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.9.2)(zod@3.25.32) + isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.6.7(typescript@5.9.2)(zod@3.25.32) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.2 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + vlq@2.0.4: {} + + vm2@3.9.19: + dependencies: + acorn: 8.14.1 + acorn-walk: 8.3.4 + + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + + wasm-ast-types@0.25.0: + dependencies: + '@babel/runtime': 7.26.9 + '@babel/types': 7.18.10 + '@jest/transform': 28.1.3 + ast-stringify: 0.1.0 + case: 1.6.3 + deepmerge: 4.2.2 + transitivePeerDependencies: + - supports-color + + watchpack@2.4.2: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + web-streams-polyfill@3.3.3: {} + + webidl-conversions@3.0.1: {} + + webpack-merge@6.0.1: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + + webpack-sources@3.2.3: {} + + webpack@5.98.0: + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.6 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.14.1 + browserslist: 4.24.4 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.1 + es-module-lexer: 1.6.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.0 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.0 + tapable: 2.2.1 + terser-webpack-plugin: 5.3.12(webpack@5.98.0) + watchpack: 2.4.2 + webpack-sources: 3.2.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + websocket@1.0.35: + dependencies: + bufferutil: 4.0.9 + debug: 2.6.9 + es5-ext: 0.10.64 + typedarray-to-buffer: 3.1.5 + utf-8-validate: 5.0.10 + yaeti: 0.0.6 + transitivePeerDependencies: + - supports-color + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-typed-array@1.1.18: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.8 + call-bound: 1.0.4 + for-each: 0.3.5 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + widest-line@3.1.0: + dependencies: + string-width: 4.2.3 + + wildcard@2.0.1: {} + + wkx@0.5.0: + dependencies: + '@types/node': 22.13.9 + + wordwrap@1.0.0: {} + + wordwrapjs@4.0.1: + dependencies: + reduce-flatten: 2.0.0 + typical: 5.2.0 + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + write-file-atomic@3.0.3: + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + xdg-basedir@4.0.0: {} + + xstream@11.14.0: + dependencies: + globalthis: 1.0.4 + symbol-observable: 2.0.3 + + xtend@4.0.2: {} + + y18n@5.0.8: {} + + yaeti@0.0.6: {} + + yallist@3.1.1: {} + + yallist@5.0.0: {} + + yaml-loader@0.8.1: + dependencies: + javascript-stringify: 2.1.0 + loader-utils: 2.0.4 + yaml: 2.7.0 + + yaml@2.7.0: {} + + yargs-parser@20.2.9: {} + + yargs-parser@21.1.1: {} + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} + + yoctocolors-cjs@2.1.2: {} + + zen-observable-ts@1.2.5: + dependencies: + zen-observable: 0.8.15 + + zen-observable@0.8.15: {} + + zod@3.25.32: {} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/down.sh b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/down.sh new file mode 100755 index 00000000..6f8540c8 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/down.sh @@ -0,0 +1,78 @@ +#!/bin/bash + +# Check if directory argument is provided +if [ $# -lt 1 ]; then + echo "Error: You must provide a directory to search for Docker Compose files." + echo "Usage: $0 [optional_specific_compose_file]" + exit 1 +fi + +SEARCH_DIR="$1" + +# Validate that the search directory exists +if [ ! -d "$SEARCH_DIR" ]; then + echo "Error: Directory '$SEARCH_DIR' does not exist." + exit 1 +fi + + +# Function to shut down a specific docker-compose file +shutdown_compose() { + local file="$1" + + if [ ! -f "$file" ]; then + echo "Error: File '$file' does not exist." + return 1 + fi + + dir=$(dirname "$file") + filename=$(basename "$file") + + echo "Shutting down services from: $dir/$filename" + + docker compose -f "$dir/$filename" --env-file ../../.env.$ENV rm -fsv + + echo "Successfully shut down: $dir/$filename" +} + +# Function to shut down all docker-compose files in a directory +shutdown_all_compose() { + local dir="$1" + + echo "Searching for Docker Compose files in $dir..." + files=$(find "$dir" -type f -name "*.yml" -o -name "*.yaml") + + if [ -z "$files" ]; then + echo "No Docker Compose files found in $dir!" + return 1 + fi + + for file in $files; do + shutdown_compose "$file" + echo "----------------------------------------" + done + + echo "All Docker Compose services have been shut down!" +} + +# Main script execution +if [ $# -eq 1 ]; then + # Only directory provided, shut down all docker-compose files in that directory + shutdown_all_compose "$SEARCH_DIR" +elif [ $# -eq 2 ]; then + # Both directory and specific file provided + SPECIFIC_FILE="$2" + + # Check if the specific file is an absolute path + if [[ "$SPECIFIC_FILE" = /* ]]; then + # It's an absolute path, use it directly + shutdown_compose "$SPECIFIC_FILE" + else + # It's a relative path, combine with the search directory + shutdown_compose "$SEARCH_DIR/$SPECIFIC_FILE" + fi +else + echo "Error: Too many arguments provided." + echo "Usage: $0 [optional_specific_compose_file]" + exit 1 +fi diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/generate-chain-yamls.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/generate-chain-yamls.ts new file mode 100755 index 00000000..a95c9ec3 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/generate-chain-yamls.ts @@ -0,0 +1,318 @@ +#!/usr/bin/env node +import fs from "node:fs" +import path from "node:path" +import { fileURLToPath } from "node:url" + +import Handlebars from "handlebars" +import { RpcWebSocketClient } from "rpc-websocket-client" +import { Hex, hexToNumber } from "viem" + +import { type Configuration, getEnv, getValidChains } from "../src/configs" + +const root = process.cwd() +const currentEnv = getEnv() +const validChains = getValidChains() + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) + +// Load and compile templates +const templatesDir = path.join(__dirname, "templates") +const partialsDir = path.join(templatesDir, "partials") + +// Register partials +Handlebars.registerPartial("handlers", fs.readFileSync(path.join(partialsDir, "handlers.hbs"), "utf8")) +Handlebars.registerPartial("metadata", fs.readFileSync(path.join(partialsDir, "metadata.hbs"), "utf8")) +Handlebars.registerPartial("network-config", fs.readFileSync(path.join(partialsDir, "network-config.hbs"), "utf8")) + +// Compile templates +const substrateTemplate = Handlebars.compile( + fs.readFileSync(path.join(templatesDir, "substrate-chain.yaml.hbs"), "utf8"), +) +const evmTemplate = Handlebars.compile(fs.readFileSync(path.join(templatesDir, "evm-chain.yaml.hbs"), "utf8")) +const multichainTemplate = Handlebars.compile(fs.readFileSync(path.join(templatesDir, "multichain.yaml.hbs"), "utf8")) + +const EVM_TRACKED = [ + // Envrionment Variable Tracked + "COIN_GECKGO_API_KEY", +] as const + +const getChainTypesPath = (chain: string) => { + // Extract base chain name before the hyphen + const baseChainName = chain.split("-")[0] + const potentialPath = `./dist/substrate-chaintypes/${baseChainName}.js` + + // Check if file exists + if (fs.existsSync(potentialPath)) { + return potentialPath + } + return null +} + +const generateEndpoints = (chain: string) => { + const envKey = chain.replace(/-/g, "_").toUpperCase() + // Expect comma-separated endpoints in env var + return process.env[envKey]?.split(",") || [] +} + +// Generate chain-specific YAML files +const generateSubstrateYaml = async (chain: string, config: Configuration) => { + const chainTypesConfig = getChainTypesPath(chain) + const endpoints = generateEndpoints(chain) + + // Expect comma-separated endpoints in env var + const rpcUrl = process.env[chain.replace(/-/g, "_").toUpperCase()]?.split(",")[0] + const rpc = new RpcWebSocketClient() + await rpc.connect(rpcUrl as string) + const header = (await rpc.call("chain_getHeader", [])) as { number: Hex } + const blockNumber = + currentEnv === "local" || currentEnv === "nexus-ci" ? hexToNumber(header.number) : config.startBlock + + // Check if this is a Hyperbridge chain (stateMachineId is KUSAMA-4009 or POLKADOT-3367) + const isHyperbridgeChain = ["KUSAMA-4009", "POLKADOT-3367"].includes(config.stateMachineId) + + // Check if price indexing should be enabled (Hyperbridge chain but not testnet) + const enablePriceIndexing = isHyperbridgeChain && currentEnv !== "testnet" + + const templateData = { + name: `${chain}-chain`, + description: `${chain.charAt(0).toUpperCase() + chain.slice(1)} Chain Indexer`, + runner: { + node: { + name: "@subql/node", + version: ">=4.0.0", + }, + }, + config, + endpoints, + chainTypesConfig, + blockNumber, + isHyperbridgeChain, + enablePriceIndexing, + handlerKind: "substrate/EventHandler", + handlers: [ + { handler: "handleIsmpStateMachineUpdatedEvent", module: "ismp", method: "StateMachineUpdated" }, + { handler: "handleSubstrateRequestEvent", module: "ismp", method: "Request" }, + { handler: "handleSubstrateResponseEvent", module: "ismp", method: "Response" }, + { handler: "handleSubstratePostRequestHandledEvent", module: "ismp", method: "PostRequestHandled" }, + { handler: "handleSubstratePostResponseHandledEvent", module: "ismp", method: "PostResponseHandled" }, + { + handler: "handleSubstratePostRequestTimeoutHandledEvent", + module: "ismp", + method: "PostRequestTimeoutHandled", + }, + { handler: "handleSubstrateGetRequestHandledEvent", module: "ismp", method: "GetRequestHandled" }, + { + handler: "handleSubstrateGetRequestTimeoutHandledEvent", + module: "ismp", + method: "GetRequestTimeoutHandled", + }, + { + handler: "handleSubstratePostResponseTimeoutHandledEvent", + module: "ismp", + method: "PostResponseTimeoutHandled", + }, + ], + } + + return substrateTemplate(templateData) +} + +const generateEvmYaml = async (chain: string, config: Configuration) => { + const endpoints = generateEndpoints(chain) + + // Expect comma-separated endpoints in env var + const rpcUrl = process.env[chain.replace(/-/g, "_").toUpperCase()]?.split(",")[0] + const response = await fetch(rpcUrl as string, { + method: "POST", + headers: { + accept: "application/json", + "content-type": "application/json", + }, + body: JSON.stringify({ + id: 1, + jsonrpc: "2.0", + method: "eth_blockNumber", + }), + }) + const data = await response.json() + const blockNumber = currentEnv === "local" ? hexToNumber(data.result) : config.startBlock + + const templateData = { + name: chain, + description: `${chain.charAt(0).toUpperCase() + chain.slice(1)} Indexer`, + runner: { + node: { + name: "@subql/node-ethereum", + version: ">=3.0.0", + }, + }, + config, + endpoints, + blockNumber, + handlerKind: "ethereum/LogHandler", + handlers: [ + { handler: "handleStateMachineUpdatedEvent", topics: ["StateMachineUpdated(string,uint256)"] }, + { + handler: "handlePostRequestEvent", + topics: ["PostRequestEvent(string,string,address,bytes,uint256,uint256,bytes,uint256)"], + }, + { + handler: "handlePostResponseEvent", + topics: ["PostResponseEvent(string,string,address,bytes,uint256,uint256,bytes,bytes,uint256,uint256)"], + }, + { handler: "handlePostRequestHandledEvent", topics: ["PostRequestHandled(bytes32,address)"] }, + { handler: "handlePostResponseHandledEvent", topics: ["PostResponseHandled(bytes32,address)"] }, + { handler: "handlePostRequestTimeoutHandledEvent", topics: ["PostRequestTimeoutHandled(bytes32,string)"] }, + { + handler: "handlePostResponseTimeoutHandledEvent", + topics: ["PostResponseTimeoutHandled(bytes32,string)"], + }, + { + handler: "handleGetRequestEvent", + topics: ["GetRequestEvent(string,string,address,bytes[],uint256,uint256,uint256,bytes,uint256)"], + }, + { handler: "handleGetRequestHandledEvent", topics: ["GetRequestHandled(bytes32,address)"] }, + { handler: "handleGetRequestTimeoutHandledEvent", topics: ["GetRequestTimeoutHandled(bytes32,string)"] }, + ], + } + + return evmTemplate(templateData) +} + +async function generateAllChainYamls() { + for (const [chain, config] of validChains) { + const yaml = + config.type === "substrate" + ? await generateSubstrateYaml(chain, config) + : await generateEvmYaml(chain, config) + + fs.writeFileSync(root + `/src/configs/${chain}.yaml`, yaml) + console.log(`Generated ${root}/src/configs/${chain}.yaml`) + } +} + +const generateMultichainYaml = () => { + const projects = Array.from(validChains.keys()).map((chain) => `./${chain}.yaml`) + + const templateData = { + projects, + } + + const yaml = multichainTemplate(templateData) + fs.writeFileSync(root + "/src/configs/subquery-multichain.yaml", yaml) + console.log("Generated subquery-multichain.yaml") +} + +const generateChainIdsByGenesis = () => { + const chainIdsByGenesis = {} + + validChains.forEach((config) => { + if (config.chainId) { + chainIdsByGenesis[config.chainId] = config.stateMachineId + } + }) + + const chainIdsByGenesisContent = `// Auto-generated, DO NOT EDIT \nexport const CHAIN_IDS_BY_GENESIS = ${JSON.stringify(chainIdsByGenesis, null, 2)}` + + fs.writeFileSync(root + "/src/chain-ids-by-genesis.ts", chainIdsByGenesisContent) + console.log("Generated chain-ids-by-genesis.ts") +} + +const generateChainsByIsmpHost = () => { + const chainsByIsmpHost = {} + + validChains.forEach((config) => { + // Only include EVM chains with ethereumHost contract + if (config.type === "evm" && config.contracts?.ethereumHost) { + chainsByIsmpHost[config.stateMachineId] = config.contracts.ethereumHost + } + }) + + const chainsByIsmpHostContent = `// Auto-generated, DO NOT EDIT \nexport const CHAINS_BY_ISMP_HOST = ${JSON.stringify(chainsByIsmpHost, null, 2)}` + + fs.writeFileSync(root + "/src/chains-by-ismp-host.ts", chainsByIsmpHostContent) + console.log("Generated chains-by-ismp-host.ts") +} + +const generateChainsTokenGatewayAddresses = () => { + const tokenGateway = {} + + validChains.forEach((config) => { + // Only include EVM chains with ethereumHost contract + if (config.type === "evm" && config.contracts?.tokenGateway) { + tokenGateway[config.stateMachineId] = config.contracts.tokenGateway + } + }) + + const value = `// Auto-generated, DO NOT EDIT \nexport const TOKEN_GATEWAY_ADDRESSES = ${JSON.stringify(tokenGateway, null, 2)}` + + fs.writeFileSync(root + "/src/token-gateway-addresses.ts", value) + console.log("Generated token-gateway-addresses.ts") +} + +const generateChainsIntentGatewayAddresses = () => { + const intentGateway = {} + + validChains.forEach((config) => { + // Only include EVM chains with ethereumHost contract + if (config.type === "evm" && config.contracts?.intentGateway) { + intentGateway[config.stateMachineId] = config.contracts.intentGateway + } + }) + + const value = `// Auto-generated, DO NOT EDIT \nexport const INTENT_GATEWAY_ADDRESSES = ${JSON.stringify(intentGateway, null, 2)}` + + fs.writeFileSync(root + "/src/intent-gateway-addresses.ts", value) + console.log("Generated intent-gateway-addresses.ts") +} + +const generateTestnetStateMachineIds = () => { + const testnetStateMachineIds = new Set() + + // Only generate testnet state machine IDs when in testnet environment + if (currentEnv === "testnet") { + validChains.forEach((config) => { + testnetStateMachineIds.add(config.stateMachineId) + }) + } + + const value = `// Auto-generated, DO NOT EDIT \nexport const TESTNET_STATE_MACHINE_IDS: string[] = ${JSON.stringify(Array.from(testnetStateMachineIds), null, 2)}` + + fs.writeFileSync(root + "/src/testnet-state-machine-ids.ts", value) + console.log("Generated testnet-state-machine-ids.ts") +} + +const generateEnvironmentConfig = () => { + const configurations = {} + + // Set evm and substrate environment configurations + validChains.forEach((config, chain) => { + const envKey = chain.replace(/-/g, "_").toUpperCase() + const endpoints = process.env[envKey]?.split(",") || [] + + if (endpoints.length > 0) { + configurations[config.stateMachineId] = endpoints[0].trim() + } + }) + + EVM_TRACKED.forEach((e: string) => (configurations[e] = process.env?.[e] ?? null)) + + fs.writeFileSync(root + "/src/env-config.json", JSON.stringify(configurations, null, 2)) + console.log("Generated env-config.json") +} + +try { + await generateAllChainYamls() + generateMultichainYaml() + generateChainIdsByGenesis() + generateChainsByIsmpHost() + generateChainsIntentGatewayAddresses() + generateChainsTokenGatewayAddresses() + generateTestnetStateMachineIds() + generateEnvironmentConfig() + process.exit(0) +} catch (err) { + console.error("Error generating YAMLs:", err) + process.exit(1) +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/generate-compose.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/generate-compose.ts new file mode 100755 index 00000000..7589eaca --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/generate-compose.ts @@ -0,0 +1,63 @@ +#!/usr/bin/env node +import fs from "node:fs" +import path from "node:path" +import { fileURLToPath } from "node:url" + +import Handlebars from "handlebars" +import { getEnv, getValidChains } from "../src/configs" + +const EVM_IMAGE = "subquerynetwork/subql-node-ethereum:v5.5.0" +const SUBSTRATE_IMAGE = "subquerynetwork/subql-node-substrate:v5.9.1" + +// Setup paths +const root = process.cwd() +const currentEnv = getEnv() +const validChains = getValidChains() + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) + +// Load and compile templates +const templatesDir = path.join(__dirname, "templates") +const partialsDir = path.join(templatesDir, "partials") + +// Register partials +Handlebars.registerPartial("docker-command", fs.readFileSync(path.join(partialsDir, "docker-command.hbs"), "utf8")) +Handlebars.registerPartial("docker-service", fs.readFileSync(path.join(partialsDir, "docker-service.hbs"), "utf8")) + +// Compile templates +const serviceTemplate = Handlebars.compile( + fs.readFileSync(path.join(templatesDir, "docker-compose-service.yaml.hbs"), "utf8"), +) + +const generateNodeServices = () => { + const dockerDir = path.join(root, "docker", currentEnv) + if (!fs.existsSync(dockerDir)) { + fs.mkdirSync(dockerDir, { recursive: true }) + } + + validChains.forEach((config, chainName) => { + const hasBlockConfirmations = config.blockConfirmations !== undefined + const serviceData = { + chainName, + image: config.type === "substrate" ? SUBSTRATE_IMAGE : EVM_IMAGE, + unfinalizedBlocks: config.type === "evm" && !hasBlockConfirmations, // Only EVM chains need unfinalized blocks handling, except chains with custom block confirmations + blockConfirmations: config.blockConfirmations, // Pass block confirmations from config + config, + volumesPath: "../../", + } + + const yaml = serviceTemplate(serviceData) + + const filePath = path.join(dockerDir, `${chainName}.yml`) + + if (!fs.existsSync(filePath)) { + fs.writeFileSync(filePath, yaml) + console.log(`Generated ${filePath}`) + } else { + console.log(`Skipping ${filePath} - File already exists`) + } + }) +} + +generateNodeServices() diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/generate-l2-chains.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/generate-l2-chains.ts new file mode 100644 index 00000000..e07ce7b5 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/generate-l2-chains.ts @@ -0,0 +1,49 @@ +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import { OPTIMISM, BASE } from '../src/constants'; + +interface OpStackChain { + name: string; + chainId: number; + identifier: string; + superchainLevel: number; +} + +function generateL2ChainsFile() { + console.log('Generating OP Stack L2 chains from local file...'); + + try { + const __dirname = path.dirname(fileURLToPath(import.meta.url)); + + const jsonPath = path.resolve(__dirname, '../src/configs/opstack-chains.json'); + const outputPath = path.resolve(__dirname, '../src/utils/l2-state-machine.helper.ts'); + + const chainList: OpStackChain[] = JSON.parse(fs.readFileSync(jsonPath, 'utf-8')); + + const hardcodedL2s = [OPTIMISM.mainnet, BASE.mainnet]; + + const fetchedL2s = chainList + .filter(chain => chain.identifier.startsWith('mainnet/')) + .map(chain => `EVM-${chain.chainId}`); + + const combinedL2s = [...hardcodedL2s, ...fetchedL2s]; + const uniqueL2s = [...new Set(combinedL2s)]; + + const fileContent = ` +// THIS FILE IS AUTO-GENERATED BY 'scripts/generate-l2-chains.ts'. DO NOT EDIT. + +export const GET_ETHEREUM_L2_STATE_MACHINES = (): string[] => { + return ${JSON.stringify(uniqueL2s.sort(), null, 8)}; +}; + `; + + fs.writeFileSync(outputPath, fileContent.trim()); + console.log(`Successfully generated ${uniqueL2s.length} unique L2 chains to ${outputPath}`); + } catch (error) { + console.error('Error generating L2 chains file:', error); + process.exit(1); + } +} + +generateL2ChainsFile(); \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/docker-compose-service.yaml.hbs b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/docker-compose-service.yaml.hbs new file mode 100644 index 00000000..69249c4a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/docker-compose-service.yaml.hbs @@ -0,0 +1,2 @@ +services: + {{> docker-service}} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/evm-chain.yaml.hbs b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/evm-chain.yaml.hbs new file mode 100644 index 00000000..e4cfb858 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/evm-chain.yaml.hbs @@ -0,0 +1,116 @@ +{{> metadata}} +{{> network-config}} +dataSources: + - kind: ethereum/Runtime + startBlock: {{blockNumber}} + options: + abi: ethereumHost + address: '{{config.contracts.ethereumHost}}' + assets: + ethereumHost: + file: ./abis/EthereumHost.abi.json + chainLinkAggregatorV3: + file: ./abis/ChainLinkAggregatorV3.abi.json + mapping: + file: ./dist/index.js + handlers: + {{> handlers}} + - kind: ethereum/Runtime + startBlock: {{blockNumber}} + options: + abi: erc6160ext20 + address: '{{config.contracts.erc6160ext20}}' + assets: + erc6160ext20: + file: ./abis/ERC6160Ext20.abi.json + mapping: + file: ./dist/index.js + handlers: + - handler: handleTransferEvent + kind: ethereum/LogHandler + filter: + topics: + - 'Transfer(address indexed from, address indexed to, uint256 amount)' + {{#if config.contracts.intentGateway}} + - kind: ethereum/Runtime + startBlock: {{blockNumber}} + options: + abi: intentGateway + address: '{{config.contracts.intentGateway}}' + assets: + intentGateway: + file: ./abis/IntentGateway.abi.json + mapping: + file: ./dist/index.js + handlers: + - kind: ethereum/LogHandler + handler: handleOrderPlacedEvent + filter: + topics: + - 'OrderPlaced(bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes)' + - kind: ethereum/LogHandler + handler: handleOrderFilledEvent + filter: + topics: + - 'OrderFilled(bytes32,address)' + - kind: ethereum/LogHandler + handler: handleEscrowReleasedEvent + filter: + topics: + - 'EscrowReleased(bytes32)' + - kind: ethereum/LogHandler + handler: handleEscrowRefundedEvent + filter: + topics: + - 'EscrowRefunded(bytes32)' + {{/if}} + {{#if config.contracts.tokenGateway}} + - kind: ethereum/Runtime + startBlock: {{blockNumber}} + options: + abi: tokenGateway + address: '{{config.contracts.tokenGateway}}' + assets: + tokenGateway: + file: ./abis/TokenGateway.abi.json + mapping: + file: ./dist/index.js + handlers: + - kind: ethereum/LogHandler + handler: handleAssetTeleportedEvent + filter: + topics: + - 'AssetTeleported(bytes32,string,uint256,bytes32,address,bytes32,bool)' + - kind: ethereum/LogHandler + handler: handleAssetReceivedEvent + filter: + topics: + - 'AssetReceived(uint256,bytes32,bytes32,address,bytes32)' + - kind: ethereum/LogHandler + handler: handleAssetRefundedEvent + filter: + topics: + - 'AssetRefunded(uint256,bytes32,address,bytes32)' + {{/if}} + # - kind: ethereum/Runtime + # startBlock: {{blockNumber}} + # options: + # abi: handlerV1 + # address: '{{config.contracts.handlerV1}}' + # assets: + # handlerV1: + # file: ./abis/HandlerV1.abi.json + # mapping: + # file: ./dist/index.js + # handlers: + # - handler: handlePostRequestTransactionHandler + # kind: ethereum/TransactionHandler + # function: >- + # handlePostRequests(address,(((uint256,uint256),bytes32[],uint256),((bytes,bytes,uint64,bytes,bytes,uint64,bytes),uint256,uint256)[])) + # - handler: handlePostResponseTransactionHandler + # kind: ethereum/TransactionHandler + # function: >- + # handlePostResponses(address,(((uint256,uint256),bytes32[],uint256),(((bytes,bytes,uint64,bytes,bytes,uint64,bytes),bytes,uint64),uint256,uint256)[])) + + +repository: 'https://github.com/polytope-labs/hyperbridge' diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/multichain.yaml.hbs b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/multichain.yaml.hbs new file mode 100644 index 00000000..48b4c9af --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/multichain.yaml.hbs @@ -0,0 +1,8 @@ +specVersion: 1.0.0 +query: + name: '@subql/query' + version: '*' +projects: +{{#each projects}} + - {{this}} +{{/each}} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/docker-command.hbs b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/docker-command.hbs new file mode 100644 index 00000000..4a20a13a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/docker-command.hbs @@ -0,0 +1,17 @@ +- ${SUB_COMMAND:-} +- -f=/app/{{chainName}}.yaml +- --db-schema=app +- --workers=${SUBQL_WORKERS:-16} +- --batch-size=${SUBQL_BATCH_SIZE:-100} +- --multi-chain +- --unsafe +- --log-level=info +{{#if unfinalizedBlocks}} +- --historical=timestamp +- --block-confirmations=0 +- --unfinalized-blocks +{{/if}} +{{#if blockConfirmations}} +- --block-confirmations={{blockConfirmations}} +{{/if}} +- --store-cache-async=true diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/docker-service.hbs b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/docker-service.hbs new file mode 100644 index 00000000..e5905d81 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/docker-service.hbs @@ -0,0 +1,19 @@ +subquery-{{chainName}}: + image: {{image}} + restart: unless-stopped + environment: + DB_USER: ${DB_USER} + DB_PASS: ${DB_PASS} + DB_DATABASE: ${DB_DATABASE} + DB_HOST: ${DB_HOST} + DB_PORT: ${DB_PORT} + volumes: + - {{volumesPath}}src/configs:/app + - {{volumesPath}}dist:/app/dist + command: + {{> docker-command}} + healthcheck: + test: ['CMD', 'curl', '-f', 'http://subquery-node-{{chainName}}:3000/ready'] + interval: 3s + timeout: 5s + retries: 10 diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/handlers.hbs b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/handlers.hbs new file mode 100644 index 00000000..3f477c37 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/handlers.hbs @@ -0,0 +1,14 @@ +{{#each handlers}} + - handler: {{this.handler}} + kind: {{../handlerKind}} + filter: + {{#if this.module}} + module: '{{this.module}}' + method: '{{this.method}}' + {{else}} + topics: + {{#each this.topics}} + - '{{this}}' + {{/each}} + {{/if}} +{{/each}} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/metadata.hbs b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/metadata.hbs new file mode 100644 index 00000000..36f57e37 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/metadata.hbs @@ -0,0 +1,14 @@ +# // Auto-generated , DO NOT EDIT +specVersion: 1.0.0 +version: 0.0.1 +name: {{name}} +description: {{description}} +runner: + node: + name: '{{{runner.node.name}}}' + version: '{{{runner.node.version}}}' + query: + name: '@subql/query' + version: '*' +schema: + file: ./schema.graphql diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/network-config.hbs b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/network-config.hbs new file mode 100644 index 00000000..2d1d2b33 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/partials/network-config.hbs @@ -0,0 +1,6 @@ +network: + chainId: '{{config.chainId}}' + endpoint: +{{#each endpoints}} + - '{{{this}}}' +{{/each}} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/substrate-chain.yaml.hbs b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/substrate-chain.yaml.hbs new file mode 100644 index 00000000..17f591a0 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/templates/substrate-chain.yaml.hbs @@ -0,0 +1,52 @@ +{{> metadata}} +{{> network-config}} +{{#if chainTypesConfig}} + chaintypes: + file: {{chainTypesConfig}} +{{/if}} +dataSources: + - kind: substrate/Runtime + startBlock: {{blockNumber}} + mapping: + file: ./dist/index.js + handlers: + {{> handlers}} +{{#if isHyperbridgeChain}} + - handler: handleRelayerRewardedEvent + kind: substrate/EventHandler + filter: + module: consensusIncentives + method: RelayerRewarded + - handler: handleFeeRewardedEvent + kind: substrate/EventHandler + filter: + module: messagingFees + method: FeeRewarded + - handler: handleTreasuryTransferEvent + kind: substrate/EventHandler + filter: + module: balances + method: Transfer + - handler: handleAccumulateFeesEvent + kind: substrate/EventHandler + filter: + module: relayer + method: AccumulateFees + - handler: handleSubstrateAssetTeleportedEvent + kind: substrate/EventHandler + filter: + module: xcmGateway + method: AssetTeleported + - handler: handleBridgeTokenSupplyIndexing + kind: substrate/BlockHandler + filter: + modulo: 3600 # Indexings 1 block every 6 hours (6 seconds per block indexing). +{{/if}} +{{#if enablePriceIndexing}} + - handler: handlePriceIndexing + kind: substrate/BlockHandler + filter: + modulo: 10 # Indexings 1 block every minute (6 seconds per block indexing). +{{/if}} + +repository: 'https://github.com/polytope-labs/hyperbridge' diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/up.sh b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/up.sh new file mode 100755 index 00000000..8e49cefa --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/scripts/up.sh @@ -0,0 +1,30 @@ + +#!/bin/bash + +# Default directory is current directory if none provided +SEARCH_DIR="${1:-.}" + +# Find all potential docker-compose files +echo "Searching for Docker Compose files in $SEARCH_DIR..." +files=$(find "$SEARCH_DIR" -type f -name "*.yml" -o -name "*.yaml") + +if [ -z "$files" ]; then + echo "No Docker Compose files found!" + exit 1 +fi + +# Process each file +for file in $files; do + dir=$(dirname "$file") + filename=$(basename "$file") + + echo "----------------------------------------" + echo "Starting Docker Compose from: $file" + + docker compose -f "$dir/$filename" --env-file ../../.env.$ENV up -d --force-recreate + + echo "Successfully started: $dir/$filename" +done + +echo "----------------------------------------" +echo "All Docker Compose files have been started!" diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/addresses/chainlink-price-feeds.addresses.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/addresses/chainlink-price-feeds.addresses.ts new file mode 100644 index 00000000..32f5d921 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/addresses/chainlink-price-feeds.addresses.ts @@ -0,0 +1,19 @@ +export const CHAINLINK_PRICE_FEED_CONTRACT_ADDRESSES: { + [key: string]: string +} = { + "EVM-11155111": "0x694AA1769357215DE4FAC081bf1f309aDC325306", // Ethereum Sepolia + "EVM-84532": "0x4aDC67696bA383F43DD60A9e78F2C97Fbbfc7cb1", // Base Sepolia + "EVM-11155420": "0x61Ec26aA57019C486B10502285c5A3D4A4750AD7", // Optimism Sepolia + "EVM-421614": "0xd30e2101a97dcbAeBCBC04F14C3f624E67A35165", // Arbitrum Sepolia + "EVM-97": "0x2514895c72f50D8bd4B4F9b1110F0D6bD2c97526", // BSC Chapel + + "EVM-1": "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419", // Ethereum Mainnet + "EVM-8453": "0x71041dddad3595F9CEd3DcCFBe3D1F4b0a16Bb70", // Base Mainnet + "EVM-10": "0x13e3Ee699D1909E989722E753853AE30b17e08c5", // Optimism Mainnet + "EVM-42161": "0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612", // Arbitrum Mainnet + "EVM-56": "0x0567F2323251f0Aab15c8dFb1967E4e8A7D42aeE", // BSC Mainnet + "EVM-1868": "0x291cF980BA12505D65ee01BDe0882F1d5e533525", //Soneium Mainnet + "EVM-100": "0xa767f745331D267c7751297D982b050c93985627", //Gnosis Mainnet + "EVM-130": "0xd9c93081210dFc33326B2af4C2c11848095E6a9a", //Unichain Mainnet + "EVM-137": "0xAB594600376Ec9fD91F8e885dADF0CE036862dE0", //Polygon Mainnet +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/addresses/token-registry.addresses.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/addresses/token-registry.addresses.ts new file mode 100644 index 00000000..55984ccf --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/addresses/token-registry.addresses.ts @@ -0,0 +1,108 @@ +const DEFAULT_TOKEN_UPDATE_FREQUENCY = 600 as const // 10 minutes + +/** + * Token configuration interface. + */ +export interface TokenConfig { + name: string + symbol: string + address?: string // Optional - zero address for native tokens + updateFrequencySeconds: number +} + +export const TOKEN_REGISTRY: TokenConfig[] = [ + // Native/Gas tokens + { + name: "ETH", + symbol: "ETH", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + { + name: "Polkadot", + symbol: "DOT", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + { + name: "Gnosis xDAI", + symbol: "XDAI", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + + // Major stablecoins + { + name: "USD coin", + symbol: "USDC", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + { + name: "Tether USD", + symbol: "USDT", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + { + name: "Maker DAI", + symbol: "DAI", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + // { + // name: "USDH", + // symbol: "USDH", + // updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + // }, + + // Substrate tokens + { + name: "Bifrost", + symbol: "BNC", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + { + name: "Cere Network", + symbol: "CERE", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + + // Parachain tokens + { + name: "Moonbeam", + symbol: "GLMR", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + { + name: "Astar", + symbol: "ASTR", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + + // Voucher/Liquid staking tokens + { + name: "Voucher DOT", + symbol: "vDOT", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + { + name: "Voucher BNC", + symbol: "vBNC", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + { + name: "Bifrost Voucher ASTR", + symbol: "vASTR", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + { + name: "Voucher GLMR", + symbol: "vGLMR", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + { + name: "BNB", + symbol: "BNB", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, + { + name: "Polygon", + symbol: "POL", + updateFrequencySeconds: DEFAULT_TOKEN_UPDATE_FREQUENCY, + }, +] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/addresses/uniswap.addresses.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/addresses/uniswap.addresses.ts new file mode 100644 index 00000000..cc19c603 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/addresses/uniswap.addresses.ts @@ -0,0 +1,115 @@ +export interface UniswapAddresses { + V2_FACTORY: string + V2_ROUTER: string + V3_FACTORY: string + V3_QUOTER: string + V4_QUOTER: string + WETH: string + USDC: string + USDT: string + DAI: string +} + +export const UNISWAP_ADDRESSES: { + [key: string]: UniswapAddresses +} = { + "EVM-97": { + V2_FACTORY: "0x12e036669DA18F4A2777853d6e2136b32AceEC86", + V2_ROUTER: "0x9639379819420704457B07A0C33B678D9E0F8Df0", + V3_FACTORY: "0x0000000000000000000000000000000000000000", + V3_QUOTER: "0x0000000000000000000000000000000000000000", + V4_QUOTER: "0x0000000000000000000000000000000000000000", + WETH: "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd", + USDC: "0xC625ec7D30A4b1AAEfb1304610CdAcD0d606aC92", + USDT: "0xc043f483373072f7f27420d6e7d7ad269c018e18", + DAI: "0x1938165569A5463327fb206bE06d8D9253aa06b7", + }, + "EVM-8453": { + V2_FACTORY: "0x8909Dc15e40173Ff4699343b6eB8132c65e18eC6", + V2_ROUTER: "0x4752ba5dbc23f44d87826276bf6fd6b1c372ad24", + V3_FACTORY: "0x33128a8fC17869897dcE68Ed026d694621f6FDfD", + V3_QUOTER: "0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a", + V4_QUOTER: "0x0d5e0F971ED27FBfF6c2837bf31316121532048D", + WETH: "0x4200000000000000000000000000000000000006", + USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + USDT: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2", + DAI: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb", + }, + "EVM-137": { + V2_FACTORY: "0x9e5A52f57b3038F1B8EeE45F28b3C1967e22799C", + V2_ROUTER: "0xedf6066a2b290C185783862C7F4776A2C8077AD1", + V3_FACTORY: "0x1F98431c8aD98523631AE4a59f267346ea31F984", + V3_QUOTER: "0x61fFE014bA17989E743c5F6cB21bF9697530B21e", + V4_QUOTER: "0xb3d5c3Dfc3a7aEbFF71895A7191796BFFc2c81b9", + WETH: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619", + USDC: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", + USDT: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", + DAI: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063", + }, + "EVM-56": { + V2_FACTORY: "0x8909Dc15e40173Ff4699343b6eB8132c65e18eC6", + V2_ROUTER: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24", + V3_FACTORY: "0xdB1d10011AD0Ff90774D0C6Bb92e5C5c8b4461F7", + V3_QUOTER: "0x78D78E420Da98ad378D7799bE8f4AF69033EB077", + V4_QUOTER: "0x9F75dD27D6664c475B90e105573E550ff69437B0", + WETH: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", + USDT: "0x55d398326f99059fF775485246999027B3197955", + DAI: "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3", + }, + "EVM-10": { + V2_FACTORY: "0x0c3c1c532F1e39EdF36BE9Fe0bE1410313E074Bf", + V2_ROUTER: "0x4A7b5Da61326A6379179b40d00F57E5bbDC962c2", + V3_FACTORY: "0x1F98431c8aD98523631AE4a59f267346ea31F984", + V3_QUOTER: "0x61fFE014bA17989E743c5F6cB21bF9697530B21e", + V4_QUOTER: "0x1f3131a13296fb91c90870043742c3cdbff1a8d7", + WETH: "0x4200000000000000000000000000000000000006", + USDC: "0x7F5c764cBc14f9669B88837ca1490cCa17c31607", + USDT: "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58", + DAI: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", + }, + "EVM-1": { + V2_FACTORY: "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f", + V2_ROUTER: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", + V3_FACTORY: "0x1F98431c8aD98523631AE4a59f267346ea31F984", + V3_QUOTER: "0x61fFE014bA17989E743c5F6cB21bF9697530B21e", + V4_QUOTER: "0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203", + WETH: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + USDC: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + USDT: "0xdAC17F958D2ee523a2206206994597C13D831ec7", + DAI: "0x6B175474E89094C44Da98b954EedeAC495271d0F", + }, + "EVM-42161": { + V2_FACTORY: "0xf1D7CC64Fb4452F05c498126312eBE29f30Fbcf9", + V2_ROUTER: "0x4752ba5dbc23f44d87826276bf6fd6b1c372ad24", + V3_FACTORY: "0x1F98431c8aD98523631AE4a59f267346ea31F984", + V3_QUOTER: "0x61fFE014bA17989E743c5F6cB21bF9697530B21e", + V4_QUOTER: "0x7de51022d70a725b508085468052e25e22b5c4c9", + WETH: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + USDC: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", + USDT: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", + DAI: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", + }, + "EVM-100": { + V2_FACTORY: "0x8c8b524ce7c9D2e3f59aB6711bE4Ac826FA46a0f", + V2_ROUTER: "0x0000000000000000000000000000000000000000", + V3_FACTORY: "0xe32F7dD7e3f098D518ff19A22d5f028e076489B1", + V3_QUOTER: "0x7E9cB3499A6cee3baBe5c8a3D328EA7FD36578f4", + V4_QUOTER: "0x0000000000000000000000000000000000000000", + WETH: "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", + USDC: "0xDDAfbb505ad214D7b80b1f830fcCc89B60fb7A83", + USDT: "0x4ecaba5870353805a9f068101a40e0f32ed605c6", + DAI: "0x0000000000000000000000000000000000000000", + }, + "EVM-1868": { + V2_FACTORY: "0x97febbc2adbd5644ba22736e962564b23f5828ce", + V2_ROUTER: "0x273f68c234fa55b550b40e563c4a488e0d334320", + V3_FACTORY: "0x42ae7ec7ff020412639d443e245d936429fbe717", + V3_QUOTER: "0x3e6c707d0125226ff60f291b6bd1404634f00aba", + V4_QUOTER: "0x0000000000000000000000000000000000000000", + WETH: "0x4200000000000000000000000000000000000006", + USDC: "0xbA9986D2381edf1DA03B0B9c1f8b00dc4AacC369", + USDT: "0x3A337a6adA9d885b6Ad95ec48F9b75f197b5AE35", + DAI: "0x0000000000000000000000000000000000000000", // Not found + }, +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/ChainLinkAggregatorV3.abi.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/ChainLinkAggregatorV3.abi.json new file mode 100644 index 00000000..6657e31e --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/ChainLinkAggregatorV3.abi.json @@ -0,0 +1,49 @@ +[ + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "description", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint80", "name": "_roundId", "type": "uint80" }], + "name": "getRoundData", + "outputs": [ + { "internalType": "uint80", "name": "roundId", "type": "uint80" }, + { "internalType": "int256", "name": "answer", "type": "int256" }, + { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, + { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "latestRoundData", + "outputs": [ + { "internalType": "uint80", "name": "roundId", "type": "uint80" }, + { "internalType": "int256", "name": "answer", "type": "int256" }, + { "internalType": "uint256", "name": "startedAt", "type": "uint256" }, + { "internalType": "uint256", "name": "updatedAt", "type": "uint256" }, + { "internalType": "uint80", "name": "answeredInRound", "type": "uint80" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + } +] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/ERC6160Ext20.abi.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/ERC6160Ext20.abi.json new file mode 100644 index 00000000..378aa9b7 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/ERC6160Ext20.abi.json @@ -0,0 +1,255 @@ +[ + { + "inputs": [ + { "internalType": "address", "name": "admin", "type": "address" }, + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "string", "name": "symbol", "type": "string" } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "name": "NotRoleAdmin", "type": "error" }, + { "inputs": [], "name": "PermissionDenied", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "BURNER_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MINTER_ROLE", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "allowance", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "approve", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "account", "type": "address" }], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_from", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "address", "name": "newAdmin", "type": "address" }], + "name": "changeAdmin", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getBurnerRole", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getMinterRole", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "_role", "type": "bytes32" }, + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "_role", "type": "bytes32" }, + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "hasRole", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "addedValue", "type": "uint256" } + ], + "name": "increaseAllowance", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_to", "type": "address" }, + { "internalType": "uint256", "name": "_amount", "type": "uint256" } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "_role", "type": "bytes32" }, + { "internalType": "address", "name": "_account", "type": "address" } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [{ "internalType": "bytes4", "name": "_interfaceId", "type": "bytes4" }], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/EthereumHost.abi.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/EthereumHost.abi.json new file mode 100644 index 00000000..3b6a8a75 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/EthereumHost.abi.json @@ -0,0 +1,1746 @@ +[ + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "defaultTimeout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "defaultPerByteFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stateCommitmentFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "handler", + "type": "address" + }, + { + "internalType": "address", + "name": "hostManager", + "type": "address" + }, + { + "internalType": "address", + "name": "uniswapV2", + "type": "address" + }, + { + "internalType": "uint256", + "name": "unStakingPeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "challengePeriod", + "type": "uint256" + }, + { + "internalType": "address", + "name": "consensusClient", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "stateMachines", + "type": "uint256[]" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "stateIdHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "perByteFee", + "type": "uint256" + } + ], + "internalType": "struct PerByteFee[]", + "name": "perByteFees", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "hyperbridge", + "type": "bytes" + } + ], + "internalType": "struct HostParams", + "name": "params", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "CannotChangeFeeToken", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateResponse", + "type": "error" + }, + { + "inputs": [], + "name": "FrozenHost", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAddressLength", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidConsensusClient", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidHandler", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidHostManager", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidHyperbridgeId", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidStateMachinesLength", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidUnstakingPeriod", + "type": "error" + }, + { + "inputs": [], + "name": "UnauthorizedAccount", + "type": "error" + }, + { + "inputs": [], + "name": "UnauthorizedAction", + "type": "error" + }, + { + "inputs": [], + "name": "UnauthorizedResponse", + "type": "error" + }, + { + "inputs": [], + "name": "UnknownRequest", + "type": "error" + }, + { + "inputs": [], + "name": "UnknownResponse", + "type": "error" + }, + { + "inputs": [], + "name": "WithdrawalFailed", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "source", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "dest", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes[]", + "name": "keys", + "type": "bytes[]" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "height", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timeoutTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "context", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "GetRequestEvent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "GetRequestHandled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "string", + "name": "dest", + "type": "string" + } + ], + "name": "GetRequestTimeoutHandled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "enum FrozenStatus", + "name": "status", + "type": "uint8" + } + ], + "name": "HostFrozen", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "defaultTimeout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "defaultPerByteFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stateCommitmentFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "handler", + "type": "address" + }, + { + "internalType": "address", + "name": "hostManager", + "type": "address" + }, + { + "internalType": "address", + "name": "uniswapV2", + "type": "address" + }, + { + "internalType": "uint256", + "name": "unStakingPeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "challengePeriod", + "type": "uint256" + }, + { + "internalType": "address", + "name": "consensusClient", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "stateMachines", + "type": "uint256[]" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "stateIdHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "perByteFee", + "type": "uint256" + } + ], + "internalType": "struct PerByteFee[]", + "name": "perByteFees", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "hyperbridge", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct HostParams", + "name": "oldParams", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "defaultTimeout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "defaultPerByteFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stateCommitmentFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "handler", + "type": "address" + }, + { + "internalType": "address", + "name": "hostManager", + "type": "address" + }, + { + "internalType": "address", + "name": "uniswapV2", + "type": "address" + }, + { + "internalType": "uint256", + "name": "unStakingPeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "challengePeriod", + "type": "uint256" + }, + { + "internalType": "address", + "name": "consensusClient", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "stateMachines", + "type": "uint256[]" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "stateIdHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "perByteFee", + "type": "uint256" + } + ], + "internalType": "struct PerByteFee[]", + "name": "perByteFees", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "hyperbridge", + "type": "bytes" + } + ], + "indexed": false, + "internalType": "struct HostParams", + "name": "newParams", + "type": "tuple" + } + ], + "name": "HostParamsUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "native", + "type": "bool" + } + ], + "name": "HostWithdrawal", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "source", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "dest", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timeoutTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "body", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "PostRequestEvent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "PostRequestHandled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "string", + "name": "dest", + "type": "string" + } + ], + "name": "PostRequestTimeoutHandled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "source", + "type": "string" + }, + { + "indexed": false, + "internalType": "string", + "name": "dest", + "type": "string" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "timeoutTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "body", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "response", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "responseTimeoutTimestamp", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "PostResponseEvent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newFee", + "type": "uint256" + } + ], + "name": "PostResponseFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "name": "PostResponseHandled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "string", + "name": "dest", + "type": "string" + } + ], + "name": "PostResponseTimeoutHandled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newFee", + "type": "uint256" + } + ], + "name": "RequestFunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "caller", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "name": "StateCommitmentRead", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "stateMachineId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "height", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "overlayRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "stateRoot", + "type": "bytes32" + } + ], + "indexed": false, + "internalType": "struct StateCommitment", + "name": "stateCommitment", + "type": "tuple" + }, + { + "indexed": true, + "internalType": "address", + "name": "fisherman", + "type": "address" + } + ], + "name": "StateCommitmentVetoed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "stateMachineId", + "type": "string" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "height", + "type": "uint256" + } + ], + "name": "StateMachineUpdated", + "type": "event" + }, + { + "inputs": [], + "name": "CHAIN_ID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "chainId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "challengePeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "consensusClient", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "consensusState", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "consensusUpdateTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "stateMachineId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "height", + "type": "uint256" + } + ], + "internalType": "struct StateMachineHeight", + "name": "height", + "type": "tuple" + }, + { + "internalType": "address", + "name": "fisherman", + "type": "address" + } + ], + "name": "deleteStateMachineCommitment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeToken", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "frozen", + "outputs": [ + { + "internalType": "enum FrozenStatus", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fundRequest", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "fundResponse", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "host", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hostParams", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "defaultTimeout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "defaultPerByteFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stateCommitmentFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "handler", + "type": "address" + }, + { + "internalType": "address", + "name": "hostManager", + "type": "address" + }, + { + "internalType": "address", + "name": "uniswapV2", + "type": "address" + }, + { + "internalType": "uint256", + "name": "unStakingPeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "challengePeriod", + "type": "uint256" + }, + { + "internalType": "address", + "name": "consensusClient", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "stateMachines", + "type": "uint256[]" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "stateIdHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "perByteFee", + "type": "uint256" + } + ], + "internalType": "struct PerByteFee[]", + "name": "perByteFees", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "hyperbridge", + "type": "bytes" + } + ], + "internalType": "struct HostParams", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "hyperbridge", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "latestStateMachineHeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "stateId", + "type": "bytes" + } + ], + "name": "perByteFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "name": "requestCommitments", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "internalType": "struct FeeMetadata", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "name": "requestReceipts", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "name": "responded", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "name": "responseCommitments", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "internalType": "struct FeeMetadata", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "commitment", + "type": "bytes32" + } + ], + "name": "responseReceipts", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "responseCommitment", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "relayer", + "type": "address" + } + ], + "internalType": "struct ResponseReceipt", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "state", + "type": "bytes" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "stateMachineId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "height", + "type": "uint256" + } + ], + "internalType": "struct StateMachineHeight", + "name": "height", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "overlayRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "stateRoot", + "type": "bytes32" + } + ], + "internalType": "struct StateCommitment", + "name": "commitment", + "type": "tuple" + } + ], + "name": "setConsensusState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "enum FrozenStatus", + "name": "newState", + "type": "uint8" + } + ], + "name": "setFrozenState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "stateCommitmentFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "stateMachineId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "height", + "type": "uint256" + } + ], + "internalType": "struct StateMachineHeight", + "name": "height", + "type": "tuple" + } + ], + "name": "stateMachineCommitment", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "overlayRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "stateRoot", + "type": "bytes32" + } + ], + "internalType": "struct StateCommitment", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "stateMachineId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "height", + "type": "uint256" + } + ], + "internalType": "struct StateMachineHeight", + "name": "height", + "type": "tuple" + } + ], + "name": "stateMachineCommitmentUpdateTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "parachainId", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "stateMachineId", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "state", + "type": "bytes" + } + ], + "name": "storeConsensusState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "stateMachineId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "height", + "type": "uint256" + } + ], + "internalType": "struct StateMachineHeight", + "name": "height", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "overlayRoot", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "stateRoot", + "type": "bytes32" + } + ], + "internalType": "struct StateCommitment", + "name": "commitment", + "type": "tuple" + } + ], + "name": "storeStateMachineCommitment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "timestamp", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "unStakingPeriod", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "uniswapV2Router", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "defaultTimeout", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "defaultPerByteFee", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "stateCommitmentFee", + "type": "uint256" + }, + { + "internalType": "address", + "name": "feeToken", + "type": "address" + }, + { + "internalType": "address", + "name": "admin", + "type": "address" + }, + { + "internalType": "address", + "name": "handler", + "type": "address" + }, + { + "internalType": "address", + "name": "hostManager", + "type": "address" + }, + { + "internalType": "address", + "name": "uniswapV2", + "type": "address" + }, + { + "internalType": "uint256", + "name": "unStakingPeriod", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "challengePeriod", + "type": "uint256" + }, + { + "internalType": "address", + "name": "consensusClient", + "type": "address" + }, + { + "internalType": "uint256[]", + "name": "stateMachines", + "type": "uint256[]" + }, + { + "components": [ + { + "internalType": "bytes32", + "name": "stateIdHash", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "perByteFee", + "type": "uint256" + } + ], + "internalType": "struct PerByteFee[]", + "name": "perByteFees", + "type": "tuple[]" + }, + { + "internalType": "bytes", + "name": "hyperbridge", + "type": "bytes" + } + ], + "internalType": "struct HostParams", + "name": "params", + "type": "tuple" + } + ], + "name": "updateHostParams", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "paraId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "height", + "type": "uint256" + } + ], + "name": "vetoes", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "beneficiary", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "native", + "type": "bool" + } + ], + "internalType": "struct WithdrawParams", + "name": "params", + "type": "tuple" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/HandlerV1.abi.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/HandlerV1.abi.json new file mode 100644 index 00000000..5d9bb129 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/HandlerV1.abi.json @@ -0,0 +1,748 @@ +[ + { + "inputs": [], + "name": "ChallengePeriodNotElapsed", + "type": "error" + }, + { + "inputs": [], + "name": "ConsensusClientExpired", + "type": "error" + }, + { + "inputs": [], + "name": "DuplicateMessage", + "type": "error" + }, + { + "inputs": [], + "name": "HostFrozen", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidMessageDestination", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidProof", + "type": "error" + }, + { + "inputs": [], + "name": "MessageNotTimedOut", + "type": "error" + }, + { + "inputs": [], + "name": "MessageTimedOut", + "type": "error" + }, + { + "inputs": [], + "name": "StateCommitmentNotFound", + "type": "error" + }, + { + "inputs": [], + "name": "UnknownMessage", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract IIsmpHost", + "name": "host", + "type": "address" + }, + { + "internalType": "bytes", + "name": "proof", + "type": "bytes" + } + ], + "name": "handleConsensus", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IIsmpHost", + "name": "host", + "type": "address" + }, + { + "components": [ + { + "components": [ + { + "internalType": "bytes", + "name": "source", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "dest", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint64", + "name": "timeoutTimestamp", + "type": "uint64" + }, + { + "internalType": "bytes[]", + "name": "keys", + "type": "bytes[]" + }, + { + "internalType": "uint64", + "name": "height", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "context", + "type": "bytes" + } + ], + "internalType": "struct GetRequest[]", + "name": "timeouts", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "stateMachineId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "height", + "type": "uint256" + } + ], + "internalType": "struct StateMachineHeight", + "name": "height", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "proof", + "type": "bytes[]" + } + ], + "internalType": "struct GetTimeoutMessage", + "name": "message", + "type": "tuple" + } + ], + "name": "handleGetRequestTimeouts", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IIsmpHost", + "name": "host", + "type": "address" + }, + { + "components": [ + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "stateMachineId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "height", + "type": "uint256" + } + ], + "internalType": "struct StateMachineHeight", + "name": "height", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "multiproof", + "type": "bytes32[]" + }, + { + "internalType": "uint256", + "name": "leafCount", + "type": "uint256" + } + ], + "internalType": "struct Proof", + "name": "proof", + "type": "tuple" + }, + { + "components": [ + { + "components": [ + { + "components": [ + { + "internalType": "bytes", + "name": "source", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "dest", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "uint64", + "name": "timeoutTimestamp", + "type": "uint64" + }, + { + "internalType": "bytes[]", + "name": "keys", + "type": "bytes[]" + }, + { + "internalType": "uint64", + "name": "height", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "context", + "type": "bytes" + } + ], + "internalType": "struct GetRequest", + "name": "request", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "bytes", + "name": "key", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "value", + "type": "bytes" + } + ], + "internalType": "struct StorageValue[]", + "name": "values", + "type": "tuple[]" + } + ], + "internalType": "struct GetResponse", + "name": "response", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "kIndex", + "type": "uint256" + } + ], + "internalType": "struct GetResponseLeaf[]", + "name": "responses", + "type": "tuple[]" + } + ], + "internalType": "struct GetResponseMessage", + "name": "message", + "type": "tuple" + } + ], + "name": "handleGetResponses", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IIsmpHost", + "name": "host", + "type": "address" + }, + { + "components": [ + { + "components": [ + { + "internalType": "bytes", + "name": "source", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "dest", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "from", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "timeoutTimestamp", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "body", + "type": "bytes" + } + ], + "internalType": "struct PostRequest[]", + "name": "timeouts", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "stateMachineId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "height", + "type": "uint256" + } + ], + "internalType": "struct StateMachineHeight", + "name": "height", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "proof", + "type": "bytes[]" + } + ], + "internalType": "struct PostRequestTimeoutMessage", + "name": "message", + "type": "tuple" + } + ], + "name": "handlePostRequestTimeouts", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IIsmpHost", + "name": "host", + "type": "address" + }, + { + "components": [ + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "stateMachineId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "height", + "type": "uint256" + } + ], + "internalType": "struct StateMachineHeight", + "name": "height", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "multiproof", + "type": "bytes32[]" + }, + { + "internalType": "uint256", + "name": "leafCount", + "type": "uint256" + } + ], + "internalType": "struct Proof", + "name": "proof", + "type": "tuple" + }, + { + "components": [ + { + "components": [ + { + "internalType": "bytes", + "name": "source", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "dest", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "from", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "timeoutTimestamp", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "body", + "type": "bytes" + } + ], + "internalType": "struct PostRequest", + "name": "request", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "kIndex", + "type": "uint256" + } + ], + "internalType": "struct PostRequestLeaf[]", + "name": "requests", + "type": "tuple[]" + } + ], + "internalType": "struct PostRequestMessage", + "name": "request", + "type": "tuple" + } + ], + "name": "handlePostRequests", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IIsmpHost", + "name": "host", + "type": "address" + }, + { + "components": [ + { + "components": [ + { + "components": [ + { + "internalType": "bytes", + "name": "source", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "dest", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "from", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "timeoutTimestamp", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "body", + "type": "bytes" + } + ], + "internalType": "struct PostRequest", + "name": "request", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "response", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "timeoutTimestamp", + "type": "uint64" + } + ], + "internalType": "struct PostResponse[]", + "name": "timeouts", + "type": "tuple[]" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "stateMachineId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "height", + "type": "uint256" + } + ], + "internalType": "struct StateMachineHeight", + "name": "height", + "type": "tuple" + }, + { + "internalType": "bytes[]", + "name": "proof", + "type": "bytes[]" + } + ], + "internalType": "struct PostResponseTimeoutMessage", + "name": "message", + "type": "tuple" + } + ], + "name": "handlePostResponseTimeouts", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IIsmpHost", + "name": "host", + "type": "address" + }, + { + "components": [ + { + "components": [ + { + "components": [ + { + "internalType": "uint256", + "name": "stateMachineId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "height", + "type": "uint256" + } + ], + "internalType": "struct StateMachineHeight", + "name": "height", + "type": "tuple" + }, + { + "internalType": "bytes32[]", + "name": "multiproof", + "type": "bytes32[]" + }, + { + "internalType": "uint256", + "name": "leafCount", + "type": "uint256" + } + ], + "internalType": "struct Proof", + "name": "proof", + "type": "tuple" + }, + { + "components": [ + { + "components": [ + { + "components": [ + { + "internalType": "bytes", + "name": "source", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "dest", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "nonce", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "from", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "to", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "timeoutTimestamp", + "type": "uint64" + }, + { + "internalType": "bytes", + "name": "body", + "type": "bytes" + } + ], + "internalType": "struct PostRequest", + "name": "request", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "response", + "type": "bytes" + }, + { + "internalType": "uint64", + "name": "timeoutTimestamp", + "type": "uint64" + } + ], + "internalType": "struct PostResponse", + "name": "response", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "kIndex", + "type": "uint256" + } + ], + "internalType": "struct PostResponseLeaf[]", + "name": "responses", + "type": "tuple[]" + } + ], + "internalType": "struct PostResponseMessage", + "name": "response", + "type": "tuple" + } + ], + "name": "handlePostResponses", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/IntentGateway.abi.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/IntentGateway.abi.json new file mode 100644 index 00000000..2a0163ac --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/IntentGateway.abi.json @@ -0,0 +1,1250 @@ +{ + "abi": [ + { + "type": "constructor", + "inputs": [{ "name": "admin", "type": "address", "internalType": "address" }], + "stateMutability": "nonpayable" + }, + { "type": "receive", "stateMutability": "payable" }, + { + "type": "function", + "name": "calculateCommitmentSlotHash", + "inputs": [{ "name": "commitment", "type": "bytes32", "internalType": "bytes32" }], + "outputs": [{ "name": "", "type": "bytes", "internalType": "bytes" }], + "stateMutability": "pure" + }, + { + "type": "function", + "name": "cancelOrder", + "inputs": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct Order", + "components": [ + { "name": "user", "type": "bytes32", "internalType": "bytes32" }, + { "name": "sourceChain", "type": "bytes", "internalType": "bytes" }, + { "name": "destChain", "type": "bytes", "internalType": "bytes" }, + { "name": "deadline", "type": "uint256", "internalType": "uint256" }, + { "name": "nonce", "type": "uint256", "internalType": "uint256" }, + { "name": "fees", "type": "uint256", "internalType": "uint256" }, + { + "name": "outputs", + "type": "tuple[]", + "internalType": "struct PaymentInfo[]", + "components": [ + { "name": "token", "type": "bytes32", "internalType": "bytes32" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" }, + { "name": "beneficiary", "type": "bytes32", "internalType": "bytes32" } + ] + }, + { + "name": "inputs", + "type": "tuple[]", + "internalType": "struct TokenInfo[]", + "components": [ + { "name": "token", "type": "bytes32", "internalType": "bytes32" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" } + ] + }, + { "name": "callData", "type": "bytes", "internalType": "bytes" } + ] + }, + { + "name": "options", + "type": "tuple", + "internalType": "struct CancelOptions", + "components": [ + { "name": "relayerFee", "type": "uint256", "internalType": "uint256" }, + { "name": "height", "type": "uint256", "internalType": "uint256" } + ] + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "fillOrder", + "inputs": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct Order", + "components": [ + { "name": "user", "type": "bytes32", "internalType": "bytes32" }, + { "name": "sourceChain", "type": "bytes", "internalType": "bytes" }, + { "name": "destChain", "type": "bytes", "internalType": "bytes" }, + { "name": "deadline", "type": "uint256", "internalType": "uint256" }, + { "name": "nonce", "type": "uint256", "internalType": "uint256" }, + { "name": "fees", "type": "uint256", "internalType": "uint256" }, + { + "name": "outputs", + "type": "tuple[]", + "internalType": "struct PaymentInfo[]", + "components": [ + { "name": "token", "type": "bytes32", "internalType": "bytes32" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" }, + { "name": "beneficiary", "type": "bytes32", "internalType": "bytes32" } + ] + }, + { + "name": "inputs", + "type": "tuple[]", + "internalType": "struct TokenInfo[]", + "components": [ + { "name": "token", "type": "bytes32", "internalType": "bytes32" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" } + ] + }, + { "name": "callData", "type": "bytes", "internalType": "bytes" } + ] + }, + { + "name": "options", + "type": "tuple", + "internalType": "struct FillOptions", + "components": [{ "name": "relayerFee", "type": "uint256", "internalType": "uint256" }] + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "host", + "inputs": [], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "instance", + "inputs": [{ "name": "stateMachineId", "type": "bytes", "internalType": "bytes" }], + "outputs": [{ "name": "", "type": "bytes32", "internalType": "bytes32" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "onAccept", + "inputs": [ + { + "name": "incoming", + "type": "tuple", + "internalType": "struct IncomingPostRequest", + "components": [ + { + "name": "request", + "type": "tuple", + "internalType": "struct PostRequest", + "components": [ + { "name": "source", "type": "bytes", "internalType": "bytes" }, + { "name": "dest", "type": "bytes", "internalType": "bytes" }, + { "name": "nonce", "type": "uint64", "internalType": "uint64" }, + { "name": "from", "type": "bytes", "internalType": "bytes" }, + { "name": "to", "type": "bytes", "internalType": "bytes" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" }, + { "name": "body", "type": "bytes", "internalType": "bytes" } + ] + }, + { "name": "relayer", "type": "address", "internalType": "address" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onGetResponse", + "inputs": [ + { + "name": "incoming", + "type": "tuple", + "internalType": "struct IncomingGetResponse", + "components": [ + { + "name": "response", + "type": "tuple", + "internalType": "struct GetResponse", + "components": [ + { + "name": "request", + "type": "tuple", + "internalType": "struct GetRequest", + "components": [ + { "name": "source", "type": "bytes", "internalType": "bytes" }, + { "name": "dest", "type": "bytes", "internalType": "bytes" }, + { "name": "nonce", "type": "uint64", "internalType": "uint64" }, + { "name": "from", "type": "address", "internalType": "address" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" }, + { "name": "keys", "type": "bytes[]", "internalType": "bytes[]" }, + { "name": "height", "type": "uint64", "internalType": "uint64" }, + { "name": "context", "type": "bytes", "internalType": "bytes" } + ] + }, + { + "name": "values", + "type": "tuple[]", + "internalType": "struct StorageValue[]", + "components": [ + { "name": "key", "type": "bytes", "internalType": "bytes" }, + { "name": "value", "type": "bytes", "internalType": "bytes" } + ] + } + ] + }, + { "name": "relayer", "type": "address", "internalType": "address" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onGetTimeout", + "inputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct GetRequest", + "components": [ + { "name": "source", "type": "bytes", "internalType": "bytes" }, + { "name": "dest", "type": "bytes", "internalType": "bytes" }, + { "name": "nonce", "type": "uint64", "internalType": "uint64" }, + { "name": "from", "type": "address", "internalType": "address" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" }, + { "name": "keys", "type": "bytes[]", "internalType": "bytes[]" }, + { "name": "height", "type": "uint64", "internalType": "uint64" }, + { "name": "context", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onPostRequestTimeout", + "inputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct PostRequest", + "components": [ + { "name": "source", "type": "bytes", "internalType": "bytes" }, + { "name": "dest", "type": "bytes", "internalType": "bytes" }, + { "name": "nonce", "type": "uint64", "internalType": "uint64" }, + { "name": "from", "type": "bytes", "internalType": "bytes" }, + { "name": "to", "type": "bytes", "internalType": "bytes" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" }, + { "name": "body", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onPostResponse", + "inputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct IncomingPostResponse", + "components": [ + { + "name": "response", + "type": "tuple", + "internalType": "struct PostResponse", + "components": [ + { + "name": "request", + "type": "tuple", + "internalType": "struct PostRequest", + "components": [ + { "name": "source", "type": "bytes", "internalType": "bytes" }, + { "name": "dest", "type": "bytes", "internalType": "bytes" }, + { "name": "nonce", "type": "uint64", "internalType": "uint64" }, + { "name": "from", "type": "bytes", "internalType": "bytes" }, + { "name": "to", "type": "bytes", "internalType": "bytes" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" }, + { "name": "body", "type": "bytes", "internalType": "bytes" } + ] + }, + { "name": "response", "type": "bytes", "internalType": "bytes" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" } + ] + }, + { "name": "relayer", "type": "address", "internalType": "address" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onPostResponseTimeout", + "inputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct PostResponse", + "components": [ + { + "name": "request", + "type": "tuple", + "internalType": "struct PostRequest", + "components": [ + { "name": "source", "type": "bytes", "internalType": "bytes" }, + { "name": "dest", "type": "bytes", "internalType": "bytes" }, + { "name": "nonce", "type": "uint64", "internalType": "uint64" }, + { "name": "from", "type": "bytes", "internalType": "bytes" }, + { "name": "to", "type": "bytes", "internalType": "bytes" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" }, + { "name": "body", "type": "bytes", "internalType": "bytes" } + ] + }, + { "name": "response", "type": "bytes", "internalType": "bytes" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "params", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct Params", + "components": [ + { "name": "host", "type": "address", "internalType": "address" }, + { "name": "dispatcher", "type": "address", "internalType": "address" } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "placeOrder", + "inputs": [ + { + "name": "order", + "type": "tuple", + "internalType": "struct Order", + "components": [ + { "name": "user", "type": "bytes32", "internalType": "bytes32" }, + { "name": "sourceChain", "type": "bytes", "internalType": "bytes" }, + { "name": "destChain", "type": "bytes", "internalType": "bytes" }, + { "name": "deadline", "type": "uint256", "internalType": "uint256" }, + { "name": "nonce", "type": "uint256", "internalType": "uint256" }, + { "name": "fees", "type": "uint256", "internalType": "uint256" }, + { + "name": "outputs", + "type": "tuple[]", + "internalType": "struct PaymentInfo[]", + "components": [ + { "name": "token", "type": "bytes32", "internalType": "bytes32" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" }, + { "name": "beneficiary", "type": "bytes32", "internalType": "bytes32" } + ] + }, + { + "name": "inputs", + "type": "tuple[]", + "internalType": "struct TokenInfo[]", + "components": [ + { "name": "token", "type": "bytes32", "internalType": "bytes32" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" } + ] + }, + { "name": "callData", "type": "bytes", "internalType": "bytes" } + ] + }, + { "name": "graffiti", "type": "bytes32", "internalType": "bytes32" } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "function", + "name": "setParams", + "inputs": [ + { + "name": "p", + "type": "tuple", + "internalType": "struct Params", + "components": [ + { "name": "host", "type": "address", "internalType": "address" }, + { "name": "dispatcher", "type": "address", "internalType": "address" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "event", + "name": "EscrowRefunded", + "inputs": [{ "name": "commitment", "type": "bytes32", "indexed": true, "internalType": "bytes32" }], + "anonymous": false + }, + { + "type": "event", + "name": "EscrowReleased", + "inputs": [{ "name": "commitment", "type": "bytes32", "indexed": true, "internalType": "bytes32" }], + "anonymous": false + }, + { + "type": "event", + "name": "NewDeploymentAdded", + "inputs": [ + { "name": "stateMachineId", "type": "bytes", "indexed": false, "internalType": "bytes" }, + { "name": "gateway", "type": "bytes32", "indexed": false, "internalType": "bytes32" } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderFilled", + "inputs": [ + { "name": "commitment", "type": "bytes32", "indexed": true, "internalType": "bytes32" }, + { "name": "filler", "type": "address", "indexed": false, "internalType": "address" } + ], + "anonymous": false + }, + { + "type": "event", + "name": "OrderPlaced", + "inputs": [ + { "name": "user", "type": "bytes32", "indexed": false, "internalType": "bytes32" }, + { "name": "sourceChain", "type": "bytes", "indexed": false, "internalType": "bytes" }, + { "name": "destChain", "type": "bytes", "indexed": false, "internalType": "bytes" }, + { "name": "deadline", "type": "uint256", "indexed": false, "internalType": "uint256" }, + { "name": "nonce", "type": "uint256", "indexed": false, "internalType": "uint256" }, + { "name": "fees", "type": "uint256", "indexed": false, "internalType": "uint256" }, + { + "name": "outputs", + "type": "tuple[]", + "indexed": false, + "internalType": "struct PaymentInfo[]", + "components": [ + { "name": "token", "type": "bytes32", "internalType": "bytes32" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" }, + { "name": "beneficiary", "type": "bytes32", "internalType": "bytes32" } + ] + }, + { + "name": "inputs", + "type": "tuple[]", + "indexed": false, + "internalType": "struct TokenInfo[]", + "components": [ + { "name": "token", "type": "bytes32", "internalType": "bytes32" }, + { "name": "amount", "type": "uint256", "internalType": "uint256" } + ] + }, + { "name": "callData", "type": "bytes", "indexed": false, "internalType": "bytes" } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ParamsUpdated", + "inputs": [ + { + "name": "previous", + "type": "tuple", + "indexed": false, + "internalType": "struct Params", + "components": [ + { "name": "host", "type": "address", "internalType": "address" }, + { "name": "dispatcher", "type": "address", "internalType": "address" } + ] + }, + { + "name": "current", + "type": "tuple", + "indexed": false, + "internalType": "struct Params", + "components": [ + { "name": "host", "type": "address", "internalType": "address" }, + { "name": "dispatcher", "type": "address", "internalType": "address" } + ] + } + ], + "anonymous": false + }, + { "type": "error", "name": "Expired", "inputs": [] }, + { "type": "error", "name": "Filled", "inputs": [] }, + { "type": "error", "name": "InsufficientNativeToken", "inputs": [] }, + { "type": "error", "name": "InvalidInput", "inputs": [] }, + { "type": "error", "name": "NotExpired", "inputs": [] }, + { "type": "error", "name": "Unauthorized", "inputs": [] }, + { "type": "error", "name": "UnauthorizedCall", "inputs": [] }, + { "type": "error", "name": "UnexpectedCall", "inputs": [] }, + { "type": "error", "name": "UnknownOrder", "inputs": [] }, + { "type": "error", "name": "WrongChain", "inputs": [] } + ], + "bytecode": { + "object": "0x608060405234801562000010575f80fd5b50604051620045673803806200456783398101604081905262000033916200015a565b5f620000476001546001600160a01b031690565b90506001600160a01b038116156200013357806001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000096573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620000bc91906200015a565b60405163095ea7b360e01b81526001600160a01b0383811660048301525f196024830152919091169063095ea7b3906044016020604051808303815f875af11580156200010b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000131919062000189565b505b50600380546001600160a01b0319166001600160a01b0392909216919091179055620001aa565b5f602082840312156200016b575f80fd5b81516001600160a01b038116811462000182575f80fd5b9392505050565b5f602082840312156200019a575f80fd5b8151801515811462000182575f80fd5b6143af80620001b85f395ff3fe60806040526004361061011e575f3560e01c8063b2a01bf51161009d578063cff0ab9611610062578063cff0ab96146102ee578063d0fff3661461033a578063d24740fb14610354578063dd92a31614610373578063f437bc5914610392575f80fd5b8063b2a01bf514610269578063b53eafe914610283578063bc0dd44714610296578063bca96c39146102b0578063c2977d2f146102cf575f80fd5b80634f3f7c05116100e35780634f3f7c05146101d957806360121a94146101f8578063632e235a14610224578063731c8b32146102435780637f84d22914610256575f80fd5b80630bc37bab146101295780630bddd96c1461014a5780630fee32ce1461017c578063108bc1dd1461019b57806344ab20f8146101ba575f80fd5b3661012557005b5f80fd5b348015610134575f80fd5b50610148610143366004612b99565b6103b9565b005b348015610155575f80fd5b50610169610164366004612bca565b6103fd565b6040519081526020015b60405180910390f35b348015610187575f80fd5b50610148610196366004612c35565b610445565b3480156101a6575f80fd5b506101696101b5366004612c8a565b610705565b3480156101c5575f80fd5b506101486101d4366004612f02565b6107c3565b3480156101e4575f80fd5b506101696101f3366004612c8a565b610afa565b348015610203575f80fd5b5061021761021236600461309c565b610d49565b6040516101739190613100565b34801561022f575f80fd5b5061016961023e366004613112565b610d92565b6101486102513660046132ed565b610d9d565b61014861026436600461342c565b611377565b348015610274575f80fd5b506101486101433660046134a6565b610148610291366004613524565b611a69565b3480156102a1575f80fd5b50610148610143366004613590565b3480156102bb575f80fd5b506101696102ca3660046135c1565b611f15565b3480156102da575f80fd5b506101486102e936600461369a565b612044565b3480156102f9575f80fd5b506040805180820182525f80825260209182015281518083019092526001546001600160a01b039081168352600254169082015260405161017391906136d9565b348015610345575f80fd5b506101486101433660046136fd565b34801561035f575f80fd5b5061016961036e3660046135c1565b612183565b34801561037e575f80fd5b5061016961038d366004613112565b61218e565b34801561039d575f80fd5b506001546040516001600160a01b039091168152602001610173565b6001546001600160a01b031633146103e457604051637bf6a16f60e01b815260040160405180910390fd5b6040516302cbc79f60e01b815260040160405180910390fd5b5f8060065f858560405161041292919061372e565b604051809103902081526020019081526020015f205490505f801b8114610439578061043b565b305b9150505b92915050565b6001546001600160a01b0316331461047057604051637bf6a16f60e01b815260040160405180910390fd5b5f61047b828061373d565b6104899060c081019061375b565b5f818110610499576104996137a4565b919091013560f81c905060028111156104b4576104b46137b8565b90505f8160028111156104c9576104c96137b8565b036104db576104d782612246565b5050565b6001546001600160a01b03166001600160a01b0316625e763e6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610520573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261054791908101906137cc565b8051602090910120610559838061373d565b610563908061375b565b60405161057192919061372e565b604051809103902014610596576040516282b42960e81b815260040160405180910390fd5b60018160028111156105aa576105aa6137b8565b03610644575f6105ba838061373d565b6105c89060c081019061375b565b6105d691600190829061383d565b8101906105e39190613864565b6020808201805183518051908401205f9081526006909352604092839020558251905191519293507ff6ef54addfd2bdaa8b0c1fa61c3a9bbf6dde3c0e2640fa16a88f7b38ce5368e39261063792906138d8565b60405180910390a1505050565b6002816002811115610658576106586137b8565b036104d7575f610668838061373d565b6106769060c081019061375b565b61068491600190829061383d565b810190610691919061369a565b90507fa71f7687ff8346b13c6f0923b96164593da1bb1ac8e6c571499fcd041d57245e6001826040516106c59291906138f9565b60405180910390a18051600180546001600160a01b03199081166001600160a01b0393841617909155602090920151600280549093169116179055505b50565b5f8082604001515160201161071f57826040015151610722565b60205b90506107366001546001600160a01b031690565b8351604051632008f60560e11b81526001600160a01b039290921691634011ec0a9161076491600401613100565b602060405180830381865afa15801561077f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107a3919061393a565b6107ad9082613965565b83608001516107bc919061397c565b9392505050565b6001546001600160a01b031633146107ee57604051637bf6a16f60e01b815260040160405180910390fd5b80516020015180515f90610804576108046137a4565b602002602001015160200151515f146108305760405163413e917360e11b815260040160405180910390fd5b80515160e0015180515f9161084d9181016020908101910161398f565b6020810151604082015151919250905f5b818110156109dd575f8460400151828151811061087d5761087d6137a4565b60200260200101515f01515f1c90505f856040015183815181106108a3576108a36137a4565b60209081029190910181015181015187515f9081526004835260408082206001600160a01b03871683529093529182205490925090036108f657604051635c1c6f4b60e11b815260040160405180910390fd5b6001600160a01b03821661097a575f856001600160a01b0316826040515f6040518083038185875af1925050503d805f811461094d576040519150601f19603f3d011682016040523d82523d5f602084013e610952565b606091505b5050905080610974576040516332201f6960e11b815260040160405180910390fd5b5061098e565b61098e6001600160a01b0383168683612553565b85515f9081526004602090815260408083206001600160a01b0386168452909152812080548392906109c1908490613a82565b92505081905550505080806109d590613a95565b91505061085e565b5082515f90815260046020908152604080832073d254fdaa2ce7841c7794b71b85f15052f5aeac8284529091529020548015610ac957610a998382610a2a6001546001600160a01b031690565b6001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a65573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a899190613aad565b6001600160a01b03169190612553565b83515f90815260046020908152604080832073d254fdaa2ce7841c7794b71b85f15052f5aeac8284529091528120555b83516040517f7b08f2d2a35d68f512d4ee819cc6c616e61aa7cd7f7b0855d95ba090d84dc436905f90a25050505050565b5f80610b0583610705565b90505f610b1a6001546001600160a01b031690565b90505f816001600160a01b0316631694505e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b59573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b7d9190613aad565b6040805160028082526060820183529293505f929091602083019080368337019050509050816001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bde573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c029190613aad565b815f81518110610c1457610c146137a4565b60200260200101906001600160a01b031690816001600160a01b031681525050826001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c70573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c949190613aad565b81600181518110610ca757610ca76137a4565b6001600160a01b0392831660209182029290920101526040516307c0329d60e21b815290831690631f00ca7490610ce49087908590600401613b0a565b5f60405180830381865afa158015610cfe573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610d259190810190613b22565b5f81518110610d3657610d366137a4565b6020026020010151945050505050919050565b6040805160056020820152908101829052606090810160408051601f19818403018152828252805160209182012090830152016040516020818303038152906040529050919050565b5f80610b058361218e565b5f610db06001546001600160a01b031690565b5f805460808601523385526040805163f437bc5960e01b815290519293506001600160a01b0384169263f437bc59926004808401939192918290030181865afa158015610dff573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610e2691908101906137cc565b83602001819052505f83604051602001610e409190613c1f565b60408051601f19818403018152919052805160209091012060e08501515190915034905f5b81811015611007578660e001518181518110610e8357610e836137a4565b6020026020010151602001515f03610eae5760405163b4fa3fb360e01b815260040160405180910390fd5b5f8760e001518281518110610ec557610ec56137a4565b60209081029190910101515190506001600160a01b038116610f57578760e001518281518110610ef757610ef76137a4565b602002602001015160200151841015610f23576040516332201f6960e11b815260040160405180910390fd5b8760e001518281518110610f3957610f396137a4565b60200260200101516020015184610f509190613a82565b9350610f98565b610f9833308a60e001518581518110610f7257610f726137a4565b602002602001015160200151846001600160a01b03166125bb909392919063ffffffff16565b8760e001518281518110610fae57610fae6137a4565b6020908102919091018101518101515f8781526004835260408082206001600160a01b0386168352909352918220805491929091610fed90849061397c565b90915550829150610fff905081613a95565b915050610e65565b5060a0860151156112ee575f846001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561104f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110739190613aad565b9050821561129d575f856001600160a01b0316631694505e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110dc9190613aad565b90505f816001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561111b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061113f9190613aad565b6040805160028082526060820183529293505f92909160208301908036833701905050905081815f81518110611177576111776137a4565b60200260200101906001600160a01b031690816001600160a01b031681525050876001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111f79190613aad565b8160018151811061120a5761120a6137a4565b6001600160a01b03928316602091820292909201015260a08b0151604051637ff36ab560e01b815291851691637ff36ab59189916112519190869030904290600401613cdb565b5f6040518083038185885af115801561126c573d5f803e3d5ffd5b50505050506040513d5f823e601f3d908101601f191682016040526112949190810190613b22565b505050506112ba565b60a08701516112ba906001600160a01b03831690339030906125bb565b5060a08601515f84815260046020908152604080832073d254fdaa2ce7841c7794b71b85f15052f5aeac8284529091529020555b60015f808282546112ff919061397c565b90915550508551602087015160408089015160608a015160808b015160a08c015160c08d015160e08e01516101008f015196517fd969ab7a9f9c7b547e1500b952901705e8ae61385f62d7b9a8baa5345a0ac07d996113679990989097969594939291613d0f565b60405180910390a1505050505050565b5f61138a6001546001600160a01b031690565b9050806001600160a01b031663f437bc596040518163ffffffff1660e01b81526004015f60405180830381865afa1580156113c7573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526113ee91908101906137cc565b8051602090910120611403604085018561375b565b60405161141192919061372e565b604051809103902014611437576040516310dfc03360e01b815260040160405180910390fd5b438360600135101561145c57604051630407b05b60e31b815260040160405180910390fd5b5f8360405160200161146e9190613efe565b60408051601f1981840301815291815281516020928301205f81815260059093529120549091506001600160a01b0316156114bc5760405163413e917360e11b815260040160405180910390fd5b345f6114cb60c0870187613ff0565b905090505f5b818110156116ba575f6114e760c0890189613ff0565b838181106114f7576114f76137a4565b606002919091013591505f905061151160c08a018a613ff0565b84818110611521576115216137a4565b905060600201604001355f1c90505f6001600160a01b0316826001600160a01b03160361165f5761155560c08a018a613ff0565b84818110611565576115656137a4565b9050606002016020013585101561158f576040516332201f6960e11b815260040160405180910390fd5b5f6001600160a01b0382166115a760c08c018c613ff0565b868181106115b7576115b76137a4565b905060600201602001356040515f6040518083038185875af1925050503d805f81146115fe576040519150601f19603f3d011682016040523d82523d5f602084013e611603565b606091505b5050905080611625576040516332201f6960e11b815260040160405180910390fd5b61163260c08b018b613ff0565b85818110611642576116426137a4565b90506060020160200135866116579190613a82565b9550506116a5565b6116a5338261167160c08d018d613ff0565b87818110611681576116816137a4565b90506060020160200135856001600160a01b03166125bb909392919063ffffffff16565b505080806116b290613a95565b9150506114d1565b505f6116ca61010088018861375b565b9050111561173c576002546001600160a01b031663ab7fff186116f161010089018961375b565b6040518363ffffffff1660e01b815260040161170e929190614034565b5f604051808303815f87803b158015611725575f80fd5b505af1158015611737573d5f803e3d5ffd5b505050505b604080516060810182528481523360208201525f91810161176060e08a018a614047565b808060200260200160405190810160405280939291908181526020015f905b828210156117ab5761179c6040830286013681900381019061408c565b8152602001906001019061177f565b50505050508152506040516020016117c391906140a6565b60408051601f1981840301815260c0830190915291505f90806117e960208b018b61375b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050509082525060209081019061183590610164908c018c61375b565b60405160200161184791815260200190565b60408051601f1981840301815291905281526020015f60f81b846040516020016118729291906140d4565b60408051601f198184030181529181529082525f602083015289519082015233606090910152905083156119155760405163b8f3e8f560e01b81526001600160a01b0387169063b8f3e8f59086906118ce908590600401614104565b60206040518083038185885af11580156118ea573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061190f919061393a565b50611a09565b5f866001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611952573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119769190613aad565b90505f61198283610705565b90506119996001600160a01b0383163330846125bb565b60405163b8f3e8f560e01b81526001600160a01b0389169063b8f3e8f5906119c5908690600401614104565b6020604051808303815f875af11580156119e1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a05919061393a565b5050505b5f8581526005602090815260409182902080546001600160a01b03191633908117909155915191825286917f0555709e59fb225fcf12cc582a9e5f7fd8eea54c91f3dc500ab9d8c37c507770910160405180910390a25050505050505050565b5f82604051602001611a7b9190613efe565b60408051601f198184030181529190528051602090910120905082353314611ab5576040516282b42960e81b815260040160405180910390fd5b8260600135826020015111611add5760405163d0404f8560e01b815260040160405180910390fd5b5f818152600560205260409020546001600160a01b031615611b125760405163413e917360e11b815260040160405180910390fd5b5f611b2060e0850185614047565b905090505f5b81811015611bb5575f83815260046020526040812090611b4960e0880188614047565b84818110611b5957611b596137a4565b9050604002015f01355f1c6001600160a01b03166001600160a01b031681526020019081526020015f20545f03611ba357604051635c1c6f4b60e11b815260040160405180910390fd5b80611bad81613a95565b915050611b26565b5060408051606081018252838152853560208201525f918101611bdb60e0880188614047565b808060200260200160405190810160405280939291908181526020015f905b82821015611c2657611c176040830286013681900381019061408c565b81526020019060010190611bfa565b5050505050815250604051602001611c3e91906140a6565b60408051808303601f19018152600180845283830190925292505f9190816020015b6060815260200190600190039081611c60579050509050611c87610164604088018861375b565b604051611caf919060200160609190911b6bffffffffffffffffffffffff1916815260140190565b604051602081830303815290604052611cc785610d49565b604051602001611cd8929190614197565b604051602081830303815290604052815f81518110611cf957611cf96137a4565b60200260200101819052505f6040518060c00160405280888060400190611d20919061375b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201829052509385525050506020898101516001600160401b03169083015260408201859052606082018190528851608083015260a0909101859052909150611d9a6001546001600160a01b031690565b90503415611e175760405163d22e334360e01b81526001600160a01b0382169063d22e3343903490611dd09086906004016141c5565b60206040518083038185885af1158015611dec573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190611e11919061393a565b50611f0b565b5f816001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e54573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e789190613aad565b90505f611e8484611f15565b9050611e9b6001600160a01b0383163330846125bb565b60405163d22e334360e01b81526001600160a01b0384169063d22e334390611ec79087906004016141c5565b6020604051808303815f875af1158015611ee3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f07919061393a565b5050505b5050505050505050565b5f80611f296001546001600160a01b031690565b90505f816001600160a01b0316634011ec0a836001600160a01b031663f437bc596040518163ffffffff1660e01b81526004015f60405180830381865afa158015611f76573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611f9d91908101906137cc565b6040518263ffffffff1660e01b8152600401611fb99190613100565b602060405180830381865afa158015611fd4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ff8919061393a565b90505f612006826020613965565b90505f8560a00151518361201a9190613965565b8660800151612029919061397c565b9050808211612038578061203a565b815b9695505050505050565b6003546001600160a01b0316331461206e576040516282b42960e81b815260040160405180910390fd5b805f01516001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120d19190613aad565b815160405163095ea7b360e01b81526001600160a01b0391821660048201525f19602482015291169063095ea7b3906044016020604051808303815f875af115801561211f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121439190614296565b50600380546001600160a01b03199081169091558151600180546001600160a01b0392831690841617905560209092015160028054919093169116179055565b5f80610b0583611f15565b5f808260200151516020116121a8578260200151516121ab565b60205b90506121bf6001546001600160a01b031690565b835151604051632008f60560e11b81526001600160a01b039290921691634011ec0a916121ee91600401613100565b602060405180830381865afa158015612209573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061222d919061393a565b6122379082613965565b83606001516107bc919061397c565b612250818061373d565b5f61225e606083018361375b565b61226c916020915f9161383d565b612275916142b5565b905080612285610164848061375b565b146122a2576040516282b42960e81b815260040160405180910390fd5b5f6122ad848061373d565b6122bb9060c081019061375b565b6122c991600190829061383d565b8101906122d691906142d2565b6020810151604082015151919250905f5b81811015612466575f84604001518281518110612306576123066137a4565b60200260200101515f01515f1c90505f8560400151838151811061232c5761232c6137a4565b60209081029190910181015181015187515f9081526004835260408082206001600160a01b038716835290935291822054909250900361237f57604051635c1c6f4b60e11b815260040160405180910390fd5b6001600160a01b038216612403575f856001600160a01b0316826040515f6040518083038185875af1925050503d805f81146123d6576040519150601f19603f3d011682016040523d82523d5f602084013e6123db565b606091505b50509050806123fd576040516332201f6960e11b815260040160405180910390fd5b50612417565b6124176001600160a01b0383168683612553565b85515f9081526004602090815260408083206001600160a01b03861684529091528120805483929061244a908490613a82565b925050819055505050808061245e90613a95565b9150506122e7565b5082515f90815260046020908152604080832073d254fdaa2ce7841c7794b71b85f15052f5aeac82845290915290205480156124e3576124b38382610a2a6001546001600160a01b031690565b83515f90815260046020908152604080832073d254fdaa2ce7841c7794b71b85f15052f5aeac8284529091528120555b6124f3604088016020890161434d565b84515f9081526005602052604080822080546001600160a01b0319166001600160a01b039490941693909317909255855191517fb6e94cf3f8e202cc261173363d27daa8f5e2e79cff984b252f786794afb499469190a250505050505050565b6040516001600160a01b0383166024820152604481018290526125b690849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526125f9565b505050565b6040516001600160a01b03808516602483015283166044820152606481018290526125f39085906323b872dd60e01b9060840161257f565b50505050565b5f61264d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166126cf9092919063ffffffff16565b8051909150156125b6578080602001905181019061266b9190614296565b6125b65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b60606126dd84845f856126e5565b949350505050565b6060824710156127465760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016126c6565b5f80866001600160a01b031685876040516127619190614368565b5f6040518083038185875af1925050503d805f811461279b576040519150601f19603f3d011682016040523d82523d5f602084013e6127a0565b606091505b50915091506127b1878383876127bc565b979650505050505050565b6060831561282a5782515f03612823576001600160a01b0385163b6128235760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016126c6565b50816126dd565b6126dd838381511561283f5781518083602001fd5b8060405162461bcd60e51b81526004016126c69190613100565b634e487b7160e01b5f52604160045260245ffd5b60405160e081016001600160401b038111828210171561288f5761288f612859565b60405290565b604051606081016001600160401b038111828210171561288f5761288f612859565b60405160c081016001600160401b038111828210171561288f5761288f612859565b60405161010081016001600160401b038111828210171561288f5761288f612859565b604080519081016001600160401b038111828210171561288f5761288f612859565b60405160a081016001600160401b038111828210171561288f5761288f612859565b60405161012081016001600160401b038111828210171561288f5761288f612859565b604051601f8201601f191681016001600160401b038111828210171561298b5761298b612859565b604052919050565b5f6001600160401b038211156129ab576129ab612859565b50601f01601f191660200190565b5f82601f8301126129c8575f80fd5b81356129db6129d682612993565b612963565b8181528460208386010111156129ef575f80fd5b816020850160208301375f918101602001919091529392505050565b80356001600160401b0381168114612a21575f80fd5b919050565b5f60e08284031215612a36575f80fd5b612a3e61286d565b905081356001600160401b0380821115612a56575f80fd5b612a62858386016129b9565b83526020840135915080821115612a77575f80fd5b612a83858386016129b9565b6020840152612a9460408501612a0b565b60408401526060840135915080821115612aac575f80fd5b612ab8858386016129b9565b60608401526080840135915080821115612ad0575f80fd5b612adc858386016129b9565b6080840152612aed60a08501612a0b565b60a084015260c0840135915080821115612b05575f80fd5b50612b12848285016129b9565b60c08301525092915050565b5f60608284031215612b2e575f80fd5b612b36612895565b905081356001600160401b0380821115612b4e575f80fd5b612b5a85838601612a26565b83526020840135915080821115612b6f575f80fd5b50612b7c848285016129b9565b602083015250612b8e60408301612a0b565b604082015292915050565b5f60208284031215612ba9575f80fd5b81356001600160401b03811115612bbe575f80fd5b61043b84828501612b1e565b5f8060208385031215612bdb575f80fd5b82356001600160401b0380821115612bf1575f80fd5b818501915085601f830112612c04575f80fd5b813581811115612c12575f80fd5b866020828501011115612c23575f80fd5b60209290920196919550909350505050565b5f60208284031215612c45575f80fd5b81356001600160401b03811115612c5a575f80fd5b8201604081850312156107bc575f80fd5b6001600160a01b0381168114610702575f80fd5b8035612a2181612c6b565b5f60208284031215612c9a575f80fd5b81356001600160401b0380821115612cb0575f80fd5b9083019060c08286031215612cc3575f80fd5b612ccb6128b7565b823582811115612cd9575f80fd5b612ce5878286016129b9565b825250602083013582811115612cf9575f80fd5b612d05878286016129b9565b602083015250604083013582811115612d1c575f80fd5b612d28878286016129b9565b604083015250612d3a60608401612a0b565b606082015260808301356080820152612d5560a08401612c7f565b60a082015295945050505050565b5f6001600160401b03821115612d7b57612d7b612859565b5060051b60200190565b5f82601f830112612d94575f80fd5b81356020612da46129d683612d63565b82815260059290921b84018101918181019086841115612dc2575f80fd5b8286015b84811015612e005780356001600160401b03811115612de4575f8081fd5b612df28986838b01016129b9565b845250918301918301612dc6565b509695505050505050565b5f6101008284031215612e1c575f80fd5b612e246128d9565b905081356001600160401b0380821115612e3c575f80fd5b612e48858386016129b9565b83526020840135915080821115612e5d575f80fd5b612e69858386016129b9565b6020840152612e7a60408501612a0b565b6040840152612e8b60608501612c7f565b6060840152612e9c60808501612a0b565b608084015260a0840135915080821115612eb4575f80fd5b612ec085838601612d85565b60a0840152612ed160c08501612a0b565b60c084015260e0840135915080821115612ee9575f80fd5b50612ef6848285016129b9565b60e08301525092915050565b5f60208284031215612f12575f80fd5b6001600160401b038083351115612f27575f80fd5b8235830160408186031215612f3a575f80fd5b612f426128fc565b8282351115612f4f575f80fd5b8135820160408188031215612f62575f80fd5b612f6a6128fc565b8482351115612f77575f80fd5b612f848883358401612e0b565b81528460208301351115612f96575f80fd5b60208201358201915087601f830112612fad575f80fd5b612fba6129d68335612d63565b82358082526020808301929160051b8501018a811115612fd8575f80fd5b602085015b81811015613073578881351115612ff2575f80fd5b803586016040818e03601f19011215613009575f80fd5b6130116128fc565b8a60208301351115613021575f80fd5b6130338e6020808501358501016129b9565b81528a60408301351115613045575f80fd5b6130588e602060408501358501016129b9565b60208201528086525050602084019350602081019050612fdd565b50508060208401525050808352505061308e60208301612c7f565b602082015295945050505050565b5f602082840312156130ac575f80fd5b5035919050565b5f5b838110156130cd5781810151838201526020016130b5565b50505f910152565b5f81518084526130ec8160208601602086016130b3565b601f01601f19169290920160200192915050565b602081525f6107bc60208301846130d5565b5f60208284031215613122575f80fd5b81356001600160401b0380821115613138575f80fd5b9083019060a0828603121561314b575f80fd5b61315361291e565b823582811115613161575f80fd5b61316d87828601612a26565b825250602083013582811115613181575f80fd5b61318d878286016129b9565b60208301525061319f60408401612a0b565b604082015260608301356060820152608083013592506131be83612c6b565b6080810192909252509392505050565b5f82601f8301126131dd575f80fd5b813560206131ed6129d683612d63565b8281526060928302850182019282820191908785111561320b575f80fd5b8387015b858110156132515781818a031215613226575f8081fd5b61322e612895565b81358152858201358682015260408083013590820152845292840192810161320f565b5090979650505050505050565b5f6040828403121561326e575f80fd5b6132766128fc565b9050813581526020820135602082015292915050565b5f82601f83011261329b575f80fd5b813560206132ab6129d683612d63565b82815260069290921b840181019181810190868411156132c9575f80fd5b8286015b84811015612e00576132df888261325e565b8352918301916040016132cd565b5f80604083850312156132fe575f80fd5b82356001600160401b0380821115613314575f80fd5b908401906101208287031215613328575f80fd5b613330612940565b82358152602083013582811115613345575f80fd5b613351888286016129b9565b602083015250604083013582811115613368575f80fd5b613374888286016129b9565b604083015250606083013560608201526080830135608082015260a083013560a082015260c0830135828111156133a9575f80fd5b6133b5888286016131ce565b60c08301525060e0830135828111156133cc575f80fd5b6133d88882860161328c565b60e08301525061010080840135838111156133f1575f80fd5b6133fd898287016129b9565b91830191909152509660209590950135955050505050565b5f6101208284031215613426575f80fd5b50919050565b5f80828403604081121561343e575f80fd5b83356001600160401b0380821115613454575f80fd5b61346087838801613415565b94506020601f1984011215613473575f80fd5b6040519250602083019150828210818311171561349257613492612859565b506040526020939093013583525092909150565b5f602082840312156134b6575f80fd5b81356001600160401b03808211156134cc575f80fd5b90830190604082860312156134df575f80fd5b6134e76128fc565b8235828111156134f5575f80fd5b61350187828601612b1e565b8252506020830135925061351483612c6b565b6020810192909252509392505050565b5f808284036060811215613536575f80fd5b83356001600160401b0381111561354b575f80fd5b61355786828701613415565b9350506040601f198201121561356b575f80fd5b506135746128fc565b6020840135815260408401356020820152809150509250929050565b5f602082840312156135a0575f80fd5b81356001600160401b038111156135b5575f80fd5b61043b84828501612a26565b5f602082840312156135d1575f80fd5b81356001600160401b03808211156135e7575f80fd5b9083019060c082860312156135fa575f80fd5b6136026128b7565b823582811115613610575f80fd5b61361c878286016129b9565b82525061362b60208401612a0b565b6020820152604083013582811115613641575f80fd5b61364d87828601612d85565b60408301525061365f60608401612a0b565b60608201526080830135608082015260a08301358281111561367f575f80fd5b61368b878286016129b9565b60a08301525095945050505050565b5f604082840312156136aa575f80fd5b6136b26128fc565b82356136bd81612c6b565b815260208301356136cd81612c6b565b60208201529392505050565b6040810161043f828480516001600160a01b03908116835260209182015116910152565b5f6020828403121561370d575f80fd5b81356001600160401b03811115613722575f80fd5b61043b84828501612e0b565b818382375f9101908152919050565b5f823560de19833603018112613751575f80fd5b9190910192915050565b5f808335601e19843603018112613770575f80fd5b8301803591506001600160401b03821115613789575f80fd5b60200191503681900382131561379d575f80fd5b9250929050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f602082840312156137dc575f80fd5b81516001600160401b038111156137f1575f80fd5b8201601f81018413613801575f80fd5b805161380f6129d682612993565b818152856020838501011115613823575f80fd5b6138348260208301602086016130b3565b95945050505050565b5f808585111561384b575f80fd5b83861115613857575f80fd5b5050820193919092039150565b5f60208284031215613874575f80fd5b81356001600160401b038082111561388a575f80fd5b908301906040828603121561389d575f80fd5b6138a56128fc565b8235828111156138b3575f80fd5b6138bf878286016129b9565b8252506020830135602082015280935050505092915050565b604081525f6138ea60408301856130d5565b90508260208301529392505050565b82546001600160a01b0390811682526001840154166020820152608081016107bc604083018480516001600160a01b03908116835260209182015116910152565b5f6020828403121561394a575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761043f5761043f613951565b8082018082111561043f5761043f613951565b5f60208083850312156139a0575f80fd5b82516001600160401b03808211156139b6575f80fd5b90840190606082870312156139c9575f80fd5b6139d1612895565b825181528383015184820152604080840151838111156139ef575f80fd5b80850194505087601f850112613a03575f80fd5b83519250613a136129d684612d63565b83815260069390931b84018501928581019089851115613a31575f80fd5b948601945b84861015613a705782868b031215613a4d575f8081fd5b613a556128fc565b86518152878701518882015282529482019490860190613a36565b91830191909152509695505050505050565b8181038181111561043f5761043f613951565b5f60018201613aa657613aa6613951565b5060010190565b5f60208284031215613abd575f80fd5b81516107bc81612c6b565b5f8151808452602080850194508084015f5b83811015613aff5781516001600160a01b031687529582019590820190600101613ada565b509495945050505050565b828152604060208201525f6126dd6040830184613ac8565b5f6020808385031215613b33575f80fd5b82516001600160401b03811115613b48575f80fd5b8301601f81018513613b58575f80fd5b8051613b666129d682612d63565b81815260059190911b82018301908381019087831115613b84575f80fd5b928401925b828410156127b157835182529284019290840190613b89565b5f8151808452602080850194508084015f5b83811015613aff5781518051885283810151848901526040908101519088015260609096019590820190600101613bb4565b5f8151808452602080850194508084015f5b83811015613aff578151805188528301518388015260409096019590820190600101613bf8565b60208152815160208201525f6020830151610120806040850152613c476101408501836130d5565b91506040850151601f1980868503016060870152613c6584836130d5565b935060608701516080870152608087015160a087015260a087015160c087015260c08701519150808685030160e0870152613ca08483613ba2565b935060e08701519150610100818786030181880152613cbf8584613be6565b90880151878203909201848801529350905061203a83826130d5565b848152608060208201525f613cf36080830186613ac8565b6001600160a01b03949094166040830152506060015292915050565b5f6101208b8352806020840152613d288184018c6130d5565b90508281036040840152613d3c818b6130d5565b90508860608401528760808401528660a084015282810360c0840152613d628187613ba2565b905082810360e0840152613d768186613be6565b9050828103610100840152613d8b81856130d5565b9c9b505050505050505050505050565b5f808335601e19843603018112613db0575f80fd5b83016020810192503590506001600160401b03811115613dce575f80fd5b80360382131561379d575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b5f808335601e19843603018112613e19575f80fd5b83016020810192503590506001600160401b03811115613e37575f80fd5b60608102360382131561379d575f80fd5b8183525f60208085019450825f5b85811015613aff578135875282820135838801526040808301359088015260609687019690910190600101613e56565b5f808335601e19843603018112613e9b575f80fd5b83016020810192503590506001600160401b03811115613eb9575f80fd5b8060061b360382131561379d575f80fd5b8183525f60208085019450825f5b85811015613aff5781358752828201358388015260409687019690910190600101613ed8565b60208152813560208201525f613f176020840184613d9b565b610120806040860152613f2f61014086018385613ddc565b9250613f3e6040870187613d9b565b9250601f1980878603016060880152613f58858584613ddc565b945060608801356080880152608088013560a088015260a088013560c0880152613f8560c0890189613e04565b94509150808786030160e0880152613f9e858584613e48565b9450613fad60e0890189613e86565b94509150610100818887030181890152613fc8868685613eca565b9550613fd6818a018a613d9b565b9550925050808786030183880152506127b1848483613ddc565b5f808335601e19843603018112614005575f80fd5b8301803591506001600160401b0382111561401e575f80fd5b602001915060608102360382131561379d575f80fd5b602081525f6126dd602083018486613ddc565b5f808335601e1984360301811261405c575f80fd5b8301803591506001600160401b03821115614075575f80fd5b6020019150600681901b360382131561379d575f80fd5b5f6040828403121561409c575f80fd5b6107bc838361325e565b6020815281516020820152602082015160408201525f604083015160608084015261043b6080840182613be6565b6001600160f81b03198316815281515f906140f68160018501602087016130b3565b919091016001019392505050565b602081525f825160c0602084015261411f60e08401826130d5565b90506020840151601f198085840301604086015261413d83836130d5565b925060408601519150808584030160608601525061415b82826130d5565b9150506001600160401b036060850151166080840152608084015160a084015260018060a01b0360a08501511660c08401528091505092915050565b5f83516141a88184602088016130b3565b8351908301906141bc8183602088016130b3565b01949350505050565b5f6020808352835160c0828501526141e060e08501826130d5565b90506001600160401b03828601511660408501526040850151601f19808684030160608701528282518085528585019150858160051b86010186850194505f5b8281101561424c578487830301845261423a8287516130d5565b95880195938801939150600101614220565b5060608a01516001600160401b03811660808b0152965060808a015160a08a015260a08a01519650838982030160c08a015261428881886130d5565b9a9950505050505050505050565b5f602082840312156142a6575f80fd5b815180151581146107bc575f80fd5b8035602083101561043f575f19602084900360031b1b1692915050565b5f602082840312156142e2575f80fd5b81356001600160401b03808211156142f8575f80fd5b908301906060828603121561430b575f80fd5b614313612895565b8235815260208301356020820152604083013582811115614332575f80fd5b61433e8782860161328c565b60408301525095945050505050565b5f6020828403121561435d575f80fd5b81356107bc81612c6b565b5f82516137518184602087016130b356fea26469706673582212207c4ae8aa6fc0549d799479a6affadce699d3ef7ca6b7e78c075adf9265f398c664736f6c63430008140033", + "sourceMap": "4610:20547:100:-:0;;;9955:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3419:16:30;3438:6;10511:7:100;:12;-1:-1:-1;;;;;10511:12:100;;10439:91;3438:6:30;3419:25;-1:-1:-1;;;;;;3452:22:30;;;3448:148;;3533:8;-1:-1:-1;;;;;3521:30:30;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3514:77;;-1:-1:-1;;;3514:77:30;;-1:-1:-1;;;;;501:32:126;;;3514:77:30;;;483:51:126;-1:-1:-1;;550:18:126;;;543:34;3514:48:30;;;;;;;456:18:126;;3514:77:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3448:148;-1:-1:-1;9992:6:100;:14;;-1:-1:-1;;;;;;9992:14:100;-1:-1:-1;;;;;9992:14:100;;;;;;;;;;4610:20547;;14:290:126;84:6;137:2;125:9;116:7;112:23;108:32;105:52;;;153:1;150;143:12;105:52;179:16;;-1:-1:-1;;;;;224:31:126;;214:42;;204:70;;270:1;267;260:12;204:70;293:5;14:290;-1:-1:-1;;;14:290:126:o;588:277::-;655:6;708:2;696:9;687:7;683:23;679:32;676:52;;;724:1;721;714:12;676:52;756:9;750:16;809:5;802:13;795:21;788:5;785:32;775:60;;831:1;828;821:12;588:277;4610:20547:100;;;;;;", + "linkReferences": {} + }, + "deployedBytecode": { + "object": "0x60806040526004361061011e575f3560e01c8063b2a01bf51161009d578063cff0ab9611610062578063cff0ab96146102ee578063d0fff3661461033a578063d24740fb14610354578063dd92a31614610373578063f437bc5914610392575f80fd5b8063b2a01bf514610269578063b53eafe914610283578063bc0dd44714610296578063bca96c39146102b0578063c2977d2f146102cf575f80fd5b80634f3f7c05116100e35780634f3f7c05146101d957806360121a94146101f8578063632e235a14610224578063731c8b32146102435780637f84d22914610256575f80fd5b80630bc37bab146101295780630bddd96c1461014a5780630fee32ce1461017c578063108bc1dd1461019b57806344ab20f8146101ba575f80fd5b3661012557005b5f80fd5b348015610134575f80fd5b50610148610143366004612b99565b6103b9565b005b348015610155575f80fd5b50610169610164366004612bca565b6103fd565b6040519081526020015b60405180910390f35b348015610187575f80fd5b50610148610196366004612c35565b610445565b3480156101a6575f80fd5b506101696101b5366004612c8a565b610705565b3480156101c5575f80fd5b506101486101d4366004612f02565b6107c3565b3480156101e4575f80fd5b506101696101f3366004612c8a565b610afa565b348015610203575f80fd5b5061021761021236600461309c565b610d49565b6040516101739190613100565b34801561022f575f80fd5b5061016961023e366004613112565b610d92565b6101486102513660046132ed565b610d9d565b61014861026436600461342c565b611377565b348015610274575f80fd5b506101486101433660046134a6565b610148610291366004613524565b611a69565b3480156102a1575f80fd5b50610148610143366004613590565b3480156102bb575f80fd5b506101696102ca3660046135c1565b611f15565b3480156102da575f80fd5b506101486102e936600461369a565b612044565b3480156102f9575f80fd5b506040805180820182525f80825260209182015281518083019092526001546001600160a01b039081168352600254169082015260405161017391906136d9565b348015610345575f80fd5b506101486101433660046136fd565b34801561035f575f80fd5b5061016961036e3660046135c1565b612183565b34801561037e575f80fd5b5061016961038d366004613112565b61218e565b34801561039d575f80fd5b506001546040516001600160a01b039091168152602001610173565b6001546001600160a01b031633146103e457604051637bf6a16f60e01b815260040160405180910390fd5b6040516302cbc79f60e01b815260040160405180910390fd5b5f8060065f858560405161041292919061372e565b604051809103902081526020019081526020015f205490505f801b8114610439578061043b565b305b9150505b92915050565b6001546001600160a01b0316331461047057604051637bf6a16f60e01b815260040160405180910390fd5b5f61047b828061373d565b6104899060c081019061375b565b5f818110610499576104996137a4565b919091013560f81c905060028111156104b4576104b46137b8565b90505f8160028111156104c9576104c96137b8565b036104db576104d782612246565b5050565b6001546001600160a01b03166001600160a01b0316625e763e6040518163ffffffff1660e01b81526004015f60405180830381865afa158015610520573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261054791908101906137cc565b8051602090910120610559838061373d565b610563908061375b565b60405161057192919061372e565b604051809103902014610596576040516282b42960e81b815260040160405180910390fd5b60018160028111156105aa576105aa6137b8565b03610644575f6105ba838061373d565b6105c89060c081019061375b565b6105d691600190829061383d565b8101906105e39190613864565b6020808201805183518051908401205f9081526006909352604092839020558251905191519293507ff6ef54addfd2bdaa8b0c1fa61c3a9bbf6dde3c0e2640fa16a88f7b38ce5368e39261063792906138d8565b60405180910390a1505050565b6002816002811115610658576106586137b8565b036104d7575f610668838061373d565b6106769060c081019061375b565b61068491600190829061383d565b810190610691919061369a565b90507fa71f7687ff8346b13c6f0923b96164593da1bb1ac8e6c571499fcd041d57245e6001826040516106c59291906138f9565b60405180910390a18051600180546001600160a01b03199081166001600160a01b0393841617909155602090920151600280549093169116179055505b50565b5f8082604001515160201161071f57826040015151610722565b60205b90506107366001546001600160a01b031690565b8351604051632008f60560e11b81526001600160a01b039290921691634011ec0a9161076491600401613100565b602060405180830381865afa15801561077f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107a3919061393a565b6107ad9082613965565b83608001516107bc919061397c565b9392505050565b6001546001600160a01b031633146107ee57604051637bf6a16f60e01b815260040160405180910390fd5b80516020015180515f90610804576108046137a4565b602002602001015160200151515f146108305760405163413e917360e11b815260040160405180910390fd5b80515160e0015180515f9161084d9181016020908101910161398f565b6020810151604082015151919250905f5b818110156109dd575f8460400151828151811061087d5761087d6137a4565b60200260200101515f01515f1c90505f856040015183815181106108a3576108a36137a4565b60209081029190910181015181015187515f9081526004835260408082206001600160a01b03871683529093529182205490925090036108f657604051635c1c6f4b60e11b815260040160405180910390fd5b6001600160a01b03821661097a575f856001600160a01b0316826040515f6040518083038185875af1925050503d805f811461094d576040519150601f19603f3d011682016040523d82523d5f602084013e610952565b606091505b5050905080610974576040516332201f6960e11b815260040160405180910390fd5b5061098e565b61098e6001600160a01b0383168683612553565b85515f9081526004602090815260408083206001600160a01b0386168452909152812080548392906109c1908490613a82565b92505081905550505080806109d590613a95565b91505061085e565b5082515f90815260046020908152604080832073d254fdaa2ce7841c7794b71b85f15052f5aeac8284529091529020548015610ac957610a998382610a2a6001546001600160a01b031690565b6001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a65573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a899190613aad565b6001600160a01b03169190612553565b83515f90815260046020908152604080832073d254fdaa2ce7841c7794b71b85f15052f5aeac8284529091528120555b83516040517f7b08f2d2a35d68f512d4ee819cc6c616e61aa7cd7f7b0855d95ba090d84dc436905f90a25050505050565b5f80610b0583610705565b90505f610b1a6001546001600160a01b031690565b90505f816001600160a01b0316631694505e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b59573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b7d9190613aad565b6040805160028082526060820183529293505f929091602083019080368337019050509050816001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bde573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c029190613aad565b815f81518110610c1457610c146137a4565b60200260200101906001600160a01b031690816001600160a01b031681525050826001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c70573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c949190613aad565b81600181518110610ca757610ca76137a4565b6001600160a01b0392831660209182029290920101526040516307c0329d60e21b815290831690631f00ca7490610ce49087908590600401613b0a565b5f60405180830381865afa158015610cfe573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610d259190810190613b22565b5f81518110610d3657610d366137a4565b6020026020010151945050505050919050565b6040805160056020820152908101829052606090810160408051601f19818403018152828252805160209182012090830152016040516020818303038152906040529050919050565b5f80610b058361218e565b5f610db06001546001600160a01b031690565b5f805460808601523385526040805163f437bc5960e01b815290519293506001600160a01b0384169263f437bc59926004808401939192918290030181865afa158015610dff573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610e2691908101906137cc565b83602001819052505f83604051602001610e409190613c1f565b60408051601f19818403018152919052805160209091012060e08501515190915034905f5b81811015611007578660e001518181518110610e8357610e836137a4565b6020026020010151602001515f03610eae5760405163b4fa3fb360e01b815260040160405180910390fd5b5f8760e001518281518110610ec557610ec56137a4565b60209081029190910101515190506001600160a01b038116610f57578760e001518281518110610ef757610ef76137a4565b602002602001015160200151841015610f23576040516332201f6960e11b815260040160405180910390fd5b8760e001518281518110610f3957610f396137a4565b60200260200101516020015184610f509190613a82565b9350610f98565b610f9833308a60e001518581518110610f7257610f726137a4565b602002602001015160200151846001600160a01b03166125bb909392919063ffffffff16565b8760e001518281518110610fae57610fae6137a4565b6020908102919091018101518101515f8781526004835260408082206001600160a01b0386168352909352918220805491929091610fed90849061397c565b90915550829150610fff905081613a95565b915050610e65565b5060a0860151156112ee575f846001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa15801561104f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110739190613aad565b9050821561129d575f856001600160a01b0316631694505e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110dc9190613aad565b90505f816001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561111b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061113f9190613aad565b6040805160028082526060820183529293505f92909160208301908036833701905050905081815f81518110611177576111776137a4565b60200260200101906001600160a01b031690816001600160a01b031681525050876001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111f79190613aad565b8160018151811061120a5761120a6137a4565b6001600160a01b03928316602091820292909201015260a08b0151604051637ff36ab560e01b815291851691637ff36ab59189916112519190869030904290600401613cdb565b5f6040518083038185885af115801561126c573d5f803e3d5ffd5b50505050506040513d5f823e601f3d908101601f191682016040526112949190810190613b22565b505050506112ba565b60a08701516112ba906001600160a01b03831690339030906125bb565b5060a08601515f84815260046020908152604080832073d254fdaa2ce7841c7794b71b85f15052f5aeac8284529091529020555b60015f808282546112ff919061397c565b90915550508551602087015160408089015160608a015160808b015160a08c015160c08d015160e08e01516101008f015196517fd969ab7a9f9c7b547e1500b952901705e8ae61385f62d7b9a8baa5345a0ac07d996113679990989097969594939291613d0f565b60405180910390a1505050505050565b5f61138a6001546001600160a01b031690565b9050806001600160a01b031663f437bc596040518163ffffffff1660e01b81526004015f60405180830381865afa1580156113c7573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526113ee91908101906137cc565b8051602090910120611403604085018561375b565b60405161141192919061372e565b604051809103902014611437576040516310dfc03360e01b815260040160405180910390fd5b438360600135101561145c57604051630407b05b60e31b815260040160405180910390fd5b5f8360405160200161146e9190613efe565b60408051601f1981840301815291815281516020928301205f81815260059093529120549091506001600160a01b0316156114bc5760405163413e917360e11b815260040160405180910390fd5b345f6114cb60c0870187613ff0565b905090505f5b818110156116ba575f6114e760c0890189613ff0565b838181106114f7576114f76137a4565b606002919091013591505f905061151160c08a018a613ff0565b84818110611521576115216137a4565b905060600201604001355f1c90505f6001600160a01b0316826001600160a01b03160361165f5761155560c08a018a613ff0565b84818110611565576115656137a4565b9050606002016020013585101561158f576040516332201f6960e11b815260040160405180910390fd5b5f6001600160a01b0382166115a760c08c018c613ff0565b868181106115b7576115b76137a4565b905060600201602001356040515f6040518083038185875af1925050503d805f81146115fe576040519150601f19603f3d011682016040523d82523d5f602084013e611603565b606091505b5050905080611625576040516332201f6960e11b815260040160405180910390fd5b61163260c08b018b613ff0565b85818110611642576116426137a4565b90506060020160200135866116579190613a82565b9550506116a5565b6116a5338261167160c08d018d613ff0565b87818110611681576116816137a4565b90506060020160200135856001600160a01b03166125bb909392919063ffffffff16565b505080806116b290613a95565b9150506114d1565b505f6116ca61010088018861375b565b9050111561173c576002546001600160a01b031663ab7fff186116f161010089018961375b565b6040518363ffffffff1660e01b815260040161170e929190614034565b5f604051808303815f87803b158015611725575f80fd5b505af1158015611737573d5f803e3d5ffd5b505050505b604080516060810182528481523360208201525f91810161176060e08a018a614047565b808060200260200160405190810160405280939291908181526020015f905b828210156117ab5761179c6040830286013681900381019061408c565b8152602001906001019061177f565b50505050508152506040516020016117c391906140a6565b60408051601f1981840301815260c0830190915291505f90806117e960208b018b61375b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525050509082525060209081019061183590610164908c018c61375b565b60405160200161184791815260200190565b60408051601f1981840301815291905281526020015f60f81b846040516020016118729291906140d4565b60408051601f198184030181529181529082525f602083015289519082015233606090910152905083156119155760405163b8f3e8f560e01b81526001600160a01b0387169063b8f3e8f59086906118ce908590600401614104565b60206040518083038185885af11580156118ea573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061190f919061393a565b50611a09565b5f866001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611952573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119769190613aad565b90505f61198283610705565b90506119996001600160a01b0383163330846125bb565b60405163b8f3e8f560e01b81526001600160a01b0389169063b8f3e8f5906119c5908690600401614104565b6020604051808303815f875af11580156119e1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a05919061393a565b5050505b5f8581526005602090815260409182902080546001600160a01b03191633908117909155915191825286917f0555709e59fb225fcf12cc582a9e5f7fd8eea54c91f3dc500ab9d8c37c507770910160405180910390a25050505050505050565b5f82604051602001611a7b9190613efe565b60408051601f198184030181529190528051602090910120905082353314611ab5576040516282b42960e81b815260040160405180910390fd5b8260600135826020015111611add5760405163d0404f8560e01b815260040160405180910390fd5b5f818152600560205260409020546001600160a01b031615611b125760405163413e917360e11b815260040160405180910390fd5b5f611b2060e0850185614047565b905090505f5b81811015611bb5575f83815260046020526040812090611b4960e0880188614047565b84818110611b5957611b596137a4565b9050604002015f01355f1c6001600160a01b03166001600160a01b031681526020019081526020015f20545f03611ba357604051635c1c6f4b60e11b815260040160405180910390fd5b80611bad81613a95565b915050611b26565b5060408051606081018252838152853560208201525f918101611bdb60e0880188614047565b808060200260200160405190810160405280939291908181526020015f905b82821015611c2657611c176040830286013681900381019061408c565b81526020019060010190611bfa565b5050505050815250604051602001611c3e91906140a6565b60408051808303601f19018152600180845283830190925292505f9190816020015b6060815260200190600190039081611c60579050509050611c87610164604088018861375b565b604051611caf919060200160609190911b6bffffffffffffffffffffffff1916815260140190565b604051602081830303815290604052611cc785610d49565b604051602001611cd8929190614197565b604051602081830303815290604052815f81518110611cf957611cf96137a4565b60200260200101819052505f6040518060c00160405280888060400190611d20919061375b565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201829052509385525050506020898101516001600160401b03169083015260408201859052606082018190528851608083015260a0909101859052909150611d9a6001546001600160a01b031690565b90503415611e175760405163d22e334360e01b81526001600160a01b0382169063d22e3343903490611dd09086906004016141c5565b60206040518083038185885af1158015611dec573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190611e11919061393a565b50611f0b565b5f816001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e54573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e789190613aad565b90505f611e8484611f15565b9050611e9b6001600160a01b0383163330846125bb565b60405163d22e334360e01b81526001600160a01b0384169063d22e334390611ec79087906004016141c5565b6020604051808303815f875af1158015611ee3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f07919061393a565b5050505b5050505050505050565b5f80611f296001546001600160a01b031690565b90505f816001600160a01b0316634011ec0a836001600160a01b031663f437bc596040518163ffffffff1660e01b81526004015f60405180830381865afa158015611f76573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052611f9d91908101906137cc565b6040518263ffffffff1660e01b8152600401611fb99190613100565b602060405180830381865afa158015611fd4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ff8919061393a565b90505f612006826020613965565b90505f8560a00151518361201a9190613965565b8660800151612029919061397c565b9050808211612038578061203a565b815b9695505050505050565b6003546001600160a01b0316331461206e576040516282b42960e81b815260040160405180910390fd5b805f01516001600160a01b031663647846a56040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120d19190613aad565b815160405163095ea7b360e01b81526001600160a01b0391821660048201525f19602482015291169063095ea7b3906044016020604051808303815f875af115801561211f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121439190614296565b50600380546001600160a01b03199081169091558151600180546001600160a01b0392831690841617905560209092015160028054919093169116179055565b5f80610b0583611f15565b5f808260200151516020116121a8578260200151516121ab565b60205b90506121bf6001546001600160a01b031690565b835151604051632008f60560e11b81526001600160a01b039290921691634011ec0a916121ee91600401613100565b602060405180830381865afa158015612209573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061222d919061393a565b6122379082613965565b83606001516107bc919061397c565b612250818061373d565b5f61225e606083018361375b565b61226c916020915f9161383d565b612275916142b5565b905080612285610164848061375b565b146122a2576040516282b42960e81b815260040160405180910390fd5b5f6122ad848061373d565b6122bb9060c081019061375b565b6122c991600190829061383d565b8101906122d691906142d2565b6020810151604082015151919250905f5b81811015612466575f84604001518281518110612306576123066137a4565b60200260200101515f01515f1c90505f8560400151838151811061232c5761232c6137a4565b60209081029190910181015181015187515f9081526004835260408082206001600160a01b038716835290935291822054909250900361237f57604051635c1c6f4b60e11b815260040160405180910390fd5b6001600160a01b038216612403575f856001600160a01b0316826040515f6040518083038185875af1925050503d805f81146123d6576040519150601f19603f3d011682016040523d82523d5f602084013e6123db565b606091505b50509050806123fd576040516332201f6960e11b815260040160405180910390fd5b50612417565b6124176001600160a01b0383168683612553565b85515f9081526004602090815260408083206001600160a01b03861684529091528120805483929061244a908490613a82565b925050819055505050808061245e90613a95565b9150506122e7565b5082515f90815260046020908152604080832073d254fdaa2ce7841c7794b71b85f15052f5aeac82845290915290205480156124e3576124b38382610a2a6001546001600160a01b031690565b83515f90815260046020908152604080832073d254fdaa2ce7841c7794b71b85f15052f5aeac8284529091528120555b6124f3604088016020890161434d565b84515f9081526005602052604080822080546001600160a01b0319166001600160a01b039490941693909317909255855191517fb6e94cf3f8e202cc261173363d27daa8f5e2e79cff984b252f786794afb499469190a250505050505050565b6040516001600160a01b0383166024820152604481018290526125b690849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526125f9565b505050565b6040516001600160a01b03808516602483015283166044820152606481018290526125f39085906323b872dd60e01b9060840161257f565b50505050565b5f61264d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166126cf9092919063ffffffff16565b8051909150156125b6578080602001905181019061266b9190614296565b6125b65760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084015b60405180910390fd5b60606126dd84845f856126e5565b949350505050565b6060824710156127465760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016126c6565b5f80866001600160a01b031685876040516127619190614368565b5f6040518083038185875af1925050503d805f811461279b576040519150601f19603f3d011682016040523d82523d5f602084013e6127a0565b606091505b50915091506127b1878383876127bc565b979650505050505050565b6060831561282a5782515f03612823576001600160a01b0385163b6128235760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016126c6565b50816126dd565b6126dd838381511561283f5781518083602001fd5b8060405162461bcd60e51b81526004016126c69190613100565b634e487b7160e01b5f52604160045260245ffd5b60405160e081016001600160401b038111828210171561288f5761288f612859565b60405290565b604051606081016001600160401b038111828210171561288f5761288f612859565b60405160c081016001600160401b038111828210171561288f5761288f612859565b60405161010081016001600160401b038111828210171561288f5761288f612859565b604080519081016001600160401b038111828210171561288f5761288f612859565b60405160a081016001600160401b038111828210171561288f5761288f612859565b60405161012081016001600160401b038111828210171561288f5761288f612859565b604051601f8201601f191681016001600160401b038111828210171561298b5761298b612859565b604052919050565b5f6001600160401b038211156129ab576129ab612859565b50601f01601f191660200190565b5f82601f8301126129c8575f80fd5b81356129db6129d682612993565b612963565b8181528460208386010111156129ef575f80fd5b816020850160208301375f918101602001919091529392505050565b80356001600160401b0381168114612a21575f80fd5b919050565b5f60e08284031215612a36575f80fd5b612a3e61286d565b905081356001600160401b0380821115612a56575f80fd5b612a62858386016129b9565b83526020840135915080821115612a77575f80fd5b612a83858386016129b9565b6020840152612a9460408501612a0b565b60408401526060840135915080821115612aac575f80fd5b612ab8858386016129b9565b60608401526080840135915080821115612ad0575f80fd5b612adc858386016129b9565b6080840152612aed60a08501612a0b565b60a084015260c0840135915080821115612b05575f80fd5b50612b12848285016129b9565b60c08301525092915050565b5f60608284031215612b2e575f80fd5b612b36612895565b905081356001600160401b0380821115612b4e575f80fd5b612b5a85838601612a26565b83526020840135915080821115612b6f575f80fd5b50612b7c848285016129b9565b602083015250612b8e60408301612a0b565b604082015292915050565b5f60208284031215612ba9575f80fd5b81356001600160401b03811115612bbe575f80fd5b61043b84828501612b1e565b5f8060208385031215612bdb575f80fd5b82356001600160401b0380821115612bf1575f80fd5b818501915085601f830112612c04575f80fd5b813581811115612c12575f80fd5b866020828501011115612c23575f80fd5b60209290920196919550909350505050565b5f60208284031215612c45575f80fd5b81356001600160401b03811115612c5a575f80fd5b8201604081850312156107bc575f80fd5b6001600160a01b0381168114610702575f80fd5b8035612a2181612c6b565b5f60208284031215612c9a575f80fd5b81356001600160401b0380821115612cb0575f80fd5b9083019060c08286031215612cc3575f80fd5b612ccb6128b7565b823582811115612cd9575f80fd5b612ce5878286016129b9565b825250602083013582811115612cf9575f80fd5b612d05878286016129b9565b602083015250604083013582811115612d1c575f80fd5b612d28878286016129b9565b604083015250612d3a60608401612a0b565b606082015260808301356080820152612d5560a08401612c7f565b60a082015295945050505050565b5f6001600160401b03821115612d7b57612d7b612859565b5060051b60200190565b5f82601f830112612d94575f80fd5b81356020612da46129d683612d63565b82815260059290921b84018101918181019086841115612dc2575f80fd5b8286015b84811015612e005780356001600160401b03811115612de4575f8081fd5b612df28986838b01016129b9565b845250918301918301612dc6565b509695505050505050565b5f6101008284031215612e1c575f80fd5b612e246128d9565b905081356001600160401b0380821115612e3c575f80fd5b612e48858386016129b9565b83526020840135915080821115612e5d575f80fd5b612e69858386016129b9565b6020840152612e7a60408501612a0b565b6040840152612e8b60608501612c7f565b6060840152612e9c60808501612a0b565b608084015260a0840135915080821115612eb4575f80fd5b612ec085838601612d85565b60a0840152612ed160c08501612a0b565b60c084015260e0840135915080821115612ee9575f80fd5b50612ef6848285016129b9565b60e08301525092915050565b5f60208284031215612f12575f80fd5b6001600160401b038083351115612f27575f80fd5b8235830160408186031215612f3a575f80fd5b612f426128fc565b8282351115612f4f575f80fd5b8135820160408188031215612f62575f80fd5b612f6a6128fc565b8482351115612f77575f80fd5b612f848883358401612e0b565b81528460208301351115612f96575f80fd5b60208201358201915087601f830112612fad575f80fd5b612fba6129d68335612d63565b82358082526020808301929160051b8501018a811115612fd8575f80fd5b602085015b81811015613073578881351115612ff2575f80fd5b803586016040818e03601f19011215613009575f80fd5b6130116128fc565b8a60208301351115613021575f80fd5b6130338e6020808501358501016129b9565b81528a60408301351115613045575f80fd5b6130588e602060408501358501016129b9565b60208201528086525050602084019350602081019050612fdd565b50508060208401525050808352505061308e60208301612c7f565b602082015295945050505050565b5f602082840312156130ac575f80fd5b5035919050565b5f5b838110156130cd5781810151838201526020016130b5565b50505f910152565b5f81518084526130ec8160208601602086016130b3565b601f01601f19169290920160200192915050565b602081525f6107bc60208301846130d5565b5f60208284031215613122575f80fd5b81356001600160401b0380821115613138575f80fd5b9083019060a0828603121561314b575f80fd5b61315361291e565b823582811115613161575f80fd5b61316d87828601612a26565b825250602083013582811115613181575f80fd5b61318d878286016129b9565b60208301525061319f60408401612a0b565b604082015260608301356060820152608083013592506131be83612c6b565b6080810192909252509392505050565b5f82601f8301126131dd575f80fd5b813560206131ed6129d683612d63565b8281526060928302850182019282820191908785111561320b575f80fd5b8387015b858110156132515781818a031215613226575f8081fd5b61322e612895565b81358152858201358682015260408083013590820152845292840192810161320f565b5090979650505050505050565b5f6040828403121561326e575f80fd5b6132766128fc565b9050813581526020820135602082015292915050565b5f82601f83011261329b575f80fd5b813560206132ab6129d683612d63565b82815260069290921b840181019181810190868411156132c9575f80fd5b8286015b84811015612e00576132df888261325e565b8352918301916040016132cd565b5f80604083850312156132fe575f80fd5b82356001600160401b0380821115613314575f80fd5b908401906101208287031215613328575f80fd5b613330612940565b82358152602083013582811115613345575f80fd5b613351888286016129b9565b602083015250604083013582811115613368575f80fd5b613374888286016129b9565b604083015250606083013560608201526080830135608082015260a083013560a082015260c0830135828111156133a9575f80fd5b6133b5888286016131ce565b60c08301525060e0830135828111156133cc575f80fd5b6133d88882860161328c565b60e08301525061010080840135838111156133f1575f80fd5b6133fd898287016129b9565b91830191909152509660209590950135955050505050565b5f6101208284031215613426575f80fd5b50919050565b5f80828403604081121561343e575f80fd5b83356001600160401b0380821115613454575f80fd5b61346087838801613415565b94506020601f1984011215613473575f80fd5b6040519250602083019150828210818311171561349257613492612859565b506040526020939093013583525092909150565b5f602082840312156134b6575f80fd5b81356001600160401b03808211156134cc575f80fd5b90830190604082860312156134df575f80fd5b6134e76128fc565b8235828111156134f5575f80fd5b61350187828601612b1e565b8252506020830135925061351483612c6b565b6020810192909252509392505050565b5f808284036060811215613536575f80fd5b83356001600160401b0381111561354b575f80fd5b61355786828701613415565b9350506040601f198201121561356b575f80fd5b506135746128fc565b6020840135815260408401356020820152809150509250929050565b5f602082840312156135a0575f80fd5b81356001600160401b038111156135b5575f80fd5b61043b84828501612a26565b5f602082840312156135d1575f80fd5b81356001600160401b03808211156135e7575f80fd5b9083019060c082860312156135fa575f80fd5b6136026128b7565b823582811115613610575f80fd5b61361c878286016129b9565b82525061362b60208401612a0b565b6020820152604083013582811115613641575f80fd5b61364d87828601612d85565b60408301525061365f60608401612a0b565b60608201526080830135608082015260a08301358281111561367f575f80fd5b61368b878286016129b9565b60a08301525095945050505050565b5f604082840312156136aa575f80fd5b6136b26128fc565b82356136bd81612c6b565b815260208301356136cd81612c6b565b60208201529392505050565b6040810161043f828480516001600160a01b03908116835260209182015116910152565b5f6020828403121561370d575f80fd5b81356001600160401b03811115613722575f80fd5b61043b84828501612e0b565b818382375f9101908152919050565b5f823560de19833603018112613751575f80fd5b9190910192915050565b5f808335601e19843603018112613770575f80fd5b8301803591506001600160401b03821115613789575f80fd5b60200191503681900382131561379d575f80fd5b9250929050565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b5f602082840312156137dc575f80fd5b81516001600160401b038111156137f1575f80fd5b8201601f81018413613801575f80fd5b805161380f6129d682612993565b818152856020838501011115613823575f80fd5b6138348260208301602086016130b3565b95945050505050565b5f808585111561384b575f80fd5b83861115613857575f80fd5b5050820193919092039150565b5f60208284031215613874575f80fd5b81356001600160401b038082111561388a575f80fd5b908301906040828603121561389d575f80fd5b6138a56128fc565b8235828111156138b3575f80fd5b6138bf878286016129b9565b8252506020830135602082015280935050505092915050565b604081525f6138ea60408301856130d5565b90508260208301529392505050565b82546001600160a01b0390811682526001840154166020820152608081016107bc604083018480516001600160a01b03908116835260209182015116910152565b5f6020828403121561394a575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b808202811582820484141761043f5761043f613951565b8082018082111561043f5761043f613951565b5f60208083850312156139a0575f80fd5b82516001600160401b03808211156139b6575f80fd5b90840190606082870312156139c9575f80fd5b6139d1612895565b825181528383015184820152604080840151838111156139ef575f80fd5b80850194505087601f850112613a03575f80fd5b83519250613a136129d684612d63565b83815260069390931b84018501928581019089851115613a31575f80fd5b948601945b84861015613a705782868b031215613a4d575f8081fd5b613a556128fc565b86518152878701518882015282529482019490860190613a36565b91830191909152509695505050505050565b8181038181111561043f5761043f613951565b5f60018201613aa657613aa6613951565b5060010190565b5f60208284031215613abd575f80fd5b81516107bc81612c6b565b5f8151808452602080850194508084015f5b83811015613aff5781516001600160a01b031687529582019590820190600101613ada565b509495945050505050565b828152604060208201525f6126dd6040830184613ac8565b5f6020808385031215613b33575f80fd5b82516001600160401b03811115613b48575f80fd5b8301601f81018513613b58575f80fd5b8051613b666129d682612d63565b81815260059190911b82018301908381019087831115613b84575f80fd5b928401925b828410156127b157835182529284019290840190613b89565b5f8151808452602080850194508084015f5b83811015613aff5781518051885283810151848901526040908101519088015260609096019590820190600101613bb4565b5f8151808452602080850194508084015f5b83811015613aff578151805188528301518388015260409096019590820190600101613bf8565b60208152815160208201525f6020830151610120806040850152613c476101408501836130d5565b91506040850151601f1980868503016060870152613c6584836130d5565b935060608701516080870152608087015160a087015260a087015160c087015260c08701519150808685030160e0870152613ca08483613ba2565b935060e08701519150610100818786030181880152613cbf8584613be6565b90880151878203909201848801529350905061203a83826130d5565b848152608060208201525f613cf36080830186613ac8565b6001600160a01b03949094166040830152506060015292915050565b5f6101208b8352806020840152613d288184018c6130d5565b90508281036040840152613d3c818b6130d5565b90508860608401528760808401528660a084015282810360c0840152613d628187613ba2565b905082810360e0840152613d768186613be6565b9050828103610100840152613d8b81856130d5565b9c9b505050505050505050505050565b5f808335601e19843603018112613db0575f80fd5b83016020810192503590506001600160401b03811115613dce575f80fd5b80360382131561379d575f80fd5b81835281816020850137505f828201602090810191909152601f909101601f19169091010190565b5f808335601e19843603018112613e19575f80fd5b83016020810192503590506001600160401b03811115613e37575f80fd5b60608102360382131561379d575f80fd5b8183525f60208085019450825f5b85811015613aff578135875282820135838801526040808301359088015260609687019690910190600101613e56565b5f808335601e19843603018112613e9b575f80fd5b83016020810192503590506001600160401b03811115613eb9575f80fd5b8060061b360382131561379d575f80fd5b8183525f60208085019450825f5b85811015613aff5781358752828201358388015260409687019690910190600101613ed8565b60208152813560208201525f613f176020840184613d9b565b610120806040860152613f2f61014086018385613ddc565b9250613f3e6040870187613d9b565b9250601f1980878603016060880152613f58858584613ddc565b945060608801356080880152608088013560a088015260a088013560c0880152613f8560c0890189613e04565b94509150808786030160e0880152613f9e858584613e48565b9450613fad60e0890189613e86565b94509150610100818887030181890152613fc8868685613eca565b9550613fd6818a018a613d9b565b9550925050808786030183880152506127b1848483613ddc565b5f808335601e19843603018112614005575f80fd5b8301803591506001600160401b0382111561401e575f80fd5b602001915060608102360382131561379d575f80fd5b602081525f6126dd602083018486613ddc565b5f808335601e1984360301811261405c575f80fd5b8301803591506001600160401b03821115614075575f80fd5b6020019150600681901b360382131561379d575f80fd5b5f6040828403121561409c575f80fd5b6107bc838361325e565b6020815281516020820152602082015160408201525f604083015160608084015261043b6080840182613be6565b6001600160f81b03198316815281515f906140f68160018501602087016130b3565b919091016001019392505050565b602081525f825160c0602084015261411f60e08401826130d5565b90506020840151601f198085840301604086015261413d83836130d5565b925060408601519150808584030160608601525061415b82826130d5565b9150506001600160401b036060850151166080840152608084015160a084015260018060a01b0360a08501511660c08401528091505092915050565b5f83516141a88184602088016130b3565b8351908301906141bc8183602088016130b3565b01949350505050565b5f6020808352835160c0828501526141e060e08501826130d5565b90506001600160401b03828601511660408501526040850151601f19808684030160608701528282518085528585019150858160051b86010186850194505f5b8281101561424c578487830301845261423a8287516130d5565b95880195938801939150600101614220565b5060608a01516001600160401b03811660808b0152965060808a015160a08a015260a08a01519650838982030160c08a015261428881886130d5565b9a9950505050505050505050565b5f602082840312156142a6575f80fd5b815180151581146107bc575f80fd5b8035602083101561043f575f19602084900360031b1b1692915050565b5f602082840312156142e2575f80fd5b81356001600160401b03808211156142f8575f80fd5b908301906060828603121561430b575f80fd5b614313612895565b8235815260208301356020820152604083013582811115614332575f80fd5b61433e8782860161328c565b60408301525095945050505050565b5f6020828403121561435d575f80fd5b81356107bc81612c6b565b5f82516137518184602087016130b356fea26469706673582212207c4ae8aa6fc0549d799479a6affadce699d3ef7ca6b7e78c075adf9265f398c664736f6c63430008140033", + "sourceMap": "4610:20547:100:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6729:109:30;;;;;;;;;;-1:-1:-1;6729:109:30;;;;;:::i;:::-;;:::i;:::-;;10619:242:100;;;;;;;;;;-1:-1:-1;10619:242:100;;;;;:::i;:::-;;:::i;:::-;;;6065:25:126;;;6053:2;6038:18;10619:242:100;;;;;;;;18488:980;;;;;;;;;;-1:-1:-1;18488:980:100;;;;;:::i;:::-;;:::i;3895:224:30:-;;;;;;;;;;-1:-1:-1;3895:224:30;;;;;:::i;:::-;;:::i;23811:1344:100:-;;;;;;;;;;-1:-1:-1;23811:1344:100;;;;;:::i;:::-;;:::i;4215:403:30:-;;;;;;;;;;-1:-1:-1;4215:403:30;;;;;:::i;:::-;;:::i;12338:203:100:-;;;;;;;;;;-1:-1:-1;12338:203:100;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;5984:411:30:-;;;;;;;;;;-1:-1:-1;5984:411:30;;;;;:::i;:::-;;:::i;12765:2388:100:-;;;;;;:::i;:::-;;:::i;15405:2835::-;;;;;;:::i;:::-;;:::i;6616:110:30:-;;;;;;;;;;-1:-1:-1;6616:110:30;;;;;:::i;21458:2059:100:-;;;;;;:::i;:::-;;:::i;6506:107:30:-;;;;;;;;;;-1:-1:-1;6506:107:30;;;;;:::i;4709:333::-;;;;;;;;;;-1:-1:-1;4709:333:30;;;;;:::i;:::-;;:::i;11408:285:100:-;;;;;;;;;;-1:-1:-1;11408:285:100;;;;;:::i;:::-;;:::i;11942:85::-;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;12006:14:100;;;;;;;;12013:7;12006:14;-1:-1:-1;;;;;12006:14:100;;;;;;;;;;;;11942:85;;;;;;:::i;6952:98:30:-;;;;;;;;;;-1:-1:-1;6952:98:30;;;;;:::i;5137:402::-;;;;;;;;;;-1:-1:-1;5137:402:30;;;;;:::i;:::-;;:::i;5632:255::-;;;;;;;;;;-1:-1:-1;5632:255:30;;;;;:::i;:::-;;:::i;10439:91:100:-;;;;;;;;;;-1:-1:-1;10511:7:100;:12;10439:91;;-1:-1:-1;;;;;10511:12:100;;;23639:51:126;;23627:2;23612:18;10439:91:100;23493:203:126;6729:109:30;10511:7:100;:12;-1:-1:-1;;;;;10511:12:100;3342:10:30;:20;3338:51;;3371:18;;-1:-1:-1;;;3371:18:30;;;;;;;;;;;3338:51;6818:16:::1;;-1:-1:-1::0;;;6818:16:30::1;;;;;;;;;;;10619:242:100::0;10689:7;10708:15;10726:10;:37;10747:14;;10737:25;;;;;;;:::i;:::-;;;;;;;;10726:37;;;;;;;;;;;;10708:55;;10799:1;10791:10;;10780:7;:21;:74;;10847:7;10780:74;;;10836:4;10780:74;10773:81;;;10619:242;;;;;:::o;18488:980::-;10511:7;:12;-1:-1:-1;;;;;10511:12:100;3342:10:30;:20;3338:51;;3371:18;;-1:-1:-1;;;3371:18:30;;;;;;;;;;;3338:51;18582:16:100::1;18619;:8:::0;;:16:::1;:::i;:::-;:21;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;18641:1;18619:24;;;;;;;:::i;:::-;::::0;;;::::1;;;;::::0;-1:-1:-1;18601:44:100::1;::::0;::::1;;;;;;:::i;:::-;18582:63:::0;-1:-1:-1;18667:24:100::1;18659:4;:32;;;;;;;;:::i;:::-;::::0;18655:61:::1;;18700:16;18707:8;18700:6;:16::i;:::-;18693:23;18488:980:::0;:::o;18655:61::-:1;10511:7:::0;:12;-1:-1:-1;;;;;10511:12:100;-1:-1:-1;;;;;18844:31:100::1;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;18844:33:100::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;18834:44:::0;;::::1;::::0;;::::1;::::0;18806:16:::1;:8:::0;;:16:::1;:::i;:::-;:23;::::0;;::::1;:::i;:::-;18796:34;;;;;;;:::i;:::-;;;;;;;;:82;18792:109;;18887:14;;-1:-1:-1::0;;;18887:14:100::1;;;;;;;;;;;18792:109;18923:25;18915:4;:33;;;;;;;;:::i;:::-;::::0;18911:551:::1;;18964:25;19003:16;:8:::0;;:16:::1;:::i;:::-;:21;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;:25;::::0;19025:1:::1;::::0;19003:25;;::::1;:::i;:::-;18992:54;;;;;;;:::i;:::-;19105:12;::::0;;::::1;::::0;;19081:19;;19071:30;;;;::::1;::::0;19060:42:::1;::::0;;;:10:::1;:42:::0;;;;;;;;:57;19173:19;;19203:12;;19137:80;;18964:82;;-1:-1:-1;19137:80:100::1;::::0;::::1;::::0;19203:12;19137:80:::1;:::i;:::-;;;;;;;;18950:278;18693:23;18488:980:::0;:::o;18911:551::-:1;19246:24;19238:4;:32;;;;;;;;:::i;:::-;::::0;19234:228:::1;;19286:18;19318:16;:8:::0;;:16:::1;:::i;:::-;:21;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;:25;::::0;19340:1:::1;::::0;19318:25;;::::1;:::i;:::-;19307:47;;;;;;;:::i;:::-;19286:68;;19373:49;19398:7;19416:4;19373:49;;;;;;;:::i;:::-;;;;;;;;19437:14:::0;;:7:::1;:14:::0;;-1:-1:-1;;;;;;19437:14:100;;::::1;-1:-1:-1::0;;;;;19437:14:100;;::::1;;::::0;;;::::1;::::0;;::::1;::::0;;;;;;::::1;::::0;::::1;;::::0;;18572:896:::1;3393:1:30;18488:980:100::0;:::o;3895:224:30:-;3960:7;3973:11;3992:7;:12;;;:19;3987:2;:24;:51;;4019:7;:12;;;:19;3987:51;;;4014:2;3987:51;3973:65;;4082:6;10511:7:100;:12;-1:-1:-1;;;;;10511:12:100;;10439:91;4082:6:30;4101:12;;4070:44;;-1:-1:-1;;;4070:44:30;;-1:-1:-1;;;;;4070:30:30;;;;;;;:44;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4064:50;;:3;:50;:::i;:::-;4049:7;:11;;;:66;;;;:::i;:::-;4042:73;3895:224;-1:-1:-1;;;3895:224:30:o;23811:1344:100:-;10511:7;:12;-1:-1:-1;;;;;10511:12:100;3342:10:30;:20;3338:51;;3371:18;;-1:-1:-1;;;3371:18:30;;;;;;;;;;;3338:51;23912:17:100;;:24:::1;;::::0;:27;;:17:::1;::::0;:27:::1;;;;:::i;:::-;;;;;;;:33;;;:40;23956:1;23912:45;23908:66;;23966:8;;-1:-1:-1::0;;;23966:8:100::1;;;;;;;;;;;23908:66;24022:17:::0;;:25;:33:::1;;::::0;24011:60;;23985:23:::1;::::0;24011:60:::1;::::0;;;::::1;::::0;;;;::::1;;:::i;:::-;24127:16;::::0;::::1;::::0;24206:11:::1;::::0;::::1;::::0;:18;23985:86;;-1:-1:-1;24127:16:100;24081:19:::1;24234:577;24258:3;24254:1;:7;24234:577;;;24282:13;24322:4;:11;;;24334:1;24322:14;;;;;;;;:::i;:::-;;;;;;;:20;;;24314:29;;24282:63;;24359:14;24376:4;:11;;;24388:1;24376:14;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;:21;::::1;::::0;24423:15;;24415:24:::1;::::0;;;:7:::1;:24:::0;;;;;;-1:-1:-1;;;;;24415:31:100;::::1;::::0;;;;;;;;;24376:21;;-1:-1:-1;24415:36:100;;24411:63:::1;;24460:14;;-1:-1:-1::0;;;24460:14:100::1;;;;;;;;;;;24411:63;-1:-1:-1::0;;;;;24493:19:100;::::1;24489:256;;24533:9;24548:11;-1:-1:-1::0;;;;;24548:16:100::1;24572:6;24548:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24532:51;;;24606:4;24601:43;;24619:25;;-1:-1:-1::0;;;24619:25:100::1;;;;;;;;;;;24601:43;24514:145;24489:256;;;24683:47;-1:-1:-1::0;;;;;24683:26:100;::::1;24710:11:::0;24723:6;24683:26:::1;:47::i;:::-;24767:15:::0;;24759:24:::1;::::0;;;:7:::1;:24;::::0;;;;;;;-1:-1:-1;;;;;24759:31:100;::::1;::::0;;;;;;;:41;;24794:6;;24759:24;:41:::1;::::0;24794:6;;24759:41:::1;:::i;:::-;;;;;;;;24268:543;;24263:3;;;;;:::i;:::-;;;;24234:577;;;-1:-1:-1::0;24871:15:100;;24848:12:::1;24863:24:::0;;;:7:::1;:24;::::0;;;;;;;:42;;;;;;;;;24919:8;;24915:173:::1;;24943:70;24995:11;25008:4;24962:6;10511:7:::0;:12;-1:-1:-1;;;;;10511:12:100;;10439:91;24962:6:::1;-1:-1:-1::0;;;;;24950:28:100::1;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;24943:51:100::1;::::0;:70;:51:::1;:70::i;:::-;25043:15:::0;;25035:24:::1;::::0;;;:7:::1;:24;::::0;;;;;;;:42;;;;;;;;25028:49;24915:173:::1;25131:15:::0;;25103:45:::1;::::0;::::1;::::0;25131:15:::1;::::0;25103:45:::1;23898:1257;;;;23811:1344:::0;:::o;4215:403:30:-;4286:7;4299:11;4313:14;4319:7;4313:5;:14::i;:::-;4299:28;;4331:13;4347:6;10511:7:100;:12;-1:-1:-1;;;;;10511:12:100;;10439:91;4347:6:30;4331:22;;4357:16;4388:5;-1:-1:-1;;;;;4376:34:30;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4440:16;;;4454:1;4440:16;;;;;;;;4357:55;;-1:-1:-1;4416:21:30;;4440:16;;;;;;;;;;;;-1:-1:-1;4440:16:30;4416:40;;4489:8;-1:-1:-1;;;;;4470:33:30;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4460:4;4465:1;4460:7;;;;;;;;:::i;:::-;;;;;;:45;-1:-1:-1;;;;;4460:45:30;;;-1:-1:-1;;;;;4460:45:30;;;;;4531:5;-1:-1:-1;;;;;4519:27:30;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4509:4;4514:1;4509:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;4509:39:30;;;:7;;;;;;;;;:39;4559:52;;-1:-1:-1;;;4559:52:30;;:41;;;;;;:52;;4601:3;;4606:4;;4559:52;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4559:52:30;;;;;;;;;;;;:::i;:::-;4612:1;4559:55;;;;;;;;:::i;:::-;;;;;;;4552:62;;;;;;4215:403;;;:::o;12338:203:100:-;12474:58;;;12491:28;12474:58;;;32314:19:126;32349:12;;;32342:28;;;12416:12:100;;32386::126;;12474:58:100;;;-1:-1:-1;;12474:58:100;;;;;;;;;12464:69;;12474:58;12464:69;;;;12447:87;;;32538:19:126;32573:12;12447:87:100;;;;;;;;;;;;12440:94;;12338:203;;;:::o;5984:411:30:-;6063:7;6076:11;6090:14;6096:7;6090:5;:14::i;12765:2388:100:-;12848:16;12867:6;10511:7;:12;-1:-1:-1;;;;;10511:12:100;;10439:91;12867:6;12936;;;12922:11;;;:20;12989:10;12952:50;;13032:28;;;-1:-1:-1;;;13032:28:100;;;;12848:25;;-1:-1:-1;;;;;;13032:26:100;;;;;:28;;;;;12936:6;;13032:28;;;;;;:26;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;13032:28:100;;;;;;;;;;;;:::i;:::-;13012:5;:17;;:48;;;;13071:18;13113:5;13102:17;;;;;;;;:::i;:::-;;;;-1:-1:-1;;13102:17:100;;;;;;;;;13092:28;;13102:17;13092:28;;;;13214:12;;;;:19;13092:28;;-1:-1:-1;13175:9:100;;13156:16;13243:638;13267:9;13263:1;:13;13243:638;;;13301:5;:12;;;13314:1;13301:15;;;;;;;;:::i;:::-;;;;;;;:22;;;13327:1;13301:27;13297:54;;13337:14;;-1:-1:-1;;;13337:14:100;;;;;;;;;;;13297:54;13365:13;13405:5;:12;;;13418:1;13405:15;;;;;;;;:::i;:::-;;;;;;;;;;;:21;;-1:-1:-1;;;;;;13447:19:100;;13443:333;;13533:5;:12;;;13546:1;13533:15;;;;;;;;:::i;:::-;;;;;;;:22;;;13522:8;:33;13518:71;;;13564:25;;-1:-1:-1;;;13564:25:100;;;;;;;;;;;13518:71;13619:5;:12;;;13632:1;13619:15;;;;;;;;:::i;:::-;;;;;;;:22;;;13607:34;;;;;:::i;:::-;;;13443:333;;;13680:81;13711:10;13731:4;13738:5;:12;;;13751:1;13738:15;;;;;;;;:::i;:::-;;;;;;;:22;;;13687:5;-1:-1:-1;;;;;13680:30:100;;;:81;;;;;;:::i;:::-;13848:5;:12;;;13861:1;13848:15;;;;;;;;:::i;:::-;;;;;;;;;;;;:22;;;13818:19;;;;:7;:19;;;;;;-1:-1:-1;;;;;13818:26:100;;;;;;;;;;:52;;13848:22;;13818:26;;:52;;13848:22;;13818:52;:::i;:::-;;;;-1:-1:-1;13278:3:100;;-1:-1:-1;13278:3:100;;-1:-1:-1;13278:3:100;;:::i;:::-;;;;13243:638;;;-1:-1:-1;13895:10:100;;;;:14;13891:874;;13952:16;13983:8;-1:-1:-1;;;;;13971:30:100;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13952:51;-1:-1:-1;14021:12:100;;14017:674;;14053:17;14085:8;-1:-1:-1;;;;;14073:37:100;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14053:59;;14130:12;14164:9;-1:-1:-1;;;;;14145:34:100;;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14223:16;;;14237:1;14223:16;;;;;;;;14130:51;;-1:-1:-1;14199:21:100;;14223:16;;;;;;;;;;;;-1:-1:-1;14223:16:100;14199:40;;14267:4;14257;14262:1;14257:7;;;;;;;;:::i;:::-;;;;;;:14;-1:-1:-1;;;;;14257:14:100;;;-1:-1:-1;;;;;14257:14:100;;;;;14311:8;-1:-1:-1;;;;;14299:30:100;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;14289:4;14294:1;14289:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;14289:42:100;;;:7;;;;;;;;;:42;14439:10;;;;14349:216;;-1:-1:-1;;;14349:216:100;;:51;;;;;;14408:8;;14349:216;;14439:10;14471:4;;14505;;14532:15;;14349:216;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;14349:216:100;;;;;;;;;;;;:::i;:::-;;14035:545;;;14017:674;;;14665:10;;;;14604:72;;-1:-1:-1;;;;;14604:33:100;;;14638:10;;14658:4;;14604:33;:72::i;:::-;-1:-1:-1;14744:10:100;;;;14704:19;;;;:7;:19;;;;;;;;:37;;;;;;;;:50;13891:874;14785:1;14775:6;;:11;;;;;;;:::i;:::-;;;;-1:-1:-1;;14833:10:100;;14870:17;;;;14912:15;;;;;14951:14;;;;14986:11;;;;15017:10;;;;15050:13;;;;15085:12;;;;15121:14;;;;14801:345;;;;;;14833:10;;14870:17;;14912:15;14951:14;14986:11;15017:10;15050:13;15085:12;14801:345;:::i;:::-;;;;;;;;12838:2315;;;;12765:2388;;:::o;15405:2835::-;15499:16;15518:6;10511:7;:12;-1:-1:-1;;;;;10511:12:100;;10439:91;15518:6;15499:25;;15655:8;-1:-1:-1;;;;;15643:26:100;;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;15643:28:100;;;;;;;;;;;;:::i;:::-;15633:39;;;;;;;15613:15;;;;:5;:15;:::i;:::-;15603:26;;;;;;;:::i;:::-;;;;;;;;:69;15599:94;;15681:12;;-1:-1:-1;;;15681:12:100;;;;;;;;;;;15599:94;15769:12;15752:5;:14;;;:29;15748:51;;;15790:9;;-1:-1:-1;;;15790:9:100;;;;;;;;;;;15748:51;15858:18;15900:5;15889:17;;;;;;;;:::i;:::-;;;;-1:-1:-1;;15889:17:100;;;;;;;;;15879:28;;15889:17;15879:28;;;;15952:1;15921:19;;;:7;:19;;;;;;15879:28;;-1:-1:-1;;;;;;15921:19:100;:33;15917:54;;15963:8;;-1:-1:-1;;;15963:8:100;;;;;;;;;;;15917:54;16027:9;16008:16;16067:13;;;;:5;:13;:::i;:::-;:20;;16046:41;;16102:9;16097:717;16121:10;16117:1;:14;16097:717;;;16152:13;16192;;;;:5;:13;:::i;:::-;16206:1;16192:16;;;;;;;:::i;:::-;;;;;;;:22;;-1:-1:-1;16192:22:100;;-1:-1:-1;16277:13:100;;;;:5;:13;:::i;:::-;16291:1;16277:16;;;;;;;:::i;:::-;;;;;;:28;;;16269:37;;16231:77;;16344:1;-1:-1:-1;;;;;16327:19:100;:5;-1:-1:-1;;;;;16327:19:100;;16323:481;;16413:13;;;;:5;:13;:::i;:::-;16427:1;16413:16;;;;;;;:::i;:::-;;;;;;:23;;;16402:8;:34;16398:72;;;16445:25;;-1:-1:-1;;;16445:25:100;;;;;;;;;;;16398:72;16489:9;-1:-1:-1;;;;;16504:16:100;;16528:13;;;;:5;:13;:::i;:::-;16542:1;16528:16;;;;;;;:::i;:::-;;;;;;:23;;;16504:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16488:68;;;16579:4;16574:43;;16592:25;;-1:-1:-1;;;16592:25:100;;;;;;;;;;;16574:43;16647:13;;;;:5;:13;:::i;:::-;16661:1;16647:16;;;;;;;:::i;:::-;;;;;;:23;;;16635:35;;;;;:::i;:::-;;;16348:337;16323:481;;;16709:80;16740:10;16752:11;16765:13;;;;:5;:13;:::i;:::-;16779:1;16765:16;;;;;;;:::i;:::-;;;;;;:23;;;16716:5;-1:-1:-1;;;;;16709:30:100;;;:80;;;;;;:::i;:::-;16138:676;;16133:3;;;;;:::i;:::-;;;;16097:717;;;-1:-1:-1;16885:1:100;16861:14;;;;:5;:14;:::i;:::-;:21;;:25;16857:116;;;16918:18;;-1:-1:-1;;;;;16918:18:100;16902:44;16947:14;16918:18;16947:14;;:5;:14;:::i;:::-;16902:60;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16857:116;17067:173;;;;;;;;;;;17212:10;17067:173;;;;17023:17;;17067:173;;17145:12;;;;:5;:12;:::i;:::-;17067:173;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;17043:207;;;;;;;;:::i;:::-;;;;-1:-1:-1;;17043:207:100;;;;;;17290:295;;;;;;17043:207;-1:-1:-1;17260:27:100;;17043:207;17323:17;17043:207;17323:17;;:5;:17;:::i;:::-;17290:295;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;17290:295:100;;;-1:-1:-1;17290:295:100;;;;;17375:27;;17384:17;;;;:5;:17;:::i;17375:27::-;17358:45;;;;;;32538:19:126;;32582:2;32573:12;;32409:182;17358:45:100;;;;-1:-1:-1;;17358:45:100;;;;;;;;;17290:295;;17358:45;17290:295;17449:24;17436:39;;17477:4;17423:59;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;17423:59:100;;;;;;;;;17290:295;;;17505:1;17423:59;17290:295;;;17525:18;;17290:295;;;;17564:10;17290:295;;;;;17260:325;-1:-1:-1;17639:12:100;;17635:484;;17742:56;;-1:-1:-1;;;17742:56:100;;-1:-1:-1;;;;;17742:30:100;;;;;17780:8;;17742:56;;17790:7;;17742:56;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;17635:484;;;17883:16;17914:8;-1:-1:-1;;;;;17902:30:100;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;17883:51;;17948:11;17962:14;17968:7;17962:5;:14::i;:::-;17948:28;-1:-1:-1;17990:65:100;-1:-1:-1;;;;;17990:33:100;;18024:10;18044:4;17948:28;17990:33;:65::i;:::-;18069:39;;-1:-1:-1;;;18069:39:100;;-1:-1:-1;;;;;18069:30:100;;;;;:39;;18100:7;;18069:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;17815:304;;17635:484;18129:19;;;;:7;:19;;;;;;;;;:32;;-1:-1:-1;;;;;;18129:32:100;18151:10;18129:32;;;;;;18176:57;;23639:51:126;;;18129:19:100;;18176:57;;23612:18:126;18176:57:100;;;;;;;15489:2751;;;;;;15405:2835;;:::o;21458:2059::-;21556:18;21598:5;21587:17;;;;;;;;:::i;:::-;;;;-1:-1:-1;;21587:17:100;;;;;;;;;21577:28;;21587:17;21577:28;;;;;-1:-1:-1;21659:10:100;;21697;21659:51;21655:78;;21719:14;;-1:-1:-1;;;21719:14:100;;;;;;;;;;;21655:78;21803:5;:14;;;21785:7;:14;;;:32;21781:57;;21826:12;;-1:-1:-1;;;21826:12:100;;;;;;;;;;;21781:57;21925:1;21894:19;;;:7;:19;;;;;;-1:-1:-1;;;;;21894:19:100;:33;21890:54;;21936:8;;-1:-1:-1;;;21936:8:100;;;;;;;;;;;21890:54;21983:17;22003:12;;;;:5;:12;:::i;:::-;:19;;21983:39;;22037:9;22032:207;22056:9;22052:1;:13;22032:207;;;22131:19;;;;:7;:19;;;;;;22175:12;;;;:5;:12;:::i;:::-;22188:1;22175:15;;;;;;;:::i;:::-;;;;;;:21;;;22167:30;;-1:-1:-1;;;;;22131:69:100;-1:-1:-1;;;;;22131:69:100;;;;;;;;;;;;;22204:1;22131:74;22127:101;;22214:14;;-1:-1:-1;;;22214:14:100;;;;;;;;;;;22127:101;22067:3;;;;:::i;:::-;;;;22032:207;;;-1:-1:-1;22296:84:100;;;;;;;;;;;22368:10;;22296:84;;;;22249:20;;22296:84;;22341:12;;;;22368:5;22341:12;:::i;:::-;22296:84;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;22272:118;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;22272:118:100;;;22435:1;22423:14;;;;;;;;;22272:118;-1:-1:-1;22401:19:100;;22272:118;22423:14;;;;;;;;;;;;;;;;;;;-1:-1:-1;22401:36:100;-1:-1:-1;22556:25:100;22565:15;;;;:5;:15;:::i;22556:25::-;22515:70;;;;22548:34;22515:70;;46008:2:126;46004:15;;;;-1:-1:-1;;46000:53:126;45988:66;;46079:2;46070:12;;45859:229;22515:70:100;;;;;;;;;;;;;22632:39;22660:10;22632:27;:39::i;:::-;22457:224;;;;;;;;;:::i;:::-;;;;;;;;;;;;;22447:4;22452:1;22447:7;;;;;;;;:::i;:::-;;;;;;:234;;;;22691:26;22720:217;;;;;;;;22752:5;:15;;;;;;;;:::i;:::-;22720:217;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;22720:217:100;;;-1:-1:-1;;;22720:217:100;22844:14;;;;-1:-1:-1;;;;;22720:217:100;;;;;;;;;;;;;;;;;22878:18;;22720:217;;;;;;;;;;;22691:246;;-1:-1:-1;23009:6:100;10511:7;:12;-1:-1:-1;;;;;10511:12:100;;10439:91;23009:6;22990:25;-1:-1:-1;23029:9:100;:13;23025:486;;23133:57;;-1:-1:-1;;;23133:57:100;;-1:-1:-1;;;;;23133:30:100;;;;;23171:9;;23133:57;;23182:7;;23133:57;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;23025:486;;;23275:16;23306:8;-1:-1:-1;;;;;23294:30:100;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;23275:51;;23340:11;23354:14;23360:7;23354:5;:14::i;:::-;23340:28;-1:-1:-1;23382:65:100;-1:-1:-1;;;;;23382:33:100;;23416:10;23436:4;23340:28;23382:33;:65::i;:::-;23461:39;;-1:-1:-1;;;23461:39:100;;-1:-1:-1;;;;;23461:30:100;;;;;:39;;23492:7;;23461:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;23207:304;;23025:486;21546:1971;;;;;;21458:2059;;:::o;4709:333:30:-;4773:7;4786:13;4802:6;10511:7:100;:12;-1:-1:-1;;;;;10511:12:100;;10439:91;4802:6:30;4786:22;;4812:11;4838:5;-1:-1:-1;;;;;4826:29:30;;4868:5;-1:-1:-1;;;;;4856:23:30;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4856:25:30;;;;;;;;;;;;:::i;:::-;4826:56;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4812:70;-1:-1:-1;4886:18:30;4907:8;4812:70;4907:2;:8;:::i;:::-;4886:29;;4919:16;4959:7;:15;;;:22;4953:3;:28;;;;:::i;:::-;4938:7;:11;;;:44;;;;:::i;:::-;4919:63;;5006:8;4993:10;:21;:45;;5030:8;4993:45;;;5017:10;4993:45;4986:52;4709:333;-1:-1:-1;;;;;;4709:333:30:o;11408:285:100:-;11479:6;;-1:-1:-1;;;;;11479:6:100;11465:10;:20;11461:47;;11494:14;;-1:-1:-1;;;11494:14:100;;;;;;;;;;;11461:47;11581:1;:6;;;-1:-1:-1;;;;;11569:28:100;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;11609:6;;11562:73;;-1:-1:-1;;;11562:73:100;;-1:-1:-1;;;;;48263:32:126;;;11562:73:100;;;48245:51:126;-1:-1:-1;;48312:18:126;;;48305:34;11562:46:100;;;;;48218:18:126;;11562:73:100;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;11646:6:100;:19;;-1:-1:-1;;;;;;11646:19:100;;;;;;11675:11;;11646:19;11675:11;;-1:-1:-1;;;;;11675:11:100;;;;;;;;;;;;;;-1:-1:-1;11675:11:100;;;;;;;;;;;11408:285::o;5137:402:30:-;5207:7;5220:11;5234:14;5240:7;5234:5;:14::i;5632:255::-;5706:7;5719:11;5738:8;:17;;;:24;5733:2;:29;:61;;5770:8;:17;;;:24;5733:61;;;5765:2;5733:61;5719:75;;5839:6;10511:7:100;:12;-1:-1:-1;;;;;10511:12:100;;10439:91;5839:6:30;5858:16;;:23;5827:55;;-1:-1:-1;;;5827:55:30;;-1:-1:-1;;;;;5827:30:30;;;;;;;:55;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5821:61;;:3;:61;:::i;:::-;5805:8;:12;;;:78;;;;:::i;19695:1319:100:-;19772:16;:8;;:16;:::i;:::-;11036:14;11061:12;;;;:7;:12;:::i;:::-;:17;;11075:2;;11061:17;;;:::i;:::-;11053:26;;;:::i;:::-;11036:43;-1:-1:-1;11036:43:100;11178:24;11187:14;:7;;:14;:::i;11178:24::-;:34;11174:61;;11221:14;;-1:-1:-1;;;11221:14:100;;;;;;;;;;;11174:61;19800:23:::1;19837:16;:8:::0;;:16:::1;:::i;:::-;:21;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;:25;::::0;19859:1:::1;::::0;19837:25;;::::1;:::i;:::-;19826:52;;;;;;;:::i;:::-;19934:16;::::0;::::1;::::0;20012:11:::1;::::0;::::1;::::0;:18;19800:78;;-1:-1:-1;19934:16:100;19888:19:::1;20040:577;20064:3;20060:1;:7;20040:577;;;20088:13;20128:4;:11;;;20140:1;20128:14;;;;;;;;:::i;:::-;;;;;;;:20;;;20120:29;;20088:63;;20165:14;20182:4;:11;;;20194:1;20182:14;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;;;:21;::::1;::::0;20229:15;;20221:24:::1;::::0;;;:7:::1;:24:::0;;;;;;-1:-1:-1;;;;;20221:31:100;::::1;::::0;;;;;;;;;20182:21;;-1:-1:-1;20221:36:100;;20217:63:::1;;20266:14;;-1:-1:-1::0;;;20266:14:100::1;;;;;;;;;;;20217:63;-1:-1:-1::0;;;;;20299:19:100;::::1;20295:256;;20339:9;20354:11;-1:-1:-1::0;;;;;20354:16:100::1;20378:6;20354:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20338:51;;;20412:4;20407:43;;20425:25;;-1:-1:-1::0;;;20425:25:100::1;;;;;;;;;;;20407:43;20320:145;20295:256;;;20489:47;-1:-1:-1::0;;;;;20489:26:100;::::1;20516:11:::0;20529:6;20489:26:::1;:47::i;:::-;20573:15:::0;;20565:24:::1;::::0;;;:7:::1;:24;::::0;;;;;;;-1:-1:-1;;;;;20565:31:100;::::1;::::0;;;;;;;:41;;20600:6;;20565:24;:41:::1;::::0;20600:6;;20565:41:::1;:::i;:::-;;;;;;;;20074:543;;20069:3;;;;;:::i;:::-;;;;20040:577;;;-1:-1:-1::0;20676:15:100;;20653:12:::1;20668:24:::0;;;:7:::1;:24;::::0;;;;;;;:42;;;;;;;;;20724:8;;20720:173:::1;;20748:70;20800:11;20813:4;20767:6;10511:7:::0;:12;-1:-1:-1;;;;;10511:12:100;;10439:91;20748:70:::1;20848:15:::0;;20840:24:::1;::::0;;;:7:::1;:24;::::0;;;;;;;:42;;;;;;;;20833:49;20720:173:::1;20930:16;::::0;;;::::1;::::0;::::1;;:::i;:::-;20911:15:::0;;20903:24:::1;::::0;;;:7:::1;:24;::::0;;;;;:43;;-1:-1:-1;;;;;;20903:43:100::1;-1:-1:-1::0;;;;;20903:43:100;;;::::1;::::0;;;::::1;::::0;;;20990:15;;20962:45;;::::1;::::0;20903:24;20962:45:::1;19790:1224;;;;11026:227:::0;19695:1319;;:::o;763:205:63:-;902:58;;-1:-1:-1;;;;;48263:32:126;;902:58:63;;;48245:51:126;48312:18;;;48305:34;;;875:86:63;;895:5;;-1:-1:-1;;;925:23:63;48218:18:126;;902:58:63;;;;-1:-1:-1;;902:58:63;;;;;;;;;;;;;;-1:-1:-1;;;;;902:58:63;-1:-1:-1;;;;;;902:58:63;;;;;;;;;;875:19;:86::i;:::-;763:205;;;:::o;974:241::-;1139:68;;-1:-1:-1;;;;;50157:15:126;;;1139:68:63;;;50139:34:126;50209:15;;50189:18;;;50182:43;50241:18;;;50234:34;;;1112:96:63;;1132:5;;-1:-1:-1;;;1162:27:63;50074:18:126;;1139:68:63;49899:375:126;1112:96:63;974:241;;;;:::o;3747:706::-;4166:23;4192:69;4220:4;4192:69;;;;;;;;;;;;;;;;;4200:5;-1:-1:-1;;;;;4192:27:63;;;:69;;;;;:::i;:::-;4275:17;;4166:95;;-1:-1:-1;4275:21:63;4271:176;;4370:10;4359:30;;;;;;;;;;;;:::i;:::-;4351:85;;;;-1:-1:-1;;;4351:85:63;;50481:2:126;4351:85:63;;;50463:21:126;50520:2;50500:18;;;50493:30;50559:34;50539:18;;;50532:62;-1:-1:-1;;;50610:18:126;;;50603:40;50660:19;;4351:85:63;;;;;;;;3873:223:64;4006:12;4037:52;4059:6;4067:4;4073:1;4076:12;4037:21;:52::i;:::-;4030:59;3873:223;-1:-1:-1;;;;3873:223:64:o;4960:446::-;5125:12;5182:5;5157:21;:30;;5149:81;;;;-1:-1:-1;;;5149:81:64;;50892:2:126;5149:81:64;;;50874:21:126;50931:2;50911:18;;;50904:30;50970:34;50950:18;;;50943:62;-1:-1:-1;;;51021:18:126;;;51014:36;51067:19;;5149:81:64;50690:402:126;5149:81:64;5241:12;5255:23;5282:6;-1:-1:-1;;;;;5282:11:64;5301:5;5308:4;5282:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5240:73;;;;5330:69;5357:6;5365:7;5374:10;5386:12;5330:26;:69::i;:::-;5323:76;4960:446;-1:-1:-1;;;;;;;4960:446:64:o;7466:628::-;7646:12;7674:7;7670:418;;;7701:10;:17;7722:1;7701:22;7697:286;;-1:-1:-1;;;;;1465:19:64;;;7908:60;;;;-1:-1:-1;;;7908:60:64;;51591:2:126;7908:60:64;;;51573:21:126;51630:2;51610:18;;;51603:30;51669:31;51649:18;;;51642:59;51718:18;;7908:60:64;51389:353:126;7908:60:64;-1:-1:-1;8003:10:64;7996:17;;7670:418;8044:33;8052:10;8064:12;8775:17;;:21;8771:379;;9003:10;8997:17;9059:15;9046:10;9042:2;9038:19;9031:44;8771:379;9126:12;9119:20;;-1:-1:-1;;;9119:20:64;;;;;;;;:::i;14:127:126:-;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:253;218:2;212:9;260:4;248:17;;-1:-1:-1;;;;;280:34:126;;316:22;;;277:62;274:88;;;342:18;;:::i;:::-;378:2;371:22;146:253;:::o;404:::-;476:2;470:9;518:4;506:17;;-1:-1:-1;;;;;538:34:126;;574:22;;;535:62;532:88;;;600:18;;:::i;662:253::-;734:2;728:9;776:4;764:17;;-1:-1:-1;;;;;796:34:126;;832:22;;;793:62;790:88;;;858:18;;:::i;920:255::-;992:2;986:9;1034:6;1022:19;;-1:-1:-1;;;;;1056:34:126;;1092:22;;;1053:62;1050:88;;;1118:18;;:::i;1180:257::-;1252:4;1246:11;;;1284:17;;-1:-1:-1;;;;;1316:34:126;;1352:22;;;1313:62;1310:88;;;1378:18;;:::i;1442:253::-;1514:2;1508:9;1556:4;1544:17;;-1:-1:-1;;;;;1576:34:126;;1612:22;;;1573:62;1570:88;;;1638:18;;:::i;1700:255::-;1772:2;1766:9;1814:6;1802:19;;-1:-1:-1;;;;;1836:34:126;;1872:22;;;1833:62;1830:88;;;1898:18;;:::i;1960:275::-;2031:2;2025:9;2096:2;2077:13;;-1:-1:-1;;2073:27:126;2061:40;;-1:-1:-1;;;;;2116:34:126;;2152:22;;;2113:62;2110:88;;;2178:18;;:::i;:::-;2214:2;2207:22;1960:275;;-1:-1:-1;1960:275:126:o;2240:186::-;2288:4;-1:-1:-1;;;;;2313:6:126;2310:30;2307:56;;;2343:18;;:::i;:::-;-1:-1:-1;2409:2:126;2388:15;-1:-1:-1;;2384:29:126;2415:4;2380:40;;2240:186::o;2431:462::-;2473:5;2526:3;2519:4;2511:6;2507:17;2503:27;2493:55;;2544:1;2541;2534:12;2493:55;2580:6;2567:20;2611:48;2627:31;2655:2;2627:31;:::i;:::-;2611:48;:::i;:::-;2684:2;2675:7;2668:19;2730:3;2723:4;2718:2;2710:6;2706:15;2702:26;2699:35;2696:55;;;2747:1;2744;2737:12;2696:55;2812:2;2805:4;2797:6;2793:17;2786:4;2777:7;2773:18;2760:55;2860:1;2835:16;;;2853:4;2831:27;2824:38;;;;2839:7;2431:462;-1:-1:-1;;;2431:462:126:o;2898:171::-;2965:20;;-1:-1:-1;;;;;3014:30:126;;3004:41;;2994:69;;3059:1;3056;3049:12;2994:69;2898:171;;;:::o;3074:1243::-;3132:5;3180:4;3168:9;3163:3;3159:19;3155:30;3152:50;;;3198:1;3195;3188:12;3152:50;3220:22;;:::i;:::-;3211:31;;3278:9;3265:23;-1:-1:-1;;;;;3348:2:126;3340:6;3337:14;3334:34;;;3364:1;3361;3354:12;3334:34;3391:45;3432:3;3423:6;3412:9;3408:22;3391:45;:::i;:::-;3384:5;3377:60;3490:2;3479:9;3475:18;3462:32;3446:48;;3519:2;3509:8;3506:16;3503:36;;;3535:1;3532;3525:12;3503:36;3571:47;3614:3;3603:8;3592:9;3588:24;3571:47;:::i;:::-;3566:2;3559:5;3555:14;3548:71;3651:37;3684:2;3673:9;3669:18;3651:37;:::i;:::-;3646:2;3639:5;3635:14;3628:61;3742:2;3731:9;3727:18;3714:32;3698:48;;3771:2;3761:8;3758:16;3755:36;;;3787:1;3784;3777:12;3755:36;3823:47;3866:3;3855:8;3844:9;3840:24;3823:47;:::i;:::-;3818:2;3811:5;3807:14;3800:71;3924:3;3913:9;3909:19;3896:33;3880:49;;3954:2;3944:8;3941:16;3938:36;;;3970:1;3967;3960:12;3938:36;4007:47;4050:3;4039:8;4028:9;4024:24;4007:47;:::i;:::-;4001:3;3994:5;3990:15;3983:72;4088:38;4121:3;4110:9;4106:19;4088:38;:::i;:::-;4082:3;4075:5;4071:15;4064:63;4180:3;4169:9;4165:19;4152:33;4136:49;;4210:2;4200:8;4197:16;4194:36;;;4226:1;4223;4216:12;4194:36;;4263:47;4306:3;4295:8;4284:9;4280:24;4263:47;:::i;:::-;4257:3;4250:5;4246:15;4239:72;;3074:1243;;;;:::o;4322:635::-;4381:5;4429:4;4417:9;4412:3;4408:19;4404:30;4401:50;;;4447:1;4444;4437:12;4401:50;4469:22;;:::i;:::-;4460:31;;4527:9;4514:23;-1:-1:-1;;;;;4597:2:126;4589:6;4586:14;4583:34;;;4613:1;4610;4603:12;4583:34;4640:58;4694:3;4685:6;4674:9;4670:22;4640:58;:::i;:::-;4633:5;4626:73;4752:2;4741:9;4737:18;4724:32;4708:48;;4781:2;4771:8;4768:16;4765:36;;;4797:1;4794;4787:12;4765:36;;4833:47;4876:3;4865:8;4854:9;4850:24;4833:47;:::i;:::-;4828:2;4821:5;4817:14;4810:71;;4913:37;4946:2;4935:9;4931:18;4913:37;:::i;:::-;4908:2;4901:5;4897:14;4890:61;4322:635;;;;:::o;4962:356::-;5052:6;5105:2;5093:9;5084:7;5080:23;5076:32;5073:52;;;5121:1;5118;5111:12;5073:52;5161:9;5148:23;-1:-1:-1;;;;;5186:6:126;5183:30;5180:50;;;5226:1;5223;5216:12;5180:50;5249:63;5304:7;5295:6;5284:9;5280:22;5249:63;:::i;5323:591::-;5393:6;5401;5454:2;5442:9;5433:7;5429:23;5425:32;5422:52;;;5470:1;5467;5460:12;5422:52;5510:9;5497:23;-1:-1:-1;;;;;5580:2:126;5572:6;5569:14;5566:34;;;5596:1;5593;5586:12;5566:34;5634:6;5623:9;5619:22;5609:32;;5679:7;5672:4;5668:2;5664:13;5660:27;5650:55;;5701:1;5698;5691:12;5650:55;5741:2;5728:16;5767:2;5759:6;5756:14;5753:34;;;5783:1;5780;5773:12;5753:34;5828:7;5823:2;5814:6;5810:2;5806:15;5802:24;5799:37;5796:57;;;5849:1;5846;5839:12;5796:57;5880:2;5872:11;;;;;5902:6;;-1:-1:-1;5323:591:126;;-1:-1:-1;;;;5323:591:126:o;6101:399::-;6200:6;6253:2;6241:9;6232:7;6228:23;6224:32;6221:52;;;6269:1;6266;6259:12;6221:52;6309:9;6296:23;-1:-1:-1;;;;;6334:6:126;6331:30;6328:50;;;6374:1;6371;6364:12;6328:50;6397:22;;6453:2;6435:16;;;6431:25;6428:45;;;6469:1;6466;6459:12;6505:131;-1:-1:-1;;;;;6580:31:126;;6570:42;;6560:70;;6626:1;6623;6616:12;6641:134;6709:20;;6738:31;6709:20;6738:31;:::i;6780:1147::-;6870:6;6923:2;6911:9;6902:7;6898:23;6894:32;6891:52;;;6939:1;6936;6929:12;6891:52;6979:9;6966:23;-1:-1:-1;;;;;7049:2:126;7041:6;7038:14;7035:34;;;7065:1;7062;7055:12;7035:34;7088:22;;;;7144:4;7126:16;;;7122:27;7119:47;;;7162:1;7159;7152:12;7119:47;7188:22;;:::i;:::-;7248:2;7235:16;7276:2;7266:8;7263:16;7260:36;;;7292:1;7289;7282:12;7260:36;7319:44;7355:7;7344:8;7340:2;7336:17;7319:44;:::i;:::-;7312:5;7305:59;;7410:2;7406;7402:11;7389:25;7439:2;7429:8;7426:16;7423:36;;;7455:1;7452;7445:12;7423:36;7491:44;7527:7;7516:8;7512:2;7508:17;7491:44;:::i;:::-;7486:2;7479:5;7475:14;7468:68;;7582:2;7578;7574:11;7561:25;7611:2;7601:8;7598:16;7595:36;;;7627:1;7624;7617:12;7595:36;7663:44;7699:7;7688:8;7684:2;7680:17;7663:44;:::i;:::-;7658:2;7651:5;7647:14;7640:68;;7740:30;7766:2;7762;7758:11;7740:30;:::i;:::-;7735:2;7728:5;7724:14;7717:54;7825:3;7821:2;7817:12;7804:26;7798:3;7791:5;7787:15;7780:51;7864:32;7891:3;7887:2;7883:12;7864:32;:::i;:::-;7858:3;7847:15;;7840:57;7851:5;6780:1147;-1:-1:-1;;;;;6780:1147:126:o;8114:181::-;8172:4;-1:-1:-1;;;;;8197:6:126;8194:30;8191:56;;;8227:18;;:::i;:::-;-1:-1:-1;8272:1:126;8268:14;8284:4;8264:25;;8114:181::o;8300:884::-;8352:5;8405:3;8398:4;8390:6;8386:17;8382:27;8372:55;;8423:1;8420;8413:12;8372:55;8459:6;8446:20;8485:4;8509:58;8525:41;8563:2;8525:41;:::i;8509:58::-;8601:15;;;8687:1;8683:10;;;;8671:23;;8667:32;;;8632:12;;;;8711:15;;;8708:35;;;8739:1;8736;8729:12;8708:35;8775:2;8767:6;8763:15;8787:368;8803:6;8798:3;8795:15;8787:368;;;8889:3;8876:17;-1:-1:-1;;;;;8912:11:126;8909:35;8906:125;;;8985:1;9014:2;9010;9003:14;8906:125;9056:56;9108:3;9103:2;9089:11;9081:6;9077:24;9073:33;9056:56;:::i;:::-;9044:69;;-1:-1:-1;9133:12:126;;;;8820;;8787:368;;;-1:-1:-1;9173:5:126;8300:884;-1:-1:-1;;;;;;8300:884:126:o;9189:1215::-;9246:5;9294:6;9282:9;9277:3;9273:19;9269:32;9266:52;;;9314:1;9311;9304:12;9266:52;9336:22;;:::i;:::-;9327:31;;9394:9;9381:23;-1:-1:-1;;;;;9464:2:126;9456:6;9453:14;9450:34;;;9480:1;9477;9470:12;9450:34;9507:45;9548:3;9539:6;9528:9;9524:22;9507:45;:::i;:::-;9500:5;9493:60;9606:2;9595:9;9591:18;9578:32;9562:48;;9635:2;9625:8;9622:16;9619:36;;;9651:1;9648;9641:12;9619:36;9687:47;9730:3;9719:8;9708:9;9704:24;9687:47;:::i;:::-;9682:2;9675:5;9671:14;9664:71;9767:37;9800:2;9789:9;9785:18;9767:37;:::i;:::-;9762:2;9755:5;9751:14;9744:61;9837:38;9871:2;9860:9;9856:18;9837:38;:::i;:::-;9832:2;9825:5;9821:14;9814:62;9909:38;9942:3;9931:9;9927:19;9909:38;:::i;:::-;9903:3;9896:5;9892:15;9885:63;10001:3;9990:9;9986:19;9973:33;9957:49;;10031:2;10021:8;10018:16;10015:36;;;10047:1;10044;10037:12;10015:36;10084:57;10137:3;10126:8;10115:9;10111:24;10084:57;:::i;:::-;10078:3;10071:5;10067:15;10060:82;10175:38;10208:3;10197:9;10193:19;10175:38;:::i;:::-;10169:3;10162:5;10158:15;10151:63;10267:3;10256:9;10252:19;10239:33;10223:49;;10297:2;10287:8;10284:16;10281:36;;;10313:1;10310;10303:12;10281:36;;10350:47;10393:3;10382:8;10371:9;10367:24;10350:47;:::i;:::-;10344:3;10337:5;10333:15;10326:72;;9189:1215;;;;:::o;10409:2155::-;10506:6;10559:2;10547:9;10538:7;10534:23;10530:32;10527:52;;;10575:1;10572;10565:12;10527:52;-1:-1:-1;;;;;10656:2:126;10644:9;10631:23;10628:31;10625:51;;;10672:1;10669;10662:12;10625:51;10723:9;10710:23;10699:9;10695:39;10768:4;10763:2;10754:7;10750:16;10746:27;10743:47;;;10786:1;10783;10776:12;10743:47;10812:22;;:::i;:::-;10867:2;10862;10849:16;10846:24;10843:44;;;10883:1;10880;10873:12;10843:44;10927:2;10914:16;10910:2;10906:25;10965:4;10960:2;10951:7;10947:16;10943:27;10940:47;;;10983:1;10980;10973:12;10940:47;11011:22;;:::i;:::-;11066:2;11061;11048:16;11045:24;11042:44;;;11082:1;11079;11072:12;11042:44;11111:64;11167:7;11161:2;11148:16;11144:2;11140:25;11111:64;:::i;:::-;11102:7;11095:81;11218:2;11212;11208;11204:11;11191:25;11188:33;11185:53;;;11234:1;11231;11224:12;11185:53;11286:2;11282;11278:11;11265:25;11261:2;11257:34;11247:44;;11329:7;11322:4;11318:2;11314:13;11310:27;11300:55;;11351:1;11348;11341:12;11300:55;11375:72;11391:55;11442:2;11429:16;11391:55;:::i;11375:72::-;11493:16;;11481:29;;;11535:2;11526:12;;;;11469:3;11577:1;11573:24;11565:33;;11561:42;11615:19;;;11612:39;;;11647:1;11644;11637:12;11612:39;11679:2;11675;11671:11;11691:708;11707:6;11702:3;11699:15;11691:708;;;11786:2;11780:3;11767:17;11764:25;11761:45;;;11802:1;11799;11792:12;11761:45;11837:17;;11829:26;;11907:4;11879:16;;;-1:-1:-1;;11875:30:126;11871:41;11868:61;;;11925:1;11922;11915:12;11868:61;11957:22;;:::i;:::-;12025:2;12019;12015;12011:11;11998:25;11995:33;11992:53;;;12041:1;12038;12031:12;11992:53;12074:70;12136:7;12131:2;12124;12120;12116:11;12103:25;12099:2;12095:34;12091:43;12074:70;:::i;:::-;12065:7;12058:87;12193:2;12185:4;12181:2;12177:13;12164:27;12161:35;12158:55;;;12209:1;12206;12199:12;12158:55;12251:72;12315:7;12310:2;12301:4;12297:2;12293:13;12280:27;12276:2;12272:36;12268:45;12251:72;:::i;:::-;12246:2;12237:7;12233:16;12226:98;12349:7;12344:3;12337:20;;;12386:2;12381:3;12377:12;12370:19;;11733:2;11728:3;11724:12;11717:19;;11691:708;;;11695:3;;12433:5;12428:2;12419:7;12415:16;12408:31;;;12462:7;12455:5;12448:22;;;12502:31;12529:2;12525;12521:11;12502:31;:::i;:::-;12497:2;12486:14;;12479:55;12490:5;10409:2155;-1:-1:-1;;;;;10409:2155:126:o;12569:180::-;12628:6;12681:2;12669:9;12660:7;12656:23;12652:32;12649:52;;;12697:1;12694;12687:12;12649:52;-1:-1:-1;12720:23:126;;12569:180;-1:-1:-1;12569:180:126:o;12754:250::-;12839:1;12849:113;12863:6;12860:1;12857:13;12849:113;;;12939:11;;;12933:18;12920:11;;;12913:39;12885:2;12878:10;12849:113;;;-1:-1:-1;;12996:1:126;12978:16;;12971:27;12754:250::o;13009:270::-;13050:3;13088:5;13082:12;13115:6;13110:3;13103:19;13131:76;13200:6;13193:4;13188:3;13184:14;13177:4;13170:5;13166:16;13131:76;:::i;:::-;13261:2;13240:15;-1:-1:-1;;13236:29:126;13227:39;;;;13268:4;13223:50;;13009:270;-1:-1:-1;;13009:270:126:o;13284:217::-;13431:2;13420:9;13413:21;13394:4;13451:44;13491:2;13480:9;13476:18;13468:6;13451:44;:::i;13506:1061::-;13604:6;13657:2;13645:9;13636:7;13632:23;13628:32;13625:52;;;13673:1;13670;13663:12;13625:52;13713:9;13700:23;-1:-1:-1;;;;;13783:2:126;13775:6;13772:14;13769:34;;;13799:1;13796;13789:12;13769:34;13822:22;;;;13878:4;13860:16;;;13856:27;13853:47;;;13896:1;13893;13886:12;13853:47;13922:22;;:::i;:::-;13982:2;13969:16;14010:2;14000:8;13997:16;13994:36;;;14026:1;14023;14016:12;13994:36;14053:57;14102:7;14091:8;14087:2;14083:17;14053:57;:::i;:::-;14046:5;14039:72;;14157:2;14153;14149:11;14136:25;14186:2;14176:8;14173:16;14170:36;;;14202:1;14199;14192:12;14170:36;14238:44;14274:7;14263:8;14259:2;14255:17;14238:44;:::i;:::-;14233:2;14226:5;14222:14;14215:68;;14315:30;14341:2;14337;14333:11;14315:30;:::i;:::-;14310:2;14303:5;14299:14;14292:54;14399:2;14395;14391:11;14378:25;14373:2;14366:5;14362:14;14355:49;14449:3;14445:2;14441:12;14428:26;14413:41;;14463:33;14488:7;14463:33;:::i;:::-;14523:3;14512:15;;14505:32;;;;-1:-1:-1;14516:5:126;13506:1061;-1:-1:-1;;;13506:1061:126:o;14572:1052::-;14637:5;14690:3;14683:4;14675:6;14671:17;14667:27;14657:55;;14708:1;14705;14698:12;14657:55;14744:6;14731:20;14770:4;14794:58;14810:41;14848:2;14810:41;:::i;14794:58::-;14886:15;;;14948:4;14991:11;;;14979:24;;14975:33;;;14917:12;;;;14874:3;15020:15;;;15017:35;;;15048:1;15045;15038:12;15017:35;15084:2;15076:6;15072:15;15096:499;15112:6;15107:3;15104:15;15096:499;;;15188:2;15182:3;15177;15173:13;15169:22;15166:112;;;15232:1;15261:2;15257;15250:14;15166:112;15304:22;;:::i;:::-;15353:17;;15339:32;;15420:12;;;15407:26;15391:14;;;15384:50;15457:2;15508:12;;;15495:26;15479:14;;;15472:50;15535:18;;15573:12;;;;15129;;15096:499;;;-1:-1:-1;15613:5:126;;14572:1052;-1:-1:-1;;;;;;;14572:1052:126:o;15629:284::-;15685:5;15733:4;15721:9;15716:3;15712:19;15708:30;15705:50;;;15751:1;15748;15741:12;15705:50;15773:22;;:::i;:::-;15764:31;;15831:9;15818:23;15811:5;15804:38;15902:2;15891:9;15887:18;15874:32;15869:2;15862:5;15858:14;15851:56;15629:284;;;;:::o;15918:691::-;15981:5;16034:3;16027:4;16019:6;16015:17;16011:27;16001:55;;16052:1;16049;16042:12;16001:55;16088:6;16075:20;16114:4;16138:58;16154:41;16192:2;16154:41;:::i;16138:58::-;16230:15;;;16316:1;16312:10;;;;16300:23;;16296:32;;;16261:12;;;;16340:15;;;16337:35;;;16368:1;16365;16358:12;16337:35;16404:2;16396:6;16392:15;16416:164;16432:6;16427:3;16424:15;16416:164;;;16500:37;16533:3;16528;16500:37;:::i;:::-;16488:50;;16558:12;;;;16458:4;16449:14;16416:164;;16614:1671;16706:6;16714;16767:2;16755:9;16746:7;16742:23;16738:32;16735:52;;;16783:1;16780;16773:12;16735:52;16823:9;16810:23;-1:-1:-1;;;;;16893:2:126;16885:6;16882:14;16879:34;;;16909:1;16906;16899:12;16879:34;16932:22;;;;16988:6;16970:16;;;16966:29;16963:49;;;17008:1;17005;16998:12;16963:49;17034:22;;:::i;:::-;17092:2;17079:16;17072:5;17065:31;17142:2;17138;17134:11;17121:25;17171:2;17161:8;17158:16;17155:36;;;17187:1;17184;17177:12;17155:36;17223:44;17259:7;17248:8;17244:2;17240:17;17223:44;:::i;:::-;17218:2;17211:5;17207:14;17200:68;;17314:2;17310;17306:11;17293:25;17343:2;17333:8;17330:16;17327:36;;;17359:1;17356;17349:12;17327:36;17395:44;17431:7;17420:8;17416:2;17412:17;17395:44;:::i;:::-;17390:2;17383:5;17379:14;17372:68;;17493:2;17489;17485:11;17472:25;17467:2;17460:5;17456:14;17449:49;17552:3;17548:2;17544:12;17531:26;17525:3;17518:5;17514:15;17507:51;17612:3;17608:2;17604:12;17591:26;17585:3;17578:5;17574:15;17567:51;17664:3;17660:2;17656:12;17643:26;17694:2;17684:8;17681:16;17678:36;;;17710:1;17707;17700:12;17678:36;17747:67;17806:7;17795:8;17791:2;17787:17;17747:67;:::i;:::-;17741:3;17734:5;17730:15;17723:92;;17861:3;17857:2;17853:12;17840:26;17891:2;17881:8;17878:16;17875:36;;;17907:1;17904;17897:12;17875:36;17944:65;18001:7;17990:8;17986:2;17982:17;17944:65;:::i;:::-;17938:3;17931:5;17927:15;17920:90;;18029:3;18078:2;18074;18070:11;18057:25;18107:2;18097:8;18094:16;18091:36;;;18123:1;18120;18113:12;18091:36;18159:44;18195:7;18184:8;18180:2;18176:17;18159:44;:::i;:::-;18143:14;;;18136:68;;;;-1:-1:-1;18147:5:126;18275:2;18260:18;;;;18247:32;;-1:-1:-1;;;;;16614:1671:126:o;18290:154::-;18348:5;18393:3;18384:6;18379:3;18375:16;18371:26;18368:46;;;18410:1;18407;18400:12;18368:46;-1:-1:-1;18432:6:126;18290:154;-1:-1:-1;18290:154:126:o;18449:764::-;18573:6;18581;18625:9;18616:7;18612:23;18655:2;18651;18647:11;18644:31;;;18671:1;18668;18661:12;18644:31;18711:9;18698:23;-1:-1:-1;;;;;18781:2:126;18773:6;18770:14;18767:34;;;18797:1;18794;18787:12;18767:34;18820:65;18877:7;18868:6;18857:9;18853:22;18820:65;:::i;:::-;18810:75;-1:-1:-1;18919:2:126;-1:-1:-1;;18901:16:126;;18897:25;18894:45;;;18935:1;18932;18925:12;18894:45;18968:2;18962:9;18948:23;;19010:2;19002:6;18998:15;18980:33;;19063:6;19051:10;19048:22;19043:2;19031:10;19028:18;19025:46;19022:72;;;19074:18;;:::i;:::-;-1:-1:-1;19110:2:126;19103:22;19177:2;19162:18;;;;19149:32;19134:48;;-1:-1:-1;18449:764:126;19141:6;;-1:-1:-1;18449:764:126:o;19218:767::-;19316:6;19369:2;19357:9;19348:7;19344:23;19340:32;19337:52;;;19385:1;19382;19375:12;19337:52;19425:9;19412:23;-1:-1:-1;;;;;19495:2:126;19487:6;19484:14;19481:34;;;19511:1;19508;19501:12;19481:34;19534:22;;;;19590:4;19572:16;;;19568:27;19565:47;;;19608:1;19605;19598:12;19565:47;19634:22;;:::i;:::-;19694:2;19681:16;19722:2;19712:8;19709:16;19706:36;;;19738:1;19735;19728:12;19706:36;19765:58;19815:7;19804:8;19800:2;19796:17;19765:58;:::i;:::-;19758:5;19751:73;;19869:2;19865;19861:11;19848:25;19833:40;;19882:33;19907:7;19882:33;:::i;:::-;19942:2;19931:14;;19924:31;;;;-1:-1:-1;19935:5:126;19218:767;-1:-1:-1;;;19218:767:126:o;19990:670::-;20116:6;20124;20168:9;20159:7;20155:23;20198:2;20194;20190:11;20187:31;;;20214:1;20211;20204:12;20187:31;20254:9;20241:23;-1:-1:-1;;;;;20279:6:126;20276:30;20273:50;;;20319:1;20316;20309:12;20273:50;20342:65;20399:7;20390:6;20379:9;20375:22;20342:65;:::i;:::-;20332:75;-1:-1:-1;;20441:4:126;-1:-1:-1;;20423:16:126;;20419:27;20416:47;;;20459:1;20456;20449:12;20416:47;;20485:22;;:::i;:::-;20558:2;20547:9;20543:18;20530:32;20523:5;20516:47;20623:4;20612:9;20608:20;20595:34;20590:2;20583:5;20579:14;20572:58;20649:5;20639:15;;;19990:670;;;;;:::o;20665:354::-;20754:6;20807:2;20795:9;20786:7;20782:23;20778:32;20775:52;;;20823:1;20820;20813:12;20775:52;20863:9;20850:23;-1:-1:-1;;;;;20888:6:126;20885:30;20882:50;;;20928:1;20925;20918:12;20882:50;20951:62;21005:7;20996:6;20985:9;20981:22;20951:62;:::i;21024:1155::-;21113:6;21166:2;21154:9;21145:7;21141:23;21137:32;21134:52;;;21182:1;21179;21172:12;21134:52;21222:9;21209:23;-1:-1:-1;;;;;21292:2:126;21284:6;21281:14;21278:34;;;21308:1;21305;21298:12;21278:34;21331:22;;;;21387:4;21369:16;;;21365:27;21362:47;;;21405:1;21402;21395:12;21362:47;21431:22;;:::i;:::-;21491:2;21478:16;21519:2;21509:8;21506:16;21503:36;;;21535:1;21532;21525:12;21503:36;21562:44;21598:7;21587:8;21583:2;21579:17;21562:44;:::i;:::-;21555:5;21548:59;;21639:30;21665:2;21661;21657:11;21639:30;:::i;:::-;21634:2;21627:5;21623:14;21616:54;21716:2;21712;21708:11;21695:25;21745:2;21735:8;21732:16;21729:36;;;21761:1;21758;21751:12;21729:36;21797:54;21843:7;21832:8;21828:2;21824:17;21797:54;:::i;:::-;21792:2;21785:5;21781:14;21774:78;;21884:30;21910:2;21906;21902:11;21884:30;:::i;:::-;21879:2;21872:5;21868:14;21861:54;21969:3;21965:2;21961:12;21948:26;21942:3;21935:5;21931:15;21924:51;22021:3;22017:2;22013:12;22000:26;22051:2;22041:8;22038:16;22035:36;;;22067:1;22064;22057:12;22035:36;22104:44;22140:7;22129:8;22125:2;22121:17;22104:44;:::i;:::-;22098:3;22087:15;;22080:69;-1:-1:-1;22091:5:126;21024:1155;-1:-1:-1;;;;;21024:1155:126:o;22184:489::-;22268:6;22321:2;22309:9;22300:7;22296:23;22292:32;22289:52;;;22337:1;22334;22327:12;22289:52;22363:22;;:::i;:::-;22422:9;22409:23;22441:33;22466:7;22441:33;:::i;:::-;22483:22;;22557:2;22542:18;;22529:32;22570:33;22529:32;22570:33;:::i;:::-;22630:2;22619:14;;22612:31;22623:5;22184:489;-1:-1:-1;;;22184:489:126:o;22886:245::-;23070:2;23055:18;;23082:43;23059:9;23107:6;22792:12;;-1:-1:-1;;;;;22788:21:126;;;22776:34;;22863:4;22852:16;;;22846:23;22842:32;22826:14;;22819:56;22678:203;23136:352;23224:6;23277:2;23265:9;23256:7;23252:23;23248:32;23245:52;;;23293:1;23290;23283:12;23245:52;23333:9;23320:23;-1:-1:-1;;;;;23358:6:126;23355:30;23352:50;;;23398:1;23395;23388:12;23352:50;23421:61;23474:7;23465:6;23454:9;23450:22;23421:61;:::i;23701:271::-;23884:6;23876;23871:3;23858:33;23840:3;23910:16;;23935:13;;;23910:16;23701:271;-1:-1:-1;23701:271:126:o;23977:330::-;24075:4;24133:11;24120:25;24227:3;24223:8;24212;24196:14;24192:29;24188:44;24168:18;24164:69;24154:97;;24247:1;24244;24237:12;24154:97;24268:33;;;;;23977:330;-1:-1:-1;;23977:330:126:o;24312:521::-;24389:4;24395:6;24455:11;24442:25;24549:2;24545:7;24534:8;24518:14;24514:29;24510:43;24490:18;24486:68;24476:96;;24568:1;24565;24558:12;24476:96;24595:33;;24647:20;;;-1:-1:-1;;;;;;24679:30:126;;24676:50;;;24722:1;24719;24712:12;24676:50;24755:4;24743:17;;-1:-1:-1;24786:14:126;24782:27;;;24772:38;;24769:58;;;24823:1;24820;24813:12;24769:58;24312:521;;;;;:::o;24838:127::-;24899:10;24894:3;24890:20;24887:1;24880:31;24930:4;24927:1;24920:15;24954:4;24951:1;24944:15;24970:127;25031:10;25026:3;25022:20;25019:1;25012:31;25062:4;25059:1;25052:15;25086:4;25083:1;25076:15;25102:647;25181:6;25234:2;25222:9;25213:7;25209:23;25205:32;25202:52;;;25250:1;25247;25240:12;25202:52;25283:9;25277:16;-1:-1:-1;;;;;25308:6:126;25305:30;25302:50;;;25348:1;25345;25338:12;25302:50;25371:22;;25424:4;25416:13;;25412:27;-1:-1:-1;25402:55:126;;25453:1;25450;25443:12;25402:55;25482:2;25476:9;25507:48;25523:31;25551:2;25523:31;:::i;25507:48::-;25578:2;25571:5;25564:17;25618:7;25613:2;25608;25604;25600:11;25596:20;25593:33;25590:53;;;25639:1;25636;25629:12;25590:53;25652:67;25716:2;25711;25704:5;25700:14;25695:2;25691;25687:11;25652:67;:::i;:::-;25738:5;25102:647;-1:-1:-1;;;;;25102:647:126:o;25754:331::-;25859:9;25870;25912:8;25900:10;25897:24;25894:44;;;25934:1;25931;25924:12;25894:44;25963:6;25953:8;25950:20;25947:40;;;25983:1;25980;25973:12;25947:40;-1:-1:-1;;26009:23:126;;;26054:25;;;;;-1:-1:-1;25754:331:126:o;26090:673::-;26181:6;26234:2;26222:9;26213:7;26209:23;26205:32;26202:52;;;26250:1;26247;26240:12;26202:52;26290:9;26277:23;-1:-1:-1;;;;;26360:2:126;26352:6;26349:14;26346:34;;;26376:1;26373;26366:12;26346:34;26399:22;;;;26455:4;26437:16;;;26433:27;26430:47;;;26473:1;26470;26463:12;26430:47;26499:22;;:::i;:::-;26559:2;26546:16;26587:2;26577:8;26574:16;26571:36;;;26603:1;26600;26593:12;26571:36;26630:44;26666:7;26655:8;26651:2;26647:17;26630:44;:::i;:::-;26623:5;26616:59;;26728:2;26724;26720:11;26707:25;26702:2;26695:5;26691:14;26684:49;26752:5;26742:15;;;;;26090:673;;;;:::o;26768:288::-;26943:2;26932:9;26925:21;26906:4;26963:44;27003:2;26992:9;26988:18;26980:6;26963:44;:::i;:::-;26955:52;;27043:6;27038:2;27027:9;27023:18;27016:34;26768:288;;;;;:::o;27061:490::-;27393:13;;-1:-1:-1;;;;;27389:22:126;;;27371:41;;27360:1;27460:17;;27454:24;27450:33;27443:4;27428:20;;27421:63;27320:3;27305:19;;27493:52;27541:2;27526:18;;27518:6;22792:12;;-1:-1:-1;;;;;22788:21:126;;;22776:34;;22863:4;22852:16;;;22846:23;22842:32;22826:14;;22819:56;22678:203;27556:184;27626:6;27679:2;27667:9;27658:7;27654:23;27650:32;27647:52;;;27695:1;27692;27685:12;27647:52;-1:-1:-1;27718:16:126;;27556:184;-1:-1:-1;27556:184:126:o;27745:127::-;27806:10;27801:3;27797:20;27794:1;27787:31;27837:4;27834:1;27827:15;27861:4;27858:1;27851:15;27877:168;27950:9;;;27981;;27998:15;;;27992:22;;27978:37;27968:71;;28019:18;;:::i;28050:125::-;28115:9;;;28136:10;;;28133:36;;;28149:18;;:::i;28180:1546::-;28280:6;28311:2;28354;28342:9;28333:7;28329:23;28325:32;28322:52;;;28370:1;28367;28360:12;28322:52;28403:9;28397:16;-1:-1:-1;;;;;28473:2:126;28465:6;28462:14;28459:34;;;28489:1;28486;28479:12;28459:34;28512:22;;;;28568:4;28550:16;;;28546:27;28543:47;;;28586:1;28583;28576:12;28543:47;28612:22;;:::i;:::-;28663:2;28657:9;28650:5;28643:24;28713:2;28709;28705:11;28699:18;28694:2;28687:5;28683:14;28676:42;28737:2;28778;28774;28770:11;28764:18;28807:2;28797:8;28794:16;28791:36;;;28823:1;28820;28813:12;28791:36;28854:8;28850:2;28846:17;28836:27;;;28901:7;28894:4;28890:2;28886:13;28882:27;28872:55;;28923:1;28920;28913:12;28872:55;28952:2;28946:9;28936:19;;28975:58;28991:41;29029:2;28991:41;:::i;28975:58::-;29067:15;;;29149:1;29145:10;;;;29137:19;;29133:28;;;29098:12;;;;29173:19;;;29170:39;;;29205:1;29202;29195:12;29170:39;29229:11;;;;29249:409;29265:6;29260:3;29257:15;29249:409;;;29345:2;29339:3;29330:7;29326:17;29322:26;29319:116;;;29389:1;29418:2;29414;29407:14;29319:116;29463:22;;:::i;:::-;29514:10;;29498:27;;29569:12;;;29563:19;29545:16;;;29538:45;29596:20;;29282:12;;;;29636;;;;29249:409;;;29674:14;;;29667:29;;;;-1:-1:-1;29678:5:126;28180:1546;-1:-1:-1;;;;;;28180:1546:126:o;29941:128::-;30008:9;;;30029:11;;;30026:37;;;30043:18;;:::i;30074:135::-;30113:3;30134:17;;;30131:43;;30154:18;;:::i;:::-;-1:-1:-1;30201:1:126;30190:13;;30074:135::o;30214:251::-;30284:6;30337:2;30325:9;30316:7;30312:23;30308:32;30305:52;;;30353:1;30350;30343:12;30305:52;30385:9;30379:16;30404:31;30429:5;30404:31;:::i;30470:461::-;30523:3;30561:5;30555:12;30588:6;30583:3;30576:19;30614:4;30643:2;30638:3;30634:12;30627:19;;30680:2;30673:5;30669:14;30701:1;30711:195;30725:6;30722:1;30719:13;30711:195;;;30790:13;;-1:-1:-1;;;;;30786:39:126;30774:52;;30846:12;;;;30881:15;;;;30822:1;30740:9;30711:195;;;-1:-1:-1;30922:3:126;;30470:461;-1:-1:-1;;;;;30470:461:126:o;30936:332::-;31143:6;31132:9;31125:25;31186:2;31181;31170:9;31166:18;31159:30;31106:4;31206:56;31258:2;31247:9;31243:18;31235:6;31206:56;:::i;31273:879::-;31368:6;31399:2;31442;31430:9;31421:7;31417:23;31413:32;31410:52;;;31458:1;31455;31448:12;31410:52;31491:9;31485:16;-1:-1:-1;;;;;31516:6:126;31513:30;31510:50;;;31556:1;31553;31546:12;31510:50;31579:22;;31632:4;31624:13;;31620:27;-1:-1:-1;31610:55:126;;31661:1;31658;31651:12;31610:55;31690:2;31684:9;31713:58;31729:41;31767:2;31729:41;:::i;31713:58::-;31805:15;;;31887:1;31883:10;;;;31875:19;;31871:28;;;31836:12;;;;31911:19;;;31908:39;;;31943:1;31940;31933:12;31908:39;31967:11;;;;31987:135;32003:6;31998:3;31995:15;31987:135;;;32069:10;;32057:23;;32020:12;;;;32100;;;;31987:135;;32596:613;32660:3;32698:5;32692:12;32725:6;32720:3;32713:19;32751:4;32780:2;32775:3;32771:12;32764:19;;32817:2;32810:5;32806:14;32838:1;32848:336;32862:6;32859:1;32856:13;32848:336;;;32921:13;;32959:9;;32947:22;;33009:11;;;33003:18;32989:12;;;32982:40;33045:4;33089:11;;;33083:18;33069:12;;;33062:40;33131:4;33122:14;;;;33159:15;;;;32884:1;32877:9;32848:336;;33214:531;33276:3;33314:5;33308:12;33341:6;33336:3;33329:19;33367:4;33396:2;33391:3;33387:12;33380:19;;33433:2;33426:5;33422:14;33454:1;33464:256;33478:6;33475:1;33472:13;33464:256;;;33537:13;;33575:9;;33563:22;;33625:11;;33619:18;33605:12;;;33598:40;33667:4;33658:14;;;;33695:15;;;;33500:1;33493:9;33464:256;;33750:1432;33927:2;33916:9;33909:21;33972:6;33966:13;33961:2;33950:9;33946:18;33939:41;33890:4;34027:2;34019:6;34015:15;34009:22;34050:6;34092:2;34087;34076:9;34072:18;34065:30;34118:51;34164:3;34153:9;34149:19;34135:12;34118:51;:::i;:::-;34104:65;;34218:2;34210:6;34206:15;34200:22;34245:2;34241:7;34312:2;34300:9;34292:6;34288:22;34284:31;34279:2;34268:9;34264:18;34257:59;34339:40;34372:6;34356:14;34339:40;:::i;:::-;34325:54;;34434:2;34426:6;34422:15;34416:22;34410:3;34399:9;34395:19;34388:51;34494:3;34486:6;34482:16;34476:23;34470:3;34459:9;34455:19;34448:52;34555:3;34547:6;34543:16;34537:23;34531:3;34520:9;34516:19;34509:52;34610:3;34602:6;34598:16;34592:23;34570:45;;34680:2;34668:9;34660:6;34656:22;34652:31;34646:3;34635:9;34631:19;34624:60;34707:63;34763:6;34747:14;34707:63;:::i;:::-;34693:77;;34819:3;34811:6;34807:16;34801:23;34779:45;;34843:3;34910:2;34898:9;34890:6;34886:22;34882:31;34877:2;34866:9;34862:18;34855:59;34937:61;34991:6;34975:14;34937:61;:::i;:::-;35035:15;;;35029:22;35091;;;35087:31;;;35067:18;;;35060:59;34923:75;-1:-1:-1;35029:22:126;-1:-1:-1;35136:40:126;34923:75;35029:22;35136:40;:::i;35187:502::-;35450:6;35439:9;35432:25;35493:3;35488:2;35477:9;35473:18;35466:31;35413:4;35514:57;35566:3;35555:9;35551:19;35543:6;35514:57;:::i;:::-;-1:-1:-1;;;;;35607:32:126;;;;35602:2;35587:18;;35580:60;-1:-1:-1;35671:2:126;35656:18;35649:34;35506:65;35187:502;-1:-1:-1;;35187:502:126:o;35694:1392::-;36280:4;36309:3;36339:6;36328:9;36321:25;36382:2;36377;36366:9;36362:18;36355:30;36408:44;36448:2;36437:9;36433:18;36425:6;36408:44;:::i;:::-;36394:58;;36500:9;36492:6;36488:22;36483:2;36472:9;36468:18;36461:50;36534:32;36559:6;36551;36534:32;:::i;:::-;36520:46;;36602:6;36597:2;36586:9;36582:18;36575:34;36646:6;36640:3;36629:9;36625:19;36618:35;36690:6;36684:3;36673:9;36669:19;36662:35;36746:9;36738:6;36734:22;36728:3;36717:9;36713:19;36706:51;36780:55;36828:6;36820;36780:55;:::i;:::-;36766:69;;36884:9;36876:6;36872:22;36866:3;36855:9;36851:19;36844:51;36918:53;36964:6;36956;36918:53;:::i;:::-;36904:67;;37020:9;37012:6;37008:22;37002:3;36991:9;36987:19;36980:51;37048:32;37073:6;37065;37048:32;:::i;:::-;37040:40;35694:1392;-1:-1:-1;;;;;;;;;;;;35694:1392:126:o;37091:500::-;37149:5;37156:6;37216:3;37203:17;37302:2;37298:7;37287:8;37271:14;37267:29;37263:43;37243:18;37239:68;37229:96;;37321:1;37318;37311:12;37229:96;37349:33;;37453:4;37440:18;;;-1:-1:-1;37401:21:126;;-1:-1:-1;;;;;;37470:30:126;;37467:50;;;37513:1;37510;37503:12;37467:50;37560:6;37544:14;37540:27;37533:5;37529:39;37526:59;;;37581:1;37578;37571:12;37596:266;37684:6;37679:3;37672:19;37736:6;37729:5;37722:4;37717:3;37713:14;37700:43;-1:-1:-1;37788:1:126;37763:16;;;37781:4;37759:27;;;37752:38;;;;37844:2;37823:15;;;-1:-1:-1;;37819:29:126;37810:39;;;37806:50;;37596:266::o;37867:543::-;37957:5;37964:6;38024:3;38011:17;38110:2;38106:7;38095:8;38079:14;38075:29;38071:43;38051:18;38047:68;38037:96;;38129:1;38126;38119:12;38037:96;38157:33;;38261:4;38248:18;;;-1:-1:-1;38209:21:126;;-1:-1:-1;;;;;;38278:30:126;;38275:50;;;38321:1;38318;38311:12;38275:50;38380:4;38372:6;38368:17;38352:14;38348:38;38341:5;38337:50;38334:70;;;38400:1;38397;38390:12;38415:617;38535:6;38530:3;38523:19;38505:3;38561:4;38590:2;38585:3;38581:12;38574:19;;38616:5;38639:1;38649:358;38663:6;38660:1;38657:13;38649:358;;;38724:20;;38712:33;;38792:15;;;38779:29;38765:12;;;38758:51;38832:4;38883:15;;;38870:29;38856:12;;;38849:51;38923:4;38947:12;;;;38982:15;;;;38685:1;38678:9;38649:358;;39037:538;39125:5;39132:6;39192:3;39179:17;39278:2;39274:7;39263:8;39247:14;39243:29;39239:43;39219:18;39215:68;39205:96;;39297:1;39294;39287:12;39205:96;39325:33;;39429:4;39416:18;;;-1:-1:-1;39377:21:126;;-1:-1:-1;;;;;;39446:30:126;;39443:50;;;39489:1;39486;39479:12;39443:50;39543:6;39540:1;39536:14;39520;39516:35;39509:5;39505:47;39502:67;;;39565:1;39562;39555:12;39580:524;39698:6;39693:3;39686:19;39668:3;39724:4;39753:2;39748:3;39744:12;39737:19;;39779:5;39802:1;39812:267;39826:6;39823:1;39820:13;39812:267;;;39887:20;;39875:33;;39955:15;;;39942:29;39928:12;;;39921:51;39995:4;40019:12;;;;40054:15;;;;39848:1;39841:9;39812:267;;40109:1908;40288:2;40277:9;40270:21;40340:6;40327:20;40322:2;40311:9;40307:18;40300:48;40251:4;40391:55;40442:2;40434:6;40430:15;40422:6;40391:55;:::i;:::-;40465:6;40507:2;40502;40491:9;40487:18;40480:30;40533:74;40602:3;40591:9;40587:19;40573:12;40559;40533:74;:::i;:::-;40519:88;;40654:55;40705:2;40697:6;40693:15;40685:6;40654:55;:::i;:::-;40616:93;;40732:2;40728:7;40799:2;40787:9;40779:6;40775:22;40771:31;40766:2;40755:9;40751:18;40744:59;40826:65;40884:6;40868:14;40852;40826:65;:::i;:::-;40812:79;;40953:2;40945:6;40941:15;40928:29;40922:3;40911:9;40907:19;40900:58;41020:3;41012:6;41008:16;40995:30;40989:3;40978:9;40974:19;40967:59;41088:3;41080:6;41076:16;41063:30;41057:3;41046:9;41042:19;41035:59;41141:88;41224:3;41216:6;41212:16;41204:6;41141:88;:::i;:::-;41103:126;;;;41294:2;41282:9;41274:6;41270:22;41266:31;41260:3;41249:9;41245:19;41238:60;41321:97;41411:6;41395:14;41379;41321:97;:::i;:::-;41307:111;;41465:86;41546:3;41538:6;41534:16;41526:6;41465:86;:::i;:::-;41427:124;;;;41570:3;41637:2;41625:9;41617:6;41613:22;41609:31;41604:2;41593:9;41589:18;41582:59;41664:95;41752:6;41736:14;41720;41664:95;:::i;:::-;41650:109;;41806:55;41857:2;41849:6;41845:15;41837:6;41806:55;:::i;:::-;41768:93;;;;;41925:2;41913:9;41905:6;41901:22;41897:31;41892:2;41881:9;41877:18;41870:59;;41946:65;42004:6;41988:14;41972;41946:65;:::i;42022:580::-;42147:4;42153:6;42213:11;42200:25;42307:2;42303:7;42292:8;42276:14;42272:29;42268:43;42248:18;42244:68;42234:96;;42326:1;42323;42316:12;42234:96;42353:33;;42405:20;;;-1:-1:-1;;;;;;42437:30:126;;42434:50;;;42480:1;42477;42470:12;42434:50;42513:4;42501:17;;-1:-1:-1;42572:4:126;42560:17;;42544:14;42540:38;42530:49;;42527:69;;;42592:1;42589;42582:12;42607:244;42764:2;42753:9;42746:21;42727:4;42784:61;42841:2;42830:9;42826:18;42818:6;42810;42784:61;:::i;42856:575::-;42979:4;42985:6;43045:11;43032:25;43139:2;43135:7;43124:8;43108:14;43104:29;43100:43;43080:18;43076:68;43066:96;;43158:1;43155;43148:12;43066:96;43185:33;;43237:20;;;-1:-1:-1;;;;;;43269:30:126;;43266:50;;;43312:1;43309;43302:12;43266:50;43345:4;43333:17;;-1:-1:-1;43396:1:126;43392:14;;;43376;43372:35;43362:46;;43359:66;;;43421:1;43418;43411:12;43436:232;43523:6;43576:2;43564:9;43555:7;43551:23;43547:32;43544:52;;;43592:1;43589;43582:12;43544:52;43615:47;43654:7;43643:9;43615:47;:::i;43673:490::-;43862:2;43851:9;43844:21;43907:6;43901:13;43896:2;43885:9;43881:18;43874:41;43969:2;43961:6;43957:15;43951:22;43946:2;43935:9;43931:18;43924:50;43825:4;44021:2;44013:6;44009:15;44003:22;44063:4;44056;44045:9;44041:20;44034:34;44085:72;44152:3;44141:9;44137:19;44123:12;44085:72;:::i;44168:377::-;-1:-1:-1;;;;;;44353:26:126;;44341:39;;44403:13;;44323:3;;44425:74;44403:13;44488:1;44479:11;;44472:4;44460:17;;44425:74;:::i;:::-;44519:16;;;;44537:1;44515:24;;44168:377;-1:-1:-1;;;44168:377:126:o;44657:1008::-;44848:2;44837:9;44830:21;44811:4;44886:6;44880:13;44929:4;44924:2;44913:9;44909:18;44902:32;44957:51;45003:3;44992:9;44988:19;44974:12;44957:51;:::i;:::-;44943:65;;45057:2;45049:6;45045:15;45039:22;45084:2;45080:7;45151:2;45139:9;45131:6;45127:22;45123:31;45118:2;45107:9;45103:18;45096:59;45178:40;45211:6;45195:14;45178:40;:::i;:::-;45164:54;;45267:2;45259:6;45255:15;45249:22;45227:44;;45335:2;45323:9;45315:6;45311:22;45307:31;45302:2;45291:9;45287:18;45280:59;;45362:40;45395:6;45379:14;45362:40;:::i;:::-;45348:54;;;-1:-1:-1;;;;;45461:2:126;45453:6;45449:15;45443:22;45439:47;45433:3;45422:9;45418:19;45411:76;45542:3;45534:6;45530:16;45524:23;45518:3;45507:9;45503:19;45496:52;45632:1;45628;45623:3;45619:11;45615:19;45608:3;45600:6;45596:16;45590:23;45586:49;45579:4;45568:9;45564:20;45557:79;45653:6;45645:14;;;44657:1008;;;;:::o;46093:492::-;46268:3;46306:6;46300:13;46322:66;46381:6;46376:3;46369:4;46361:6;46357:17;46322:66;:::i;:::-;46451:13;;46410:16;;;;46473:70;46451:13;46410:16;46520:4;46508:17;;46473:70;:::i;:::-;46559:20;;46093:492;-1:-1:-1;;;;46093:492:126:o;46590:1476::-;46742:4;46771:2;46800;46789:9;46782:21;46838:6;46832:13;46881:4;46876:2;46865:9;46861:18;46854:32;46909:51;46955:3;46944:9;46940:19;46926:12;46909:51;:::i;:::-;46895:65;;-1:-1:-1;;;;;47018:2:126;47010:6;47006:15;47000:22;46996:47;46991:2;46980:9;46976:18;46969:75;47093:2;47085:6;47081:15;47075:22;47120:2;47116:7;47187:2;47175:9;47167:6;47163:22;47159:31;47154:2;47143:9;47139:18;47132:59;47211:6;47246:14;47240:21;47285:6;47277;47270:22;47320:2;47312:6;47308:15;47301:22;;47379:2;47369:6;47366:1;47362:14;47354:6;47350:27;47346:36;47425:2;47409:14;47405:23;47391:37;;47446:1;47456:246;47470:6;47467:1;47464:13;47456:246;;;47556:2;47547:6;47539;47535:19;47531:28;47526:3;47519:41;47583:39;47615:6;47606;47600:13;47583:39;:::i;:::-;47645:15;;;;47680:12;;;;47573:49;-1:-1:-1;47492:1:126;47485:9;47456:246;;;-1:-1:-1;47751:2:126;47739:15;;47733:22;-1:-1:-1;;;;;44615:30:126;;47813:3;47798:19;;44603:43;47733:22;-1:-1:-1;47873:3:126;47865:6;47861:16;47855:23;47849:3;47838:9;47834:19;47827:52;47928:3;47920:6;47916:16;47910:23;47888:45;;47999:2;47987:9;47979:6;47975:22;47971:31;47964:4;47953:9;47949:20;47942:61;48020:40;48053:6;48037:14;48020:40;:::i;:::-;48012:48;46590:1476;-1:-1:-1;;;;;;;;;;46590:1476:126:o;48350:277::-;48417:6;48470:2;48458:9;48449:7;48445:23;48441:32;48438:52;;;48486:1;48483;48476:12;48438:52;48518:9;48512:16;48571:5;48564:13;48557:21;48550:5;48547:32;48537:60;;48593:1;48590;48583:12;48632:255;48752:19;;48791:2;48783:11;;48780:101;;;-1:-1:-1;;48852:2:126;48848:12;;;48845:1;48841:20;48837:33;48826:45;48632:255;;;;:::o;48892:750::-;48981:6;49034:2;49022:9;49013:7;49009:23;49005:32;49002:52;;;49050:1;49047;49040:12;49002:52;49090:9;49077:23;-1:-1:-1;;;;;49160:2:126;49152:6;49149:14;49146:34;;;49176:1;49173;49166:12;49146:34;49199:22;;;;49255:4;49237:16;;;49233:27;49230:47;;;49273:1;49270;49263:12;49230:47;49299:22;;:::i;:::-;49357:2;49344:16;49337:5;49330:31;49414:2;49410;49406:11;49393:25;49388:2;49381:5;49377:14;49370:49;49465:2;49461;49457:11;49444:25;49494:2;49484:8;49481:16;49478:36;;;49510:1;49507;49500:12;49478:36;49546:65;49603:7;49592:8;49588:2;49584:17;49546:65;:::i;:::-;49541:2;49530:14;;49523:89;-1:-1:-1;49534:5:126;48892:750;-1:-1:-1;;;;;48892:750:126:o;49647:247::-;49706:6;49759:2;49747:9;49738:7;49734:23;49730:32;49727:52;;;49775:1;49772;49765:12;49727:52;49814:9;49801:23;49833:31;49858:5;49833:31;:::i;51097:287::-;51226:3;51264:6;51258:13;51280:66;51339:6;51334:3;51327:4;51319:6;51315:17;51280:66;:::i", + "linkReferences": {} + }, + "methodIdentifiers": { + "calculateCommitmentSlotHash(bytes32)": "60121a94", + "cancelOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),(uint256,uint256))": "b53eafe9", + "fillOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),(uint256))": "7f84d229", + "host()": "f437bc59", + "instance(bytes)": "0bddd96c", + "onAccept(((bytes,bytes,uint64,bytes,bytes,uint64,bytes),address))": "0fee32ce", + "onGetResponse((((bytes,bytes,uint64,address,uint64,bytes[],uint64,bytes),(bytes,bytes)[]),address))": "44ab20f8", + "onGetTimeout((bytes,bytes,uint64,address,uint64,bytes[],uint64,bytes))": "d0fff366", + "onPostRequestTimeout((bytes,bytes,uint64,bytes,bytes,uint64,bytes))": "bc0dd447", + "onPostResponse((((bytes,bytes,uint64,bytes,bytes,uint64,bytes),bytes,uint64),address))": "b2a01bf5", + "onPostResponseTimeout(((bytes,bytes,uint64,bytes,bytes,uint64,bytes),bytes,uint64))": "0bc37bab", + "params()": "cff0ab96", + "placeOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),bytes32)": "731c8b32", + "setParams((address,address))": "c2977d2f" + }, + "rawMetadata": "{\"compiler\":{\"version\":\"0.8.20+commit.a1b79de6\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"admin\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"Expired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Filled\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientNativeToken\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInput\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnauthorizedCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnexpectedCall\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnknownOrder\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WrongChain\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"}],\"name\":\"EscrowRefunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"}],\"name\":\"EscrowReleased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"stateMachineId\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"gateway\",\"type\":\"bytes32\"}],\"name\":\"NewDeploymentAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"filler\",\"type\":\"address\"}],\"name\":\"OrderFilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"user\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"sourceChain\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"destChain\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"token\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"beneficiary\",\"type\":\"bytes32\"}],\"indexed\":false,\"internalType\":\"struct PaymentInfo[]\",\"name\":\"outputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"token\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"indexed\":false,\"internalType\":\"struct TokenInfo[]\",\"name\":\"inputs\",\"type\":\"tuple[]\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"name\":\"OrderPlaced\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"host\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dispatcher\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"struct Params\",\"name\":\"previous\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"host\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dispatcher\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"struct Params\",\"name\":\"current\",\"type\":\"tuple\"}],\"name\":\"ParamsUpdated\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitment\",\"type\":\"bytes32\"}],\"name\":\"calculateCommitmentSlotHash\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"user\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"sourceChain\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destChain\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"token\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"beneficiary\",\"type\":\"bytes32\"}],\"internalType\":\"struct PaymentInfo[]\",\"name\":\"outputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"token\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct TokenInfo[]\",\"name\":\"inputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Order\",\"name\":\"order\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"relayerFee\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"height\",\"type\":\"uint256\"}],\"internalType\":\"struct CancelOptions\",\"name\":\"options\",\"type\":\"tuple\"}],\"name\":\"cancelOrder\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"user\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"sourceChain\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destChain\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"token\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"beneficiary\",\"type\":\"bytes32\"}],\"internalType\":\"struct PaymentInfo[]\",\"name\":\"outputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"token\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct TokenInfo[]\",\"name\":\"inputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Order\",\"name\":\"order\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"relayerFee\",\"type\":\"uint256\"}],\"internalType\":\"struct FillOptions\",\"name\":\"options\",\"type\":\"tuple\"}],\"name\":\"fillOrder\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"host\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"stateMachineId\",\"type\":\"bytes\"}],\"name\":\"instance\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"source\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"dest\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"from\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"timeoutTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"body\",\"type\":\"bytes\"}],\"internalType\":\"struct PostRequest\",\"name\":\"request\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"relayer\",\"type\":\"address\"}],\"internalType\":\"struct IncomingPostRequest\",\"name\":\"incoming\",\"type\":\"tuple\"}],\"name\":\"onAccept\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"source\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"dest\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"timeoutTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"keys\",\"type\":\"bytes[]\"},{\"internalType\":\"uint64\",\"name\":\"height\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"internalType\":\"struct GetRequest\",\"name\":\"request\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"key\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"value\",\"type\":\"bytes\"}],\"internalType\":\"struct StorageValue[]\",\"name\":\"values\",\"type\":\"tuple[]\"}],\"internalType\":\"struct GetResponse\",\"name\":\"response\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"relayer\",\"type\":\"address\"}],\"internalType\":\"struct IncomingGetResponse\",\"name\":\"incoming\",\"type\":\"tuple\"}],\"name\":\"onGetResponse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"source\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"dest\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"timeoutTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"keys\",\"type\":\"bytes[]\"},{\"internalType\":\"uint64\",\"name\":\"height\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"internalType\":\"struct GetRequest\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"onGetTimeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"source\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"dest\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"from\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"timeoutTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"body\",\"type\":\"bytes\"}],\"internalType\":\"struct PostRequest\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"onPostRequestTimeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"source\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"dest\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"from\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"timeoutTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"body\",\"type\":\"bytes\"}],\"internalType\":\"struct PostRequest\",\"name\":\"request\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"timeoutTimestamp\",\"type\":\"uint64\"}],\"internalType\":\"struct PostResponse\",\"name\":\"response\",\"type\":\"tuple\"},{\"internalType\":\"address\",\"name\":\"relayer\",\"type\":\"address\"}],\"internalType\":\"struct IncomingPostResponse\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"onPostResponse\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"source\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"dest\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"from\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"timeoutTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"body\",\"type\":\"bytes\"}],\"internalType\":\"struct PostRequest\",\"name\":\"request\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"timeoutTimestamp\",\"type\":\"uint64\"}],\"internalType\":\"struct PostResponse\",\"name\":\"\",\"type\":\"tuple\"}],\"name\":\"onPostResponseTimeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"params\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"host\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dispatcher\",\"type\":\"address\"}],\"internalType\":\"struct Params\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"user\",\"type\":\"bytes32\"},{\"internalType\":\"bytes\",\"name\":\"sourceChain\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"destChain\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"deadline\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fees\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"token\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"beneficiary\",\"type\":\"bytes32\"}],\"internalType\":\"struct PaymentInfo[]\",\"name\":\"outputs\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"token\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"internalType\":\"struct TokenInfo[]\",\"name\":\"inputs\",\"type\":\"tuple[]\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"internalType\":\"struct Order\",\"name\":\"order\",\"type\":\"tuple\"},{\"internalType\":\"bytes32\",\"name\":\"graffiti\",\"type\":\"bytes32\"}],\"name\":\"placeOrder\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"dest\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"body\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"timeout\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"internalType\":\"struct DispatchPost\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"quote\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"dest\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"height\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"keys\",\"type\":\"bytes[]\"},{\"internalType\":\"uint64\",\"name\":\"timeout\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"internalType\":\"struct DispatchGet\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"quote\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"source\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"dest\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"from\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"timeoutTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"body\",\"type\":\"bytes\"}],\"internalType\":\"struct PostRequest\",\"name\":\"request\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"timeout\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"internalType\":\"struct DispatchPostResponse\",\"name\":\"response\",\"type\":\"tuple\"}],\"name\":\"quote\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"dest\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"body\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"timeout\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"internalType\":\"struct DispatchPost\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"quoteNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"source\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"dest\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"from\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"to\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"timeoutTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"body\",\"type\":\"bytes\"}],\"internalType\":\"struct PostRequest\",\"name\":\"request\",\"type\":\"tuple\"},{\"internalType\":\"bytes\",\"name\":\"response\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"timeout\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"payer\",\"type\":\"address\"}],\"internalType\":\"struct DispatchPostResponse\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"quoteNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"dest\",\"type\":\"bytes\"},{\"internalType\":\"uint64\",\"name\":\"height\",\"type\":\"uint64\"},{\"internalType\":\"bytes[]\",\"name\":\"keys\",\"type\":\"bytes[]\"},{\"internalType\":\"uint64\",\"name\":\"timeout\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"context\",\"type\":\"bytes\"}],\"internalType\":\"struct DispatchGet\",\"name\":\"request\",\"type\":\"tuple\"}],\"name\":\"quoteNative\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"host\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"dispatcher\",\"type\":\"address\"}],\"internalType\":\"struct Params\",\"name\":\"p\",\"type\":\"tuple\"}],\"name\":\"setParams\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"stateMutability\":\"payable\",\"type\":\"receive\"}],\"devdoc\":{\"author\":\"Polytope Labs (hello@polytope.technology)\",\"details\":\"The IntentGateway allows for the creation and fulfillment of cross-chain orders.\",\"errors\":{\"UnauthorizedCall()\":[{\"details\":\"Account is unauthorized\"}],\"UnexpectedCall()\":[{\"details\":\"Call was not expected\"}]},\"events\":{\"EscrowRefunded(bytes32)\":{\"details\":\"Emitted when an escrow is refunded.\",\"params\":{\"commitment\":\"The unique identifier of the order.\"}},\"EscrowReleased(bytes32)\":{\"details\":\"Emitted when an escrow is released.\",\"params\":{\"commitment\":\"The unique identifier of the order.\"}},\"NewDeploymentAdded(bytes,bytes32)\":{\"details\":\"Emitted when a new deployment of IntentGateway is added.\",\"params\":{\"gateway\":\"The gateway identifier.\",\"stateMachineId\":\"The identifier for the state machine.\"}},\"OrderFilled(bytes32,address)\":{\"details\":\"Emitted when an order is filled.\",\"params\":{\"commitment\":\"The unique identifier of the order.\",\"filler\":\"The address of the entity that filled the order.\"}},\"OrderPlaced(bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes)\":{\"details\":\"Emitted when an order is placed.\"},\"ParamsUpdated((address,address),(address,address))\":{\"details\":\"Emitted when the parameters are updated.\",\"params\":{\"current\":\"The current parameters.\",\"previous\":\"The previous parameters.\"}}},\"kind\":\"dev\",\"methods\":{\"calculateCommitmentSlotHash(bytes32)\":{\"details\":\"The commitment slot hash is used as part of the proof verification process\",\"params\":{\"commitment\":\"The commitment value as a bytes32 hash\"},\"returns\":{\"_0\":\"bytes The calculated commitment slot hash\"}},\"cancelOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),(uint256,uint256))\":{\"details\":\"This function can only be called by the order owner and requires a payment. It will initiate a storage query on the source chain to verify the order has not yet been filled. If the order has not been filled, the tokens will be released.\",\"params\":{\"options\":\"Additional options for the cancellation process.\",\"order\":\"The order to be canceled.\"}},\"fillOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),(uint256))\":{\"details\":\"This function is payable and can accept Ether.\",\"params\":{\"options\":\"The options to be used when filling the order.\",\"order\":\"The order to be filled.\"}},\"host()\":{\"details\":\"Should return the `IsmpHost` address for the current chain. The `IsmpHost` is an immutable contract that will never change.\"},\"instance(bytes)\":{\"details\":\"Fetch the IntentGateway contract instance for a chain.\"},\"onAccept(((bytes,bytes,uint64,bytes,bytes,uint64,bytes),address))\":{\"details\":\"This function is called when an incoming post request is accepted. It is only accessible by the host.\",\"params\":{\"incoming\":\"The incoming post request data.\"}},\"onGetResponse((((bytes,bytes,uint64,address,uint64,bytes[],uint64,bytes),(bytes,bytes)[]),address))\":{\"details\":\"This function is called by the host to process the response of a GET request.\",\"params\":{\"incoming\":\"The response data structure for the GET request. Only the host can call this function.\"}},\"params()\":{\"details\":\"Returns a struct containing all configurable parameters\",\"returns\":{\"_0\":\"Params A struct containing the module's current parameters\"}},\"placeOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),bytes32)\":{\"details\":\"This function allows users to place an order by providing the order details.\",\"params\":{\"order\":\"The order details to be placed.\"}},\"quote(((bytes,bytes,uint64,bytes,bytes,uint64,bytes),bytes,uint64,uint256,address))\":{\"details\":\"returns the quoted fee in the feeToken for dispatching a POST response\"},\"quote((bytes,bytes,bytes,uint64,uint256,address))\":{\"details\":\"returns the quoted fee in the feeToken for dispatching a POST request\"},\"quote((bytes,uint64,bytes[],uint64,uint256,bytes))\":{\"details\":\"returns the quoted fee in the feeToken for dispatching a GET request\"},\"quoteNative(((bytes,bytes,uint64,bytes,bytes,uint64,bytes),bytes,uint64,uint256,address))\":{\"details\":\"returns the quoted fee in the native token for dispatching a POST response\"},\"quoteNative((bytes,bytes,bytes,uint64,uint256,address))\":{\"details\":\"returns the quoted fee in the native token for dispatching a POST request\"},\"quoteNative((bytes,uint64,bytes[],uint64,uint256,bytes))\":{\"details\":\"returns the quoted fee in the native token for dispatching a GET request\"},\"setParams((address,address))\":{\"params\":{\"p\":\"The parameters to be set, encapsulated in a Params struct.\"}}},\"stateVariables\":{\"FILLED_SLOT_BIG_ENDIAN_BYTES\":{\"details\":\"Hex value 0x05 padded with leading zeros to fill 32 bytes\"},\"TRANSACTION_FEES\":{\"details\":\"Address constant for transaction fees, derived from the keccak256 hash of the string \\\"txFees\\\". This address is used to store or reference the transaction fees within the contract.\"},\"_admin\":{\"details\":\"Address of the admin, which can initialize the contract. The admin is reset to the zero address after initialization.\"},\"_filled\":{\"details\":\"Mapping to store the addresses associated with filled intents. The key is a bytes32 hash representing the intent, and the value is the address that filled the intent.\"},\"_instances\":{\"details\":\"Mapping to store instances of contracts. The key the keccak(stateMachineId) and the value is the address of a known contract instance.\"},\"_nonce\":{\"details\":\"Private variable to store the nonce value. This nonce is used to ensure the uniqueness of orders.\"},\"_orders\":{\"details\":\"Mapping to store orders. The outer mapping key is a bytes32 value representing the order commitment. The inner mapping key is an address representing the escrowed token contract. The inner mapping value is a uint256 representing the order amount.\"},\"_params\":{\"details\":\"Private variable to store the parameters for the IntentGateway module. This variable is of type `Params` and is used internally within the contract.\"}},\"title\":\"IntentGateway\",\"version\":1},\"userdoc\":{\"errors\":{\"Expired()\":[{\"notice\":\"Thrown when an action is attempted on an expired order.\"}],\"Filled()\":[{\"notice\":\"Thrown when an action is attempted on an order that has already been filled.\"}],\"InsufficientNativeToken()\":[{\"notice\":\"Thrown when there are insufficient native tokens to complete an action.\"}],\"InvalidInput()\":[{\"notice\":\"Thrown when an invalid input is provided.\"}],\"NotExpired()\":[{\"notice\":\"Thrown when an action is attempted on an order that has not yet expired.\"}],\"Unauthorized()\":[{\"notice\":\"Thrown when an unauthorized action is attempted.\"}],\"UnknownOrder()\":[{\"notice\":\"Thrown when an action is attempted on an unknown order.\"}],\"WrongChain()\":[{\"notice\":\"Thrown when an action is attempted on the wrong chain.\"}]},\"kind\":\"user\",\"methods\":{\"calculateCommitmentSlotHash(bytes32)\":{\"notice\":\"Calculates the commitment slot hash required for storage queries.\"},\"cancelOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),(uint256,uint256))\":{\"notice\":\"Cancels an existing order.\"},\"fillOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),(uint256))\":{\"notice\":\"Fills an order with the specified options.\"},\"onAccept(((bytes,bytes,uint64,bytes,bytes,uint64,bytes),address))\":{\"notice\":\"Executes an incoming post request.\"},\"onGetResponse((((bytes,bytes,uint64,address,uint64,bytes[],uint64,bytes),(bytes,bytes)[]),address))\":{\"notice\":\"Handles the response for an incoming GET request.\"},\"params()\":{\"notice\":\"Retrieves the current parameter settings for the IntentGateway module\"},\"placeOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),bytes32)\":{\"notice\":\"Places an order with the given order details.\"},\"setParams((address,address))\":{\"notice\":\"Sets the parameters for the IntentGateway.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"src/modules/IntentGateway.sol\":\"IntentGateway\"},\"evmVersion\":\"shanghai\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@openzeppelin/=node_modules/openzeppelin-solidity/\",\":@polytope-labs/erc6160/=node_modules/@polytope-labs/erc6160/src/\",\":@polytope-labs/ismp-solidity-v1/=node_modules/@polytope-labs/ismp-solidity-v1/interfaces/\",\":@polytope-labs/ismp-solidity/=node_modules/@polytope-labs/ismp-solidity/interfaces/\",\":@polytope-labs/solidity-merkle-trees/=node_modules/@polytope-labs/solidity-merkle-trees/\",\":@sp1-contracts/=lib/sp1-contracts/contracts/src/\",\":@uniswap/v2-periphery/=node_modules/@uniswap/v2-periphery/\",\":@uniswap/v3-core/=node_modules/@uniswap/v3-core/\",\":@uniswap/v3-periphery/=node_modules/@uniswap/v3-periphery/\",\":ds-test/=lib/forge-std/lib/ds-test/src/\",\":erc4626-tests/=lib/sp1-contracts/contracts/lib/openzeppelin-contracts/lib/erc4626-tests/\",\":forge-std/=lib/forge-std/src/\",\":openzeppelin-contracts/=lib/sp1-contracts/contracts/lib/openzeppelin-contracts/\",\":solidity-stringutils/=lib/solidity-stringutils/\",\":sp1-contracts/=lib/sp1-contracts/contracts/\",\":stringutils/=lib/solidity-stringutils/src/\"]},\"sources\":{\"node_modules/@polytope-labs/ismp-solidity-v1/interfaces/IDispatcher.sol\":{\"keccak256\":\"0x220d9365250827d30fb727ad11444f5a8a25892ac153885781d4be517441c8fd\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://3c6e2ad430f0eb2cff6a0db61143a99a7f890c71a1ae3bb6bb022b35b515167b\",\"dweb:/ipfs/QmYhMmQ3f3f484VDjYNd6d4UqmyQbDD3X6ZwVcHjgaZ3u3\"]},\"node_modules/@polytope-labs/ismp-solidity-v1/interfaces/IIsmpModule.sol\":{\"keccak256\":\"0x2cb695831aa5107f33902edefe881ca150a0aeb35b18026f1aaa4f7605bd16a1\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://b9d230894c969efcc34aed5109d6485f04c1871232b5df564b651eb719c67841\",\"dweb:/ipfs/QmfURyZxK23ZU4wZMfowYuSau76o2S4nTKy9jH4nx6xBRi\"]},\"node_modules/@polytope-labs/ismp-solidity-v1/interfaces/Message.sol\":{\"keccak256\":\"0xca108a8f8c3c58610997c4e5bf37ca664cf2626e39f6f61d2b11f832cfa9747a\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://c783d92821ecb178e519d175302b4d5519eeacba461918ad974afd8b82e17dcb\",\"dweb:/ipfs/QmfKCvXkZW1fP5E6TUMmn85krvdER3QqLv9S51v3yNy6Xq\"]},\"node_modules/@polytope-labs/ismp-solidity-v1/interfaces/StateMachine.sol\":{\"keccak256\":\"0x1f284f85fe36f41f23913e334a19b1ef9a4cda35f986827ae4794bef4c815cc5\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://0eb2538be2fee628f1e2f752fb7c4ee51c8681abbcbb33592097fa721a2bcd42\",\"dweb:/ipfs/QmdoNkpveXBCo67iLb2NQhFwCxconoWfZEEfmteSf2adCJ\"]},\"node_modules/@polytope-labs/solidity-merkle-trees/src/Types.sol\":{\"keccak256\":\"0x02d8395b46f33e9ad4a85275e31519035129fa01905a26cdf8d88512f1ae4ec5\",\"license\":\"Apache2\",\"urls\":[\"bzz-raw://9d3d151eaf7c0944530e3fb6dced088b39212fa9d5090711af2dc3d67f87d359\",\"dweb:/ipfs/QmQovNTb2cQaEpeNHm64EGoLRqZJjisrSMkebNvh4bZPXh\"]},\"node_modules/@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol\":{\"keccak256\":\"0x8a3c5c449d4b7cd76513ed6995f4b86e4a86f222c770f8442f5fc128ce29b4d2\",\"urls\":[\"bzz-raw://1df63ca373dafae3bd0ee7fe70f890a1dc7c45ed869c01de68413e0e97ff9deb\",\"dweb:/ipfs/QmefJgEYGUL8KX7kQKYTrDweF8GB7yjy3nw5Bmqzryg7PG\"]},\"node_modules/@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol\":{\"keccak256\":\"0x744e30c133bd0f7ca9e7163433cf6d72f45c6bb1508c2c9c02f1a6db796ae59d\",\"urls\":[\"bzz-raw://9bf2f4454ad63d4cff03a0630e787d9e8a9deed80aec89682cd8ad6379d9ef8c\",\"dweb:/ipfs/Qme51hQNR2wpax7ooUadhtqLtXm8ffeVVYyubLkTT4wMCG\"]},\"node_modules/openzeppelin-solidity/contracts/token/ERC20/IERC20.sol\":{\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34\",\"dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr\"]},\"node_modules/openzeppelin-solidity/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"keccak256\":\"0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://b2717fd2bdac99daa960a6de500754ea1b932093c946388c381da48658234b95\",\"dweb:/ipfs/QmP6QVMn6UeA3ByahyJbYQr5M6coHKBKsf3ySZSfbyA8R7\"]},\"node_modules/openzeppelin-solidity/contracts/token/ERC20/utils/SafeERC20.sol\":{\"keccak256\":\"0x9b72f93be69ca894d8492c244259615c4a742afc8d63720dbc8bb81087d9b238\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://f5a7b96e511be78d5cdf635c784e6ab8cdd38625bb8cafb8a80914a1c89cf0f6\",\"dweb:/ipfs/QmVzTCwJxQAkjRQHboT5QrvsVJGWQHgfEjeTbvyxoKBrds\"]},\"node_modules/openzeppelin-solidity/contracts/utils/Address.sol\":{\"keccak256\":\"0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ec772b45a624be516f1c81970caa8a2e144301e9d0921cbc1a2789fef39a1269\",\"dweb:/ipfs/QmNyjwxCrGhQMyzLD93oUobJXVe9ceJvRvfXwbEtuxPiEj\"]},\"node_modules/openzeppelin-solidity/contracts/utils/Strings.sol\":{\"keccak256\":\"0xa4d1d62251f8574deb032a35fc948386a9b4de74b812d4f545a1ac120486b48a\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://8c969013129ba9e651a20735ef659fef6d8a1139ea3607bd4b26ddea2d645634\",\"dweb:/ipfs/QmVhVa6LGuzAcB8qgDtVHRkucn4ihj5UZr8xBLcJkP6ucb\"]},\"node_modules/openzeppelin-solidity/contracts/utils/math/Math.sol\":{\"keccak256\":\"0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://33bbf48cc069be677705037ba7520c22b1b622c23b33e1a71495f2d36549d40b\",\"dweb:/ipfs/Qmct36zWXv3j7LZB83uwbg7TXwnZSN1fqHNDZ93GG98bGz\"]},\"src/interfaces/ICallDispatcher.sol\":{\"keccak256\":\"0x5b4312af9f135197c9e3ffab10627991342c4152fd15b46c4202836b5ea0347d\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://3c4e0d719f41f232cc88f759e9bf2200f628356efaf24645bdd3d665ee186c98\",\"dweb:/ipfs/Qmc7ZubmCh4v3ZMSDDSMeqy5hLsw365XQUrm5Z931PMkyd\"]},\"src/modules/IntentGateway.sol\":{\"keccak256\":\"0x3fa199452e860425bf0f393d88a9a7d5408e7870454df7be9a82ca62c87a879d\",\"license\":\"Apache-2.0\",\"urls\":[\"bzz-raw://b65c7776ee362ab3756e48155d1b8b2bcde820ea9c702140f8d073b8a99d8907\",\"dweb:/ipfs/QmQ2Ket8FYRuys3b5APYPwVJy7LsVQMBqo4ZNY6khRF8Sv\"]}},\"version\":1}", + "metadata": { + "compiler": { "version": "0.8.20+commit.a1b79de6" }, + "language": "Solidity", + "output": { + "abi": [ + { + "inputs": [{ "internalType": "address", "name": "admin", "type": "address" }], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { "inputs": [], "type": "error", "name": "Expired" }, + { "inputs": [], "type": "error", "name": "Filled" }, + { "inputs": [], "type": "error", "name": "InsufficientNativeToken" }, + { "inputs": [], "type": "error", "name": "InvalidInput" }, + { "inputs": [], "type": "error", "name": "NotExpired" }, + { "inputs": [], "type": "error", "name": "Unauthorized" }, + { "inputs": [], "type": "error", "name": "UnauthorizedCall" }, + { "inputs": [], "type": "error", "name": "UnexpectedCall" }, + { "inputs": [], "type": "error", "name": "UnknownOrder" }, + { "inputs": [], "type": "error", "name": "WrongChain" }, + { + "inputs": [{ "internalType": "bytes32", "name": "commitment", "type": "bytes32", "indexed": true }], + "type": "event", + "name": "EscrowRefunded", + "anonymous": false + }, + { + "inputs": [{ "internalType": "bytes32", "name": "commitment", "type": "bytes32", "indexed": true }], + "type": "event", + "name": "EscrowReleased", + "anonymous": false + }, + { + "inputs": [ + { "internalType": "bytes", "name": "stateMachineId", "type": "bytes", "indexed": false }, + { "internalType": "bytes32", "name": "gateway", "type": "bytes32", "indexed": false } + ], + "type": "event", + "name": "NewDeploymentAdded", + "anonymous": false + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "commitment", "type": "bytes32", "indexed": true }, + { "internalType": "address", "name": "filler", "type": "address", "indexed": false } + ], + "type": "event", + "name": "OrderFilled", + "anonymous": false + }, + { + "inputs": [ + { "internalType": "bytes32", "name": "user", "type": "bytes32", "indexed": false }, + { "internalType": "bytes", "name": "sourceChain", "type": "bytes", "indexed": false }, + { "internalType": "bytes", "name": "destChain", "type": "bytes", "indexed": false }, + { "internalType": "uint256", "name": "deadline", "type": "uint256", "indexed": false }, + { "internalType": "uint256", "name": "nonce", "type": "uint256", "indexed": false }, + { "internalType": "uint256", "name": "fees", "type": "uint256", "indexed": false }, + { + "internalType": "struct PaymentInfo[]", + "name": "outputs", + "type": "tuple[]", + "components": [ + { "internalType": "bytes32", "name": "token", "type": "bytes32" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "bytes32", "name": "beneficiary", "type": "bytes32" } + ], + "indexed": false + }, + { + "internalType": "struct TokenInfo[]", + "name": "inputs", + "type": "tuple[]", + "components": [ + { "internalType": "bytes32", "name": "token", "type": "bytes32" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "indexed": false + }, + { "internalType": "bytes", "name": "callData", "type": "bytes", "indexed": false } + ], + "type": "event", + "name": "OrderPlaced", + "anonymous": false + }, + { + "inputs": [ + { + "internalType": "struct Params", + "name": "previous", + "type": "tuple", + "components": [ + { "internalType": "address", "name": "host", "type": "address" }, + { "internalType": "address", "name": "dispatcher", "type": "address" } + ], + "indexed": false + }, + { + "internalType": "struct Params", + "name": "current", + "type": "tuple", + "components": [ + { "internalType": "address", "name": "host", "type": "address" }, + { "internalType": "address", "name": "dispatcher", "type": "address" } + ], + "indexed": false + } + ], + "type": "event", + "name": "ParamsUpdated", + "anonymous": false + }, + { + "inputs": [{ "internalType": "bytes32", "name": "commitment", "type": "bytes32" }], + "stateMutability": "pure", + "type": "function", + "name": "calculateCommitmentSlotHash", + "outputs": [{ "internalType": "bytes", "name": "", "type": "bytes" }] + }, + { + "inputs": [ + { + "internalType": "struct Order", + "name": "order", + "type": "tuple", + "components": [ + { "internalType": "bytes32", "name": "user", "type": "bytes32" }, + { "internalType": "bytes", "name": "sourceChain", "type": "bytes" }, + { "internalType": "bytes", "name": "destChain", "type": "bytes" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { "internalType": "uint256", "name": "fees", "type": "uint256" }, + { + "internalType": "struct PaymentInfo[]", + "name": "outputs", + "type": "tuple[]", + "components": [ + { "internalType": "bytes32", "name": "token", "type": "bytes32" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "bytes32", "name": "beneficiary", "type": "bytes32" } + ] + }, + { + "internalType": "struct TokenInfo[]", + "name": "inputs", + "type": "tuple[]", + "components": [ + { "internalType": "bytes32", "name": "token", "type": "bytes32" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ] + }, + { "internalType": "bytes", "name": "callData", "type": "bytes" } + ] + }, + { + "internalType": "struct CancelOptions", + "name": "options", + "type": "tuple", + "components": [ + { "internalType": "uint256", "name": "relayerFee", "type": "uint256" }, + { "internalType": "uint256", "name": "height", "type": "uint256" } + ] + } + ], + "stateMutability": "payable", + "type": "function", + "name": "cancelOrder" + }, + { + "inputs": [ + { + "internalType": "struct Order", + "name": "order", + "type": "tuple", + "components": [ + { "internalType": "bytes32", "name": "user", "type": "bytes32" }, + { "internalType": "bytes", "name": "sourceChain", "type": "bytes" }, + { "internalType": "bytes", "name": "destChain", "type": "bytes" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { "internalType": "uint256", "name": "fees", "type": "uint256" }, + { + "internalType": "struct PaymentInfo[]", + "name": "outputs", + "type": "tuple[]", + "components": [ + { "internalType": "bytes32", "name": "token", "type": "bytes32" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "bytes32", "name": "beneficiary", "type": "bytes32" } + ] + }, + { + "internalType": "struct TokenInfo[]", + "name": "inputs", + "type": "tuple[]", + "components": [ + { "internalType": "bytes32", "name": "token", "type": "bytes32" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ] + }, + { "internalType": "bytes", "name": "callData", "type": "bytes" } + ] + }, + { + "internalType": "struct FillOptions", + "name": "options", + "type": "tuple", + "components": [{ "internalType": "uint256", "name": "relayerFee", "type": "uint256" }] + } + ], + "stateMutability": "payable", + "type": "function", + "name": "fillOrder" + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "host", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }] + }, + { + "inputs": [{ "internalType": "bytes", "name": "stateMachineId", "type": "bytes" }], + "stateMutability": "view", + "type": "function", + "name": "instance", + "outputs": [{ "internalType": "bytes32", "name": "", "type": "bytes32" }] + }, + { + "inputs": [ + { + "internalType": "struct IncomingPostRequest", + "name": "incoming", + "type": "tuple", + "components": [ + { + "internalType": "struct PostRequest", + "name": "request", + "type": "tuple", + "components": [ + { "internalType": "bytes", "name": "source", "type": "bytes" }, + { "internalType": "bytes", "name": "dest", "type": "bytes" }, + { "internalType": "uint64", "name": "nonce", "type": "uint64" }, + { "internalType": "bytes", "name": "from", "type": "bytes" }, + { "internalType": "bytes", "name": "to", "type": "bytes" }, + { "internalType": "uint64", "name": "timeoutTimestamp", "type": "uint64" }, + { "internalType": "bytes", "name": "body", "type": "bytes" } + ] + }, + { "internalType": "address", "name": "relayer", "type": "address" } + ] + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "onAccept" + }, + { + "inputs": [ + { + "internalType": "struct IncomingGetResponse", + "name": "incoming", + "type": "tuple", + "components": [ + { + "internalType": "struct GetResponse", + "name": "response", + "type": "tuple", + "components": [ + { + "internalType": "struct GetRequest", + "name": "request", + "type": "tuple", + "components": [ + { "internalType": "bytes", "name": "source", "type": "bytes" }, + { "internalType": "bytes", "name": "dest", "type": "bytes" }, + { "internalType": "uint64", "name": "nonce", "type": "uint64" }, + { "internalType": "address", "name": "from", "type": "address" }, + { + "internalType": "uint64", + "name": "timeoutTimestamp", + "type": "uint64" + }, + { "internalType": "bytes[]", "name": "keys", "type": "bytes[]" }, + { "internalType": "uint64", "name": "height", "type": "uint64" }, + { "internalType": "bytes", "name": "context", "type": "bytes" } + ] + }, + { + "internalType": "struct StorageValue[]", + "name": "values", + "type": "tuple[]", + "components": [ + { "internalType": "bytes", "name": "key", "type": "bytes" }, + { "internalType": "bytes", "name": "value", "type": "bytes" } + ] + } + ] + }, + { "internalType": "address", "name": "relayer", "type": "address" } + ] + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "onGetResponse" + }, + { + "inputs": [ + { + "internalType": "struct GetRequest", + "name": "", + "type": "tuple", + "components": [ + { "internalType": "bytes", "name": "source", "type": "bytes" }, + { "internalType": "bytes", "name": "dest", "type": "bytes" }, + { "internalType": "uint64", "name": "nonce", "type": "uint64" }, + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "uint64", "name": "timeoutTimestamp", "type": "uint64" }, + { "internalType": "bytes[]", "name": "keys", "type": "bytes[]" }, + { "internalType": "uint64", "name": "height", "type": "uint64" }, + { "internalType": "bytes", "name": "context", "type": "bytes" } + ] + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "onGetTimeout" + }, + { + "inputs": [ + { + "internalType": "struct PostRequest", + "name": "", + "type": "tuple", + "components": [ + { "internalType": "bytes", "name": "source", "type": "bytes" }, + { "internalType": "bytes", "name": "dest", "type": "bytes" }, + { "internalType": "uint64", "name": "nonce", "type": "uint64" }, + { "internalType": "bytes", "name": "from", "type": "bytes" }, + { "internalType": "bytes", "name": "to", "type": "bytes" }, + { "internalType": "uint64", "name": "timeoutTimestamp", "type": "uint64" }, + { "internalType": "bytes", "name": "body", "type": "bytes" } + ] + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "onPostRequestTimeout" + }, + { + "inputs": [ + { + "internalType": "struct IncomingPostResponse", + "name": "", + "type": "tuple", + "components": [ + { + "internalType": "struct PostResponse", + "name": "response", + "type": "tuple", + "components": [ + { + "internalType": "struct PostRequest", + "name": "request", + "type": "tuple", + "components": [ + { "internalType": "bytes", "name": "source", "type": "bytes" }, + { "internalType": "bytes", "name": "dest", "type": "bytes" }, + { "internalType": "uint64", "name": "nonce", "type": "uint64" }, + { "internalType": "bytes", "name": "from", "type": "bytes" }, + { "internalType": "bytes", "name": "to", "type": "bytes" }, + { + "internalType": "uint64", + "name": "timeoutTimestamp", + "type": "uint64" + }, + { "internalType": "bytes", "name": "body", "type": "bytes" } + ] + }, + { "internalType": "bytes", "name": "response", "type": "bytes" }, + { "internalType": "uint64", "name": "timeoutTimestamp", "type": "uint64" } + ] + }, + { "internalType": "address", "name": "relayer", "type": "address" } + ] + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "onPostResponse" + }, + { + "inputs": [ + { + "internalType": "struct PostResponse", + "name": "", + "type": "tuple", + "components": [ + { + "internalType": "struct PostRequest", + "name": "request", + "type": "tuple", + "components": [ + { "internalType": "bytes", "name": "source", "type": "bytes" }, + { "internalType": "bytes", "name": "dest", "type": "bytes" }, + { "internalType": "uint64", "name": "nonce", "type": "uint64" }, + { "internalType": "bytes", "name": "from", "type": "bytes" }, + { "internalType": "bytes", "name": "to", "type": "bytes" }, + { "internalType": "uint64", "name": "timeoutTimestamp", "type": "uint64" }, + { "internalType": "bytes", "name": "body", "type": "bytes" } + ] + }, + { "internalType": "bytes", "name": "response", "type": "bytes" }, + { "internalType": "uint64", "name": "timeoutTimestamp", "type": "uint64" } + ] + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "onPostResponseTimeout" + }, + { + "inputs": [], + "stateMutability": "view", + "type": "function", + "name": "params", + "outputs": [ + { + "internalType": "struct Params", + "name": "", + "type": "tuple", + "components": [ + { "internalType": "address", "name": "host", "type": "address" }, + { "internalType": "address", "name": "dispatcher", "type": "address" } + ] + } + ] + }, + { + "inputs": [ + { + "internalType": "struct Order", + "name": "order", + "type": "tuple", + "components": [ + { "internalType": "bytes32", "name": "user", "type": "bytes32" }, + { "internalType": "bytes", "name": "sourceChain", "type": "bytes" }, + { "internalType": "bytes", "name": "destChain", "type": "bytes" }, + { "internalType": "uint256", "name": "deadline", "type": "uint256" }, + { "internalType": "uint256", "name": "nonce", "type": "uint256" }, + { "internalType": "uint256", "name": "fees", "type": "uint256" }, + { + "internalType": "struct PaymentInfo[]", + "name": "outputs", + "type": "tuple[]", + "components": [ + { "internalType": "bytes32", "name": "token", "type": "bytes32" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "bytes32", "name": "beneficiary", "type": "bytes32" } + ] + }, + { + "internalType": "struct TokenInfo[]", + "name": "inputs", + "type": "tuple[]", + "components": [ + { "internalType": "bytes32", "name": "token", "type": "bytes32" }, + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ] + }, + { "internalType": "bytes", "name": "callData", "type": "bytes" } + ] + }, + { "internalType": "bytes32", "name": "graffiti", "type": "bytes32" } + ], + "stateMutability": "payable", + "type": "function", + "name": "placeOrder" + }, + { + "inputs": [ + { + "internalType": "struct Params", + "name": "p", + "type": "tuple", + "components": [ + { "internalType": "address", "name": "host", "type": "address" }, + { "internalType": "address", "name": "dispatcher", "type": "address" } + ] + } + ], + "stateMutability": "nonpayable", + "type": "function", + "name": "setParams" + }, + { "inputs": [], "stateMutability": "payable", "type": "receive" } + ], + "devdoc": { + "kind": "dev", + "methods": { + "calculateCommitmentSlotHash(bytes32)": { + "details": "The commitment slot hash is used as part of the proof verification process", + "params": { "commitment": "The commitment value as a bytes32 hash" }, + "returns": { "_0": "bytes The calculated commitment slot hash" } + }, + "cancelOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),(uint256,uint256))": { + "details": "This function can only be called by the order owner and requires a payment. It will initiate a storage query on the source chain to verify the order has not yet been filled. If the order has not been filled, the tokens will be released.", + "params": { + "options": "Additional options for the cancellation process.", + "order": "The order to be canceled." + } + }, + "fillOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),(uint256))": { + "details": "This function is payable and can accept Ether.", + "params": { + "options": "The options to be used when filling the order.", + "order": "The order to be filled." + } + }, + "host()": { + "details": "Should return the `IsmpHost` address for the current chain. The `IsmpHost` is an immutable contract that will never change." + }, + "instance(bytes)": { "details": "Fetch the IntentGateway contract instance for a chain." }, + "onAccept(((bytes,bytes,uint64,bytes,bytes,uint64,bytes),address))": { + "details": "This function is called when an incoming post request is accepted. It is only accessible by the host.", + "params": { "incoming": "The incoming post request data." } + }, + "onGetResponse((((bytes,bytes,uint64,address,uint64,bytes[],uint64,bytes),(bytes,bytes)[]),address))": { + "details": "This function is called by the host to process the response of a GET request.", + "params": { + "incoming": "The response data structure for the GET request. Only the host can call this function." + } + }, + "params()": { + "details": "Returns a struct containing all configurable parameters", + "returns": { "_0": "Params A struct containing the module's current parameters" } + }, + "placeOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),bytes32)": { + "details": "This function allows users to place an order by providing the order details.", + "params": { "order": "The order details to be placed." } + }, + "setParams((address,address))": { + "params": { "p": "The parameters to be set, encapsulated in a Params struct." } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "calculateCommitmentSlotHash(bytes32)": { + "notice": "Calculates the commitment slot hash required for storage queries." + }, + "cancelOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),(uint256,uint256))": { + "notice": "Cancels an existing order." + }, + "fillOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),(uint256))": { + "notice": "Fills an order with the specified options." + }, + "onAccept(((bytes,bytes,uint64,bytes,bytes,uint64,bytes),address))": { + "notice": "Executes an incoming post request." + }, + "onGetResponse((((bytes,bytes,uint64,address,uint64,bytes[],uint64,bytes),(bytes,bytes)[]),address))": { + "notice": "Handles the response for an incoming GET request." + }, + "params()": { "notice": "Retrieves the current parameter settings for the IntentGateway module" }, + "placeOrder((bytes32,bytes,bytes,uint256,uint256,uint256,(bytes32,uint256,bytes32)[],(bytes32,uint256)[],bytes),bytes32)": { + "notice": "Places an order with the given order details." + }, + "setParams((address,address))": { "notice": "Sets the parameters for the IntentGateway." } + }, + "version": 1 + } + }, + "settings": { + "remappings": [ + "@openzeppelin/=node_modules/openzeppelin-solidity/", + "@polytope-labs/erc6160/=node_modules/@polytope-labs/erc6160/src/", + "@polytope-labs/ismp-solidity-v1/=node_modules/@polytope-labs/ismp-solidity-v1/interfaces/", + "@polytope-labs/ismp-solidity/=node_modules/@polytope-labs/ismp-solidity/interfaces/", + "@polytope-labs/solidity-merkle-trees/=node_modules/@polytope-labs/solidity-merkle-trees/", + "@sp1-contracts/=lib/sp1-contracts/contracts/src/", + "@uniswap/v2-periphery/=node_modules/@uniswap/v2-periphery/", + "@uniswap/v3-core/=node_modules/@uniswap/v3-core/", + "@uniswap/v3-periphery/=node_modules/@uniswap/v3-periphery/", + "ds-test/=lib/forge-std/lib/ds-test/src/", + "erc4626-tests/=lib/sp1-contracts/contracts/lib/openzeppelin-contracts/lib/erc4626-tests/", + "forge-std/=lib/forge-std/src/", + "openzeppelin-contracts/=lib/sp1-contracts/contracts/lib/openzeppelin-contracts/", + "solidity-stringutils/=lib/solidity-stringutils/", + "sp1-contracts/=lib/sp1-contracts/contracts/", + "stringutils/=lib/solidity-stringutils/src/" + ], + "optimizer": { "enabled": true, "runs": 200 }, + "metadata": { "bytecodeHash": "ipfs" }, + "compilationTarget": { "src/modules/IntentGateway.sol": "IntentGateway" }, + "evmVersion": "shanghai", + "libraries": {} + }, + "sources": { + "node_modules/@polytope-labs/ismp-solidity-v1/interfaces/IDispatcher.sol": { + "keccak256": "0x220d9365250827d30fb727ad11444f5a8a25892ac153885781d4be517441c8fd", + "urls": [ + "bzz-raw://3c6e2ad430f0eb2cff6a0db61143a99a7f890c71a1ae3bb6bb022b35b515167b", + "dweb:/ipfs/QmYhMmQ3f3f484VDjYNd6d4UqmyQbDD3X6ZwVcHjgaZ3u3" + ], + "license": "Apache-2.0" + }, + "node_modules/@polytope-labs/ismp-solidity-v1/interfaces/IIsmpModule.sol": { + "keccak256": "0x2cb695831aa5107f33902edefe881ca150a0aeb35b18026f1aaa4f7605bd16a1", + "urls": [ + "bzz-raw://b9d230894c969efcc34aed5109d6485f04c1871232b5df564b651eb719c67841", + "dweb:/ipfs/QmfURyZxK23ZU4wZMfowYuSau76o2S4nTKy9jH4nx6xBRi" + ], + "license": "Apache-2.0" + }, + "node_modules/@polytope-labs/ismp-solidity-v1/interfaces/Message.sol": { + "keccak256": "0xca108a8f8c3c58610997c4e5bf37ca664cf2626e39f6f61d2b11f832cfa9747a", + "urls": [ + "bzz-raw://c783d92821ecb178e519d175302b4d5519eeacba461918ad974afd8b82e17dcb", + "dweb:/ipfs/QmfKCvXkZW1fP5E6TUMmn85krvdER3QqLv9S51v3yNy6Xq" + ], + "license": "Apache-2.0" + }, + "node_modules/@polytope-labs/ismp-solidity-v1/interfaces/StateMachine.sol": { + "keccak256": "0x1f284f85fe36f41f23913e334a19b1ef9a4cda35f986827ae4794bef4c815cc5", + "urls": [ + "bzz-raw://0eb2538be2fee628f1e2f752fb7c4ee51c8681abbcbb33592097fa721a2bcd42", + "dweb:/ipfs/QmdoNkpveXBCo67iLb2NQhFwCxconoWfZEEfmteSf2adCJ" + ], + "license": "Apache-2.0" + }, + "node_modules/@polytope-labs/solidity-merkle-trees/src/Types.sol": { + "keccak256": "0x02d8395b46f33e9ad4a85275e31519035129fa01905a26cdf8d88512f1ae4ec5", + "urls": [ + "bzz-raw://9d3d151eaf7c0944530e3fb6dced088b39212fa9d5090711af2dc3d67f87d359", + "dweb:/ipfs/QmQovNTb2cQaEpeNHm64EGoLRqZJjisrSMkebNvh4bZPXh" + ], + "license": "Apache2" + }, + "node_modules/@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router01.sol": { + "keccak256": "0x8a3c5c449d4b7cd76513ed6995f4b86e4a86f222c770f8442f5fc128ce29b4d2", + "urls": [ + "bzz-raw://1df63ca373dafae3bd0ee7fe70f890a1dc7c45ed869c01de68413e0e97ff9deb", + "dweb:/ipfs/QmefJgEYGUL8KX7kQKYTrDweF8GB7yjy3nw5Bmqzryg7PG" + ], + "license": null + }, + "node_modules/@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol": { + "keccak256": "0x744e30c133bd0f7ca9e7163433cf6d72f45c6bb1508c2c9c02f1a6db796ae59d", + "urls": [ + "bzz-raw://9bf2f4454ad63d4cff03a0630e787d9e8a9deed80aec89682cd8ad6379d9ef8c", + "dweb:/ipfs/Qme51hQNR2wpax7ooUadhtqLtXm8ffeVVYyubLkTT4wMCG" + ], + "license": null + }, + "node_modules/openzeppelin-solidity/contracts/token/ERC20/IERC20.sol": { + "keccak256": "0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b", + "urls": [ + "bzz-raw://5a7d5b1ef5d8d5889ad2ed89d8619c09383b80b72ab226e0fe7bde1636481e34", + "dweb:/ipfs/QmebXWgtEfumQGBdVeM6c71McLixYXQP5Bk6kKXuoY4Bmr" + ], + "license": "MIT" + }, + "node_modules/openzeppelin-solidity/contracts/token/ERC20/extensions/draft-IERC20Permit.sol": { + "keccak256": "0xf41ca991f30855bf80ffd11e9347856a517b977f0a6c2d52e6421a99b7840329", + "urls": [ + "bzz-raw://b2717fd2bdac99daa960a6de500754ea1b932093c946388c381da48658234b95", + "dweb:/ipfs/QmP6QVMn6UeA3ByahyJbYQr5M6coHKBKsf3ySZSfbyA8R7" + ], + "license": "MIT" + }, + "node_modules/openzeppelin-solidity/contracts/token/ERC20/utils/SafeERC20.sol": { + "keccak256": "0x9b72f93be69ca894d8492c244259615c4a742afc8d63720dbc8bb81087d9b238", + "urls": [ + "bzz-raw://f5a7b96e511be78d5cdf635c784e6ab8cdd38625bb8cafb8a80914a1c89cf0f6", + "dweb:/ipfs/QmVzTCwJxQAkjRQHboT5QrvsVJGWQHgfEjeTbvyxoKBrds" + ], + "license": "MIT" + }, + "node_modules/openzeppelin-solidity/contracts/utils/Address.sol": { + "keccak256": "0xf96f969e24029d43d0df89e59d365f277021dac62b48e1c1e3ebe0acdd7f1ca1", + "urls": [ + "bzz-raw://ec772b45a624be516f1c81970caa8a2e144301e9d0921cbc1a2789fef39a1269", + "dweb:/ipfs/QmNyjwxCrGhQMyzLD93oUobJXVe9ceJvRvfXwbEtuxPiEj" + ], + "license": "MIT" + }, + "node_modules/openzeppelin-solidity/contracts/utils/Strings.sol": { + "keccak256": "0xa4d1d62251f8574deb032a35fc948386a9b4de74b812d4f545a1ac120486b48a", + "urls": [ + "bzz-raw://8c969013129ba9e651a20735ef659fef6d8a1139ea3607bd4b26ddea2d645634", + "dweb:/ipfs/QmVhVa6LGuzAcB8qgDtVHRkucn4ihj5UZr8xBLcJkP6ucb" + ], + "license": "MIT" + }, + "node_modules/openzeppelin-solidity/contracts/utils/math/Math.sol": { + "keccak256": "0xa1e8e83cd0087785df04ac79fb395d9f3684caeaf973d9e2c71caef723a3a5d6", + "urls": [ + "bzz-raw://33bbf48cc069be677705037ba7520c22b1b622c23b33e1a71495f2d36549d40b", + "dweb:/ipfs/Qmct36zWXv3j7LZB83uwbg7TXwnZSN1fqHNDZ93GG98bGz" + ], + "license": "MIT" + }, + "src/interfaces/ICallDispatcher.sol": { + "keccak256": "0x5b4312af9f135197c9e3ffab10627991342c4152fd15b46c4202836b5ea0347d", + "urls": [ + "bzz-raw://3c4e0d719f41f232cc88f759e9bf2200f628356efaf24645bdd3d665ee186c98", + "dweb:/ipfs/Qmc7ZubmCh4v3ZMSDDSMeqy5hLsw365XQUrm5Z931PMkyd" + ], + "license": "Apache-2.0" + }, + "src/modules/IntentGateway.sol": { + "keccak256": "0x3fa199452e860425bf0f393d88a9a7d5408e7870454df7be9a82ca62c87a879d", + "urls": [ + "bzz-raw://b65c7776ee362ab3756e48155d1b8b2bcde820ea9c702140f8d073b8a99d8907", + "dweb:/ipfs/QmQ2Ket8FYRuys3b5APYPwVJy7LsVQMBqo4ZNY6khRF8Sv" + ], + "license": "Apache-2.0" + } + }, + "version": 1 + }, + "id": 100 +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/TokenGateway.abi.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/TokenGateway.abi.json new file mode 100644 index 00000000..930ed96d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/TokenGateway.abi.json @@ -0,0 +1,415 @@ +[ + { + "type": "constructor", + "inputs": [{ "name": "admin", "type": "address", "internalType": "address" }], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "erc20", + "inputs": [{ "name": "assetId", "type": "bytes32", "internalType": "bytes32" }], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "erc6160", + "inputs": [{ "name": "assetId", "type": "bytes32", "internalType": "bytes32" }], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "host", + "inputs": [], + "outputs": [{ "name": "h", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "init", + "inputs": [ + { + "name": "teleportParams", + "type": "tuple", + "internalType": "struct TokenGatewayParamsExt", + "components": [ + { + "name": "params", + "type": "tuple", + "internalType": "struct TokenGatewayParams", + "components": [ + { "name": "host", "type": "address", "internalType": "address" }, + { "name": "dispatcher", "type": "address", "internalType": "address" } + ] + }, + { + "name": "assets", + "type": "tuple[]", + "internalType": "struct AssetMetadata[]", + "components": [ + { "name": "erc20", "type": "address", "internalType": "address" }, + { "name": "erc6160", "type": "address", "internalType": "address" }, + { "name": "name", "type": "string", "internalType": "string" }, + { "name": "symbol", "type": "string", "internalType": "string" }, + { "name": "initialSupply", "type": "uint256", "internalType": "uint256" }, + { "name": "beneficiary", "type": "address", "internalType": "address" } + ] + } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "instance", + "inputs": [{ "name": "destination", "type": "bytes", "internalType": "bytes" }], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "onAccept", + "inputs": [ + { + "name": "incoming", + "type": "tuple", + "internalType": "struct IncomingPostRequest", + "components": [ + { + "name": "request", + "type": "tuple", + "internalType": "struct PostRequest", + "components": [ + { "name": "source", "type": "bytes", "internalType": "bytes" }, + { "name": "dest", "type": "bytes", "internalType": "bytes" }, + { "name": "nonce", "type": "uint64", "internalType": "uint64" }, + { "name": "from", "type": "bytes", "internalType": "bytes" }, + { "name": "to", "type": "bytes", "internalType": "bytes" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" }, + { "name": "body", "type": "bytes", "internalType": "bytes" } + ] + }, + { "name": "relayer", "type": "address", "internalType": "address" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onGetResponse", + "inputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct IncomingGetResponse", + "components": [ + { + "name": "response", + "type": "tuple", + "internalType": "struct GetResponse", + "components": [ + { + "name": "request", + "type": "tuple", + "internalType": "struct GetRequest", + "components": [ + { "name": "source", "type": "bytes", "internalType": "bytes" }, + { "name": "dest", "type": "bytes", "internalType": "bytes" }, + { "name": "nonce", "type": "uint64", "internalType": "uint64" }, + { "name": "from", "type": "address", "internalType": "address" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" }, + { "name": "keys", "type": "bytes[]", "internalType": "bytes[]" }, + { "name": "height", "type": "uint64", "internalType": "uint64" }, + { "name": "context", "type": "bytes", "internalType": "bytes" } + ] + }, + { + "name": "values", + "type": "tuple[]", + "internalType": "struct StorageValue[]", + "components": [ + { "name": "key", "type": "bytes", "internalType": "bytes" }, + { "name": "value", "type": "bytes", "internalType": "bytes" } + ] + } + ] + }, + { "name": "relayer", "type": "address", "internalType": "address" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onGetTimeout", + "inputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct GetRequest", + "components": [ + { "name": "source", "type": "bytes", "internalType": "bytes" }, + { "name": "dest", "type": "bytes", "internalType": "bytes" }, + { "name": "nonce", "type": "uint64", "internalType": "uint64" }, + { "name": "from", "type": "address", "internalType": "address" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" }, + { "name": "keys", "type": "bytes[]", "internalType": "bytes[]" }, + { "name": "height", "type": "uint64", "internalType": "uint64" }, + { "name": "context", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onPostRequestTimeout", + "inputs": [ + { + "name": "request", + "type": "tuple", + "internalType": "struct PostRequest", + "components": [ + { "name": "source", "type": "bytes", "internalType": "bytes" }, + { "name": "dest", "type": "bytes", "internalType": "bytes" }, + { "name": "nonce", "type": "uint64", "internalType": "uint64" }, + { "name": "from", "type": "bytes", "internalType": "bytes" }, + { "name": "to", "type": "bytes", "internalType": "bytes" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" }, + { "name": "body", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onPostResponse", + "inputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct IncomingPostResponse", + "components": [ + { + "name": "response", + "type": "tuple", + "internalType": "struct PostResponse", + "components": [ + { + "name": "request", + "type": "tuple", + "internalType": "struct PostRequest", + "components": [ + { "name": "source", "type": "bytes", "internalType": "bytes" }, + { "name": "dest", "type": "bytes", "internalType": "bytes" }, + { "name": "nonce", "type": "uint64", "internalType": "uint64" }, + { "name": "from", "type": "bytes", "internalType": "bytes" }, + { "name": "to", "type": "bytes", "internalType": "bytes" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" }, + { "name": "body", "type": "bytes", "internalType": "bytes" } + ] + }, + { "name": "response", "type": "bytes", "internalType": "bytes" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" } + ] + }, + { "name": "relayer", "type": "address", "internalType": "address" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "onPostResponseTimeout", + "inputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct PostResponse", + "components": [ + { + "name": "request", + "type": "tuple", + "internalType": "struct PostRequest", + "components": [ + { "name": "source", "type": "bytes", "internalType": "bytes" }, + { "name": "dest", "type": "bytes", "internalType": "bytes" }, + { "name": "nonce", "type": "uint64", "internalType": "uint64" }, + { "name": "from", "type": "bytes", "internalType": "bytes" }, + { "name": "to", "type": "bytes", "internalType": "bytes" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" }, + { "name": "body", "type": "bytes", "internalType": "bytes" } + ] + }, + { "name": "response", "type": "bytes", "internalType": "bytes" }, + { "name": "timeoutTimestamp", "type": "uint64", "internalType": "uint64" } + ] + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "params", + "inputs": [], + "outputs": [ + { + "name": "", + "type": "tuple", + "internalType": "struct TokenGatewayParams", + "components": [ + { "name": "host", "type": "address", "internalType": "address" }, + { "name": "dispatcher", "type": "address", "internalType": "address" } + ] + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "teleport", + "inputs": [ + { + "name": "teleportParams", + "type": "tuple", + "internalType": "struct TeleportParams", + "components": [ + { "name": "amount", "type": "uint256", "internalType": "uint256" }, + { "name": "relayerFee", "type": "uint256", "internalType": "uint256" }, + { "name": "assetId", "type": "bytes32", "internalType": "bytes32" }, + { "name": "redeem", "type": "bool", "internalType": "bool" }, + { "name": "to", "type": "bytes32", "internalType": "bytes32" }, + { "name": "dest", "type": "bytes", "internalType": "bytes" }, + { "name": "timeout", "type": "uint64", "internalType": "uint64" }, + { "name": "nativeCost", "type": "uint256", "internalType": "uint256" }, + { "name": "data", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "outputs": [], + "stateMutability": "payable" + }, + { + "type": "event", + "name": "AssetAdminChanged", + "inputs": [ + { "name": "asset", "type": "address", "indexed": false, "internalType": "address" }, + { "name": "newAdmin", "type": "address", "indexed": false, "internalType": "address" } + ], + "anonymous": false + }, + { + "type": "event", + "name": "AssetReceived", + "inputs": [ + { "name": "amount", "type": "uint256", "indexed": false, "internalType": "uint256" }, + { "name": "commitment", "type": "bytes32", "indexed": false, "internalType": "bytes32" }, + { "name": "from", "type": "bytes32", "indexed": true, "internalType": "bytes32" }, + { "name": "beneficiary", "type": "address", "indexed": true, "internalType": "address" }, + { "name": "assetId", "type": "bytes32", "indexed": true, "internalType": "bytes32" } + ], + "anonymous": false + }, + { + "type": "event", + "name": "AssetRefunded", + "inputs": [ + { "name": "amount", "type": "uint256", "indexed": false, "internalType": "uint256" }, + { "name": "commitment", "type": "bytes32", "indexed": false, "internalType": "bytes32" }, + { "name": "beneficiary", "type": "address", "indexed": true, "internalType": "address" }, + { "name": "assetId", "type": "bytes32", "indexed": true, "internalType": "bytes32" } + ], + "anonymous": false + }, + { + "type": "event", + "name": "AssetRegistered", + "inputs": [ + { "name": "erc20", "type": "address", "indexed": false, "internalType": "address" }, + { "name": "erc6160", "type": "address", "indexed": false, "internalType": "address" }, + { "name": "name", "type": "string", "indexed": false, "internalType": "string" }, + { "name": "symbol", "type": "string", "indexed": false, "internalType": "string" }, + { "name": "assetId", "type": "bytes32", "indexed": false, "internalType": "bytes32" }, + { "name": "initialSupply", "type": "uint256", "indexed": false, "internalType": "uint256" }, + { "name": "beneficiary", "type": "address", "indexed": false, "internalType": "address" } + ], + "anonymous": false + }, + { + "type": "event", + "name": "AssetRemoved", + "inputs": [{ "name": "assetId", "type": "bytes32", "indexed": false, "internalType": "bytes32" }], + "anonymous": false + }, + { + "type": "event", + "name": "AssetTeleported", + "inputs": [ + { "name": "to", "type": "bytes32", "indexed": false, "internalType": "bytes32" }, + { "name": "dest", "type": "string", "indexed": false, "internalType": "string" }, + { "name": "amount", "type": "uint256", "indexed": false, "internalType": "uint256" }, + { "name": "commitment", "type": "bytes32", "indexed": false, "internalType": "bytes32" }, + { "name": "from", "type": "address", "indexed": true, "internalType": "address" }, + { "name": "assetId", "type": "bytes32", "indexed": true, "internalType": "bytes32" }, + { "name": "redeem", "type": "bool", "indexed": false, "internalType": "bool" } + ], + "anonymous": false + }, + { + "type": "event", + "name": "NewContractInstance", + "inputs": [ + { "name": "chain", "type": "string", "indexed": false, "internalType": "string" }, + { "name": "moduleId", "type": "address", "indexed": false, "internalType": "address" } + ], + "anonymous": false + }, + { + "type": "event", + "name": "ParamsUpdated", + "inputs": [ + { + "name": "oldParams", + "type": "tuple", + "indexed": false, + "internalType": "struct TokenGatewayParams", + "components": [ + { "name": "host", "type": "address", "internalType": "address" }, + { "name": "dispatcher", "type": "address", "internalType": "address" } + ] + }, + { + "name": "newParams", + "type": "tuple", + "indexed": false, + "internalType": "struct TokenGatewayParams", + "components": [ + { "name": "host", "type": "address", "internalType": "address" }, + { "name": "dispatcher", "type": "address", "internalType": "address" } + ] + } + ], + "anonymous": false + }, + { "type": "error", "name": "InconsistentState", "inputs": [] }, + { "type": "error", "name": "InvalidAddressLength", "inputs": [] }, + { "type": "error", "name": "InvalidAmount", "inputs": [] }, + { "type": "error", "name": "UnauthorizedAction", "inputs": [] }, + { "type": "error", "name": "UnauthorizedCall", "inputs": [] }, + { "type": "error", "name": "UnexpectedCall", "inputs": [] }, + { "type": "error", "name": "UnknownAsset", "inputs": [] }, + { "type": "error", "name": "ZeroAddress", "inputs": [] } +] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV2.abi.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV2.abi.json new file mode 100644 index 00000000..137da488 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV2.abi.json @@ -0,0 +1,79 @@ +{ + "factory": [ + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + } + ], + "name": "getPair", + "outputs": [ + { + "internalType": "address", + "name": "pair", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "pair": [ + { + "inputs": [], + "name": "getReserves", + "outputs": [ + { + "internalType": "uint112", + "name": "reserve0", + "type": "uint112" + }, + { + "internalType": "uint112", + "name": "reserve1", + "type": "uint112" + }, + { + "internalType": "uint32", + "name": "blockTimestampLast", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ] +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV3Factory.abi.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV3Factory.abi.json new file mode 100644 index 00000000..82735913 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV3Factory.abi.json @@ -0,0 +1,198 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + } + ], + "name": "FeeAmountEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnerChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "token0", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token1", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + }, + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolCreated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + } + ], + "name": "createPool", + "outputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + } + ], + "name": "enableFeeAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + } + ], + "name": "feeAmountTickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenA", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenB", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + } + ], + "name": "getPool", + "outputs": [ + { + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + } + ], + "name": "setOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV3Pool.abi.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV3Pool.abi.json new file mode 100644 index 00000000..e6767679 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV3Pool.abi.json @@ -0,0 +1,983 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Burn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "Collect", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "name": "CollectProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "paid1", + "type": "uint256" + } + ], + "name": "Flash", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextOld", + "type": "uint16" + }, + { + "indexed": false, + "internalType": "uint16", + "name": "observationCardinalityNextNew", + "type": "uint16" + } + ], + "name": "IncreaseObservationCardinalityNext", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Initialize", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "indexed": true, + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "name": "Mint", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1Old", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol0New", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "feeProtocol1New", + "type": "uint8" + } + ], + "name": "SetFeeProtocol", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "amount1", + "type": "int256" + }, + { + "indexed": false, + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "indexed": false, + "internalType": "uint128", + "name": "liquidity", + "type": "uint128" + }, + { + "indexed": false, + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "Swap", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + } + ], + "name": "burn", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collect", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint128", + "name": "amount0Requested", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1Requested", + "type": "uint128" + } + ], + "name": "collectProtocol", + "outputs": [ + { + "internalType": "uint128", + "name": "amount0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "amount1", + "type": "uint128" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "factory", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "fee", + "outputs": [ + { + "internalType": "uint24", + "name": "", + "type": "uint24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal0X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeGrowthGlobal1X128", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "flash", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + } + ], + "name": "increaseObservationCardinalityNext", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "liquidity", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLiquidityPerTick", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + }, + { + "internalType": "uint128", + "name": "amount", + "type": "uint128" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "mint", + "outputs": [ + { + "internalType": "uint256", + "name": "amount0", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount1", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "observations", + "outputs": [ + { + "internalType": "uint32", + "name": "blockTimestamp", + "type": "uint32" + }, + { + "internalType": "int56", + "name": "tickCumulative", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityCumulativeX128", + "type": "uint160" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32[]", + "name": "secondsAgos", + "type": "uint32[]" + } + ], + "name": "observe", + "outputs": [ + { + "internalType": "int56[]", + "name": "tickCumulatives", + "type": "int56[]" + }, + { + "internalType": "uint160[]", + "name": "secondsPerLiquidityCumulativeX128s", + "type": "uint160[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "positions", + "outputs": [ + { + "internalType": "uint128", + "name": "_liquidity", + "type": "uint128" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside0LastX128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthInside1LastX128", + "type": "uint256" + }, + { + "internalType": "uint128", + "name": "tokensOwed0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "tokensOwed1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "protocolFees", + "outputs": [ + { + "internalType": "uint128", + "name": "token0", + "type": "uint128" + }, + { + "internalType": "uint128", + "name": "token1", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint8", + "name": "feeProtocol0", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "feeProtocol1", + "type": "uint8" + } + ], + "name": "setFeeProtocol", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "slot0", + "outputs": [ + { + "internalType": "uint160", + "name": "sqrtPriceX96", + "type": "uint160" + }, + { + "internalType": "int24", + "name": "tick", + "type": "int24" + }, + { + "internalType": "uint16", + "name": "observationIndex", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinality", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "observationCardinalityNext", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "feeProtocol", + "type": "uint8" + }, + { + "internalType": "bool", + "name": "unlocked", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tickLower", + "type": "int24" + }, + { + "internalType": "int24", + "name": "tickUpper", + "type": "int24" + } + ], + "name": "snapshotCumulativesInside", + "outputs": [ + { + "internalType": "int56", + "name": "tickCumulativeInside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityInsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsInside", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "bool", + "name": "zeroForOne", + "type": "bool" + }, + { + "internalType": "int256", + "name": "amountSpecified", + "type": "int256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "swap", + "outputs": [ + { + "internalType": "int256", + "name": "amount0", + "type": "int256" + }, + { + "internalType": "int256", + "name": "amount1", + "type": "int256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int16", + "name": "wordPosition", + "type": "int16" + } + ], + "name": "tickBitmap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tickSpacing", + "outputs": [ + { + "internalType": "int24", + "name": "", + "type": "int24" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "int24", + "name": "tick", + "type": "int24" + } + ], + "name": "ticks", + "outputs": [ + { + "internalType": "uint128", + "name": "liquidityGross", + "type": "uint128" + }, + { + "internalType": "int128", + "name": "liquidityNet", + "type": "int128" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside0X128", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "feeGrowthOutside1X128", + "type": "uint256" + }, + { + "internalType": "int56", + "name": "tickCumulativeOutside", + "type": "int56" + }, + { + "internalType": "uint160", + "name": "secondsPerLiquidityOutsideX128", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "secondsOutside", + "type": "uint32" + }, + { + "internalType": "bool", + "name": "initialized", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token0", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "token1", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV3QuoterV2.abi.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV3QuoterV2.abi.json new file mode 100644 index 00000000..4143f676 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV3QuoterV2.abi.json @@ -0,0 +1,202 @@ +[ + { + "inputs": [ + { + "internalType": "bytes", + "name": "path", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + } + ], + "name": "quoteExactInput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint160[]", + "name": "sqrtPriceX96AfterList", + "type": "uint160[]" + }, + { + "internalType": "uint32[]", + "name": "initializedTicksCrossedList", + "type": "uint32[]" + }, + { + "internalType": "uint256", + "name": "gasEstimate", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + } + ], + "internalType": "struct IQuoterV2.QuoteExactInputSingleParams", + "name": "params", + "type": "tuple" + } + ], + "name": "quoteExactInputSingle", + "outputs": [ + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceX96After", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "initializedTicksCrossed", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "gasEstimate", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "path", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "amountOut", + "type": "uint256" + } + ], + "name": "quoteExactOutput", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint160[]", + "name": "sqrtPriceX96AfterList", + "type": "uint160[]" + }, + { + "internalType": "uint32[]", + "name": "initializedTicksCrossedList", + "type": "uint32[]" + }, + { + "internalType": "uint256", + "name": "gasEstimate", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "tokenIn", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenOut", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "uint160", + "name": "sqrtPriceLimitX96", + "type": "uint160" + } + ], + "internalType": "struct IQuoterV2.QuoteExactOutputSingleParams", + "name": "params", + "type": "tuple" + } + ], + "name": "quoteExactOutputSingle", + "outputs": [ + { + "internalType": "uint256", + "name": "amountIn", + "type": "uint256" + }, + { + "internalType": "uint160", + "name": "sqrtPriceX96After", + "type": "uint160" + }, + { + "internalType": "uint32", + "name": "initializedTicksCrossed", + "type": "uint32" + }, + { + "internalType": "uint256", + "name": "gasEstimate", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV4Quoter.abi.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV4Quoter.abi.json new file mode 100644 index 00000000..7cb9619d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/abis/UniswapV4Quoter.abi.json @@ -0,0 +1,294 @@ +[ + { + "type": "constructor", + "inputs": [{ "name": "_poolManager", "type": "address", "internalType": "contract IPoolManager" }], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "_quoteExactInput", + "inputs": [ + { + "name": "params", + "type": "tuple", + "internalType": "struct IV4Quoter.QuoteExactParams", + "components": [ + { "name": "exactCurrency", "type": "address", "internalType": "Currency" }, + { + "name": "path", + "type": "tuple[]", + "internalType": "struct PathKey[]", + "components": [ + { "name": "intermediateCurrency", "type": "address", "internalType": "Currency" }, + { "name": "fee", "type": "uint24", "internalType": "uint24" }, + { "name": "tickSpacing", "type": "int24", "internalType": "int24" }, + { "name": "hooks", "type": "address", "internalType": "contract IHooks" }, + { "name": "hookData", "type": "bytes", "internalType": "bytes" } + ] + }, + { "name": "exactAmount", "type": "uint128", "internalType": "uint128" } + ] + } + ], + "outputs": [{ "name": "", "type": "bytes", "internalType": "bytes" }], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "_quoteExactInputSingle", + "inputs": [ + { + "name": "params", + "type": "tuple", + "internalType": "struct IV4Quoter.QuoteExactSingleParams", + "components": [ + { + "name": "poolKey", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { "name": "currency0", "type": "address", "internalType": "Currency" }, + { "name": "currency1", "type": "address", "internalType": "Currency" }, + { "name": "fee", "type": "uint24", "internalType": "uint24" }, + { "name": "tickSpacing", "type": "int24", "internalType": "int24" }, + { "name": "hooks", "type": "address", "internalType": "contract IHooks" } + ] + }, + { "name": "zeroForOne", "type": "bool", "internalType": "bool" }, + { "name": "exactAmount", "type": "uint128", "internalType": "uint128" }, + { "name": "hookData", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "outputs": [{ "name": "", "type": "bytes", "internalType": "bytes" }], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "_quoteExactOutput", + "inputs": [ + { + "name": "params", + "type": "tuple", + "internalType": "struct IV4Quoter.QuoteExactParams", + "components": [ + { "name": "exactCurrency", "type": "address", "internalType": "Currency" }, + { + "name": "path", + "type": "tuple[]", + "internalType": "struct PathKey[]", + "components": [ + { "name": "intermediateCurrency", "type": "address", "internalType": "Currency" }, + { "name": "fee", "type": "uint24", "internalType": "uint24" }, + { "name": "tickSpacing", "type": "int24", "internalType": "int24" }, + { "name": "hooks", "type": "address", "internalType": "contract IHooks" }, + { "name": "hookData", "type": "bytes", "internalType": "bytes" } + ] + }, + { "name": "exactAmount", "type": "uint128", "internalType": "uint128" } + ] + } + ], + "outputs": [{ "name": "", "type": "bytes", "internalType": "bytes" }], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "_quoteExactOutputSingle", + "inputs": [ + { + "name": "params", + "type": "tuple", + "internalType": "struct IV4Quoter.QuoteExactSingleParams", + "components": [ + { + "name": "poolKey", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { "name": "currency0", "type": "address", "internalType": "Currency" }, + { "name": "currency1", "type": "address", "internalType": "Currency" }, + { "name": "fee", "type": "uint24", "internalType": "uint24" }, + { "name": "tickSpacing", "type": "int24", "internalType": "int24" }, + { "name": "hooks", "type": "address", "internalType": "contract IHooks" } + ] + }, + { "name": "zeroForOne", "type": "bool", "internalType": "bool" }, + { "name": "exactAmount", "type": "uint128", "internalType": "uint128" }, + { "name": "hookData", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "outputs": [{ "name": "", "type": "bytes", "internalType": "bytes" }], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "msgSender", + "inputs": [], + "outputs": [{ "name": "", "type": "address", "internalType": "address" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "poolManager", + "inputs": [], + "outputs": [{ "name": "", "type": "address", "internalType": "contract IPoolManager" }], + "stateMutability": "view" + }, + { + "type": "function", + "name": "quoteExactInput", + "inputs": [ + { + "name": "params", + "type": "tuple", + "internalType": "struct IV4Quoter.QuoteExactParams", + "components": [ + { "name": "exactCurrency", "type": "address", "internalType": "Currency" }, + { + "name": "path", + "type": "tuple[]", + "internalType": "struct PathKey[]", + "components": [ + { "name": "intermediateCurrency", "type": "address", "internalType": "Currency" }, + { "name": "fee", "type": "uint24", "internalType": "uint24" }, + { "name": "tickSpacing", "type": "int24", "internalType": "int24" }, + { "name": "hooks", "type": "address", "internalType": "contract IHooks" }, + { "name": "hookData", "type": "bytes", "internalType": "bytes" } + ] + }, + { "name": "exactAmount", "type": "uint128", "internalType": "uint128" } + ] + } + ], + "outputs": [ + { "name": "amountOut", "type": "uint256", "internalType": "uint256" }, + { "name": "gasEstimate", "type": "uint256", "internalType": "uint256" } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "quoteExactInputSingle", + "inputs": [ + { + "name": "params", + "type": "tuple", + "internalType": "struct IV4Quoter.QuoteExactSingleParams", + "components": [ + { + "name": "poolKey", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { "name": "currency0", "type": "address", "internalType": "Currency" }, + { "name": "currency1", "type": "address", "internalType": "Currency" }, + { "name": "fee", "type": "uint24", "internalType": "uint24" }, + { "name": "tickSpacing", "type": "int24", "internalType": "int24" }, + { "name": "hooks", "type": "address", "internalType": "contract IHooks" } + ] + }, + { "name": "zeroForOne", "type": "bool", "internalType": "bool" }, + { "name": "exactAmount", "type": "uint128", "internalType": "uint128" }, + { "name": "hookData", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "outputs": [ + { "name": "amountOut", "type": "uint256", "internalType": "uint256" }, + { "name": "gasEstimate", "type": "uint256", "internalType": "uint256" } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "quoteExactOutput", + "inputs": [ + { + "name": "params", + "type": "tuple", + "internalType": "struct IV4Quoter.QuoteExactParams", + "components": [ + { "name": "exactCurrency", "type": "address", "internalType": "Currency" }, + { + "name": "path", + "type": "tuple[]", + "internalType": "struct PathKey[]", + "components": [ + { "name": "intermediateCurrency", "type": "address", "internalType": "Currency" }, + { "name": "fee", "type": "uint24", "internalType": "uint24" }, + { "name": "tickSpacing", "type": "int24", "internalType": "int24" }, + { "name": "hooks", "type": "address", "internalType": "contract IHooks" }, + { "name": "hookData", "type": "bytes", "internalType": "bytes" } + ] + }, + { "name": "exactAmount", "type": "uint128", "internalType": "uint128" } + ] + } + ], + "outputs": [ + { "name": "amountIn", "type": "uint256", "internalType": "uint256" }, + { "name": "gasEstimate", "type": "uint256", "internalType": "uint256" } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "quoteExactOutputSingle", + "inputs": [ + { + "name": "params", + "type": "tuple", + "internalType": "struct IV4Quoter.QuoteExactSingleParams", + "components": [ + { + "name": "poolKey", + "type": "tuple", + "internalType": "struct PoolKey", + "components": [ + { "name": "currency0", "type": "address", "internalType": "Currency" }, + { "name": "currency1", "type": "address", "internalType": "Currency" }, + { "name": "fee", "type": "uint24", "internalType": "uint24" }, + { "name": "tickSpacing", "type": "int24", "internalType": "int24" }, + { "name": "hooks", "type": "address", "internalType": "contract IHooks" } + ] + }, + { "name": "zeroForOne", "type": "bool", "internalType": "bool" }, + { "name": "exactAmount", "type": "uint128", "internalType": "uint128" }, + { "name": "hookData", "type": "bytes", "internalType": "bytes" } + ] + } + ], + "outputs": [ + { "name": "amountIn", "type": "uint256", "internalType": "uint256" }, + { "name": "gasEstimate", "type": "uint256", "internalType": "uint256" } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "unlockCallback", + "inputs": [{ "name": "data", "type": "bytes", "internalType": "bytes" }], + "outputs": [{ "name": "", "type": "bytes", "internalType": "bytes" }], + "stateMutability": "nonpayable" + }, + { + "type": "error", + "name": "NotEnoughLiquidity", + "inputs": [{ "name": "poolId", "type": "bytes32", "internalType": "PoolId" }] + }, + { "type": "error", "name": "NotPoolManager", "inputs": [] }, + { "type": "error", "name": "NotSelf", "inputs": [] }, + { + "type": "error", + "name": "QuoteSwap", + "inputs": [{ "name": "amount", "type": "uint256", "internalType": "uint256" }] + }, + { "type": "error", "name": "UnexpectedCallSuccess", "inputs": [] }, + { + "type": "error", + "name": "UnexpectedRevertBytes", + "inputs": [{ "name": "revertData", "type": "bytes", "internalType": "bytes" }] + } +] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-local.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-local.json new file mode 100644 index 00000000..5c8aaa35 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-local.json @@ -0,0 +1,40 @@ +{ + "hyperbridge-gargantua": { + "type": "substrate", + "chainId": "0x5388faf792c5232566d21493929b32c1f20a9c2b03e95615eefec2aa26d64b73", + "startBlock": 2056979, + "stateMachineId": "KUSAMA-4009" + }, + "bsc-chapel": { + "type": "evm", + "chainId": "97", + "startBlock": 44742412, + "stateMachineId": "EVM-97", + "contracts": { + "ethereumHost": "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7", + "handlerV1": "0xb45A4078A2D0B036C324A0046C2845aD59e769F6", + "erc6160ext20": "0xA801da100bF16D07F668F4A49E1f71fc54D05177", + "intentGateway": "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509", + "tokenGateway": "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6" + } + }, + "gnosis-chiado": { + "type": "evm", + "chainId": "10200", + "startBlock": 12294845, + "stateMachineId": "EVM-10200", + "contracts": { + "ethereumHost": "0x58A41B89F4871725E5D898d98eF4BF917601c5eB", + "handlerV1": "0x01b40De26Ba4C63c17A6f4Ed2cF96927C280B029", + "erc6160ext20": "0xA801da100bF16D07F668F4A49E1f71fc54D05177", + "intentGateway": "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509", + "tokenGateway": "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6" + } + }, + "cere-disabled": { + "type": "substrate", + "chainId": "0x42b9b44b4950b6c1edae543a7696caf8d0a160e9bc0424ab4ab217f7a8ba30dc", + "startBlock": 7599812, + "stateMachineId": "SUBSTRATE-cere" + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-mainnet.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-mainnet.json new file mode 100644 index 00000000..813287c0 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-mainnet.json @@ -0,0 +1,153 @@ +{ + "hyperbridge-nexus": { + "type": "substrate", + "chainId": "0x61ea8a51fd4a058ee8c0e86df0a89cc85b8b67a0a66432893d09719050c9f540", + "startBlock": 2541729, + "stateMachineId": "POLKADOT-3367" + }, + "bifrost-mainnet": { + "type": "substrate", + "chainId": "0x262e1b2ad728475fd6fe88e62d34c200abe6fd693931ddad144059b1eb884e5b", + "startBlock": 6425711, + "stateMachineId": "POLKADOT-2030" + }, + "cere-mainnet": { + "type": "substrate", + "chainId": "0x81443836a9a24caaa23f1241897d1235717535711d1d3fe24eae4fdc942c092c", + "startBlock": 19167175, + "stateMachineId": "SUBSTRATE-cere" + }, + "argon-mainnet": { + "type": "substrate", + "chainId": "0xee11bf2ff8838fcb0832c09085c5319a08ba6111c225ecd899fe659872d9d45d", + "startBlock": 70515, + "stateMachineId": "SUBSTRATE-argn" + }, + "kilt-mainnet": { + "type": "substrate", + "chainId": "0x411f057b9107718c9624d6aa4a3f23c1653898297f3d4d529d9bb6511a39dd21", + "startBlock": 9081787, + "stateMachineId": "POLKADOT-2086" + }, + "zkverify-mainnet": { + "type": "substrate", + "chainId": "0x060e3dd3fa2904d031206bb913c954687a2bcc350e5a83d33d9e273ad21460f1", + "startBlock": 124841, + "stateMachineId": "SUBSTRATE-zkv_" + }, + "ethereum-mainnet": { + "type": "evm", + "chainId": "1", + "startBlock": 21099382, + "stateMachineId": "EVM-1", + "contracts": { + "ethereumHost": "0x792A6236AF69787C40cF76b69B4c8c7B28c4cA20", + "erc6160ext20": "0x6B175474E89094C44Da98b954EedeAC495271d0F", + "handlerV1": "0x089248E869AEcd66199b64637207D366D6Cfe92D", + "intentGateway": "0x1a4ee689a004b10210a1df9f24a387ea13359acf", + "tokenGateway": "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE" + } + }, + "arbitrum-mainnet": { + "type": "evm", + "chainId": "42161", + "startBlock": 270229930, + "stateMachineId": "EVM-42161", + "contracts": { + "ethereumHost": "0xE05AFD4Eb2ce6d65c40e1048381BD0Ef8b4B299e", + "erc6160ext20": "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", + "handlerV1": "0x089248E869AEcd66199b64637207D366D6Cfe92D", + "intentGateway": "0x1a4ee689a004b10210a1df9f24a387ea13359acf", + "tokenGateway": "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE" + } + }, + "optimism-mainnet": { + "type": "evm", + "chainId": "10", + "startBlock": 127472624, + "stateMachineId": "EVM-10", + "contracts": { + "ethereumHost": "0x78c8A5F27C06757EA0e30bEa682f1FD5C8d7645d", + "erc6160ext20": "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", + "handlerV1": "0x089248E869AEcd66199b64637207D366D6Cfe92D", + "tokenGateway": "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE" + } + }, + "base-mainnet": { + "type": "evm", + "chainId": "8453", + "startBlock": 21877423, + "stateMachineId": "EVM-8453", + "contracts": { + "ethereumHost": "0x6FFe92e4d7a9D589549644544780e6725E84b248", + "erc6160ext20": "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb", + "handlerV1": "0x089248E869AEcd66199b64637207D366D6Cfe92D", + "intentGateway": "0x1a4ee689a004b10210a1df9f24a387ea13359acf", + "tokenGateway": "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE" + } + }, + "bsc-mainnet": { + "type": "evm", + "chainId": "56", + "startBlock": 43654810, + "stateMachineId": "EVM-56", + "contracts": { + "ethereumHost": "0x24B5d421Ec373FcA57325dd2F0C074009Af021F7", + "erc6160ext20": "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3", + "handlerV1": "0x089248E869AEcd66199b64637207D366D6Cfe92D", + "intentGateway": "0x1a4ee689a004b10210a1df9f24a387ea13359acf", + "tokenGateway": "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE" + } + }, + "gnosis-mainnet": { + "type": "evm", + "chainId": "100", + "startBlock": 36816861, + "stateMachineId": "EVM-100", + "contracts": { + "ethereumHost": "0x50c236247447B9d4Ee0561054ee596fbDa7791b1", + "erc6160ext20": "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d", + "handlerV1": "0x089248E869AEcd66199b64637207D366D6Cfe92D", + "tokenGateway": "0xFd413e3AFe560182C4471F4d143A96d3e259B6dE" + } + }, + "soneium-mainnet": { + "type": "evm", + "chainId": "1868", + "startBlock": 2762568, + "stateMachineId": "EVM-1868", + "contracts": { + "ethereumHost": "0x7F0165140D0f3251c8f6465e94E9d12C7FD40711", + "erc6160ext20": "0xbA9986D2381edf1DA03B0B9c1f8b00dc4AacC369", + "handlerV1": "0x59AaE0639Afd39d98d000f3c1E2b69Da359F1Def", + "tokenGateway": "0xCe304770236f39F9911BfCC51afBdfF3b8635718" + } + }, + "polygon-mainnet": { + "type": "evm", + "chainId": "137", + "startBlock": 75599047, + "stateMachineId": "EVM-137", + "blockConfirmations": 30, + "contracts": { + "ethereumHost": "0xD8d3db17C1dF65b301D45C84405CcAC1395C559a", + "erc6160ext20": "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063", + "handlerV1": "0x61f56ee7D15F4a11ba7ee9f233c136563cB5ad37", + "intentGateway": "0x1a4ee689a004b10210a1df9f24a387ea13359acf", + "tokenGateway": "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E" + } + }, + "unichain-mainnet": { + "type": "evm", + "chainId": "130", + "startBlock": 25296880, + "stateMachineId": "EVM-130", + "contracts": { + "ethereumHost": "0x2A17C1c3616Bbc33FCe5aF5B965F166ba76cEDAf", + "erc6160ext20": "0x078d782b760474a361dda0af3839290b0ef57ad6", + "handlerV1": "0x85F82D70ceED45ca0D1b154C297946BabCf4d344", + "tokenGateway": "0x8b536105b6Fae2aE9199f5146D3C57Dfe53b614E", + "intentGateway": "0x1a4ee689a004b10210a1df9f24a387ea13359acf" + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-nexus-ci.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-nexus-ci.json new file mode 100644 index 00000000..5af41449 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-nexus-ci.json @@ -0,0 +1,21 @@ +{ + "hyperbridge-nexus": { + "type": "substrate", + "chainId": "0x61ea8a51fd4a058ee8c0e86df0a89cc85b8b67a0a66432893d09719050c9f540", + "startBlock": 7179658, + "stateMachineId": "POLKADOT-3367" + }, + "gnosis-chiado": { + "type": "evm", + "chainId": "10200", + "startBlock": 12294845, + "stateMachineId": "EVM-10200", + "contracts": { + "ethereumHost": "0x58A41B89F4871725E5D898d98eF4BF917601c5eB", + "handlerV1": "0x01b40De26Ba4C63c17A6f4Ed2cF96927C280B029", + "erc6160ext20": "0xA801da100bF16D07F668F4A49E1f71fc54D05177", + "intentGateway": "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509", + "tokenGateway": "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6" + } + } +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-testnet.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-testnet.json new file mode 100644 index 00000000..f433d271 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/config-testnet.json @@ -0,0 +1,113 @@ +{ + "hyperbridge-gargantua": { + "type": "substrate", + "chainId": "0x5388faf792c5232566d21493929b32c1f20a9c2b03e95615eefec2aa26d64b73", + "startBlock": 2056979, + "stateMachineId": "KUSAMA-4009" + }, + "bifrost-paseo": { + "type": "substrate", + "chainId": "0xec39b15e5a1945ff19b8e8c0f76990b5758ce19faa4578e8ed57eda33e844452", + "startBlock": 940053, + "stateMachineId": "KUSAMA-2030" + }, + "zkverify-testnet": { + "type": "substrate", + "chainId": "0xff7fe5a610f15fe7a0c52f94f86313fb7db7d3786e7f8acf2b66c11d5be7c242", + "startBlock": 1, + "stateMachineId": "SUBSTRATE-zkv_" + }, + "hydration-paseo": { + "type": "substrate", + "chainId": "0x5f52a76d9a13fcc0c9094ba62c284f4f2f5e5f031f7e60eecaa7339f7f77c23f", + "startBlock": 34996, + "stateMachineId": "KUSAMA-2034" + }, + "sepolia": { + "type": "evm", + "chainId": "11155111", + "startBlock": 6876874, + "stateMachineId": "EVM-11155111", + "contracts": { + "ethereumHost": "0x2EdB74C269948b60ec1000040E104cef0eABaae8", + "handlerV1": "0xBf814fb3fD3eAaEB6a08C5A245c92da8b586f670", + "erc6160ext20": "0xA801da100bF16D07F668F4A49E1f71fc54D05177", + "tokenGateway": "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6" + } + }, + "arbitrum-sepolia": { + "type": "evm", + "chainId": "421614", + "startBlock": 88722044, + "stateMachineId": "EVM-421614", + "contracts": { + "ethereumHost": "0x3435bD7e5895356535459D6087D1eB982DAd90e7", + "handlerV1": "0x84b962657aA916286D7B24D37f458a2D823180dc", + "erc6160ext20": "0xA801da100bF16D07F668F4A49E1f71fc54D05177", + "tokenGateway": "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6" + } + }, + "optimism-sepolia": { + "type": "evm", + "chainId": "11155420", + "startBlock": 18572226, + "stateMachineId": "EVM-11155420", + "contracts": { + "ethereumHost": "0x6d51b678836d8060d980605d2999eF211809f3C2", + "handlerV1": "0x39c4085CcAe262fb8970578A2c703a87ed9842eF", + "erc6160ext20": "0xA801da100bF16D07F668F4A49E1f71fc54D05177", + "tokenGateway": "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6" + } + }, + "base-sepolia": { + "type": "evm", + "chainId": "84532", + "startBlock": 16589470, + "stateMachineId": "EVM-84532", + "contracts": { + "ethereumHost": "0xD198c01839dd4843918617AfD1e4DDf44Cc3BB4a", + "handlerV1": "0x63259e5ad3992CC91a662edd75AcD55125046E0B", + "erc6160ext20": "0xA801da100bF16D07F668F4A49E1f71fc54D05177", + "tokenGateway": "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6" + } + }, + "bsc-chapel": { + "type": "evm", + "chainId": "97", + "startBlock": 44742412, + "stateMachineId": "EVM-97", + "contracts": { + "ethereumHost": "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7", + "handlerV1": "0xb45A4078A2D0B036C324A0046C2845aD59e769F6", + "erc6160ext20": "0xA801da100bF16D07F668F4A49E1f71fc54D05177", + "intentGateway": "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509", + "tokenGateway": "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6" + } + }, + "gnosis-chiado": { + "type": "evm", + "chainId": "10200", + "startBlock": 12294845, + "stateMachineId": "EVM-10200", + "contracts": { + "ethereumHost": "0x58A41B89F4871725E5D898d98eF4BF917601c5eB", + "handlerV1": "0x01b40De26Ba4C63c17A6f4Ed2cF96927C280B029", + "erc6160ext20": "0xA801da100bF16D07F668F4A49E1f71fc54D05177", + "intentGateway": "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509", + "tokenGateway": "0xFcDa26cA021d5535C3059547390E6cCd8De7acA6" + } + }, + "polygon-amoy": { + "type": "evm", + "chainId": "80002", + "startBlock": 24949552, + "stateMachineId": "EVM-80002", + "blockConfirmations": 30, + "contracts": { + "ethereumHost": "0x9a2840D050e64Db89c90Ac5857536E4ec66641DE", + "handlerV1": "0xf0b4024F15d07912953184840682690C31aD9bcC", + "erc6160ext20": "0x693B854D6965ffEAaE21C74049deA644b56FCaCB", + "tokenGateway": "0x2efdc11b11cac34697b992a56e1d245c137a05b2" + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/index.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/index.ts new file mode 100644 index 00000000..f3535594 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/index.ts @@ -0,0 +1,114 @@ +import fs from "node:fs" +import path from "node:path" + +import dotenv from "dotenv" +import { z } from "zod" + +// EVM contract addresses schema +const evmContractsSchema = z.object({ + ethereumHost: z.string().min(3, "Invalid Ethereum address"), + handlerV1: z.string().min(3, "Invalid Ethereum address"), + erc6160ext20: z.string().min(3, "Invalid Ethereum address"), + intentGateway: z.string().optional(), + tokenGateway: z.string().optional(), +}) + +// Base chain configuration schema +const baseChainConfigSchema = z.object({ + chainId: z.string(), + startBlock: z.number().int().min(0), + blockConfirmations: z.number().int().min(0).optional(), + stateMachineId: z.string().min(3, "Invalid state machine ID format"), +}) + +// Configuration object schema (maps chain name to chain config) +export const schemaConfiguration = z.record( + z.string(), + z.discriminatedUnion("type", [ + baseChainConfigSchema.extend({ type: z.literal("substrate") }), + baseChainConfigSchema.extend({ type: z.literal("evm"), contracts: evmContractsSchema.optional() }), + ]), +) + +export type ConfigObject = z.infer +export type Configuration = ConfigObject[0] +export type Environment = "local" | "testnet" | "mainnet" | "nexus-ci" + +/** + * Validate configuration for the configuration structure and validate the schema. + * @param config + * @returns + */ +function validateConfig(config: unknown): ConfigObject { + return schemaConfiguration.parse(config) +} + +/** + * Load configuration for the specified environment + * @param env - The environment to load configuration for + * @param rootPath - Optional root path, defaults to process.cwd() + * @returns The validated configuration + * @throws {z.ZodError} If the configuration is invalid + * @throws {Error} If the configuration file cannot be read + */ +function loadConfig(env: Environment): ConfigObject { + const root = process.cwd() + dotenv.config({ path: path.resolve(root, `../../.env.${env}`) }) + + const configPath = path.join(root, `src/configs/config-${env}.json`) + + try { + const rawConfig = JSON.parse(fs.readFileSync(configPath, "utf8")) + const config = validateConfig(rawConfig) + // const environment = env + return config + } catch (error) { + if (error instanceof z.ZodError) { + throw new Error( + `Invalid configuration for environment '${env}':\n${error.errors + .map((e) => ` - ${e.path.join(".")}: ${e.message}`) + .join("\n")}`, + ) + } + if (error instanceof Error && "code" in error && error.code === "ENOENT") { + throw new Error(`Configuration file not found: ${configPath}`) + } + throw error + } +} + +export function getEnv(): Environment { + const currentEnv = process.env.ENV as Environment + if (!currentEnv) throw new Error("$ENV variable not set") + + return currentEnv +} + +/** + * Convenience function to get configuration for current environment + * @returns ConfigObject + */ +export function getConfigs(): ConfigObject { + const env = getEnv() + return loadConfig(env) +} + +export function getValidChains(): Map { + const configs = getConfigs() + + let validChains = new Map() + + for (const [chain, config] of Object.entries(configs)) { + const envKey = chain.replace(/-/g, "_").toUpperCase() + const endpoint = process.env[envKey] + + if (!endpoint) { + console.log(`Skipping ${chain}.yaml - No endpoint configured in environment`) + continue + } + + validChains.set(chain, config) + } + + return validChains +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/opstack-chains.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/opstack-chains.json new file mode 100644 index 00000000..cb86ce55 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/opstack-chains.json @@ -0,0 +1,1331 @@ +[ + { + "name": "Automata Mainnet", + "identifier": "mainnet/automata", + "chainId": 65536, + "rpc": [ + "https://rpc.ata.network" + ], + "explorers": [ + "https://explorer.ata.network" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "alt-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "gasPayingToken": "0xA2120b9e674d3fC3875f415A7DF52e382F141225", + "faultProofs": { + "status": "none" + } + }, + { + "name": "BOB", + "identifier": "mainnet/bob", + "chainId": 60808, + "rpc": [ + "https://rpc.gobob.xyz" + ], + "explorers": [ + "https://explorer.gobob.xyz" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissionless" + } + }, + { + "name": "Base", + "identifier": "mainnet/base", + "chainId": 8453, + "rpc": [ + "https://mainnet.base.org" + ], + "explorers": [ + "https://explorer.base.org" + ], + "superchainLevel": 1, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissionless" + } + }, + { + "name": "Binary Mainnet", + "identifier": "mainnet/tbn", + "chainId": 624, + "rpc": [ + "https://rpc.zero.thebinaryholdings.com" + ], + "explorers": [ + "https://explorer.thebinaryholdings.com" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "gasPayingToken": "0x04E9D7e336f79Cdab911b06133D3Ca2Cd0721ce3", + "faultProofs": { + "status": "none" + } + }, + { + "name": "Cyber Mainnet", + "identifier": "mainnet/cyber", + "chainId": 7560, + "rpc": [ + "https://rpc.cyber.co" + ], + "explorers": [ + "https://cyberscan.co/" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "alt-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "Ethernity", + "identifier": "mainnet/ethernity", + "chainId": 183, + "rpc": [ + "https://mainnet.ethernitychain.io" + ], + "explorers": [ + "https://ernscan.io" + ], + "superchainLevel": 1, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "Fraxtal", + "identifier": "mainnet/fraxtal", + "chainId": 252, + "rpc": [ + "https://rpc.frax.com" + ], + "explorers": [ + "https://fraxscan.com" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "alt-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "Funki", + "identifier": "mainnet/funki", + "chainId": 33979, + "rpc": [ + "https://rpc-mainnet.funkichain.com" + ], + "explorers": [ + "https://funki.superscan.network" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "alt-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "HashKey Chain", + "identifier": "mainnet/hashkeychain", + "chainId": 177, + "rpc": [ + "https://mainnet.hsk.xyz" + ], + "explorers": [ + "https://explorer.hsk.xyz" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "gasPayingToken": "0xE7C6BF469e97eEB0bFB74C8dbFF5BD47D4C1C98a", + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Ink", + "identifier": "mainnet/ink", + "chainId": 57073, + "rpc": [ + "https://rpc-gel.inkonchain.com" + ], + "explorers": [ + "https://explorer.inkonchain.com" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissionless" + } + }, + { + "name": "Lisk", + "identifier": "mainnet/lisk", + "chainId": 1135, + "rpc": [ + "https://rpc.api.lisk.com" + ], + "explorers": [ + "https://blockscout.lisk.com" + ], + "superchainLevel": 1, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Lyra Chain", + "identifier": "mainnet/lyra", + "chainId": 957, + "rpc": [ + "https://rpc.lyra.finance" + ], + "explorers": [ + "https://explorer.lyra.finance" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "alt-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Metal L2", + "identifier": "mainnet/metal", + "chainId": 1750, + "rpc": [ + "https://rpc.metall2.com" + ], + "explorers": [ + "https://explorer.metall2.com" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Mint Mainnet", + "identifier": "mainnet/mint", + "chainId": 185, + "rpc": [ + "https://rpc.mintchain.io" + ], + "explorers": [ + "https://explorer.mintchain.io" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Mode", + "identifier": "mainnet/mode", + "chainId": 34443, + "rpc": [ + "https://mainnet.mode.network" + ], + "explorers": [ + "https://explorer.mode.network" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "OP Mainnet", + "identifier": "mainnet/op", + "chainId": 10, + "rpc": [ + "https://mainnet.optimism.io" + ], + "explorers": [ + "https://explorer.optimism.io" + ], + "superchainLevel": 2, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissionless" + } + }, + { + "name": "Orderly Mainnet", + "identifier": "mainnet/orderly", + "chainId": 291, + "rpc": [ + "https://rpc.orderly.network" + ], + "explorers": [ + "https://explorer.orderly.network" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "alt-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Polynomial", + "identifier": "mainnet/polynomial", + "chainId": 8008, + "rpc": [ + "https://rpc.polynomial.fi" + ], + "explorers": [ + "https://polynomialscan.io" + ], + "superchainLevel": 1, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "RACE Mainnet", + "identifier": "mainnet/race", + "chainId": 6805, + "rpc": [ + "https://racemainnet.io" + ], + "explorers": [ + "https://racescan.io/" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "Redstone", + "identifier": "mainnet/redstone", + "chainId": 690, + "rpc": [ + "https://rpc.redstonechain.com" + ], + "explorers": [ + "https://explorer.redstone.xyz" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "alt-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "Settlus Mainnet", + "identifier": "mainnet/settlus-mainnet", + "chainId": 5371, + "rpc": [ + "https://settlus-mainnet.g.alchemy.com/public" + ], + "explorers": [ + "mainnet.settlus.network" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Shape", + "identifier": "mainnet/shape", + "chainId": 360, + "rpc": [ + "https://mainnet.shape.network/" + ], + "explorers": [ + "https://shape-mainnet.explorer.alchemy.com/" + ], + "superchainLevel": 1, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "SnaxChain", + "identifier": "mainnet/snax", + "chainId": 2192, + "rpc": [ + "https://mainnet.snaxchain.io" + ], + "explorers": [ + "https://explorer.snaxchain.io" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Soneium", + "identifier": "mainnet/soneium", + "chainId": 1868, + "rpc": [ + "https://rpc.soneium.org" + ], + "explorers": [ + "https://soneium.blockscout.com/" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Superseed", + "identifier": "mainnet/sseed", + "chainId": 5330, + "rpc": [ + "https://mainnet.superseed.xyz" + ], + "explorers": [ + "https://explorer.superseed.xyz" + ], + "superchainLevel": 1, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Swan Chain Mainnet", + "identifier": "mainnet/swan", + "chainId": 254, + "rpc": [ + "https://mainnet-rpc.swanchain.org" + ], + "explorers": [ + "https://swanscan.io" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "Swellchain", + "identifier": "mainnet/swell", + "chainId": 1923, + "rpc": [ + "https://swell-mainnet.alt.technology" + ], + "explorers": [ + "https://explorer.swellnetwork.io" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Unichain", + "identifier": "mainnet/unichain", + "chainId": 130, + "rpc": [ + "https://mainnet.unichain.org" + ], + "explorers": [ + "https://explorer.unichain.org" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissionless" + } + }, + { + "name": "World Chain", + "identifier": "mainnet/worldchain", + "chainId": 480, + "rpc": [ + "https://worldchain-mainnet.g.alchemy.com/public" + ], + "explorers": [ + "https://worldchain-mainnet.explorer.alchemy.com/" + ], + "superchainLevel": 1, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Xterio Chain (ETH)", + "identifier": "mainnet/xterio-eth", + "chainId": 2702128, + "rpc": [ + "https://xterio-eth.alt.technology/" + ], + "explorers": [ + "https://eth.xterscan.io/" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "alt-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "Zora", + "identifier": "mainnet/zora", + "chainId": 7777777, + "rpc": [ + "https://rpc.zora.energy" + ], + "explorers": [ + "https://explorer.zora.energy" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "arena-z", + "identifier": "mainnet/arena-z", + "chainId": 7897, + "rpc": [ + "https://rpc.arena-z.gg" + ], + "explorers": [ + "https://explorer.arena-z.gg" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Base Sepolia Testnet", + "identifier": "sepolia/base", + "chainId": 84532, + "rpc": [ + "https://sepolia.base.org" + ], + "explorers": [ + "https://sepolia-explorer.base.org" + ], + "superchainLevel": 1, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissionless" + } + }, + { + "name": "Binary Sepolia", + "identifier": "sepolia/tbn", + "chainId": 625, + "rpc": [ + "https://rpc.testnet.thebinaryholdings.com" + ], + "explorers": [ + "https://explorer.sepolia.thebinaryholdings.com" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "gasPayingToken": "0x46d878bf7BF62Ec542953CB89Ac0bF58d991181e", + "faultProofs": { + "status": "none" + } + }, + { + "name": "Boba Sepolia Testnet", + "identifier": "sepolia/boba", + "chainId": 28882, + "rpc": [ + "https://sepolia.boba.network" + ], + "explorers": [ + "https://testnet.bobascan.com" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Creator Chain Testnet", + "identifier": "sepolia/creator-chain-testnet", + "chainId": 66665, + "rpc": [ + "https://rpc.creatorchain.io" + ], + "explorers": [ + "https://explorer.creatorchain.io" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Cyber Testnet", + "identifier": "sepolia/cyber", + "chainId": 111557560, + "rpc": [ + "https://rpc.testnet.cyber.co" + ], + "explorers": [ + "https://testnet.cyberscan.co/" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "Ethernity Testnet", + "identifier": "sepolia/ethernity", + "chainId": 233, + "rpc": [ + "https://testnet.ethernitychain.io" + ], + "explorers": [ + "https://testnet.ernscan.io" + ], + "superchainLevel": 1, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "Funki Sepolia Testnet", + "identifier": "sepolia/funki", + "chainId": 3397901, + "rpc": [ + "https://funki-testnet.alt.technology" + ], + "explorers": [ + "https://sepolia-sandbox.funkichain.com/" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "alt-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "Ink Sepolia", + "identifier": "sepolia/ink", + "chainId": 763373, + "rpc": [ + "https://rpc-gel-sepolia.inkonchain.com" + ], + "explorers": [ + "https://explorer-sepolia.inkonchain.com" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissionless" + } + }, + { + "name": "Lisk Sepolia Testnet", + "identifier": "sepolia/lisk", + "chainId": 4202, + "rpc": [ + "https://rpc.sepolia-api.lisk.com" + ], + "explorers": [ + "https://sepolia-blockscout.lisk.com" + ], + "superchainLevel": 1, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "Metal L2 Testnet", + "identifier": "sepolia/metal", + "chainId": 1740, + "rpc": [ + "https://testnet.rpc.metall2.com" + ], + "explorers": [ + "https://testnet.explorer.metall2.com" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Mode Testnet", + "identifier": "sepolia/mode", + "chainId": 919, + "rpc": [ + "https://sepolia.mode.network" + ], + "explorers": [ + "https://sepolia.explorer.mode.network" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "OP Sepolia Testnet", + "identifier": "sepolia/op", + "chainId": 11155420, + "rpc": [ + "https://sepolia.optimism.io" + ], + "explorers": [ + "https://testnet-explorer.optimism.io" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissionless" + } + }, + { + "name": "Ozean Poseidon Testnet", + "identifier": "sepolia/ozean", + "chainId": 7849306, + "rpc": [ + "https://ozean-testnet.rpc.caldera.xyz/http" + ], + "explorers": [ + "https://ozean-testnet.explorer.caldera.xyz" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "gasPayingToken": "0x43bd82D1e29a1bEC03AfD11D5a3252779b8c760c", + "faultProofs": { + "status": "none" + } + }, + { + "name": "Pivotal Sepolia", + "identifier": "sepolia/pivotal", + "chainId": 16481, + "rpc": [ + "https://sepolia.pivotalprotocol.com/" + ], + "explorers": [ + "https://sepolia.pivotalscan.org/" + ], + "superchainLevel": 1, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "RACE Testnet", + "identifier": "sepolia/race", + "chainId": 6806, + "rpc": [ + "https://racetestnet.io" + ], + "explorers": [ + "https://testnet.racescan.io/" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Settlus Sepolia", + "identifier": "sepolia/settlus-sepolia", + "chainId": 5373, + "rpc": [ + "https://settlus-septestnet.g.alchemy.com/public" + ], + "explorers": [ + "sepolia.settlus.network" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Shape Sepolia Testnet", + "identifier": "sepolia/shape", + "chainId": 11011, + "rpc": [ + "https://sepolia.shape.network/" + ], + "explorers": [ + "https://shape-sepolia.explorer.alchemy.com/" + ], + "superchainLevel": 1, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Soneium Testnet Minato", + "identifier": "sepolia/soneium-minato", + "chainId": 1946, + "rpc": [ + "https://rpc.minato.soneium.org" + ], + "explorers": [ + "https://soneium-minato.blockscout.com/" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Unichain Sepolia Testnet", + "identifier": "sepolia/unichain", + "chainId": 1301, + "rpc": [ + "https://sepolia.unichain.org" + ], + "explorers": [ + "https://sepolia.uniscan.xyz" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissionless" + } + }, + { + "name": "World Chain Sepolia Testnet", + "identifier": "sepolia/worldchain", + "chainId": 4801, + "rpc": [ + "https://worldchain-sepolia.g.alchemy.com/public" + ], + "explorers": [ + "https://worldchain-sepolia.explorer.alchemy.com/" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Zora Sepolia Testnet", + "identifier": "sepolia/zora", + "chainId": 999999999, + "rpc": [ + "https://sepolia.rpc.zora.energy" + ], + "explorers": [ + "https://sepolia.explorer.zora.energy" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Base devnet 0", + "identifier": "sepolia-dev-0/base-devnet-0", + "chainId": 11763072, + "rpc": [ + "" + ], + "explorers": [ + "" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia-dev-0" + }, + "faultProofs": { + "status": "permissionless" + } + }, + { + "name": "OP Labs Sepolia devnet 0", + "identifier": "sepolia-dev-0/oplabs-devnet-0", + "chainId": 11155421, + "rpc": [ + "" + ], + "explorers": [ + "" + ], + "superchainLevel": 0, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia-dev-0" + }, + "faultProofs": { + "status": "permissionless" + } + }, + { + "name": "Boba Mainnet", + "identifier": "mainnet/boba", + "chainId": 288, + "rpc": [ + "https://mainnet.boba.network" + ], + "explorers": [ + "https://bobascan.com" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Radius testnet", + "identifier": "sepolia/radius_testnet", + "chainId": 863, + "rpc": [ + "testnet-rpc.theradius.xyz" + ], + "explorers": [ + "https://testnet-rpc.theradius.xyz/" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Camp Network Testnet V2", + "identifier": "sepolia/camp", + "chainId": 325000, + "rpc": [ + "https://rpc.camp-network-testnet.gelato.digital" + ], + "explorers": [ + "https://camp-network-testnet.blockscout.com" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "none" + } + }, + { + "name": "Celo", + "identifier": "mainnet/celo", + "chainId": 42220, + "rpc": [ + "https://forno.celo.org" + ], + "explorers": [ + "https://celoscan.io/" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "alt-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "gasPayingToken": "0x057898f3C43F129a17517B9056D23851F124b19f", + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "rehearsal-0-bn-0", + "identifier": "rehearsal-0-bn/rehearsal-0-bn-0", + "chainId": 420120009, + "rpc": [ + "" + ], + "explorers": [ + "" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "rehearsal-0-bn" + }, + "faultProofs": { + "status": "permissionless" + } + }, + { + "name": "rehearsal-0-bn-1", + "identifier": "rehearsal-0-bn/rehearsal-0-bn-1", + "chainId": 420120010, + "rpc": [ + "" + ], + "explorers": [ + "" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "rehearsal-0-bn" + }, + "faultProofs": { + "status": "permissionless" + } + }, + { + "name": "arena-z-testnet", + "identifier": "sepolia/arena-z", + "chainId": 9899, + "rpc": [ + "https://testnet-rpc.arena-z.gg" + ], + "explorers": [ + "https://testnet-explorer.arena-z.gg" + ], + "superchainLevel": 1, + "governedByOptimism": true, + "dataAvailabilityType": "eth-da", + "parent": { + "type": "L2", + "chain": "sepolia" + }, + "faultProofs": { + "status": "permissioned" + } + }, + { + "name": "Silent Data Mainnet", + "identifier": "mainnet/silent-data-mainnet", + "chainId": 380929, + "rpc": [ + "https://mainnet.silentdata.com/${SILENTDATA_AUTH_TOKEN}" + ], + "explorers": [ + "https://explorer-mainnet.rollup.silentdata.com" + ], + "superchainLevel": 0, + "governedByOptimism": false, + "dataAvailabilityType": "alt-da", + "parent": { + "type": "L2", + "chain": "mainnet" + }, + "faultProofs": { + "status": "permissioned" + } + } +] \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/schema.graphql b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/schema.graphql new file mode 100644 index 00000000..cb18519b --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/configs/schema.graphql @@ -0,0 +1,1478 @@ +# To improve query performance, we strongly suggest adding indexes to any field that you plan to filter or sort by +# Add the `@index` or `@index(unique: true)` annotation after any non-key field +# https://academy.subquery.network/build/graphql.html#indexing-by-non-primary-key-field + +""" +The status of a request +""" +enum Status { + """ + The request has been dispatched + """ + SOURCE + """ + The request has been verified and aggregated by Hyperbridge + """ + HYPERBRIDGE_DELIVERED + """ + The request has reached the destination chain + """ + DESTINATION + """ + The request has been timed out on Hyperbridge + """ + HYPERBRIDGE_TIMED_OUT + """ + The request has been timed out on the source chain + """ + TIMED_OUT +} + +""" +The status of an order +""" +enum OrderStatus { + """ + The order has been placed + """ + PLACED + """ + The order has been filled + """ + FILLED + """ + The order has been redeemed on the source chain + """ + REDEEMED + """ + The order has been cancelled and refunded on the source chain + """ + REFUNDED +} + +""" +The status of an asset teleported via the Token Gateway +""" +enum TeleportStatus { + """ + The asset has been teleported to another chain + """ + TELEPORTED + """ + The asset has been received on the destination chain + """ + RECEIVED + """ + The asset has been refunded due to failed teleport + """ + REFUNDED +} + +""" +Types of participants in the Hyperbridge Protocol +""" +enum ProtocolParticipantType { + RELAYER + FILLER + USER + REFERRER +} + +""" +System activity types related to reward points +""" +enum PointsActivityType { + REWARD_POINTS_EARNED + ORDER_PLACED_POINTS + ORDER_FILLED_POINTS + TOKEN_TELEPORTED_POINTS + ORDER_REFERRED_POINTS +} + +""" +Important Hyperbridge Stats for a specific chain +""" +type HyperBridgeChainStats @entity { + """ + The chain the metrics are for + """ + id: ID! + + """ + Total number of messages sent on Hyperbridge on this chain + """ + numberOfMessagesSent: BigInt! @index + + """ + Total number of messages delivered by Hyperbridge on this chain + """ + numberOfDeliveredMessages: BigInt! @index + + """ + Total number of failed messages sent by Hyperbridge on this chain + """ + numberOfFailedDeliveries: BigInt! @index + + """ + Total number of timed out messages on this chain + """ + numberOfTimedOutMessages: BigInt! @index + + """ + The total amount of transfers sent into the Hyperbridge Host Contracts (transfers in = protocol fee + relayer fee) + """ + totalTransfersIn: BigInt! @index + + """ + Total amount of fees earned by Hyperbridge on the chain (protocol fees) + """ + protocolFeesEarned: BigInt! @index + + """ + Total amount of fees payed out by Hyperbridge to relayers on the chain (relayer fees) + """ + feesPayedOutToRelayers: BigInt! @index +} + +""" +Hyperbridge Stats for a specific Relayer on a specific chain +""" +type RelayerStatsPerChain @entity @compositeIndexes(fields: [["relayer", "chain"], ["feesEarned", "chain"]]) { + """ + Unique identifier of the RelayerChainMetrics entry. + """ + id: ID! + + """ + The relayer the metrics are for + """ + relayer: Relayer! + + """ + The chain the metrics are for + """ + chain: String! @index + + """ + Total number of successful post requests or post responses handled by the Relayer + """ + numberOfSuccessfulMessagesDelivered: BigInt! + + """ + Total number of failed post requests handled by the Relayer + """ + numberOfFailedMessagesDelivered: BigInt! + + """ + Amount of gas spent on successful messages (Gas Cost) + """ + gasUsedForSuccessfulMessages: BigInt! + + """ + Amount of gas spent on failed messages (Gas Cost) + """ + gasUsedForFailedMessages: BigInt! + + """ + Gas fee spent on successful post requests (Gas Cost * Gas Price) + """ + gasFeeForSuccessfulMessages: BigInt! + + """ + Gas fee spent on failed post requests (Gas Cost * Gas Price) + """ + gasFeeForFailedMessages: BigInt! + + """ + The USD value of the gas fee spent on successful post requests + """ + usdGasFeeForSuccessfulMessages: BigInt! + + """ + The USD value of the gas fee spent on failed post requests + """ + usdGasFeeForFailedMessages: BigInt! + + """ + Total fees earned by the relayer + """ + feesEarned: BigInt! @index +} + +""" +A Hyperbridge Relayer +""" +type Relayer @entity { + """ + Unique identifier of the Relayer (also the relayer's address) + """ + id: ID! + + """ + A list of important stats for the Relayer on every network that they support + """ + perChainStats: [RelayerStatsPerChain]! @derivedFrom(field: "relayer") + + """ + Latest activity for this relayer + """ + latestActivity: RelayerActivity @derivedFrom(field: "relayer") +} + +""" +Hyperbridge Relayer Activity +""" +type RelayerActivity @entity { + """ + Unique Identifier for the activity + """ + id: ID! + + """ + Relayer the activities are for + """ + relayer: Relayer! + + """ + Last updated at + """ + lastUpdatedAt: BigInt! +} + +""" +Transfers made from/to the Hyperbridge Host +- The host transfers fees to Relayers +- The host receives fees from protocol users +""" +type Transfer @entity @compositeIndexes(fields: [["from", "to"], ["from", "chain"], ["to", "chain"]]) { + """ + Unique identifier of the Transfer + """ + id: ID! + + """ + The chain on which the transfer was made + """ + chain: String! @index + + """ + The amount transferred + """ + amount: BigInt! @index + + """ + The address that made the transfer (the hyperbridge host address) + """ + from: String! @index + + """ + The address that received the transfer (the relayer address) + """ + to: String! @index +} + +""" +A StateMachine Update Event +""" +type StateMachineUpdateEvent + @entity + @compositeIndexes(fields: [["stateMachineId", "chain"], ["blockNumber", "chain"], ["height", "chain"]]) { + """ + The ID of the StateMachineUpdate (hash of concatenation of stateMachineId and height) + """ + id: ID! + + """ + The ID of the StateMachine + """ + stateMachineId: String! @index + + """ + The height of the block in which the event occured + """ + height: Int! @index + + """ + The chain on which the event occured + """ + chain: String! @index + + """ + The hash of the block in which the event occured + """ + blockHash: String! + + """ + The number of the block in which the event occured + """ + blockNumber: Int! @index + + """ + The hash of the transaction in which the event occured + """ + transactionHash: String! + + """ + The index of the transaction in the block + """ + transactionIndex: Int! + + """ + The state machine commitment timestamp + """ + commitmentTimestamp: BigInt! + + """ + The timestamp of the event + """ + createdAt: Date! @index +} + +""" +A Hyperbridge Request +""" +type Request @entity @compositeIndexes(fields: [["commitment", "chain"]]) { + """ + Unique identifier of the Request (This is the request commitment) + """ + id: ID! + + """ + The commitment of the request + """ + commitment: String! @index + + """ + The chain on which the request was made + """ + chain: String! @index + + """ + This is the statemachine id where this request originated from + """ + source: String + + """ + This is the statemachine where this request is been dispatched to + """ + dest: String + + """ + This is the timestamp when the request would timeout + """ + timeoutTimestamp: BigInt + + """ + The address that dispatched this request + """ + from: String! + + """ + The address receiving this request + """ + to: String! + + """ + Nonce of the request + """ + nonce: BigInt! + + """ + Body of the request + """ + body: String! + + """ + This is the fee set for this request + """ + fee: BigInt! + + """ + Status of the request + """ + status: Status! + + """ + Metatdata about the request's progression through different statuses + """ + statusMetadata: [RequestStatusMetadata]! @derivedFrom(field: "request") + + """ + The timestamp when this record was created + """ + createdAt: Date! @index +} + +""" +Metadata about the status of a Request +""" +type RequestStatusMetadata @entity { + """ + The ID of the RequestStatusMetadata + """ + id: ID! + + """ + The status of the request + """ + status: Status! + + """ + The chain on which the request occured + """ + chain: String! + + """ + The timestamp of the event + """ + timestamp: BigInt! + + """ + The number of the block in which the event occured + """ + blockNumber: String! + + """ + The hash of the block in which the event occured + """ + blockHash: String! + + """ + The hash of the transaction in which the event occured + """ + transactionHash: String! + + """ + The request that owns this status change + """ + request: Request! + + """ + The timestamp when this record was created + """ + createdAt: Date! @index +} + +""" +A Hyperbridge Response +""" +type Response @entity @compositeIndexes(fields: [["commitment", "chain"]]) { + """ + Unique identifier of the Response (This is the response commitment) + """ + id: ID! + + """ + The chain on which the response was made + """ + chain: String! @index + + """ + The commitment of the response + """ + commitment: String! @index + + """ + The response message + """ + response_message: String + + """ + The Timestamp at which this response expires in seconds + """ + responseTimeoutTimestamp: BigInt + + """ + Status of the response + """ + status: Status! + + """ + The request that triggered this response + """ + request: Request + + """ + Metatdata about the response's progression through different statuses + """ + statusMetadata: [ResponseStatusMetadata]! @derivedFrom(field: "response") + + """ + The timestamp when this record was created + """ + createdAt: Date! @index +} + +""" +Metadata about the status of a Response +""" +type ResponseStatusMetadata @entity { + """ + The ID of the ResponseStatusMetadata + """ + id: ID! + + """ + The status of the response + """ + status: Status! + + """ + The chain on which the response occured + """ + chain: String! + + """ + The timestamp of the event + """ + timestamp: BigInt! + + """ + The number of the block in which the event occured + """ + blockNumber: String! + + """ + The hash of the block in which the event occured + """ + blockHash: String! + + """ + The hash of the transaction in which the event occured + """ + transactionHash: String! + + """ + The response that owns this status change + """ + response: Response! + + """ + The timestamp when this record was created + """ + createdAt: Date! @index +} + +""" +Reward points earned by participants in the hyperbridge protocol +""" +type Rewards @entity @compositeIndexes(fields: [["address", "chain"], ["earnerType", "chain"]]) { + id: ID! + address: String! @index + chain: String! @index + points: BigInt! @index + earnerType: ProtocolParticipantType +} + +type RewardsActivityLog + @entity + @compositeIndexes(fields: [["earnerAddress", "chain"], ["earnerType", "chain"], ["activityType", "chain"]]) { + id: ID! + chain: String! @index + points: BigInt! @index + transactionHash: String! @index + earnerAddress: String! @index + earnerType: ProtocolParticipantType + activityType: PointsActivityType + description: String! + createdAt: Date! @index +} + +""" +Record of assets teleported via the XCM Gateway +""" +type AssetTeleported @entity { + """ + Unique identifier of the teleported asset + """ + id: ID! + + """ + The chain on which the teleport event occurred + """ + chain: String! + + """ + Source account on the relaychain + """ + from: String! @index + + """ + Beneficiary account on destination + """ + to: String! @index + + """ + Amount transferred + """ + amount: BigInt! @index + + """ + Destination chain + """ + dest: String! @index + + """ + Request commitment + """ + commitment: String! @index + + """ + The timestamp of the event + """ + createdAt: Date! @index + + """ + The block in which the event occurred + """ + blockNumber: Int! +} + +""" +Represents a cross-chain get request event +This entity stores information about requests to fetch data from a source chain to a destination chain +""" +type GetRequest @entity { + """ + Unique identifier for the get request, computed as keccak256 hash of the encoded request parameters + """ + id: ID! + """ + Source chain identifier where the data is being requested from + """ + source: String! + """ + Destination chain identifier where the data will be sent to + """ + dest: String! + """ + Address of the account that initiated the get request + """ + from: String! + """ + Array of keys that need to be fetched from the source chain + """ + keys: [String!]! + """ + Sequential number to ensure uniqueness of the request + """ + nonce: BigInt! + """ + Block height at which the request was made + """ + height: BigInt! + """ + Additional context or metadata for the request + """ + context: String! + """ + Timestamp after which the request expires + """ + timeoutTimestamp: BigInt! + """ + Fee paid for processing the request + """ + fee: BigInt! + """ + Block number where the request was made + """ + blockNumber: String! + """ + Hash of the block containing the request + """ + blockHash: String! + """ + Hash of the transaction that created the request + """ + transactionHash: String! + """ + Timestamp of the block containing the request + """ + blockTimestamp: BigInt! + """ + Status of the request + """ + status: Status! + """ + Metatdata about the request's progression through different statuses + """ + statusMetadata: [GetRequestStatusMetadata]! @derivedFrom(field: "request") + """ + Chain on which the request was made + """ + chain: String! + """ + commitment of the request + """ + commitment: String! +} + +""" +Metadata about the status of a Request +""" +type GetRequestStatusMetadata @entity { + """ + The ID of the GetRequestStatusMetadata + """ + id: ID! + + """ + The status of the request + """ + status: Status! + + """ + The chain on which the request occured + """ + chain: String! + + """ + The timestamp of the event + """ + timestamp: BigInt! + + """ + The number of the block in which the event occured + """ + blockNumber: String! + + """ + The hash of the block in which the event occured + """ + blockHash: String! + + """ + The hash of the transaction in which the event occured + """ + transactionHash: String! + + """ + The request that owns this status change + """ + request: GetRequest! + + """ + The timestamp when this record was created + """ + createdAt: Date! @index +} + +""" +A Hyperbridge Response for a Get Request +""" +type GetResponse @entity @compositeIndexes(fields: [["commitment", "chain"]]) { + """ + Unique identifier of the GetResponse (This is the response commitment) + """ + id: ID! + + """ + The commitment of the response + """ + commitment: String! @index + + """ + The chain on which the response was made + """ + chain: String! @index + + """ + The key-values fetch from hyperbridge host + """ + response_message: [String!]! + + """ + The Timestamp at which this response expires in seconds + """ + responseTimeoutTimestamp: BigInt + + """ + The request that triggered this response + """ + request: GetRequest + + """ + The timestamp when this record was created + """ + createdAt: Date! @index + """ + Block number where the response was made + """ + blockNumber: String! + """ + Hash of the block containing the response + """ + blockHash: String! + """ + Hash of the transaction that created the response + """ + transactionHash: String! +} + +""" +Represents an order placed through the IntentGateway contract. +This entity tracks cross-chain orders. +""" +type Order @entity { + """ + Unique identifier for the order (commitment) + """ + id: ID! + + """ + Address of the user who placed the order + """ + user: String! + + """ + Source chain identifier where the order originates from + """ + sourceChain: String! + + """ + Destination chain identifier where the order will be executed + """ + destChain: String! + + """ + Unique commitment hash of the order used for verification + """ + commitment: String! + + """ + Timestamp after which the order expires + """ + deadline: BigInt! + + """ + Sequential number to ensure uniqueness of the order + """ + nonce: BigInt! + + """ + Total fees supplied by the user for executing the order + """ + fees: BigInt! + + """ + Array of input token addresses + """ + inputTokens: [String!]! + + """ + Array of input token amounts corresponding to inputTokens + """ + inputAmounts: [BigInt!]! + + """ + Array of input token values in USD + """ + inputValuesUSD: [String!]! + + """ + Total input value in USD + """ + inputUSD: String! + + """ + Array of output token addresses + """ + outputTokens: [String!]! + + """ + Array of output token amounts corresponding to outputTokens + """ + outputAmounts: [BigInt!]! + + """ + Array of beneficiary addresses that will receive the output tokens + """ + outputBeneficiaries: [String!]! + + """ + Encoded function call data to be executed on the destination chain + """ + calldata: String! + + """ + Status of the order + """ + status: OrderStatus! + + """ + Metatdata about the order's progression through different statuses + """ + statusMetadata: [OrderStatusMetadata]! @derivedFrom(field: "order") + + """ + Referrer address that referred the user + """ + referrer: String + + """ + Timestamp when the order was created + """ + createdAt: Date! @index + + """ + Block number where the order was placed + """ + blockNumber: BigInt! @index + + """ + Timestamp of the block where the order was placed + """ + blockTimestamp: BigInt! @index + + """ + Hash of the transaction that placed the order + """ + transactionHash: String! @index +} + +""" +Metadata about the status of an Order +""" +type OrderStatusMetadata @entity { + """ + The ID of the OrderStatusMetadata + """ + id: ID! + + """ + The status of the order + """ + status: OrderStatus! + + """ + The chain on which the status change occurred + """ + chain: String! + + """ + The timestamp of the event + """ + timestamp: BigInt! + + """ + The number of the block in which the event occurred + """ + blockNumber: String! + + """ + The hash of the transaction in which the event occurred + """ + transactionHash: String! + + """ + The order that owns this status change + """ + order: Order + + """ + The filler of the order if the order has been filled + """ + filler: String + + """ + The timestamp when this record was created + """ + createdAt: Date! @index +} + +""" +Represents a teleport of assets through the TokenGateway contract. +This entity tracks cross-chain asset teleports. +""" +type TokenGatewayAssetTeleported @entity { + """ + Unique identifier for the teleport (commitment) + """ + id: ID! + + """ + Address of the user who initiated the teleport + """ + from: String! + + """ + Beneficiary address that will receive the teleported assets + """ + to: String! + + """ + Source chain identifier where the teleport originates from + """ + sourceChain: String! + + """ + Destination chain identifier where the teleport will be executed + """ + destChain: String! + + """ + Unique commitment hash of the teleport used for verification + """ + commitment: String! + + """ + Amount of assets being teleported + """ + amount: BigInt! + + """ + Amount of value in USD being teleported + """ + usdValue: String! + + """ + Asset ID being teleported + """ + assetId: String! + + """ + Whether the assets should be redeemed on the destination chain + """ + redeem: Boolean! + + """ + Status of the teleport + """ + status: TeleportStatus! + + """ + Metadata about the teleport's progression through different statuses + """ + statusMetadata: [TeleportStatusMetadata]! @derivedFrom(field: "teleport") + + """ + Timestamp when the teleport was created + """ + createdAt: Date! + + """ + Block number where the teleport was initiated + """ + blockNumber: BigInt! + + """ + Timestamp of the block where the teleport was initiated + """ + blockTimestamp: BigInt! + + """ + Hash of the transaction that initiated the teleport + """ + transactionHash: String! +} + +""" +Metadata about the status of a Teleport +""" +type TeleportStatusMetadata @entity { + """ + The ID of the TeleportStatusMetadata + """ + id: ID! + + """ + The status of the teleport + """ + status: TeleportStatus! + + """ + The chain on which the status change occurred + """ + chain: String! + + """ + The timestamp of the event + """ + timestamp: BigInt! + + """ + The number of the block in which the event occurred + """ + blockNumber: String! + + """ + The hash of the transaction in which the event occurred + """ + transactionHash: String! + + """ + The teleport that owns this status change + """ + teleport: TokenGatewayAssetTeleported! + + """ + The timestamp when this record was created + """ + createdAt: Date! +} + +type CumulativeVolumeUSD @entity { + """ + Unique identifier for the cumulative stats + """ + id: ID! + + """ + Last updated at + """ + lastUpdatedAt: BigInt! + + """ + Volume in USD + """ + volumeUSD: String! +} + +type DailyVolumeUSD @entity { + """ + Unique identifier for the daily volume stats + """ + id: ID! + + """ + Last updated at + """ + lastUpdatedAt: BigInt! + + """ + The timestamp when this record was created + """ + createdAt: Date! + + """ + Last 24hrs Volume in USD + """ + last24HoursVolumeUSD: String! +} + +""" +Daily Hyperbridge Protocol Fees Stats +""" +type DailyProtocolFeesStats @entity { + """ + Unique identifier of the daily protocol fees + """ + id: ID! + + """ + The chain on which the protocol fees are charged + """ + chain: String! @index + + """ + The ID of the StateMachine + """ + stateMachineId: String! @index + + """ + Last updated at + """ + lastUpdatedAt: BigInt! + + """ + The timestamp when this record was created + """ + createdAt: Date! + + """ + Last 24Hrs Protocol Fees Earned + """ + last24HoursProtocolFeesEarned: BigInt! @index +} + +""" +Current price data for tokens across supported chains +""" +type TokenPrice @entity @compositeIndexes(fields: [["symbol", "lastUpdatedAt"]]) { + """ + Unique identifier: symbol + currency (e.g., ETH-USD) + """ + id: ID! + + """ + Token symbol (e.g., ETH, USDC, USDT, DOT) + """ + symbol: String! @index + + """ + Token contract address (zero address for native tokens) + """ + address: String + + """ + Token price currency (e.g USD) + """ + currency: String! + + """ + Current price at the specified currency value + """ + price: String! + + """ + Timestamp when price was last updated + """ + lastUpdatedAt: BigInt! @index +} + +""" +Historical price feed logs for tokens +""" +type TokenPriceLog @entity @compositeIndexes(fields: [["symbol", "timestamp"], ["provider", "timestamp"]]) { + """ + Unique identifier: symbol + currency + provider + timestamp + """ + id: ID! + + """ + Token symbol (e.g., ETH, USDC, DOT) + """ + symbol: String! @index + + """ + Token price currency (e.g USD) + """ + currency: String! + + """ + Current price at the specified currency value + """ + price: String! + + """ + Price data provider (e.g., COINGECKO, CHAINLINK) + """ + provider: String! @index + + """ + Timestamp when price was recorded + """ + timestamp: BigInt! @index + + """ + Record creation timestamp + """ + createdAt: Date! @index +} + +""" +Token Registry - Configuration and metadata for supported tokens +""" +type TokenRegistry @entity @compositeIndexes(fields: [["symbol", "lastUpdatedAt"], ["symbol", "createdAt"]]) { + """ + Unique identifier: symbol (e.g., ETH, DOT) + """ + id: ID! + + """ + Token name (e.g., Ethereum, Polkadot, USD Coin) + """ + name: String! + + """ + Token symbol (e.g., ETH, DOT, USDC) + """ + symbol: String! @index + + """ + Token contract address (zero address for native tokens) + """ + address: String + + """ + Update frequency in seconds for price feeds + """ + updateFrequencySeconds: Int! + + """ + Timestamp when this token configuration was last updated + """ + lastUpdatedAt: BigInt! @index + + """ + Record creation timestamp + """ + createdAt: Date! @index +} + +""" +Bridge token supply tracking for Hyperbridge +""" +type BridgeTokenSupply @entity { + """ + Unique identifier for the token supply entry + """ + id: ID! + + """ + Total supply of the token + """ + totalSupply: BigInt! @index + + """ + Circulating supply of the token (total supply minus locked/staked amounts) + """ + circulatingSupply: BigInt! @index + + """ + Timestamp when this supply data was last updated + """ + lastUpdatedAt: BigInt! @index + + """ + Record creation timestamp + """ + createdAt: Date! @index +} + +""" +Record of rewards for Relayers +""" +type HyperbridgeRelayerReward @entity { + """ + Unique identifier for the incentive entry, this is the relayer address + """ + id: ID! + + """ + The total amount of rewards this relayer has ever received. + """ + totalRewardAmount: BigInt + + """ + The total amount of messaging rewards this relayer has ever received. + """ + totalMessagingRewardAmount: BigInt + + """ + The total amount of consensus rewards this relayer has ever received. + """ + totalConsensusRewardAmount: BigInt + + """ + The balance of reputation assets accrued. + """ + reputationAssetBalance: BigInt +} + +""" +Record of daily relayer rewards paid out by the treasury +""" +type DailyTreasuryRelayerReward @entity { + id: ID! # ID is: {YYYY-MM-DD} + date: Date! + dailyRewardAmount: BigInt! +} + +""" +A single entity that tracks the aggregate balance and transfers for the treasury. +The ID is the treasury's account address. +""" +type Treasury @entity { + id: ID! + + """ + The total amount of tokens ever transferred INTO the treasury. + """ + totalAmountTransferredIn: BigInt! + + """ + The total amount of tokens ever transferred OUT of the treasury. + """ + totalAmountTransferredOut: BigInt! + + """ + The current calculated balance of the treasury (In - Out). + """ + totalBalance: BigInt! + + """ + The timestamp of the last update. + """ + lastUpdatedAt: Date! +} + +""" +Stores the total accumulated fees for a specific relayer on a specific chain. +""" +type AccumulatedFee @entity { + """ + The unique ID, format: {relayerAddress}-{chainId} + """ + id: ID! + + """ + The relayer's address. + """ + relayer: String! @index + + """ + A string identifier for the source chain of the fee. + """ + chainId: String! @index + + """ + The aggregated raw amount of fees, in the token's smallest unit. + """ + lifetimeFees: BigInt! + + """ + The timestamp of the last update. + """ + lastUpdatedAt: Date! +} + +""" +Stores user data related to the Hyperbridge protocol +""" +type UserActivity @entity { + """ + Unique identifier for the user + """ + id: ID! + """ + Referrer address + """ + referrer: String + """ + Total orders placed by the user + """ + totalOrdersPlaced: BigInt! + """ + Filled orders that were placed by the user + """ + totalFilledOrders: BigInt! + """ + Total volume in USD for orders placed by the user + """ + totalOrderPlacedVolumeUSD: String! + """ + Total volume in USD for filled orders that were placed by the user + """ + totalOrderFilledVolumeUSD: String! + """ + Total teleports initiated by the user + """ + totalTeleports: BigInt! + """ + Successful teleports initiated by the user + """ + totalSuccessfulTeleports: BigInt! + """ + Total volume in USD for teleports initiated by the user + """ + totalTeleportedVolumeUSD: String! + """ + Total volume in USD for successful teleports initiated by the user + """ + totalSuccessfulTeleportedVolumeUSD: String! + """ + Timestamp when the user was created + """ + createdAt: Date! @index +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/constants.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/constants.ts new file mode 100644 index 00000000..698f8248 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/constants.ts @@ -0,0 +1,96 @@ +// Purpose: Contains all the constants used in the application. + +enum SupportedAssets { + WETH, + WBTC, + USDT, + USDC, + DAI, + DOT, +} + +export const HYPERBRIDGE = { + testnet: "KUSAMA-4009", + mainnet: "POLKADOT-3367", +} as const + +export const BIFROST = { + testnet: "KUSAMA-2030", + mainnet: "POLKADOT-2030", +} as const + +export const ETHEREUM = { + testnet: "EVM-11155111", + mainnet: "EVM-1", +} as const + +export const ARBITRUM = { + testnet: "EVM-421614", + mainnet: "EVM-42161", +} as const + +export const OPTIMISM = { + testnet: "EVM-11155420", + mainnet: "EVM-10", +} as const + +export const BASE = { + testnet: "EVM-84532", + mainnet: "EVM-8453", +} as const + +export const BSC = { + testnet: "EVM-97", + mainnet: "EVM-56", +} as const + +export const GNOSIS = { + testnet: "EVM-10200", + mainnet: "EVM-100", +} as const + +export const SONEMIUM = { + testnet: "EVM-1946", + mainnet: "EVM-1868", +} as const + +import ENV_CONFIG from "./env-config.json" +import { CHAIN_IDS_BY_GENESIS } from "./chain-ids-by-genesis" +import { CHAINS_BY_ISMP_HOST } from "./chains-by-ismp-host" +import { INTENT_GATEWAY_ADDRESSES } from "./intent-gateway-addresses" +import { TOKEN_GATEWAY_ADDRESSES } from "./token-gateway-addresses" +export { CHAIN_IDS_BY_GENESIS, CHAINS_BY_ISMP_HOST, ENV_CONFIG, TOKEN_GATEWAY_ADDRESSES, INTENT_GATEWAY_ADDRESSES } + +// Replaced by auto-generated version + +export interface ITokenPriceFeedDetails { + name: SupportedAssets + address: string + chain_link_price_feed: string +} + +export const SUPPORTED_ASSETS_CONTRACT_ADDRESSES: Record> = { + "EVM-11155111": [ + { + name: SupportedAssets.WETH, + address: "0x980B62Da83eFf3D4576C647993b0c1D7faf17c73", + chain_link_price_feed: "0x694AA1769357215DE4FAC081bf1f309aDC325306", + }, + // { + // name: SupportedAssets.WBTC, + // address: "0x806D0637Fbbfb4EB9efD5119B0895A5C7Cbc66e7", + // }, + // { + // name: SupportedAssets.USDT, + // address: "0xaA8E23Fb1079EA71e0a56F48a2aA51851D8433D0", + // }, + // { + // name: SupportedAssets.USDC, + // address: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238", + // }, + // { + // name: SupportedAssets.DAI, + // address: "0x6C7661e66256eaEb3B06d397089cda7C025b61b3s", + // }, + ], +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/__tests__/graphql/incentives.graphql.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/__tests__/graphql/incentives.graphql.test.ts new file mode 100644 index 00000000..df7d4683 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/__tests__/graphql/incentives.graphql.test.ts @@ -0,0 +1,83 @@ +import fetch from "node-fetch" + +const GRAPHQL_ENDPOINT = "http://localhost:3100/graphql" + +interface HyperbridgeRelayerReward { + id: string + totalRewardAmount: string + totalConsensusRewardAmount: string + totalMessagingRewardAmount: string + reputationAssetBalance: string +} + +describe("Incentives GraphQL Test", () => { + it("should fetch a list of HyperbridgeRelayerReward entities", async () => { + const query = ` + query { + hyperbridgeRelayerRewards(first: 5, orderBy: TOTAL_REWARD_AMOUNT_DESC) { + nodes { + id + totalRewardAmount + totalConsensusRewardAmount + totalMessagingRewardAmount + reputationAssetBalance + } + } + } + ` + const startTime = Date.now() + const timeout = 240000 + const pollInterval = 2000 + + let rewardNodes: HyperbridgeRelayerReward[] | null = null + + while (Date.now() - startTime < timeout) { + const response = await fetch(GRAPHQL_ENDPOINT, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ query }), + }) + + if (!response.ok) { + console.error(`Received non-ok response: ${response.status}`) + await new Promise(resolve => setTimeout(resolve, pollInterval)) + continue + } + + const json = (await response.json()) as any + + if (json.errors) { + throw new Error( + `GraphQL query failed: ${JSON.stringify(json.errors)}`, + ) + } + + if ( + json.data?.hyperbridgeRelayerRewards?.nodes && + json.data.hyperbridgeRelayerRewards.nodes.length > 0 + ) { + rewardNodes = json.data.hyperbridgeRelayerRewards.nodes + break + } + + await new Promise(resolve => setTimeout(resolve, pollInterval)) + } + + if (!rewardNodes) { + throw new Error( + `Test timed out after ${ + timeout / 1000 + }s waiting for HyperbridgeRelayerReward entities to be created.`, + ) + } + + console.log( + `Successfully fetched ${rewardNodes.length} relayer rewards.`, + ) + expect(rewardNodes.length).toBeGreaterThan(0) + + const firstReward = rewardNodes[0] + expect(firstReward.id).toBeDefined() + expect(firstReward.totalRewardAmount).toBeDefined() + }, 30000) +}) \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/__tests__/graphql/treasury.graphql.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/__tests__/graphql/treasury.graphql.test.ts new file mode 100644 index 00000000..6e74e930 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/__tests__/graphql/treasury.graphql.test.ts @@ -0,0 +1,67 @@ +import fetch from "node-fetch" + +const TREASURY_ADDRESS = "13UVJyLkyUpEiXBx5p776dHQoBuuk3Y5PYp5Aa89rYWePWA3" +const GRAPHQL_ENDPOINT = "http://localhost:3100/graphql" + +describe("Incentives GraphQL Test", () => { + it("should fetch the single Treasury entity", async () => { + const query = ` + query { + treasury(id: "${TREASURY_ADDRESS}") { + id + totalAmountTransferredIn + totalAmountTransferredOut + totalBalance + lastUpdatedAt + } + } + ` + + const startTime = Date.now() + const timeout = 240000 + const pollInterval = 2000 + + let treasuryEntity = null + + while (Date.now() - startTime < timeout) { + const response = await fetch(GRAPHQL_ENDPOINT, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ query }), + }) + + if (!response.ok) { + console.error(`Received non-ok response: ${response.status}`) + await new Promise(resolve => setTimeout(resolve, pollInterval)) + continue + } + + const json = (await response.json()) as any + + if (json.errors) { + throw new Error( + `GraphQL query failed: ${JSON.stringify(json.errors)}`, + ) + } + + if (json.data && json.data.treasury) { + treasuryEntity = json.data.treasury + break + } + + await new Promise(resolve => setTimeout(resolve, pollInterval)) + } + + if (!treasuryEntity) { + throw new Error( + `Test timed out after ${timeout / 1000}s waiting for the Treasury entity.`, + ) + } + + console.log("Successfully fetched the Treasury entity.") + // @ts-ignore + expect(treasuryEntity.id).toEqual(TREASURY_ADDRESS) + // @ts-ignore + expect(treasuryEntity.totalBalance).toBeDefined() + }, 30000) +}) \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/erc6160ext20/transfer.event.handlers.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/erc6160ext20/transfer.event.handlers.ts new file mode 100644 index 00000000..aab1c700 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/erc6160ext20/transfer.event.handlers.ts @@ -0,0 +1,60 @@ +import { HyperBridgeService } from "@/services/hyperbridge.service" +import { RelayerService } from "@/services/relayer.service" +import { TransferService } from "@/services/transfer.service" +import { TransferLog } from "@/configs/src/types/abi-interfaces/ERC6160Ext20Abi" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { CHAINS_BY_ISMP_HOST } from "@/chains-by-ismp-host" + +/** + * Handles the Transfer event from the Fee Token contract + */ +export async function handleTransferEvent(event: TransferLog): Promise { + if (!event.args) return + + const { args, transactionHash, transaction, blockNumber, blockHash } = event + const { from, to, value } = args + const HOST_ADDRESSES = Object.values(CHAINS_BY_ISMP_HOST) + + const chain: string = getHostStateMachine(chainId) + + // Only handle transfers from/to the Hyperbridge host contracts + if (!HOST_ADDRESSES.includes(from) && !HOST_ADDRESSES.includes(to)) { + return + } + + logger.info( + `Handling Transfer event: ${JSON.stringify({ + blockNumber, + transactionHash, + })}`, + ) + + const transfer = await TransferService.storeTransfer({ + from, + to, + value: BigInt(value.toString()), + transactionHash, + chain, + }) + + if (HOST_ADDRESSES.includes(from)) { + try { + const timestamp = await getBlockTimestamp(blockHash, chain) + + await RelayerService.updateFeesEarned(transfer, timestamp) + await HyperBridgeService.handleTransferOutOfHostAccounts(transfer, chain) + } catch (error) { + logger.error( + `Error handling transfer event: ${JSON.stringify({ + error, + transfer, + })}`, + ) + } + } + + if (HOST_ADDRESSES.includes(to)) { + await HyperBridgeService.updateTotalTransfersIn(transfer, chain) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/getRequest.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/getRequest.event.handler.ts new file mode 100644 index 00000000..ffcc9f7f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/getRequest.event.handler.ts @@ -0,0 +1,139 @@ +import { GetRequestEventLog } from "@/configs/src/types/abi-interfaces/EthereumHostAbi" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { HyperBridgeService } from "@/services/hyperbridge.service" +import { GetRequestService } from "@/services/getRequest.service" +import { GetRequestStatusMetadata, Status, Transfer } from "@/configs/src/types" +import { timestampToDate } from "@/utils/date.helpers" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" +import { extractAddressFromTopic, getPriceDataFromEthereumLog, isERC20TransferEvent } from "@/utils/transfer.helpers" +import { TransferService } from "@/services/transfer.service" +import { VolumeService } from "@/services/volume.service" +import { safeArray } from "@/utils/data.helper" + +/** + * Handles the GetRequest event from Evm Hosts + */ +export const handleGetRequestEvent = wrap(async (event: GetRequestEventLog): Promise => { + logger.info( + `Handling GetRequest Event: ${stringify({ + event, + })}`, + ) + if (!event.args) return + + const { blockNumber, transactionHash, args, block, blockHash, transaction } = event + let { source, dest, from, nonce, height, context, timeoutTimestamp, fee } = args + let keys = args[3] + + const chain: string = getHostStateMachine(chainId) + const timestamp = await getBlockTimestamp(blockHash, chain) + + // Update HyperBridge stats + await HyperBridgeService.incrementNumberOfSentMessages(chain) + + logger.info( + `Processing GetRequest Event: ${stringify({ + source, + dest, + from, + keys, + nonce, + height, + context, + timeoutTimestamp, + fee, + })}`, + ) + + let get_request_commitment = GetRequestService.computeRequestCommitment( + source, + dest, + BigInt(nonce.toString()), + BigInt(height.toString()), + BigInt(timeoutTimestamp.toString()), + from, + keys, + context, + ) + + logger.info( + `Get Request Commitment: ${stringify({ + commitment: get_request_commitment, + })}`, + ) + + const blockTimestamp = block.timestamp + + await GetRequestService.createOrUpdate({ + id: get_request_commitment, + source, + dest, + from, + keys, + nonce: BigInt(nonce.toString()), + height: BigInt(height.toString()), + context, + timeoutTimestamp: BigInt(timeoutTimestamp.toString()), + fee: BigInt(fee.toString()), + transactionHash, + blockNumber: blockNumber.toString(), + blockHash, + blockTimestamp, + status: Status.SOURCE, + chain, + }) + + const getRequestStatusMetadata = GetRequestStatusMetadata.create({ + id: `${get_request_commitment}.${Status.SOURCE}`, + requestId: get_request_commitment, + status: Status.SOURCE, + chain, + timestamp: blockTimestamp, + blockNumber: blockNumber.toString(), + blockHash, + transactionHash, + createdAt: timestampToDate(timestamp), + }) + + await getRequestStatusMetadata.save() + + // Process transfer logs associated with the get request + for (const [index, log] of safeArray(transaction?.logs).entries()) { + if (!isERC20TransferEvent(log)) { + continue + } + + const value = BigInt(log.data) + const transferId = `${log.transactionHash}-index-${index}` + const transfer = await Transfer.get(transferId) + + if (!transfer) { + const [_, fromTopic, toTopic] = log.topics + const logFrom = extractAddressFromTopic(fromTopic) + const logTo = extractAddressFromTopic(toTopic) + + // Compute USD value first; skip zero-USD transfers + const { symbol, amountValueInUSD } = await getPriceDataFromEthereumLog(log.address, value, blockTimestamp) + if (amountValueInUSD === "0") { + continue + } + + await TransferService.storeTransfer({ + transactionHash: transferId, + chain, + value, + from: logFrom, + to: logTo, + }) + + await VolumeService.updateVolume(`Transfer.${symbol}`, amountValueInUSD, blockTimestamp) + + // Only update contract volume for transfers associated with the request's from address + if (logFrom.toLowerCase() === from.toLowerCase() || logTo.toLowerCase() === from.toLowerCase()) { + await VolumeService.updateVolume(`Contract.${from}`, amountValueInUSD, blockTimestamp) + } + } + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/getRequestHandled.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/getRequestHandled.event.handler.ts new file mode 100644 index 00000000..e13b829d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/getRequestHandled.event.handler.ts @@ -0,0 +1,111 @@ +import { HyperBridgeService } from "@/services/hyperbridge.service" +import { Status, Transfer } from "@/configs/src/types" +import { GetRequestHandledLog } from "@/configs/src/types/abi-interfaces/EthereumHostAbi" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { GetRequestService } from "@/services/getRequest.service" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" +import { getPriceDataFromEthereumLog, isERC20TransferEvent, extractAddressFromTopic } from "@/utils/transfer.helpers" +import { TransferService } from "@/services/transfer.service" +import { VolumeService } from "@/services/volume.service" +import { safeArray } from "@/utils/data.helper" +import HandlerV1Abi from "@/configs/abis/HandlerV1.abi.json" +import { GetResponseMessage } from "@/types/ismp" +import { Interface } from "@ethersproject/abi" + +/** + * Handles the GetRequestHandled event from EVMHost + */ +export const handleGetRequestHandledEvent = wrap(async (event: GetRequestHandledLog): Promise => { + if (!event.args) return + + const { args, block, transaction, transactionHash, blockNumber, blockHash } = event + + const { relayer: relayer_id, commitment } = args + + logger.info( + `Handling GetRequestHandled Event: ${stringify({ + blockNumber, + transactionHash, + })}`, + ) + + const chain = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(blockHash, chain) + + try { + await HyperBridgeService.handlePostRequestOrResponseHandledEvent(relayer_id, chain, blockTimestamp) + + await GetRequestService.updateStatus({ + commitment, + chain, + blockNumber: blockNumber.toString(), + blockHash: block.hash, + blockTimestamp, + status: Status.DESTINATION, + transactionHash, + }) + + let fromAddresses = [] as string[] + + if (transaction?.input) { + const { name, args } = new Interface(HandlerV1Abi).parseTransaction({ data: transaction.input }) + + if (name === "handleGetResponses" && args && args.length > 1) { + const getResponses = args[1] as GetResponseMessage + for (const getResponse of getResponses.responses) { + const { get } = getResponse.response + const { from: getRequestFrom } = get + fromAddresses.push(getRequestFrom) + } + } + } + + for (const [index, log] of safeArray(transaction?.logs).entries()) { + if (!isERC20TransferEvent(log)) { + continue + } + + const value = BigInt(log.data) + const transferId = `${log.transactionHash}-index-${index}` + const transfer = await Transfer.get(transferId) + + if (!transfer) { + const [_, fromTopic, toTopic] = log.topics + const from = extractAddressFromTopic(fromTopic) + const to = extractAddressFromTopic(toTopic) + + // Compute USD value first; skip zero-USD transfers + const { symbol, amountValueInUSD } = await getPriceDataFromEthereumLog( + log.address, + value, + blockTimestamp, + ) + if (amountValueInUSD === "0") { + continue + } + + await TransferService.storeTransfer({ + transactionHash: transferId, + chain, + value, + from, + to, + }) + + await VolumeService.updateVolume(`Transfer.${symbol}`, amountValueInUSD, blockTimestamp) + + const matchingContract = fromAddresses.find( + (addr) => addr.toLowerCase() === from.toLowerCase() || addr.toLowerCase() === to.toLowerCase(), + ) + + if (matchingContract) { + await VolumeService.updateVolume(`Contract.${matchingContract}`, amountValueInUSD, blockTimestamp) + } + } + } + } catch (error) { + logger.error(`Error handling GetRequestHandled Event: ${error}`) + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/getRequestTimeoutHandled.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/getRequestTimeoutHandled.event.handler.ts new file mode 100644 index 00000000..310c4170 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/getRequestTimeoutHandled.event.handler.ts @@ -0,0 +1,109 @@ +import { HyperBridgeService } from "@/services/hyperbridge.service" +import { Status, Transfer } from "@/configs/src/types" +import { GetRequestTimeoutHandledLog } from "@/configs/src/types/abi-interfaces/EthereumHostAbi" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { GetRequestService } from "@/services/getRequest.service" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" +import { Interface } from "@ethersproject/abi" +import HandlerV1Abi from "@/configs/abis/HandlerV1.abi.json" +import { GetTimeoutMessage } from "@/types/ismp" +import { safeArray } from "@/utils/data.helper" +import { extractAddressFromTopic, getPriceDataFromEthereumLog, isERC20TransferEvent } from "@/utils/transfer.helpers" +import { TransferService } from "@/services/transfer.service" +import { VolumeService } from "@/services/volume.service" + +/** + * Handles the GetRequestTimeoutHandled event from EVMHost + */ +export const handleGetRequestTimeoutHandled = wrap(async (event: GetRequestTimeoutHandledLog): Promise => { + if (!event.args) return + + const { args, block, transactionHash, blockNumber, blockHash, transaction } = event + const { commitment } = args + + logger.info( + `Handling GetRequestTimeoutHandled Event: ${stringify({ + blockNumber, + transactionHash, + })}`, + ) + + const chain = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(blockHash, chain) + + await HyperBridgeService.incrementNumberOfTimedOutMessagesSent(chain) + + await GetRequestService.updateStatus({ + commitment, + chain, + blockNumber: blockNumber.toString(), + blockHash: block.hash, + blockTimestamp, + status: Status.TIMED_OUT, + transactionHash, + }) + + let fromAddresses = [] as string[] + + if (transaction?.input) { + const { name, args } = new Interface(HandlerV1Abi).parseTransaction({ data: transaction.input }) + + try { + if (name === "handleGetRequestTimeouts" && args && args.length > 1) { + const { timeouts } = args[1] as GetTimeoutMessage + for (const getRequest of timeouts) { + const { from: getRequestFrom } = getRequest + fromAddresses.push(getRequestFrom) + } + } + } catch (e: any) { + logger.error( + `Error decoding Post Request Handled event: ${stringify({ + error: e as unknown as Error, + })}`, + ) + } + } + + for (const [index, log] of safeArray(transaction.logs).entries()) { + if (!isERC20TransferEvent(log)) { + continue + } + + const value = BigInt(log.data) + const transferId = `${log.transactionHash}-index-${index}` + const transfer = await Transfer.get(transferId) + + if (!transfer) { + const [_, fromTopic, toTopic] = log.topics + const from = extractAddressFromTopic(fromTopic) + const to = extractAddressFromTopic(toTopic) + + // Compute USD value first; skip zero-USD transfers + const { symbol, amountValueInUSD } = await getPriceDataFromEthereumLog(log.address, value, blockTimestamp) + if (amountValueInUSD === "0") { + continue + } + + await TransferService.storeTransfer({ + transactionHash: transferId, + chain, + value, + from, + to, + }) + + await VolumeService.updateVolume(`Transfer.${symbol}`, amountValueInUSD, blockTimestamp) + + const matchingContract = fromAddresses.find( + (addr) => addr.toLowerCase() === from.toLowerCase() || addr.toLowerCase() === to.toLowerCase(), + ) + + if (matchingContract) { + await VolumeService.updateVolume(`Contract.${matchingContract}`, amountValueInUSD, blockTimestamp) + } + } + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postRequest.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postRequest.event.handler.ts new file mode 100644 index 00000000..f2359050 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postRequest.event.handler.ts @@ -0,0 +1,137 @@ +import { HyperBridgeService } from "@/services/hyperbridge.service" +import { RequestService } from "@/services/request.service" +import { RequestStatusMetadata, Status, Transfer } from "@/configs/src/types" +import { PostRequestEventLog } from "@/configs/src/types/abi-interfaces/EthereumHostAbi" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { timestampToDate } from "@/utils/date.helpers" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" +import { extractAddressFromTopic, getPriceDataFromEthereumLog, isERC20TransferEvent } from "@/utils/transfer.helpers" +import { TransferService } from "@/services/transfer.service" +import { safeArray } from "@/utils/data.helper" +import { VolumeService } from "@/services/volume.service" + +/** + * Handles the PostRequest event from Evm Hosts + */ +export const handlePostRequestEvent = wrap(async (event: PostRequestEventLog): Promise => { + logger.info( + `Handling PostRequest Event: ${stringify({ + event, + })}`, + ) + if (!event.args) return + + const { transaction, blockNumber, transactionHash, args, block } = event + let { dest, fee, from, nonce, source, timeoutTimestamp, to, body } = args + + const chain: string = getHostStateMachine(chainId) + const timestamp = await getBlockTimestamp(block.hash, chain) + + await HyperBridgeService.handlePostRequestOrResponseEvent(chain, event) + + logger.info( + `Computing Request Commitment Event: ${stringify({ + dest, + fee, + from, + nonce, + source, + timeoutTimestamp, + to, + body, + })}`, + ) + + // Compute the request commitment + let request_commitment = RequestService.computeRequestCommitment( + source, + dest, + BigInt(nonce.toString()), + BigInt(timeoutTimestamp.toString()), + from, + to, + body, + ) + + logger.info( + `Request Commitment: ${stringify({ + commitment: request_commitment, + })}`, + ) + + const blockTimestamp = timestamp + + // Create the request entity + await RequestService.createOrUpdate({ + chain, + commitment: request_commitment, + body, + dest, + fee: BigInt(fee.toString()), + from, + nonce: BigInt(nonce.toString()), + source, + status: Status.SOURCE, + timeoutTimestamp: BigInt(timeoutTimestamp.toString()), + to, + blockNumber: blockNumber.toString(), + blockHash: block.hash, + transactionHash, + blockTimestamp, + createdAt: timestampToDate(timestamp), + }) + + // Always create a new status metadata entry + let requestStatusMetadata = RequestStatusMetadata.create({ + id: `${request_commitment}.${Status.SOURCE}`, + requestId: request_commitment, + status: Status.SOURCE, + chain, + timestamp: blockTimestamp, + blockNumber: blockNumber.toString(), + blockHash: block.hash, + transactionHash, + createdAt: timestampToDate(timestamp), + }) + + await requestStatusMetadata.save() + + for (const [index, log] of safeArray(transaction?.logs).entries()) { + if (!isERC20TransferEvent(log)) { + continue + } + + const value = BigInt(log.data) + const transferId = `${log.transactionHash}-index-${index}` + const transfer = await Transfer.get(transferId) + + if (!transfer) { + const [_, fromTopic, toTopic] = log.topics + const logFrom = extractAddressFromTopic(fromTopic) + const logTo = extractAddressFromTopic(toTopic) + + // Compute USD value first; skip zero-USD transfers + const { symbol, amountValueInUSD } = await getPriceDataFromEthereumLog(log.address, value, blockTimestamp) + if (amountValueInUSD === "0") { + continue + } + + await TransferService.storeTransfer({ + transactionHash: transferId, + chain, + value, + from: logFrom, + to: logTo, + }) + + await VolumeService.updateVolume(`Transfer.${symbol}`, amountValueInUSD, blockTimestamp) + + // Only update contract volume for transfers associated with the request's from address + if (logFrom.toLowerCase() === from.toLowerCase() || logTo.toLowerCase() === from.toLowerCase()) { + await VolumeService.updateVolume(`Contract.${from}`, amountValueInUSD, blockTimestamp) + } + } + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postRequestHandled.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postRequestHandled.event.handler.ts new file mode 100644 index 00000000..093d2b4a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postRequestHandled.event.handler.ts @@ -0,0 +1,117 @@ +import { HyperBridgeService } from "@/services/hyperbridge.service" +import { Status, Transfer, Request } from "@/configs/src/types" +import { PostRequestHandledLog } from "@/configs/src/types/abi-interfaces/EthereumHostAbi" +import { RequestService } from "@/services/request.service" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" +import { VolumeService } from "@/services/volume.service" +import { getPriceDataFromEthereumLog, isERC20TransferEvent, extractAddressFromTopic } from "@/utils/transfer.helpers" +import { TransferService } from "@/services/transfer.service" +import { safeArray } from "@/utils/data.helper" +import HandlerV1Abi from "@/configs/abis/HandlerV1.abi.json" +import { PostRequestMessage } from "@/types/ismp" +import { Interface } from "@ethersproject/abi" + +/** + * Handles the PostRequestHandled event from Hyperbridge + */ +export const handlePostRequestHandledEvent = wrap(async (event: PostRequestHandledLog): Promise => { + if (!event.args) return + + const { args, block, transaction, transactionHash, transactionIndex, blockHash, blockNumber, data } = event + const { relayer: relayer_id, commitment } = args + + logger.info( + `Handling PostRequestHandled Event: ${stringify({ + blockNumber, + transactionHash, + })}`, + ) + + const chain = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(blockHash, chain) + + try { + await HyperBridgeService.handlePostRequestOrResponseHandledEvent(relayer_id, chain, blockTimestamp) + + await RequestService.updateStatus({ + commitment, + chain, + blockNumber: blockNumber.toString(), + blockHash: block.hash, + blockTimestamp, + status: Status.DESTINATION, + transactionHash, + }) + + let toAddresses = [] as string[] + + if (transaction?.input) { + const { name, args } = new Interface(HandlerV1Abi).parseTransaction({ data: transaction.input }) + + try { + if (name === "handlePostRequests" && args && args.length > 1) { + const postRequests = args[1] as PostRequestMessage + for (const postRequest of postRequests.requests) { + const { to: postRequestTo } = postRequest.request + toAddresses.push(postRequestTo) + } + } + } catch (e: any) { + logger.error( + `Error decoding Post Request Handled event: ${stringify({ + error: e as unknown as Error, + })}`, + ) + } + } + + for (const [index, log] of safeArray(transaction.logs).entries()) { + if (!isERC20TransferEvent(log)) { + continue + } + + const value = BigInt(log.data) + const transferId = `${log.transactionHash}-index-${index}` + const transfer = await Transfer.get(transferId) + + if (!transfer) { + const [_, fromTopic, toTopic] = log.topics + const from = extractAddressFromTopic(fromTopic) + const to = extractAddressFromTopic(toTopic) + + // Compute USD value first; skip zero-USD transfers + const { symbol, amountValueInUSD } = await getPriceDataFromEthereumLog( + log.address, + value, + blockTimestamp, + ) + if (amountValueInUSD === "0") { + continue + } + + await TransferService.storeTransfer({ + transactionHash: transferId, + chain, + value, + from, + to, + }) + + await VolumeService.updateVolume(`Transfer.${symbol}`, amountValueInUSD, blockTimestamp) + + const matchingContract = toAddresses.find( + (addr) => addr.toLowerCase() === from.toLowerCase() || addr.toLowerCase() === to.toLowerCase(), + ) + + if (matchingContract) { + await VolumeService.updateVolume(`Contract.${matchingContract}`, amountValueInUSD, blockTimestamp) + } + } + } + } catch (error) { + console.error(`Error handling PostRequestHandled event: ${stringify(error)}`) + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postRequestTimeoutHandled.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postRequestTimeoutHandled.event.handler.ts new file mode 100644 index 00000000..01e832e3 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postRequestTimeoutHandled.event.handler.ts @@ -0,0 +1,109 @@ +import { Status, Transfer, Request } from "@/configs/src/types" +import { PostRequestTimeoutHandledLog } from "@/configs/src/types/abi-interfaces/EthereumHostAbi" +import { HyperBridgeService } from "@/services/hyperbridge.service" +import { RequestService } from "@/services/request.service" +import { wrap } from "@/utils/event.utils" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import stringify from "safe-stable-stringify" +import { VolumeService } from "@/services/volume.service" +import { getPriceDataFromEthereumLog, isERC20TransferEvent, extractAddressFromTopic } from "@/utils/transfer.helpers" +import { TransferService } from "@/services/transfer.service" +import { safeArray } from "@/utils/data.helper" +import HandlerV1Abi from "@/configs/abis/HandlerV1.abi.json" +import { PostRequestTimeoutMessage } from "@/types/ismp" +import { Interface } from "@ethersproject/abi" + +/** + * Handles the PostRequestTimeoutHandled event + */ +export const handlePostRequestTimeoutHandledEvent = wrap(async (event: PostRequestTimeoutHandledLog): Promise => { + if (!event.args) return + + const { args, block, transaction, transactionHash, transactionIndex, blockHash, blockNumber, data } = event + const { commitment, dest } = args + + logger.info( + `Handling PostRequestTimeoutHandled Event: ${stringify({ + blockNumber, + transactionHash, + })}`, + ) + + const chain: string = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(blockHash, chain) + + try { + await HyperBridgeService.incrementNumberOfTimedOutMessagesSent(chain) + + await RequestService.updateStatus({ + commitment, + chain, + blockNumber: blockNumber.toString(), + blockHash: block.hash, + blockTimestamp, + status: Status.TIMED_OUT, + transactionHash, + }) + + let fromAddresses = [] as string[] + + if (transaction?.input) { + const { name, args } = new Interface(HandlerV1Abi).parseTransaction({ data: transaction.input }) + + if (name === "handlePostRequestTimeouts" && args && args.length > 1) { + const { timeouts } = args[1] as PostRequestTimeoutMessage + for (const timeout of timeouts) { + const { from } = timeout + fromAddresses.push(from) + } + } + } + + for (const [index, log] of safeArray(transaction.logs).entries()) { + if (!isERC20TransferEvent(log)) { + continue + } + + const value = BigInt(log.data) + const transferId = `${log.transactionHash}-index-${index}` + const transfer = await Transfer.get(transferId) + + if (!transfer) { + const [_, fromTopic, toTopic] = log.topics + const from = extractAddressFromTopic(fromTopic) + const to = extractAddressFromTopic(toTopic) + + // Compute USD value first; skip zero-USD transfers + const { symbol, amountValueInUSD } = await getPriceDataFromEthereumLog( + log.address, + value, + blockTimestamp, + ) + if (amountValueInUSD === "0") { + continue + } + + await TransferService.storeTransfer({ + transactionHash: transferId, + chain, + value, + from, + to, + }) + + await VolumeService.updateVolume(`Transfer.${symbol}`, amountValueInUSD, blockTimestamp) + + const matchingContract = fromAddresses.find( + (addr) => addr.toLowerCase() === from.toLowerCase() || addr.toLowerCase() === to.toLowerCase(), + ) + + if (matchingContract) { + await VolumeService.updateVolume(`Contract.${matchingContract}`, amountValueInUSD, blockTimestamp) + } + } + } + } catch (error) { + logger.error(`Error updating handling post request timeout: ${stringify(error)}`) + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postResponse.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postResponse.event.handler.ts new file mode 100644 index 00000000..cc08de95 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postResponse.event.handler.ts @@ -0,0 +1,146 @@ +import { Status, Request, Transfer } from "@/configs/src/types" +import { PostResponseEventLog } from "@/configs/src/types/abi-interfaces/EthereumHostAbi" +import { HyperBridgeService } from "@/services/hyperbridge.service" +import { ResponseService } from "@/services/response.service" +import { RequestService } from "@/services/request.service" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" +import { safeArray } from "@/utils/data.helper" +import { extractAddressFromTopic, getPriceDataFromEthereumLog, isERC20TransferEvent } from "@/utils/transfer.helpers" +import { TransferService } from "@/services/transfer.service" +import { VolumeService } from "@/services/volume.service" + +/** + * Handles the PostResponse event from Evm Hosts + */ +export const handlePostResponseEvent = wrap(async (event: PostResponseEventLog): Promise => { + logger.info( + `Handling PostRequest Event: ${stringify({ + event, + })}`, + ) + if (!event.args) return + + const { transaction, blockNumber, transactionHash, args, block, blockHash } = event + let { + body, + dest, + fee, + from: eventFrom, + nonce, + source, + timeoutTimestamp, + to: eventTo, + response, + responseTimeoutTimestamp, + } = args + + const chain: string = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(blockHash, chain) + + await HyperBridgeService.handlePostRequestOrResponseEvent(chain, event) + + logger.info( + `Computing Response Commitment Event: ${stringify({ + dest, + fee, + eventFrom, + nonce, + source, + timeoutTimestamp, + eventTo, + body, + })}`, + ) + + // Compute the response commitment + let response_commitment = ResponseService.computeResponseCommitment( + source, + dest, + BigInt(nonce.toString()), + BigInt(timeoutTimestamp.toString()), + eventFrom, + eventTo, + body, + response, + BigInt(responseTimeoutTimestamp.toString()), + ) + + logger.info( + `Response Commitment: ${stringify({ + commitment: response_commitment, + })}`, + ) + + // Compute the request commitment + let request_commitment = RequestService.computeRequestCommitment( + source, + dest, + BigInt(nonce.toString()), + BigInt(timeoutTimestamp.toString()), + eventFrom, + eventTo, + body, + ) + + let request = await Request.get(request_commitment) + + if (typeof request === "undefined") { + logger.error( + `Error handling PostResponseEvent because request with commitment: ${request_commitment} was not found`, + ) + return + } + + // Create the response entity + await ResponseService.findOrCreate({ + chain, + commitment: response_commitment, + responseTimeoutTimestamp: BigInt(responseTimeoutTimestamp.toString()), + response_message: response, + status: Status.SOURCE, + request, + blockNumber: blockNumber.toString(), + blockHash: block.hash, + transactionHash, + blockTimestamp, + }) + + for (const [index, log] of safeArray(transaction.logs).entries()) { + if (!isERC20TransferEvent(log)) { + continue + } + + const value = BigInt(log.data) + const transferId = `${log.transactionHash}-index-${index}` + const transfer = await Transfer.get(transferId) + + if (!transfer) { + const [_, fromTopic, toTopic] = log.topics + const logFrom = extractAddressFromTopic(fromTopic) + const logTo = extractAddressFromTopic(toTopic) + + // Compute USD value first; skip zero-USD transfers + const { symbol, amountValueInUSD } = await getPriceDataFromEthereumLog(log.address, value, blockTimestamp) + if (amountValueInUSD === "0") { + continue + } + + await TransferService.storeTransfer({ + transactionHash: transferId, + chain, + value, + from: logFrom, + to: logTo, + }) + + await VolumeService.updateVolume(`Transfer.${symbol}`, amountValueInUSD, blockTimestamp) + + if (logFrom.toLowerCase() === eventTo.toLowerCase() || logTo.toLowerCase() === eventTo.toLowerCase()) { + await VolumeService.updateVolume(`Contract.${eventTo}`, amountValueInUSD, blockTimestamp) + } + } + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postResponseHandled.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postResponseHandled.event.handler.ts new file mode 100644 index 00000000..32c18fce --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postResponseHandled.event.handler.ts @@ -0,0 +1,110 @@ +import { HyperBridgeService } from "@/services/hyperbridge.service" +import { Status } from "@/configs/src/types" +import { PostResponseHandledLog } from "@/configs/src/types/abi-interfaces/EthereumHostAbi" +import { ResponseService } from "@/services/response.service" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" +import { Transfer, Response, Request } from "@/configs/src/types" +import { VolumeService } from "@/services/volume.service" +import { getPriceDataFromEthereumLog, isERC20TransferEvent, extractAddressFromTopic } from "@/utils/transfer.helpers" +import { TransferService } from "@/services/transfer.service" +import { safeArray } from "@/utils/data.helper" +import HandlerV1Abi from "@/configs/abis/HandlerV1.abi.json" +import { PostResponseMessage } from "@/types/ismp" +import { Interface } from "@ethersproject/abi" + +/** + * Handles the PostResponseHandled event from Hyperbridge + */ +export const handlePostResponseHandledEvent = wrap(async (event: PostResponseHandledLog): Promise => { + if (!event.args) return + + const { args, block, transaction, transactionHash, transactionIndex, blockHash, blockNumber, data } = event + const { relayer: relayer_id, commitment } = args + + logger.info( + `Handling PostResponseHandled Event: ${stringify({ + blockNumber, + transactionHash, + })}`, + ) + + const chain: string = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(blockHash, chain) + + try { + await HyperBridgeService.handlePostRequestOrResponseHandledEvent(relayer_id, chain, blockTimestamp) + + await ResponseService.updateStatus({ + commitment, + chain, + blockNumber: blockNumber.toString(), + blockTimestamp, + blockHash: block.hash, + status: Status.DESTINATION, + transactionHash, + }) + + let fromAddresses = [] as string[] + + if (transaction?.input) { + const { name, args } = new Interface(HandlerV1Abi).parseTransaction({ data: transaction.input }) + if (name === "handlePostResponses" && args && args.length > 1) { + const postResponses = args[1] as PostResponseMessage + for (const postResponse of postResponses.responses) { + const { post } = postResponse.response + const { from: postRequestFrom } = post + fromAddresses.push(postRequestFrom) + } + } + } + + for (const [index, log] of safeArray(transaction?.logs).entries()) { + if (!isERC20TransferEvent(log)) { + continue + } + + const value = BigInt(log.data) + const transferId = `${log.transactionHash}-index-${index}` + const transfer = await Transfer.get(transferId) + + if (!transfer) { + const [_, fromTopic, toTopic] = log.topics + const from = extractAddressFromTopic(fromTopic) + const to = extractAddressFromTopic(toTopic) + + // Compute USD value first; skip zero-USD transfers + const { symbol, amountValueInUSD } = await getPriceDataFromEthereumLog( + log.address, + value, + blockTimestamp, + ) + if (amountValueInUSD === "0") { + continue + } + + await TransferService.storeTransfer({ + transactionHash: transferId, + chain, + value, + from, + to, + }) + + await VolumeService.updateVolume(`Transfer.${symbol}`, amountValueInUSD, blockTimestamp) + + const matchingContract = fromAddresses.find( + (addr) => addr.toLowerCase() === from.toLowerCase() || addr.toLowerCase() === to.toLowerCase(), + ) + + if (matchingContract) { + await VolumeService.updateVolume(`Contract.${matchingContract}`, amountValueInUSD, blockTimestamp) + } + } + } + } catch (error) { + logger.error(`Error updating handling post response: ${stringify(error)}`) + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postResponseTimeoutHandled.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postResponseTimeoutHandled.event.handler.ts new file mode 100644 index 00000000..0683b3bc --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/postResponseTimeoutHandled.event.handler.ts @@ -0,0 +1,116 @@ +import { Status } from "@/configs/src/types" +import { PostResponseTimeoutHandledLog } from "@/configs/src/types/abi-interfaces/EthereumHostAbi" +import { HyperBridgeService } from "@/services/hyperbridge.service" +import { ResponseService } from "@/services/response.service" +import { wrap } from "@/utils/event.utils" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import stringify from "safe-stable-stringify" +import { Transfer } from "@/configs/src/types" +import { VolumeService } from "@/services/volume.service" +import { getPriceDataFromEthereumLog, isERC20TransferEvent, extractAddressFromTopic } from "@/utils/transfer.helpers" +import { TransferService } from "@/services/transfer.service" +import { safeArray } from "@/utils/data.helper" +import { PostResponseTimeoutMessage } from "@/types/ismp" +import HandlerV1Abi from "@/configs/abis/HandlerV1.abi.json" +import { Interface } from "@ethersproject/abi" + +/** + * Handles the PostResponseTimeoutHandled event + */ +export const handlePostResponseTimeoutHandledEvent = wrap( + async (event: PostResponseTimeoutHandledLog): Promise => { + if (!event.args) return + const { args, block, transaction, transactionHash, transactionIndex, blockHash, blockNumber, data } = event + const { commitment, dest } = args + + logger.info( + `Handling PostResponseTimeoutHandled Event: ${stringify({ + blockNumber, + transactionHash, + })}`, + ) + + const chain: string = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(blockHash, chain) + + try { + await HyperBridgeService.incrementNumberOfTimedOutMessagesSent(chain) + + await ResponseService.updateStatus({ + commitment, + chain, + blockNumber: blockNumber.toString(), + blockHash: block.hash, + blockTimestamp, + status: Status.TIMED_OUT, + transactionHash, + }) + + let toAddresses = [] as string[] + + if (transaction?.input) { + const { name, args } = new Interface(HandlerV1Abi).parseTransaction({ data: transaction.input }) + if (name === "handlePostResponseTimeouts" && args && args.length > 1) { + const { timeouts } = args[1] as PostResponseTimeoutMessage + for (const timeout of timeouts) { + const { + post: { to }, + } = timeout + toAddresses.push(to) + } + } + } + + for (const [index, log] of safeArray(transaction?.logs).entries()) { + if (!isERC20TransferEvent(log)) { + continue + } + + const value = BigInt(log.data) + const transferId = `${log.transactionHash}-index-${index}` + const transfer = await Transfer.get(transferId) + + if (!transfer) { + const [_, fromTopic, toTopic] = log.topics + const from = extractAddressFromTopic(fromTopic) + const to = extractAddressFromTopic(toTopic) + + // Compute USD value first; skip zero-USD transfers + const { symbol, amountValueInUSD } = await getPriceDataFromEthereumLog( + log.address, + value, + blockTimestamp, + ) + if (amountValueInUSD === "0") { + continue + } + + await TransferService.storeTransfer({ + transactionHash: transferId, + chain, + value, + from, + to, + }) + + await VolumeService.updateVolume(`Transfer.${symbol}`, amountValueInUSD, blockTimestamp) + + const matchingContract = toAddresses.find( + (addr) => addr.toLowerCase() === from.toLowerCase() || addr.toLowerCase() === to.toLowerCase(), + ) + + if (matchingContract) { + await VolumeService.updateVolume( + `Contract.${matchingContract}`, + amountValueInUSD, + blockTimestamp, + ) + } + } + } + } catch (error) { + logger.error(`Error updating handling post response timeout: ${stringify(error)}`) + } + }, +) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/stateMachineUpdated.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/stateMachineUpdated.event.handler.ts new file mode 100644 index 00000000..3bea2181 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/evmHost/stateMachineUpdated.event.handler.ts @@ -0,0 +1,48 @@ +import { StateMachineUpdatedLog } from "@/configs/src/types/abi-interfaces/EthereumHostAbi" +import { StateMachineService } from "@/services/stateMachine.service" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" + +/** + * Handle the StateMachineUpdated event + */ +export const handleStateMachineUpdatedEvent = wrap(async (event: StateMachineUpdatedLog): Promise => { + if (!event.args) return + + const { blockHash, blockNumber, transactionHash, transactionIndex, block, args } = event + const { stateMachineId, height } = args + + logger.info( + `Handling StateMachineUpdated Event: ${stringify({ + blockNumber, + transactionHash, + })}`, + ) + + const chain: string = getHostStateMachine(chainId) + const timestamp = await getBlockTimestamp(blockHash, chain) + + // Determine if we're on testnet or mainnet based on stateMachineId + const isTestnet = stateMachineId.includes("KUSAMA") + + // Set consensusStateId to PAS0 for testnet, DOT0 for mainnet + const consensusStateId = isTestnet ? "PAS0" : "DOT0" + + logger.info(`Using consensusStateId: ${consensusStateId} for stateMachineId: ${stateMachineId}`) + + await StateMachineService.createEvmStateMachineUpdatedEvent( + { + transactionHash, + transactionIndex, + blockHash, + blockNumber, + timestamp: Number(timestamp), + stateMachineId: stateMachineId, + height: height.toNumber(), + consensusStateId, + }, + chain, + ) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/fees/accumulatedFees.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/fees/accumulatedFees.event.handler.ts new file mode 100644 index 00000000..41087177 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/fees/accumulatedFees.event.handler.ts @@ -0,0 +1,75 @@ +import { SubstrateEvent } from "@subql/types" +import { AccumulatedFee } from "@/configs/src/types" +import { DailyTreasuryRewardService } from "@/services/dailyTreasuryReward.service" +import { RelayerService } from "@/services/relayer.service" +import { encodeAddress } from "@polkadot/util-crypto" +import { wrap } from "@/utils/event.utils" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { formatChain, getHostStateMachine } from "@/utils/substrate.helpers" +import { timestampToDate } from "@/utils/date.helpers" + + +export const handleAccumulateFeesEvent = wrap(async (event: SubstrateEvent): Promise => { + try { + logger.info(`iN ACCumulated fee event`) + + const { + event: { data }, + block, + } = event + + const [relayerBytes, stateMachine, rawAmountCodec] = data + + logger.info( + `accumulated fees event ${data} ${block.block.header.number} gotten for relayer ${relayerBytes} on chain ${stateMachine} with amount ${rawAmountCodec}`, + ) + + const relayerAddress = encodeAddress(relayerBytes.toHex()) + const rawAmount = (rawAmountCodec as any).toBigInt() + + const stateMachineId = formatChain(stateMachine.toString()) + + logger.info( + `accumulated fees event gotten for relayer ${relayerBytes} on chain ${stateMachineId} with amount ${rawAmountCodec}`, + ) + + const recordId = `${relayerAddress}-${stateMachineId}` + + const hyperbridgeChain = getHostStateMachine(chainId) + const timestamp = await getBlockTimestamp(event.block.block.header.hash.toString(), hyperbridgeChain) + const date = timestampToDate(timestamp) + + let record = await AccumulatedFee.get(recordId) + if (!record) { + record = AccumulatedFee.create({ + id: recordId, + relayer: relayerAddress, + chainId: stateMachineId, + lifetimeFees: BigInt(0), + lastUpdatedAt: date, + }) + } + + const decimals = await DailyTreasuryRewardService.getFeeTokenDecimals(stateMachineId) + logger.info(`accumulated fees event gotten for relayer ${relayerBytes}, with token fee decimals ${decimals}`) + + const normalizedAmount = rawAmount / 10n ** (18n - BigInt(decimals)) + + record.lifetimeFees += normalizedAmount + record.lastUpdatedAt = date + + await RelayerService.updateFeesEarnedViaAccumulation( + relayerAddress, + normalizedAmount, + stateMachineId, + timestamp, + ) + + await record.save() + + logger.info(`Updated accumulated fees for relayer ${relayerAddress} on chain ${stateMachineId}`) + } catch (e) { + const errorMessage = e instanceof Error ? e.message : String(e) + logger.error(`Failed to update accumulated fees: ${errorMessage}`) + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/incentives/feeRewarded.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/incentives/feeRewarded.event.handler.ts new file mode 100644 index 00000000..e316fad5 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/incentives/feeRewarded.event.handler.ts @@ -0,0 +1,40 @@ +import { SubstrateEvent } from "@subql/types" +import { HyperbridgeRelayerReward } from "@/configs/src/types" +import { Balance } from "@polkadot/types/interfaces" +import { DailyTreasuryRewardService } from "@/services/dailyTreasuryReward.service" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { getHostStateMachine } from "@/utils/substrate.helpers" + +export async function handleFeeRewardedEvent(event: SubstrateEvent): Promise { + try { + const { + event: { data }, + block, + } = event + + const [relayer, amount] = data + const relayerAddress = relayer.toString() + const rewardAmount = (amount as unknown as Balance).toBigInt() + + let record = await HyperbridgeRelayerReward.get(relayerAddress) + if (!record) { + record = HyperbridgeRelayerReward.create({ + id: relayerAddress, + }) + } + + record.totalMessagingRewardAmount = (record.totalMessagingRewardAmount ?? BigInt(0)) + rewardAmount + record.totalRewardAmount = (record.totalRewardAmount ?? BigInt(0)) + rewardAmount + record.reputationAssetBalance = await DailyTreasuryRewardService.getReputationAssetBalance(relayerAddress) + + await record.save() + + const hyperbridgeChain = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(event.block.block.header.hash.toString(), hyperbridgeChain) + + await DailyTreasuryRewardService.update(blockTimestamp, rewardAmount) + } catch (e) { + const errorMessage = e instanceof Error ? e.message : String(e) + logger.error(`Failed to handle fee rewarded event: ${errorMessage}`) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/incentives/relayerRewarded.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/incentives/relayerRewarded.event.handler.ts new file mode 100644 index 00000000..3f4acfe4 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/incentives/relayerRewarded.event.handler.ts @@ -0,0 +1,44 @@ +import { SubstrateEvent } from "@subql/types" +import { HyperbridgeRelayerReward } from "@/configs/src/types" +import { wrap } from "@/utils/event.utils" +import { Balance } from "@polkadot/types/interfaces" +import { DailyTreasuryRewardService } from "@/services/dailyTreasuryReward.service" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { getHostStateMachine } from "@/utils/substrate.helpers" + +export const handleRelayerRewardedEvent = wrap(async (event: SubstrateEvent): Promise => { + try { + const { + event: { data, method }, + block, + } = event + logger.info(`Relayer Rewarded Event ${method} event at block: ${block.block.header.number.toString()}`) + + const [relayer, amount, stateMachineHeight] = data + + const relayerAddress = relayer.toString() + const rewardAmount = (amount as unknown as Balance).toBigInt() + + let record = await HyperbridgeRelayerReward.get(relayerAddress) + if (!record) { + record = HyperbridgeRelayerReward.create({ + id: relayerAddress, + }) + } + + logger.info(`Saving Relayer Rewarded Event ${method} event at block: ${record}`) + + record.totalConsensusRewardAmount = (record.totalConsensusRewardAmount ?? BigInt(0)) + rewardAmount + record.totalRewardAmount = (record.totalRewardAmount ?? BigInt(0)) + rewardAmount + record.reputationAssetBalance = await DailyTreasuryRewardService.getReputationAssetBalance(relayerAddress) + + await record.save() + + const hyperbridgeChain = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(event.block.block.header.hash.toString(), hyperbridgeChain) + await DailyTreasuryRewardService.update(blockTimestamp, rewardAmount) + } catch (e) { + const errorMessage = e instanceof Error ? e.message : String(e) + logger.error(`Failed to handle relayer rewarded event: ${errorMessage}`) + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/escrowRefunded.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/escrowRefunded.event.handler.ts new file mode 100644 index 00000000..78d1c8fd --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/escrowRefunded.event.handler.ts @@ -0,0 +1,31 @@ +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { EscrowRefundedLog } from "@/configs/src/types/abi-interfaces/IntentGatewayAbi" +import { IntentGatewayService } from "@/services/intentGateway.service" +import { OrderStatus } from "@/configs/src/types" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { wrap } from "@/utils/event.utils" + +export const handleEscrowRefundedEvent = wrap(async (event: EscrowRefundedLog): Promise => { + logger.info(`Order Filled Event: ${stringify(event)}`) + + const { blockNumber, transactionHash, args, block, blockHash } = event + const { commitment } = args! + + if (!args) return + + const chain = getHostStateMachine(chainId) + const timestamp = await getBlockTimestamp(blockHash, chain) + + logger.info( + `Escrow Refunded: ${stringify({ + commitment, + })}`, + ) + + await IntentGatewayService.updateOrderStatus(commitment, OrderStatus.REFUNDED, { + transactionHash, + blockNumber, + timestamp, + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/escrowReleased.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/escrowReleased.event.handler.ts new file mode 100644 index 00000000..53939306 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/escrowReleased.event.handler.ts @@ -0,0 +1,31 @@ +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { EscrowReleasedLog } from "@/configs/src/types/abi-interfaces/IntentGatewayAbi" +import { IntentGatewayService } from "@/services/intentGateway.service" +import { OrderStatus } from "@/configs/src/types" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { wrap } from "@/utils/event.utils" + +export const handleEscrowReleasedEvent = wrap(async (event: EscrowReleasedLog): Promise => { + logger.info(`Order Filled Event: ${stringify(event)}`) + + const { blockNumber, transactionHash, args, block, blockHash } = event + const { commitment } = args! + + if (!args) return + + const chain = getHostStateMachine(chainId) + const timestamp = await getBlockTimestamp(blockHash, chain) + + logger.info( + `Escrow Released: ${stringify({ + commitment, + })}`, + ) + + await IntentGatewayService.updateOrderStatus(commitment, OrderStatus.REDEEMED, { + transactionHash, + blockNumber, + timestamp, + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/orderFilled.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/orderFilled.event.handler.ts new file mode 100644 index 00000000..eee4d38c --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/orderFilled.event.handler.ts @@ -0,0 +1,36 @@ +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { OrderFilledLog } from "@/configs/src/types/abi-interfaces/IntentGatewayAbi" +import { IntentGatewayService } from "@/services/intentGateway.service" +import { OrderStatus } from "@/configs/src/types" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { wrap } from "@/utils/event.utils" + +export const handleOrderFilledEvent = wrap(async (event: OrderFilledLog): Promise => { + logger.info(`Order Filled Event: ${stringify(event)}`) + + const { blockNumber, transactionHash, args, blockHash } = event + const { commitment, filler } = args! + + if (!args) return + + const chain = getHostStateMachine(chainId) + const timestamp = await getBlockTimestamp(blockHash, chain) + + logger.info( + `Order Filled: ${stringify({ + commitment, + })} by ${stringify({ filler })}`, + ) + + await IntentGatewayService.updateOrderStatus( + commitment, + OrderStatus.FILLED, + { + transactionHash, + blockNumber, + timestamp, + }, + filler, + ) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/orderPlaced.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/orderPlaced.event.handler.ts new file mode 100644 index 00000000..29bec679 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/intentGateway/orderPlaced.event.handler.ts @@ -0,0 +1,92 @@ +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { OrderPlacedLog } from "@/configs/src/types/abi-interfaces/IntentGatewayAbi" +import { DEFAULT_REFERRER, IntentGatewayService, Order } from "@/services/intentGateway.service" +import { OrderStatus } from "@/configs/src/types" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { Hex } from "viem" +import { wrap } from "@/utils/event.utils" +import { Interface } from "@ethersproject/abi" +import IntentGatewayAbi from "@/configs/abis/IntentGateway.abi.json" + +export const handleOrderPlacedEvent = wrap(async (event: OrderPlacedLog): Promise => { + logger.info(`Order Placed Event: ${stringify(event)}`) + + const { blockNumber, transactionHash, args, block, blockHash, transaction } = event + if (!args) return + + const chain = getHostStateMachine(chainId) + const timestamp = await getBlockTimestamp(blockHash, chain) + let graffiti = DEFAULT_REFERRER + + if (transaction?.input) { + logger.info(`Decoding transaction data for referral points: ${stringify(transaction.input)}`) + + try { + const { name, args: decodedArgs } = new Interface(IntentGatewayAbi.abi).parseTransaction({ + data: transaction.input, + }) + logger.info(`Decoded graffiti: ${stringify({ graffiti: decodedArgs[1] })}`) + + if (name === "placeOrder" && decodedArgs[1].toLowerCase() !== args.user.toLowerCase()) { + // Either Default Referrer or Actual Referrer + logger.info(`Using ${stringify(decodedArgs[1])} as graffiti`) + graffiti = decodedArgs[1] as Hex + } + } catch (e: any) { + logger.error( + `Error decoding placeOrder args, using default referrer: ${stringify({ + error: e as unknown as Error, + })}`, + ) + } + } + + const order: Order = { + id: "", + user: args.user as Hex, + sourceChain: args.sourceChain, + destChain: args.destChain, + deadline: args.deadline.toBigInt(), + nonce: args.nonce.toBigInt(), + fees: args.fees.toBigInt(), + inputs: args.inputs.map((input) => ({ + token: input.token as Hex, + amount: input.amount.toBigInt(), + })), + outputs: args.outputs.map((output) => ({ + token: output.token as Hex, + amount: output.amount.toBigInt(), + beneficiary: output.beneficiary as Hex, + })), + callData: args.callData as Hex, + } + + logger.info( + `Computing Order Commitment: ${stringify({ + order, + })}`, + ) + + const commitment = IntentGatewayService.computeOrderCommitment(order) + + order.id = commitment + + logger.info(`Order Commitment: ${commitment}`) + + await IntentGatewayService.getOrCreateOrder( + { ...order, user: IntentGatewayService.bytes32ToBytes20(order.user) as Hex }, + graffiti, + { + transactionHash, + blockNumber, + timestamp, + }, + ) + + await IntentGatewayService.updateOrderStatus(commitment, OrderStatus.PLACED, { + transactionHash, + blockNumber, + timestamp, + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/price/handlePriceIndexing.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/price/handlePriceIndexing.event.handler.ts new file mode 100644 index 00000000..b3db36eb --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/price/handlePriceIndexing.event.handler.ts @@ -0,0 +1,32 @@ +import { SubstrateBlock } from "@subql/types" +import { wrap } from "@/utils/event.utils" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { TokenPriceService } from "@/services/token-price.service" + +/** + * Handle Price Indexing for all registered tokens on a supported chain + */ +export const handlePriceIndexing = wrap(async (event: SubstrateBlock): Promise => { + try { + const chain = getHostStateMachine(chainId) + + const { + block: { + header: { hash }, + }, + } = event + + const blockHash = hash.toHex() + const timestamp = await getBlockTimestamp(blockHash, chain) + + logger.info(`[handlePriceIndexing] Updating prices ${timestamp} via ${chain}`) + + await TokenPriceService.initializePriceIndexing(timestamp) + + logger.info(`Price update completed for chain: ${chain}`) + } catch (error) { + // @ts-ignore + logger.error(`[handlePriceIndexing] failed ${error.message}`) + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleAssetTeleportedEvent.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleAssetTeleportedEvent.handler.ts new file mode 100644 index 00000000..de1d6965 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleAssetTeleportedEvent.handler.ts @@ -0,0 +1,60 @@ +import { SubstrateEvent } from "@subql/types" +import { formatChain, getHostStateMachine } from "@/utils/substrate.helpers" +import { AssetTeleportedService } from "@/services/assetTeleported.service" +import { decodeAddress } from "@polkadot/util-crypto" +import { u8aToHex } from "@polkadot/util" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" + +export const handleSubstrateAssetTeleportedEvent = wrap(async (event: SubstrateEvent): Promise => { + logger.info(`Saw XcmGateway.AssetTeleported Event on ${getHostStateMachine(chainId)}`) + + if (!event.event.data) return + + const [from, to, amount, dest, commitment, message_id] = event.event.data + + // Convert the SS58 address to hex format + let fromHex: string + try { + // Decode SS58 address to get the public key as Uint8Array + const publicKey = decodeAddress(from.toString()) + // Convert the public key to hex format with 0x prefix + fromHex = u8aToHex(publicKey) + + logger.info(`Decoded SS58 address ${from.toString()} to hex ${fromHex}`) + } catch (error) { + logger.error(`Failed to decode SS58 address ${from.toString()}: ${error}`) + // Fall back to the original address if decoding fails + fromHex = from.toString() + } + + logger.info( + `Handling AssetTeleported Event: ${stringify({ + from: fromHex, + to: to.toString(), + amount: amount.toString(), + dest: dest.toString(), + commitment: commitment.toString(), + message_id: message_id.toString(), + })}`, + ) + + const destId = formatChain(dest.toString()) + const host = getHostStateMachine(chainId) + + const blockTimestamp = await getBlockTimestamp(event.block.block.header.hash.toString(), host) + + await AssetTeleportedService.createOrUpdate({ + from: fromHex, + to: to.toString(), + amount: BigInt(amount.toString()), + dest: destId, + commitment: commitment.toString(), + message_id: message_id.toString(), + chain: host, + blockNumber: event.block.block.header.number.toString(), + blockHash: event.block.block.header.hash.toString(), + blockTimestamp, + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleGetRequestHandledEvent.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleGetRequestHandledEvent.handler.ts new file mode 100644 index 00000000..e01a268f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleGetRequestHandledEvent.handler.ts @@ -0,0 +1,63 @@ +import { SubstrateEvent } from "@subql/types" +import { Status } from "@/configs/src/types" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { HyperBridgeService } from "@/services/hyperbridge.service" +import { GetRequestService } from "@/services/getRequest.service" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" + +type EventData = { + commitment: string + relayer: string +} +export const handleSubstrateGetRequestHandledEvent = wrap(async (event: SubstrateEvent): Promise => { + logger.info(`Saw Ismp.GetRequestHandled Event on ${getHostStateMachine(chainId)}`) + + if (!event.extrinsic && event.event.data) return + + const { + extrinsic, + block: { + block: { + header: { number: blockNumber, hash: blockHash }, + }, + }, + } = event + + const eventData = event.event.data[0] as unknown as EventData + const relayer_id = eventData.relayer.toString() + + logger.info( + `Handling ISMP GetRequestHandled Event: ${stringify({ + data: event.event.data, + })}`, + ) + + const host = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(blockHash.toString(), host) + + const request = await GetRequestService.createOrUpdate({ + id: eventData.commitment.toString(), + }) + + let status: Status + if (request.source === host) { + status = Status.DESTINATION + } else { + status = Status.HYPERBRIDGE_DELIVERED + } + + logger.info(`Updating Hyperbridge chain stats for ${host}`) + await HyperBridgeService.handlePostRequestOrResponseHandledEvent(relayer_id, host, blockTimestamp) + + await GetRequestService.updateStatus({ + commitment: eventData.commitment.toString(), + chain: host, + blockNumber: blockNumber.toString(), + blockHash: blockHash.toString(), + blockTimestamp, + status, + transactionHash: extrinsic?.extrinsic.hash.toString() || "", + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleGetRequestTimeoutHandledEvent.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleGetRequestTimeoutHandledEvent.handler.ts new file mode 100644 index 00000000..a61168d2 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleGetRequestTimeoutHandledEvent.handler.ts @@ -0,0 +1,60 @@ +import { SubstrateEvent } from "@subql/types" +import { Status } from "@/configs/src/types" +import { GetRequest } from "@/configs/src/types/models" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { GetRequestService } from "@/services/getRequest.service" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { wrap } from "@/utils/event.utils" + +export const handleSubstrateGetRequestTimeoutHandledEvent = wrap(async (event: SubstrateEvent): Promise => { + logger.info(`Saw Ismp.GetRequestTimeoutHandled Event on ${getHostStateMachine(chainId)}`) + + const host = getHostStateMachine(chainId) + + if (!event.extrinsic) return + + const { + event: { data }, + extrinsic, + block: { + block: { + header: { number: blockNumber, hash: blockHash }, + }, + }, + } = event + + const eventData = data.toJSON() + const timeoutData = Array.isArray(eventData) + ? (eventData[0] as { commitment: any; source: any; dest: any }) + : undefined + + if (!timeoutData) { + logger.error(`Could not parse event data for ${extrinsic.extrinsic.hash.toString()}`) + return + } + + const request = await GetRequest.get(timeoutData.commitment.toString()) + if (!request) { + logger.error(`Get Request not found for commitment ${timeoutData.commitment.toString()}`) + return + } + + let timeoutStatus: Status + if (request.source === host) { + timeoutStatus = Status.TIMED_OUT + } else { + timeoutStatus = Status.HYPERBRIDGE_TIMED_OUT + } + + const blockTimestamp = await getBlockTimestamp(blockHash.toString(), host) + + await GetRequestService.updateStatus({ + commitment: timeoutData.commitment.toString(), + chain: host, + blockNumber: blockNumber.toString(), + blockHash: blockHash.toString(), + blockTimestamp, + status: timeoutStatus, + transactionHash: extrinsic.extrinsic.hash.toString(), + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleIsmpStateMachineUpdatedEvent.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleIsmpStateMachineUpdatedEvent.handler.ts new file mode 100644 index 00000000..dd003c68 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleIsmpStateMachineUpdatedEvent.handler.ts @@ -0,0 +1,158 @@ +import { SubstrateEvent } from "@subql/types" +import { StateMachineService } from "@/services/stateMachine.service" +import { + extractStateMachineIdFromSubstrateEventData, + getHostStateMachine, + StateMachineError, + SubstrateEventValidator, +} from "@/utils/substrate.helpers" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" + +/** + * Extract consensusStateId from event data + * @param event SubstrateEvent containing StateMachineUpdated event data + * @returns consensusStateId string if found, undefined otherwise + */ +export function extractConsensusStateIdFromEvent(event: SubstrateEvent): string | undefined { + try { + const { data } = event.event + + // Validate data structure + if (!Array.isArray(data) || data.length < 1) { + logger.error("Invalid event data structure for extracting consensusStateId") + return undefined + } + + // Extract the first element's JSON representation which contains consensusStateId + const stateData = data[0].toJSON() + + // Ensure stateData is an object with consensusStateId + if (typeof stateData !== "object" || stateData === null || !("consensusStateId" in stateData)) { + logger.error("Missing consensusStateId in event data", { stateData }) + return undefined + } + + let consensusStateId = stateData.consensusStateId + if (typeof consensusStateId !== "string") { + logger.error("Invalid consensusStateId format", { consensusStateId }) + return undefined + } + + // Convert hex to UTF-8 string if it's a hex string + if (consensusStateId.startsWith("0x")) { + try { + // Remove 0x prefix and convert to Buffer + const buffer = Buffer.from(consensusStateId.slice(2), "hex") + // Convert buffer to UTF-8 string + const utf8String = buffer.toString("utf8") + + // Log the conversion for debugging + logger.info(`Converted consensusStateId from hex ${consensusStateId} to UTF-8: ${utf8String}`) + + consensusStateId = utf8String + } catch (hexError) { + logger.error("Error converting hex consensusStateId to UTF-8", { + hexError, + originalConsensusStateId: consensusStateId, + }) + // Return the original hex string if conversion fails + } + } + + // Extract the consensusStateId + return consensusStateId + } catch (error) { + logger.error("Error extracting consensusStateId from event", { error }) + return undefined + } +} + +export const handleIsmpStateMachineUpdatedEvent = wrap(async (event: SubstrateEvent): Promise => { + logger.info(`Saw Ismp.StateMachineUpdated Event on ${getHostStateMachine(chainId)}`) + + const stateMachineId = extractStateMachineIdFromSubstrateEventData(event.event.data.toString()) + const consensusStateId = extractConsensusStateIdFromEvent(event) + + const host = getHostStateMachine(chainId) + + if (typeof stateMachineId === "undefined") { + logger.error("Failed to extract stateMachineId from event data") + return + } + + if (typeof consensusStateId === "undefined") { + logger.error("Failed to extract consensusStateId from event data") + return + } + + try { + if (!SubstrateEventValidator.validateChainMetadata(host, stateMachineId)) { + throw new StateMachineError("Invalid chain metadata", host, event.block.block.header.number.toNumber()) + } + + if (!SubstrateEventValidator.validateStateMachineEvent(event)) { + logger.error(`Invalid state machine event data: ${stringify(event.event)}`) + throw new StateMachineError( + "Invalid state machine event data", + host, + event.block.block.header.number.toNumber(), + ) + } + + logger.info( + `Handling ISMP StateMachineUpdatedEvent. Block Number: ${event.block.block.header.number.toNumber()}`, + ) + + const { method, data } = event.event + + const height = Number(data[1].toString()) + const blockNumber = event.block.block.header.number.toNumber() + const blockHash = event.block.block.header.hash.toString() + const transactionHash = event.extrinsic?.extrinsic?.hash?.toString() || "" + const transactionIndex = event.extrinsic?.idx || 0 + + if (isNaN(height)) { + logger.error(`Invalid height value in event data: ${data[1].toString()}`) + return + } + + const timestamp = await getBlockTimestamp(blockHash, host) + + switch (method) { + case "StateMachineUpdated": + await StateMachineService.createSubstrateStateMachineUpdatedEvent( + { + blockHash, + blockNumber, + transactionHash, + transactionIndex, + timestamp: Number(timestamp), + stateMachineId, + height, + consensusStateId, + }, + host, + ) + break + + default: + throw new StateMachineError( + `Unsupported method: ${method}`, + host, + event.block.block.header.number.toNumber(), + ) + } + } catch (error) { + logger.error("State machine event processing failed", { + error: error instanceof Error ? error.message : "Unknown error", + host, + blockNumber: event.block.block.header.number.toNumber(), + method: event.event.method, + }) + + // Re-throw to maintain indexer state + throw error + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostRequestHandledEvent.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostRequestHandledEvent.handler.ts new file mode 100644 index 00000000..8a86ac15 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostRequestHandledEvent.handler.ts @@ -0,0 +1,75 @@ +import { SubstrateEvent } from "@subql/types" +import { RequestService } from "@/services/request.service" +import { Status } from "@/configs/src/types" +import { getHostStateMachine, isHyperbridge } from "@/utils/substrate.helpers" +import { HyperBridgeService } from "@/services/hyperbridge.service" +import { Request } from "@/configs/src/types/models" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { stringify } from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" + +type EventData = { + commitment: string + relayer: string +} +export const handleSubstratePostRequestHandledEvent = wrap(async (event: SubstrateEvent): Promise => { + logger.info(`Saw Ismp.PostRequestHandled Event on ${getHostStateMachine(chainId)}`) + + if (!event.extrinsic && event.event.data) return + + const { + extrinsic, + block: { + block: { + header: { number: blockNumber, hash: blockHash }, + }, + }, + } = event + + const eventData = event.event.data[0] as unknown as EventData + const relayer_id = eventData.relayer.toString() + + logger.info(`Handling ISMP PostRequestHandled Event Data: ${stringify({ eventData })}`) + + const host = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(blockHash.toString(), host) + + const request = await Request.get(eventData.commitment.toString()) + + if (!request) { + logger.error(`Request not found for commitment ${eventData.commitment.toString()}`) + return + } + + let status: Status + if (request.dest === host) { + status = Status.DESTINATION + } else { + status = Status.HYPERBRIDGE_DELIVERED + } + + logger.info(`Updating Hyperbridge chain stats for ${host}`) + await HyperBridgeService.handlePostRequestOrResponseHandledEvent(relayer_id, host, blockTimestamp) + + logger.info( + `Handling ISMP PostRequestHandled Event: ${stringify({ + commitment: eventData.commitment.toString(), + chain: host, + blockNumber: blockNumber, + blockHash: blockHash, + blockTimestamp, + status, + transactionHash: extrinsic?.extrinsic.hash || "", + })}`, + ) + + await RequestService.updateStatus({ + commitment: eventData.commitment.toString(), + chain: host, + blockNumber: blockNumber.toString(), + blockHash: blockHash.toString(), + blockTimestamp, + status, + transactionHash: extrinsic?.extrinsic.hash.toString() || "", + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostRequestTimeoutHandledEvent.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostRequestTimeoutHandledEvent.handler.ts new file mode 100644 index 00000000..c9f5fa54 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostRequestTimeoutHandledEvent.handler.ts @@ -0,0 +1,59 @@ +import { SubstrateEvent } from "@subql/types" +import { RequestService } from "@/services/request.service" +import { Status } from "@/configs/src/types" +import { Request } from "@/configs/src/types/models" +import { getHostStateMachine, isHyperbridge } from "@/utils/substrate.helpers" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { wrap } from "@/utils/event.utils" + +export const handleSubstratePostRequestTimeoutHandledEvent = wrap(async (event: SubstrateEvent): Promise => { + logger.info(`Saw Ismp.PostRequestTimeoutHandled Event on ${getHostStateMachine(chainId)}`) + + if (!event.extrinsic) return + + const { + event: { data }, + extrinsic, + block: { + block: { + header: { number: blockNumber, hash: blockHash }, + }, + }, + } = event + + const host = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(blockHash.toString(), host) + + const eventData = data.toJSON() + const timeoutData = Array.isArray(eventData) + ? (eventData[0] as { commitment: any; source: any; dest: any }) + : undefined + + if (!timeoutData) { + logger.error(`Could not parse event data for ${extrinsic.extrinsic.hash.toString()}`) + return + } + + const request = await Request.get(timeoutData.commitment.toString()) + if (!request) { + logger.error(`Request not found for commitment ${timeoutData.commitment.toString()}`) + return + } + + let timeoutStatus: Status + if (request.source === host) { + timeoutStatus = Status.TIMED_OUT + } else { + timeoutStatus = Status.HYPERBRIDGE_TIMED_OUT + } + + await RequestService.updateStatus({ + commitment: timeoutData.commitment.toString(), + chain: host, + blockNumber: blockNumber.toString(), + blockHash: blockHash.toString(), + blockTimestamp, + status: timeoutStatus, + transactionHash: extrinsic.extrinsic.hash.toString(), + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostResponseHandledEvent.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostResponseHandledEvent.handler.ts new file mode 100644 index 00000000..187c36d0 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostResponseHandledEvent.handler.ts @@ -0,0 +1,77 @@ +import { SubstrateEvent } from "@subql/types" +import { ResponseService } from "@/services/response.service" +import { Status } from "@/configs/src/types" +import { getHostStateMachine, isHyperbridge } from "@/utils/substrate.helpers" +import { HyperBridgeService } from "@/services/hyperbridge.service" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" + +type EventData = { + commitment: string + relayer: string +} + +export const handleSubstratePostResponseHandledEvent = wrap(async (event: SubstrateEvent): Promise => { + logger.info(`Saw Ismp.PostResponseHandled Event on ${getHostStateMachine(chainId)}`) + + if (!event.extrinsic && event.event.data) return + + const { + event: { + data: [dest_chain, source_chain, request_nonce, commitment, response_commitment], + }, + extrinsic, + block: { + timestamp, + block: { + header: { number: blockNumber, hash: blockHash }, + }, + }, + } = event + + const eventData = event.event.data[0] as unknown as EventData + const relayer_id = eventData.relayer.toString() + + logger.info( + `Handling ISMP PostRequestHandled Event: ${stringify({ + data: event.event.data, + })}`, + ) + + const host = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(blockHash.toString(), host) + + let status: Status + + // todo: actually check if host is hyperbridge and response source is hyperbridge + if (isHyperbridge(host)) { + status = Status.HYPERBRIDGE_DELIVERED + } else { + status = Status.DESTINATION + } + + logger.info(`Updating Hyperbridge chain stats for ${host}`) + await HyperBridgeService.handlePostRequestOrResponseHandledEvent(relayer_id, host, blockTimestamp) + + logger.info( + `Handling ISMP PostRequestHandled Event: ${stringify({ + commitment: response_commitment.toString(), + chain: host, + blockNumber: blockNumber, + blockHash: blockHash, + blockTimestamp, + status, + transactionHash: extrinsic?.extrinsic.hash || "", + })}`, + ) + await ResponseService.updateStatus({ + commitment: response_commitment.toString(), + chain: host, + blockNumber: blockNumber.toString(), + blockHash: blockHash.toString(), + blockTimestamp, + status, + transactionHash: extrinsic?.extrinsic.hash.toString() || "", + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostResponseTimeoutHandledEvent.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostResponseTimeoutHandledEvent.handler.ts new file mode 100644 index 00000000..41caa46c --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handlePostResponseTimeoutHandledEvent.handler.ts @@ -0,0 +1,45 @@ +import { SubstrateEvent } from "@subql/types" + +import { ResponseService } from "@/services/response.service" +import { Status } from "@/configs/src/types" +import { getHostStateMachine, isHyperbridge } from "@/utils/substrate.helpers" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { wrap } from "@/utils/event.utils" + +export const handleSubstratePostResponseTimeoutHandledEvent = wrap(async (event: SubstrateEvent): Promise => { + logger.info(`Saw Ismp.PostResponseTimeoutHandled Event on ${getHostStateMachine(chainId)}`) + + if (!event.extrinsic && event.event.data) return + + const { + event: { data }, + extrinsic, + block: { + block: { + header: { number: blockNumber, hash: blockHash }, + }, + }, + } = event + + const host = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(blockHash.toString(), host) + + const timeoutStatus = isHyperbridge(host) ? Status.HYPERBRIDGE_TIMED_OUT : Status.TIMED_OUT + + const eventData = data.toJSON() + const timeoutData = Array.isArray(eventData) + ? (eventData[0] as { commitment: any; source: any; dest: any }) + : undefined + + if (!timeoutData) return + + await ResponseService.updateStatus({ + commitment: timeoutData.commitment.toString(), + chain: host, + blockNumber: blockNumber.toString(), + blockHash: blockHash.toString(), + blockTimestamp, + status: timeoutStatus, + transactionHash: extrinsic!.extrinsic.hash.toString(), + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleRequestEvent.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleRequestEvent.handler.ts new file mode 100644 index 00000000..af947658 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleRequestEvent.handler.ts @@ -0,0 +1,141 @@ +import { SubstrateEvent } from "@subql/types" +import fetch from "node-fetch" +import { bytesToHex, hexToBytes, toHex } from "viem" + +import { RequestService } from "@/services/request.service" +import { RequestStatusMetadata, Status } from "@/configs/src/types" +import { formatChain, getHostStateMachine, isHyperbridge, isSubstrateChain } from "@/utils/substrate.helpers" +import { ENV_CONFIG } from "@/constants" +import { RequestMetadata } from "@/utils/state-machine.helper" +import { getBlockTimestamp, replaceWebsocketWithHttp } from "@/utils/rpc.helpers" +import { timestampToDate } from "@/utils/date.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" + +export const handleSubstrateRequestEvent = wrap(async (event: SubstrateEvent): Promise => { + logger.info(`Saw Ismp.Request Event on ${getHostStateMachine(chainId)}`) + + if (!event.event.data) return + + const [dest_chain, source_chain, request_nonce, commitment] = event.event.data + + const sourceId = formatChain(source_chain.toString()) + const destId = formatChain(dest_chain.toString()) + const hostId = getHostStateMachine(chainId) + + logger.info( + `Handling ISMP Request Event: ${stringify({ + sourceId, + destId, + request_nonce, + commitment, + })}`, + ) + + if (!isSubstrateChain(sourceId) || (!isHyperbridge(sourceId) && isHyperbridge(hostId))) { + logger.error(`Skipping hyperbridge aggregated request`) + return + } + + if (!ENV_CONFIG[sourceId]) { + logger.error(`No WS URL found for chain ${sourceId}`) + return + } + + const method = { + id: 1, + jsonrpc: "2.0", + method: "ismp_queryRequests", + params: [[{ commitment: commitment.toString() }]], + } + + const response = await fetch(replaceWebsocketWithHttp(ENV_CONFIG[sourceId]), { + method: "POST", + headers: { + accept: "application/json", + "content-type": "application/json", + }, + body: stringify(method), + }) + const data = await response.json() + + if (data.result.length === 0) { + logger.error(`No requests found for commitment ${commitment.toString()}`) + return + } + + // todo: support GET requests + const postRequest = data.result[0].Post + + if (!postRequest) { + logger.error(`Request not found for commitment ${commitment.toString()}`) + return + } + + const { body, from, to, nonce, timeoutTimestamp } = postRequest + const prefix = toHex(":child_storage:default:ISMP") + const key = bytesToHex( + new Uint8Array([ + ...new TextEncoder().encode("RequestCommitments"), + ...hexToBytes(commitment.toString() as any), + ]), + ) + + const metadataResponse = await fetch(replaceWebsocketWithHttp(ENV_CONFIG[sourceId]), { + method: "POST", + headers: { + accept: "application/json", + "content-type": "application/json", + }, + body: stringify({ + id: 1, + jsonrpc: "2.0", + method: "childstate_getStorage", + params: [prefix, key], + }), + }) + const storageValue = (await metadataResponse.json()).result as `0x${string}` | undefined + + let fee = BigInt(0) + if (typeof storageValue === "string") { + const metadata = RequestMetadata.dec(hexToBytes(storageValue)) + fee = BigInt(Number(metadata.fee.fee)) + } + + const host = getHostStateMachine(chainId) + const blockTimestamp = await getBlockTimestamp(event.block.block.header.hash.toString(), host) + + await RequestService.createOrUpdate({ + chain: host, + commitment: commitment.toString(), + body, + dest: destId, + fee, + from, + nonce: BigInt(nonce), + source: sourceId, + timeoutTimestamp: BigInt(Number(timeoutTimestamp)), + to, + status: Status.SOURCE, + blockNumber: event.block.block.header.number.toString(), + blockHash: event.block.block.header.hash.toString(), + transactionHash: event.extrinsic?.extrinsic.hash.toString() || "", + blockTimestamp: BigInt(blockTimestamp), + createdAt: timestampToDate(blockTimestamp), + }) + + // Always create a new status metadata entry + let requestStatusMetadata = RequestStatusMetadata.create({ + id: `${commitment.toHex()}.${Status.SOURCE}`, + requestId: commitment.toHex(), + status: Status.SOURCE, + chain: host, + timestamp: BigInt(blockTimestamp), + blockNumber: event.block.block.header.number.toString(), + blockHash: event.block.block.header.hash.toString(), + transactionHash: event.extrinsic?.extrinsic.hash.toString() || "", + createdAt: timestampToDate(blockTimestamp), + }) + + await requestStatusMetadata.save() +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleResponseEvent.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleResponseEvent.handler.ts new file mode 100644 index 00000000..4d4a8613 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/substrateChains/handleResponseEvent.handler.ts @@ -0,0 +1,76 @@ +import { SubstrateEvent } from "@subql/types" +import fetch from "node-fetch" +import { formatChain, getHostStateMachine } from "@/utils/substrate.helpers" +import { ENV_CONFIG } from "@/constants" +import { Get } from "@/utils/substrate.helpers" +import { GetResponseService } from "@/services/getResponse.service" +import { Status } from "@/configs/src/types" +import { getBlockTimestamp, replaceWebsocketWithHttp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { wrap } from "@/utils/event.utils" + +export const handleSubstrateResponseEvent = wrap(async (event: SubstrateEvent): Promise => { + const host = getHostStateMachine(chainId) + logger.info(`Saw Ismp.Response Event on ${host}`) + + if (!event.event.data) return + + const [dest_chain, source_chain, request_nonce, commitment, req_commitment] = event.event.data + + const sourceId = formatChain(source_chain.toString()) + const destId = formatChain(dest_chain.toString()) + + const blockTimestamp = await getBlockTimestamp(event.block.block.header.hash.toString(), host) + + logger.info( + `Handling ISMP Response Event: ${stringify({ + sourceId, + destId, + request_nonce, + commitment, + req_commitment, + })}`, + ) + + const method = { + id: 1, + jsonrpc: "2.0", + method: "ismp_queryResponses", + params: [[{ commitment: commitment.toString() }]], + } + + const response = await fetch(replaceWebsocketWithHttp(ENV_CONFIG[host]), { + method: "POST", + headers: { + accept: "application/json", + "content-type": "application/json", + }, + body: stringify(method), + }) + const data = await response.json() + + logger.info(`Response from calling ismp_queryResponses: ${stringify(data)}`) + + if (data.result.length === 0) { + logger.error(`No responses found for commitment ${commitment.toString()}`) + return + } + + // Only handling get response here as we not using post response anywhere. + if (data.result[0].Get) { + const getResponse = data.result[0].Get as Get + + await GetResponseService.findOrCreate({ + chain: host, + commitment: commitment.toString(), + request: req_commitment.toString(), + response_message: getResponse.values.map((value) => value.value), + responseTimeoutTimestamp: BigInt(Number(getResponse.get.timeoutTimestamp)), + status: Status.SOURCE, + blockNumber: event.block.block.header.number.toString(), + blockHash: event.block.block.header.hash.toString(), + transactionHash: event.extrinsic?.extrinsic.hash.toString() || "", + blockTimestamp, + }) + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/supply/handleBridgeTokenSupplyIndexing.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/supply/handleBridgeTokenSupplyIndexing.event.handler.ts new file mode 100644 index 00000000..863fb7cf --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/supply/handleBridgeTokenSupplyIndexing.event.handler.ts @@ -0,0 +1,32 @@ +import { SubstrateBlock } from "@subql/types" +import { wrap } from "@/utils/event.utils" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { BridgeTokenSupplyService } from "@/services/bridgeTokenSupply.service" + +/** + * Handle Bridge Token Supply Indexing for Hyperbridge token + */ +export const handleBridgeTokenSupplyIndexing = wrap(async (event: SubstrateBlock): Promise => { + try { + const chain = getHostStateMachine(chainId) + + const { + block: { + header: { hash }, + }, + } = event + + const blockHash = hash.toHex() + const timestamp = await getBlockTimestamp(blockHash, chain) + + logger.info(`[handleBridgeTokenSupplyIndexing] Updating bridge token supply ${timestamp} via ${chain}`) + + await BridgeTokenSupplyService.updateTokenSupply(timestamp) + + logger.info(`Bridge token supply update completed for chain: ${chain}`) + } catch (error) { + // @ts-ignore + logger.error(`[handleBridgeTokenSupplyIndexing] failed ${error.message}`) + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/tokenGateway/assetReceived.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/tokenGateway/assetReceived.event.handler.ts new file mode 100644 index 00000000..ba359609 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/tokenGateway/assetReceived.event.handler.ts @@ -0,0 +1,34 @@ +import stringify from "safe-stable-stringify" + +import { TeleportStatus } from "@/configs/src/types" +import { AssetReceivedLog } from "@/configs/src/types/abi-interfaces/TokenGatewayAbi" +import { TokenGatewayService } from "@/services/tokenGateway.service" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { wrap } from "@/utils/event.utils" + +export const handleAssetReceivedEvent = wrap(async (event: AssetReceivedLog): Promise => { + logger.info(`Asset Received Event: ${stringify(event)}`) + + const { blockNumber, transactionHash, args, blockHash } = event + const { amount, commitment, from, beneficiary, assetId } = args! + + const chain = getHostStateMachine(chainId) + const timestamp = await getBlockTimestamp(blockHash, chain) + + logger.info( + `Asset Received Event: ${stringify({ + amount, + commitment, + from, + beneficiary, + assetId, + })}`, + ) + + await TokenGatewayService.updateTeleportStatus(commitment, TeleportStatus.RECEIVED, { + transactionHash, + blockNumber, + timestamp, + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/tokenGateway/assetRefunded.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/tokenGateway/assetRefunded.event.handler.ts new file mode 100644 index 00000000..1567a120 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/tokenGateway/assetRefunded.event.handler.ts @@ -0,0 +1,32 @@ +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { AssetRefundedLog } from "@/configs/src/types/abi-interfaces/TokenGatewayAbi" +import { TokenGatewayService } from "@/services/tokenGateway.service" +import { TeleportStatus } from "@/configs/src/types" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { wrap } from "@/utils/event.utils" + +export const handleAssetRefundedEvent = wrap(async (event: AssetRefundedLog): Promise => { + logger.info(`Asset Refunded Event: ${stringify(event)}`) + + const { blockNumber, transactionHash, args, blockHash } = event + const { amount, commitment, beneficiary, assetId } = args! + + const chain = getHostStateMachine(chainId) + const timestamp = await getBlockTimestamp(blockHash, chain) + + logger.info( + `Asset Refunded Event: ${stringify({ + amount, + commitment, + beneficiary, + assetId, + })}`, + ) + + await TokenGatewayService.updateTeleportStatus(commitment, TeleportStatus.REFUNDED, { + transactionHash, + blockNumber, + timestamp, + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/tokenGateway/assetTeleported.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/tokenGateway/assetTeleported.event.handler.ts new file mode 100644 index 00000000..f7d9d10d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/tokenGateway/assetTeleported.event.handler.ts @@ -0,0 +1,54 @@ +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { AssetTeleportedLog } from "@/configs/src/types/abi-interfaces/TokenGatewayAbi" +import { TokenGatewayService } from "@/services/tokenGateway.service" +import { TeleportStatus } from "@/configs/src/types" +import { getHostStateMachine, isSubstrateChain } from "@/utils/substrate.helpers" +import { wrap } from "@/utils/event.utils" +import { TokenPriceService } from "@/services/token-price.service" +import PriceHelper from "@/utils/price.helpers" + +export const handleAssetTeleportedEvent = wrap(async (event: AssetTeleportedLog): Promise => { + logger.info(`Asset Teleported Event: ${stringify(event)}`) + + const { blockNumber, transactionHash, args, block, blockHash } = event + const { to, dest, amount, commitment, from, assetId, redeem } = args! + + const chain = getHostStateMachine(chainId) + const timestamp = await getBlockTimestamp(blockHash, chain) + + logger.info( + `Asset Teleported Event: ${stringify({ + to, + dest, + amount, + commitment, + from, + assetId, + redeem, + })}`, + ) + + await TokenGatewayService.getOrCreate( + { + to, + dest, + amount: amount.toBigInt(), + commitment, + from, + assetId, + redeem, + }, + { + transactionHash, + blockNumber, + timestamp, + }, + ) + + await TokenGatewayService.updateTeleportStatus(commitment, TeleportStatus.TELEPORTED, { + transactionHash, + blockNumber, + timestamp, + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/treasury/treasuryTransfer.event.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/treasury/treasuryTransfer.event.handler.ts new file mode 100644 index 00000000..df0559f2 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/events/treasury/treasuryTransfer.event.handler.ts @@ -0,0 +1,53 @@ +import { SubstrateEvent } from "@subql/types" +import { Treasury } from "@/configs/src/types" +import { wrap } from "@/utils/event.utils" +import { Balance } from "@polkadot/types/interfaces" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { timestampToDate } from "@/utils/date.helpers" +import { DailyTreasuryRewardService, TREASURY_ADDRESS } from "@/services/dailyTreasuryReward.service" + +export const handleTreasuryTransferEvent = wrap(async (event: SubstrateEvent): Promise => { + try { + const { + event: { data }, + block, + } = event + + const fromAddress = data[0].toString() + const toAddress = data[1].toString() + + if (fromAddress !== TREASURY_ADDRESS && toAddress !== TREASURY_ADDRESS) { + return + } + + const amount = (data[2] as unknown as Balance).toBigInt() + + let treasury = await Treasury.get(TREASURY_ADDRESS) + if (!treasury) { + treasury = Treasury.create({ + id: TREASURY_ADDRESS, + totalAmountTransferredIn: BigInt(0), + totalAmountTransferredOut: BigInt(0), + totalBalance: BigInt(0), + lastUpdatedAt: new Date(block.timestamp!), + }) + } + + if (fromAddress === TREASURY_ADDRESS) { + treasury.totalAmountTransferredOut += amount + } else { + treasury.totalAmountTransferredIn += amount + } + + treasury.totalBalance = await DailyTreasuryRewardService.getTreasuryBalance() + const hyperbridgeChain = getHostStateMachine(chainId) + const timestamp = await getBlockTimestamp(event.block.block.header.hash.toString(), hyperbridgeChain) + treasury.lastUpdatedAt = timestampToDate(timestamp) + + await treasury.save() + } catch (e) { + const errorMessage = e instanceof Error ? e.message : String(e) + logger.error(`Failed to handle treasury transfer event: ${errorMessage}`) + } +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/transactions/handlerV1/handlePostRequestTransactionHandler.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/transactions/handlerV1/handlePostRequestTransactionHandler.handler.ts new file mode 100644 index 00000000..e60a0e7c --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/transactions/handlerV1/handlePostRequestTransactionHandler.handler.ts @@ -0,0 +1,45 @@ +// import { CHAINS_BY_ISMP_HOST } from "@/constants" +// import { HyperBridgeService } from "@/services/hyperbridge.service" +// import { RelayerService } from "@/services/relayer.service" +// import { HandlePostRequestsTransaction } from "@/configs/src/types/abi-interfaces/HandlerV1Abi" +// import { getHostStateMachine } from "@/utils/substrate.helpers" + +// /** +// * Handles the handlePostRequest transaction from handlerV1 contract +// */ +// export async function handlePostRequestTransactionHandler(transaction: HandlePostRequestsTransaction): Promise { +// if (!transaction.args) { +// logger.info("Not handling post request transaction - args is empty") +// return +// } + +// const chain: string = getHostStateMachine(chainId) +// logger.info(`Chain: ${chain}`) + +// const expectedHostAddress = CHAINS_BY_ISMP_HOST[chain] +// const incomimgHostAddress = transaction.args![0] + +// if (incomimgHostAddress !== expectedHostAddress) { +// logger.info( +// `Skipping transaction - host address mismatch for chain ${chain}. Host address: ${incomimgHostAddress}, expected host address: ${expectedHostAddress}`, +// ) +// return +// } + +// const { blockNumber, hash } = transaction + +// logger.info( +// `Handling PostRequests Transaction: ${JSON.stringify({ +// blockNumber, +// transactionHash: hash, +// })}`, +// ) + +// try { +// await RelayerService.handlePostRequestOrResponseTransaction(chain, transaction) + +// await HyperBridgeService.handlePostRequestOrResponseTransaction(chain, transaction) +// } catch (error) { +// logger.error(`Error while handling PostRequest transaction: ${error}`) +// } +// } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/transactions/handlerV1/handlePostResponseTransactionHandler.handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/transactions/handlerV1/handlePostResponseTransactionHandler.handler.ts new file mode 100644 index 00000000..1c505b4f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/handlers/transactions/handlerV1/handlePostResponseTransactionHandler.handler.ts @@ -0,0 +1,48 @@ +// import { CHAINS_BY_ISMP_HOST } from "@/constants" +// import { HyperBridgeService } from "@/services/hyperbridge.service" +// import { RelayerService } from "@/services/relayer.service" +// import { getHostStateMachine } from "@/utils/substrate.helpers" +// import { HandlePostResponsesTransaction } from "@/configs/src/types/abi-interfaces/HandlerV1Abi" + +// /** +// * Handles the handlePostResponse transaction from handlerV1 contract +// */ +// export async function handlePostResponseTransactionHandler(transaction: HandlePostResponsesTransaction): Promise { +// if (!transaction.args) { +// logger.info("Not handling transaction - args is empty") +// return +// } + +// const chain: string = getHostStateMachine(chainId) + +// const expectedHostAddress = CHAINS_BY_ISMP_HOST[chain] +// const incomimgHostAddress = transaction.args![0] + +// if (incomimgHostAddress !== expectedHostAddress) { +// logger.info( +// `Skipping transaction - host address mismatch for chain ${chain}. Hostt address: ${incomimgHostAddress}, expected host address: ${expectedHostAddress}`, +// ) +// return +// } +// const { blockNumber, hash } = transaction + +// logger.info( +// `Handling PostResponse Transaction: ${JSON.stringify({ +// blockNumber, +// transactionHash: hash, +// })}`, +// ) + +// try { +// await RelayerService.handlePostRequestOrResponseTransaction(chain, transaction) +// await HyperBridgeService.handlePostRequestOrResponseTransaction(chain, transaction) +// } catch (error: unknown) { +// logger.error( +// `Error handling PostResponse Transaction: ${JSON.stringify({ +// blockNumber, +// transactionHash: hash, +// error, +// })}`, +// ) +// } +// } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/index.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/index.ts new file mode 100644 index 00000000..016e3628 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/index.ts @@ -0,0 +1,15 @@ +import { URL } from "url" +// @ts-ignore +global.URL = URL + +// Required for ethers to work in node +import "@ethersproject/shims" + +// required for scale-ts +import "fast-text-encoding" + +// @ts-ignore +import { logger } from "@subql/types-core" + +//Exports all handler functions +export * from "@/mappings/mappingHandlers" diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/mappings/mappingHandlers.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/mappings/mappingHandlers.ts new file mode 100644 index 00000000..4cbabb4a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/mappings/mappingHandlers.ts @@ -0,0 +1,52 @@ +// EVM Host Handlers +export { handlePostRequestEvent } from "@/handlers/events/evmHost/postRequest.event.handler" +export { handlePostRequestHandledEvent } from "@/handlers/events/evmHost/postRequestHandled.event.handler" +export { handlePostRequestTimeoutHandledEvent } from "@/handlers/events/evmHost/postRequestTimeoutHandled.event.handler" + +export { handlePostResponseEvent } from "@/handlers/events/evmHost/postResponse.event.handler" +export { handlePostResponseHandledEvent } from "@/handlers/events/evmHost/postResponseHandled.event.handler" +export { handlePostResponseTimeoutHandledEvent } from "@/handlers/events/evmHost/postResponseTimeoutHandled.event.handler" + +export { handleTransferEvent } from "@/handlers/events/erc6160ext20/transfer.event.handlers" +export { handleStateMachineUpdatedEvent } from "@/handlers/events/evmHost/stateMachineUpdated.event.handler" + +export { handleGetRequestEvent } from "@/handlers/events/evmHost/getRequest.event.handler" +export { handleGetRequestHandledEvent } from "@/handlers/events/evmHost/getRequestHandled.event.handler" +export { handleGetRequestTimeoutHandled } from "@/handlers/events/evmHost/getRequestTimeoutHandled.event.handler" + +// Intent Gateway Handlers +export { handleOrderPlacedEvent } from "@/handlers/events/intentGateway/orderPlaced.event.handler" +export { handleOrderFilledEvent } from "@/handlers/events/intentGateway/orderFilled.event.handler" +export { handleEscrowReleasedEvent } from "@/handlers/events/intentGateway/escrowReleased.event.handler" +export { handleEscrowRefundedEvent } from "@/handlers/events/intentGateway/escrowRefunded.event.handler" + +// Token Gateway Handlers +export { handleAssetTeleportedEvent } from "@/handlers/events/tokenGateway/assetTeleported.event.handler" +export { handleAssetReceivedEvent } from "@/handlers/events/tokenGateway/assetReceived.event.handler" +export { handleAssetRefundedEvent } from "@/handlers/events/tokenGateway/assetRefunded.event.handler" + +// HandlerV1 Handlers +// export { handlePostRequestTransactionHandler } from "@/handlers/transactions/handlerV1/handlePostRequestTransactionHandler.handler" +// export { handlePostResponseTransactionHandler } from "@/handlers/transactions/handlerV1/handlePostResponseTransactionHandler.handler" + +// Substrate Chains Handlers +export { handleIsmpStateMachineUpdatedEvent } from "@/handlers/events/substrateChains/handleIsmpStateMachineUpdatedEvent.handler" +export { handleSubstratePostRequestTimeoutHandledEvent } from "@/handlers/events/substrateChains/handlePostRequestTimeoutHandledEvent.handler" +export { handleSubstratePostResponseTimeoutHandledEvent } from "@/handlers/events/substrateChains/handlePostResponseTimeoutHandledEvent.handler" +export { handleSubstrateRequestEvent } from "@/handlers/events/substrateChains/handleRequestEvent.handler" +export { handleSubstrateResponseEvent } from "@/handlers/events/substrateChains/handleResponseEvent.handler" +export { handleSubstratePostRequestHandledEvent } from "@/handlers/events/substrateChains/handlePostRequestHandledEvent.handler" +export { handleSubstratePostResponseHandledEvent } from "@/handlers/events/substrateChains/handlePostResponseHandledEvent.handler" +export { handleSubstrateAssetTeleportedEvent } from "@/handlers/events/substrateChains/handleAssetTeleportedEvent.handler" +export { handleSubstrateGetRequestHandledEvent } from "@/handlers/events/substrateChains/handleGetRequestHandledEvent.handler" +export { handleSubstrateGetRequestTimeoutHandledEvent } from "@/handlers/events/substrateChains/handleGetRequestTimeoutHandledEvent.handler" + +// Price Handlers +export { handlePriceIndexing } from "@/handlers/events/price/handlePriceIndexing.event.handler" +export { handleBridgeTokenSupplyIndexing } from "@/handlers/events/supply/handleBridgeTokenSupplyIndexing.event.handler" + +export { handleRelayerRewardedEvent } from "@/handlers/events/incentives/relayerRewarded.event.handler" +export { handleFeeRewardedEvent } from "@/handlers/events/incentives/feeRewarded.event.handler" + +export { handleTreasuryTransferEvent } from "@/handlers/events/treasury/treasuryTransfer.event.handler" +export { handleAccumulateFeesEvent } from "@/handlers/events/fees/accumulatedFees.event.handler" diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/__tests__/bridgeTokenSupply.service.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/__tests__/bridgeTokenSupply.service.test.ts new file mode 100644 index 00000000..e6d38675 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/__tests__/bridgeTokenSupply.service.test.ts @@ -0,0 +1,108 @@ +import { BridgeTokenSupplyService } from "../bridgeTokenSupply.service" +import { replaceWebsocketWithHttp } from "@/utils/rpc.helpers" + +// Mock the logger to avoid console output during tests +;(global as any).logger = { + debug: jest.fn(), + info: jest.fn(), + warn: jest.fn(), + error: jest.fn(), +} + +// Mock chainId global +;(global as any).chainId = "0x1234567890abcdef" + +describe("BridgeTokenSupplyService", () => { + const TEST_RPC_URL = "wss://nexus.ibp.network" + const HTTP_RPC_URL = replaceWebsocketWithHttp(TEST_RPC_URL) + + describe("getCirculatingSupply", () => { + it("should successfully calculate circulating supply from live network", async () => { + // This test connects to the live network, so it might be slow + // and could fail if the network is unavailable + const result = await BridgeTokenSupplyService["getCirculatingSupply"](HTTP_RPC_URL) + + // Verify the result is not an error + expect(result).not.toBeInstanceOf(Error) + + // Verify the result is a valid BigInt + expect(typeof result).toBe("bigint") + expect(result).toBeGreaterThanOrEqual(BigInt(0)) + + console.log(`Circulating supply: ${result}`) + }, 30000) // 30 second timeout for network calls + + it("should successfully get total supply from live network", async () => { + const result = await BridgeTokenSupplyService["getTotalSupply"](HTTP_RPC_URL) + + // Verify the result is not an error + expect(result).not.toBeInstanceOf(Error) + + // Verify the result is a valid BigInt + expect(typeof result).toBe("bigint") + expect(result).toBeGreaterThan(BigInt(0)) + + console.log(`Total supply: ${result}`) + }, 15000) // 15 second timeout + + it("should successfully get inactive issuance from live network", async () => { + const result = await BridgeTokenSupplyService["getInactiveIssuance"](HTTP_RPC_URL) + + // Verify the result is not an error + expect(result).not.toBeInstanceOf(Error) + + // Verify the result is a valid BigInt + expect(typeof result).toBe("bigint") + expect(result).toBeGreaterThanOrEqual(BigInt(0)) + + console.log(`Inactive issuance: ${result}`) + }, 15000) // 15 second timeout + + it("should successfully get team and foundation balance", async () => { + const result = await BridgeTokenSupplyService["getTeamAndFoundationBalance"](HTTP_RPC_URL) + + // Verify the result is not an error + expect(result).not.toBeInstanceOf(Error) + + // Verify the result is a valid BigInt + expect(typeof result).toBe("bigint") + expect(result).toBeGreaterThan(BigInt(0)) + + console.log(`Team and Foundation Balance: ${result}`) + }, 15000) // 15 second timeout + + it("should successfully get total account locks from live network", async () => { + const result = await BridgeTokenSupplyService["getTotalAccountLocks"](HTTP_RPC_URL) + + // Verify the result is not an error + expect(result).not.toBeInstanceOf(Error) + + // Verify the result is a valid BigInt + expect(typeof result).toBe("bigint") + expect(result).toBeGreaterThanOrEqual(BigInt(0)) + + console.log(`Total account locks: ${result}`) + }, 45000) // 45 second timeout for potentially many RPC calls + + it("should have circulating supply less than or equal to total supply", async () => { + // Get both values + const totalSupply = await BridgeTokenSupplyService["getTotalSupply"](HTTP_RPC_URL) + const circulatingSupply = await BridgeTokenSupplyService["getCirculatingSupply"](HTTP_RPC_URL) + + // Verify neither is an error + expect(totalSupply).not.toBeInstanceOf(Error) + expect(circulatingSupply).not.toBeInstanceOf(Error) + + // Type assertions for proper type checking + const totalSupplyBigInt = totalSupply as bigint + const circulatingSupplyBigInt = circulatingSupply as bigint + + // Verify circulating supply is not greater than total supply + expect(circulatingSupplyBigInt).toBeLessThanOrEqual(totalSupplyBigInt) + + console.log(`Total supply: ${totalSupplyBigInt}`) + console.log(`Circulating supply: ${circulatingSupplyBigInt}`) + console.log(`Locked/Inactive: ${totalSupplyBigInt - circulatingSupplyBigInt}`) + }, 45000) // 45 second timeout + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/__tests__/volume.service.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/__tests__/volume.service.test.ts new file mode 100644 index 00000000..a12abdf9 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/__tests__/volume.service.test.ts @@ -0,0 +1,309 @@ +import Decimal from "decimal.js" + +import { CumulativeVolumeUSD, DailyVolumeUSD } from "@/configs/src/types" +import { timestampToDate } from "@/utils/date.helpers" + +import { VolumeService } from "../volume.service" + +const mockStore = new Map() + +// Mock the global store +;(global as any).store = { + get: jest.fn().mockImplementation((entityName: string, id: string) => { + const key = `${entityName}:${id}` + return Promise.resolve(mockStore.get(key)) + }), + set: jest.fn().mockImplementation((entityName: string, id: string, entity: any) => { + const key = `${entityName}:${id}` + mockStore.set(key, entity) + return Promise.resolve() + }), + remove: jest.fn().mockImplementation((entityName: string, id: string) => { + const key = `${entityName}:${id}` + mockStore.delete(key) + return Promise.resolve() + }), +} + +// Mock the model classes +jest.mock("@/configs/src/types", () => ({ + CumulativeVolumeUSD: { + get: jest.fn().mockImplementation((id: string) => { + const key = `CumulativeVolumeUSD:${id}` + const data = mockStore.get(key) + if (data) { + return Promise.resolve({ + id: data.id, + volumeUSD: data.volumeUSD, + lastUpdatedAt: data.lastUpdatedAt, + save: jest.fn().mockImplementation(function (this: any) { + const key = `CumulativeVolumeUSD:${this.id}` + mockStore.set(key, this) + return Promise.resolve() + }), + }) + } + return Promise.resolve(undefined) + }), + create: jest.fn().mockImplementation((data: any) => { + const entity = { + id: data.id, + volumeUSD: data.volumeUSD, + lastUpdatedAt: data.lastUpdatedAt, + save: jest.fn().mockImplementation(function (this: any) { + const key = `CumulativeVolumeUSD:${this.id}` + mockStore.set(key, this) + return Promise.resolve() + }), + } + return entity + }), + }, + DailyVolumeUSD: { + get: jest.fn().mockImplementation((id: string) => { + const key = `DailyVolumeUSD:${id}` + const data = mockStore.get(key) + if (data) { + return Promise.resolve({ + id: data.id, + last24HoursVolumeUSD: data.last24HoursVolumeUSD, + lastUpdatedAt: data.lastUpdatedAt, + createdAt: data.createdAt, + save: jest.fn().mockImplementation(function (this: any) { + const key = `DailyVolumeUSD:${this.id}` + mockStore.set(key, this) + return Promise.resolve() + }), + }) + } + return Promise.resolve(undefined) + }), + create: jest.fn().mockImplementation((data: any) => { + const entity = { + id: data.id, + last24HoursVolumeUSD: data.last24HoursVolumeUSD, + lastUpdatedAt: data.lastUpdatedAt, + createdAt: data.createdAt, + save: jest.fn().mockImplementation(function (this: any) { + const key = `DailyVolumeUSD:${this.id}` + mockStore.set(key, this) + return Promise.resolve() + }), + } + return entity + }), + }, +})) + +describe("VolumeService", () => { + beforeAll(() => { + ;(global as any).chainId = "97" + }) + + beforeEach(() => { + // Clear the mock store before each test + mockStore.clear() + jest.clearAllMocks() + }) + + afterAll(() => { + mockStore.clear() + jest.clearAllMocks() + }) + + describe("updateCumulativeVolume", () => { + it("should create a new cumulative volume record when none exists", async () => { + const id = "TokenGateway" + const volume = "1000.50" + const timestamp = BigInt(1700000000) + + await VolumeService.updateCumulativeVolume(id, volume, timestamp) + + expect(CumulativeVolumeUSD.get).toHaveBeenCalledWith(VolumeService.getChainTypeId(id)) + expect(CumulativeVolumeUSD.create).toHaveBeenCalledWith({ + id: VolumeService.getChainTypeId(id), + volumeUSD: new Decimal(volume).toFixed(18), + lastUpdatedAt: timestamp, + }) + }) + + it("should update existing cumulative volume record", async () => { + const id = "TokenGateway" + const volume = "500.25" + const additionalVolume = "200.75" + const timestamp = BigInt(1700000000) + const updatedTimestamp = BigInt(1700000100) + + await VolumeService.updateCumulativeVolume(id, volume, timestamp) + await VolumeService.updateCumulativeVolume(id, additionalVolume, updatedTimestamp) + + const stored = mockStore.get(`CumulativeVolumeUSD:${VolumeService.getChainTypeId(id)}`) + expect(stored).toBeDefined() + expect(stored.volumeUSD).toBe("701.000000000000000000") + expect(stored.lastUpdatedAt).toBe(updatedTimestamp) + }) + + it("should handle decimal precision correctly", async () => { + const id = "TokenGateway" + await VolumeService.updateCumulativeVolume(id, "0.123456789012345678", BigInt(1700000000)) + + const stored = mockStore.get(`CumulativeVolumeUSD:${VolumeService.getChainTypeId(id)}`) + expect(stored).toBeDefined() + expect(stored.volumeUSD).toBe("0.123456789012345678") + }) + }) + + describe("updateDailyVolume", () => { + it("should create a new daily volume record when none exists", async () => { + const id = "TokenGateway" + const volume = "1000.50" + const timestamp = BigInt(1752145126274) + + await VolumeService.updateDailyVolume(id, volume, timestamp) + + const expectedId = `${VolumeService.getChainTypeId(id)}.2025-07-10` + expect(DailyVolumeUSD.get).toHaveBeenCalledWith(expectedId) + expect(DailyVolumeUSD.create).toHaveBeenCalledWith({ + id: expectedId, + last24HoursVolumeUSD: new Decimal(volume).toFixed(18), + lastUpdatedAt: timestamp, + createdAt: timestampToDate(timestamp), + }) + }) + + it("should update existing daily volume record within 24 hours", async () => { + const id = "TokenGateway" + const volume = "500.25" + const additionalVolume = "200.75" + const timestamp = BigInt(1752145126274) + const updatedTimestamp = timestamp + BigInt(3600) + + await VolumeService.updateDailyVolume(id, volume, timestamp) + await VolumeService.updateDailyVolume(id, additionalVolume, updatedTimestamp) + + const stored = mockStore.get(`DailyVolumeUSD:${VolumeService.getChainTypeId(id)}.2025-07-10`) + expect(stored).toBeDefined() + expect(stored.last24HoursVolumeUSD).toBe(new Decimal(volume).plus(additionalVolume).toFixed(18)) + expect(stored.lastUpdatedAt).toBe(updatedTimestamp) + }) + + it("should create new daily volume record after 24 hours", async () => { + const id = "TokenGateway" + const volume = "5000.25" + const additionalVolume = "2100.75" + const firstDayTimestamp = BigInt(1752495664445) + const secondDayTimestamp = firstDayTimestamp + BigInt(60 * 60 * 25 * 1000) // 25 hours later + + await VolumeService.updateDailyVolume(id, volume, firstDayTimestamp) + await VolumeService.updateDailyVolume(id, additionalVolume, secondDayTimestamp) + + const firstDayStored = mockStore.get(`DailyVolumeUSD:${VolumeService.getChainTypeId(id)}.2025-07-14`) + expect(firstDayStored).toBeDefined() + expect(firstDayStored.last24HoursVolumeUSD).toBe(new Decimal(volume).toFixed(18)) + + const secondDayStored = mockStore.get(`DailyVolumeUSD:${VolumeService.getChainTypeId(id)}.2025-07-15`) + expect(secondDayStored).toBeDefined() + expect(secondDayStored.last24HoursVolumeUSD).toBe(new Decimal(additionalVolume).toFixed(18)) + }) + + it("should generate correct daily record ID based on timestamp", async () => { + const id = "TokenGateway" + await VolumeService.updateDailyVolume(id, "1000.50", BigInt(1752145126274)) + expect(DailyVolumeUSD.get).toHaveBeenCalledWith(`${VolumeService.getChainTypeId(id)}.2025-07-10`) + }) + }) + + describe("updateVolume", () => { + it("should update both cumulative and daily volume", async () => { + const id = "TokenGateway" + const volume = "1000.50" + const timestamp = BigInt(1752497885694) + + await VolumeService.updateVolume(id, volume, timestamp) + + expect(CumulativeVolumeUSD.get).toHaveBeenCalledWith(VolumeService.getChainTypeId(id)) + expect(CumulativeVolumeUSD.create).toHaveBeenCalledWith({ + id: VolumeService.getChainTypeId(id), + volumeUSD: new Decimal(volume).toFixed(18), + lastUpdatedAt: timestamp, + }) + + const expectedDailyId = `${VolumeService.getChainTypeId(id)}.2025-07-14` + expect(DailyVolumeUSD.get).toHaveBeenCalledWith(expectedDailyId) + expect(DailyVolumeUSD.create).toHaveBeenCalledWith({ + id: expectedDailyId, + last24HoursVolumeUSD: new Decimal(volume).toFixed(18), + lastUpdatedAt: timestamp, + createdAt: timestampToDate(timestamp), + }) + }) + + it("should handle parallel updates correctly", async () => { + const id = "TokenGateway" + const volume = "1000.50" + const timestamp = BigInt(1700000000) + + const promises = [ + VolumeService.updateVolume(id, volume, timestamp), + VolumeService.updateVolume(id, volume, timestamp), + VolumeService.updateVolume(id, volume, timestamp), + ] + + await Promise.all(promises) + + expect(CumulativeVolumeUSD.get).toHaveBeenCalledTimes(3) + expect(DailyVolumeUSD.get).toHaveBeenCalledTimes(3) + }) + }) + + describe("edge cases", () => { + it("should handle very large volume amounts", async () => { + const id = "TokenGateway" + const volume = "999999999999999999.999999999999999999" + const timestamp = BigInt(1700000000) + + await VolumeService.updateCumulativeVolume(id, volume, timestamp) + const stored = mockStore.get(`CumulativeVolumeUSD:${VolumeService.getChainTypeId(id)}`) + + expect(stored).toBeDefined() + expect(stored.volumeUSD).toBe(new Decimal(volume).toFixed(18)) + }) + + it("should handle zero volume amounts", async () => { + const id = "TokenGateway" + const volume = "0" + const timestamp = BigInt(1700000000) + + await VolumeService.updateCumulativeVolume(id, volume, timestamp) + const stored = mockStore.get(`CumulativeVolumeUSD:${VolumeService.getChainTypeId(id)}`) + + expect(stored).toBeDefined() + expect(stored.volumeUSD).toBe("0.000000000000000000") + }) + + it("should handle very small volume amounts", async () => { + const id = "TokenGateway" + const volume = "0.000000000000000001" + + await VolumeService.updateCumulativeVolume(id, volume, BigInt(1700000000)) + const stored = mockStore.get(`CumulativeVolumeUSD:${VolumeService.getChainTypeId(id)}`) + + expect(stored).toBeDefined() + expect(stored.volumeUSD).toBe(new Decimal(volume).toFixed(18)) + }) + + it("should handle different ID formats", async () => { + const ids = ["TokenGateway", "IntentGateway.USER", "IntentGateway.FILLER"] + const volume = "100.50" + const timestamp = BigInt(1700000000) + + for (const id of ids) { + await VolumeService.updateCumulativeVolume(id, volume, BigInt(1700000000)) + const stored = mockStore.get(`CumulativeVolumeUSD:${VolumeService.getChainTypeId(id)}`) + + expect(stored).toBeDefined() + expect(stored.volumeUSD).toBe(new Decimal(volume).toFixed(18)) + } + }) + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/assetTeleported.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/assetTeleported.service.ts new file mode 100644 index 00000000..8239c935 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/assetTeleported.service.ts @@ -0,0 +1,49 @@ +import { AssetTeleported } from "@/configs/src/types/models" +import { timestampToDate } from "@/utils/date.helpers" + +// Arguments for creating AssetTeleported records +export interface IAssetTeleportedArgs { + from: string + to: string + amount: bigint + dest: string + commitment: string + message_id: string + chain: string + blockNumber: string + blockHash: string + blockTimestamp: bigint +} + +export class AssetTeleportedService { + /** + * Create or update an AssetTeleported record + */ + static async createOrUpdate(args: IAssetTeleportedArgs): Promise { + const { from, to, amount, dest, commitment, message_id, chain, blockNumber, blockHash, blockTimestamp } = args + + // Use commitment as the unique identifier for the asset teleport + const id = message_id + + // Try to find an existing record + let assetTeleported = await AssetTeleported.get(id) + + // If not found, create a new one + if (!assetTeleported) { + assetTeleported = AssetTeleported.create({ + id, + from, + to, + amount, + dest, + commitment, + chain, + blockNumber: parseInt(blockNumber), + createdAt: timestampToDate(blockTimestamp), // Using block timestamp for createdAt instead of current time + }) + } + + await assetTeleported.save() + return assetTeleported + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/bridgeTokenSupply.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/bridgeTokenSupply.service.ts new file mode 100644 index 00000000..fcb39096 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/bridgeTokenSupply.service.ts @@ -0,0 +1,548 @@ +import { BridgeTokenSupply } from "@/configs/src/types" +import { normalizeTimestamp, timestampToDate } from "@/utils/date.helpers" +import { replaceWebsocketWithHttp } from "@/utils/rpc.helpers" +import { ENV_CONFIG } from "@/constants" +import fetch from "node-fetch" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { Codec, Vector, Struct, u128, u8, Tuple, u64, u32 } from "scale-ts" +import { hexToBytes } from "viem" + +const FOUNDATION = "1e3df2cbfa10ceadc854bd5aa305462c2f81bbc81cc7f6ef462ce857bd0c90b3" +const TEAM = "5525104d00c439213dcbf428b867f0930754f100b75873382f2103ce5f846163" + +interface SubstrateStorageResponse { + jsonrpc: "2.0" + id: number + result?: string + error?: { + code: number + message: string + } +} + +interface SubstrateKeysResponse { + jsonrpc: "2.0" + id: number + result?: string[] + error?: { + code: number + message: string + } +} + +export const AccountInfo = Struct({ + nonce: u32, + consumers: u32, + providers: u32, + sufficients: u32, + data: Struct({ + free: u128, + reserve: u128, + frozen: u128, + flags: u128, + }), +}) + +// Define the BalanceLock codec using scale-ts +// BalanceLock struct: [u8; 8] (lock ID), u128 (amount), enum (reasons) +const BalanceLock = Struct({ + id: Tuple(u8, u8, u8, u8, u8, u8, u8, u8), // [u8; 8] - 8-byte lock ID + amount: u128, // u128 lock amount + reasons: u8, // Simplified enum as u8 (in practice, this could be more complex) +}) + +// Vector of BalanceLocks +const BalanceLocksVec = Vector(BalanceLock) + +/** + * Bridge Token Supply Service manages token supply data for Hyperbridge + */ +export class BridgeTokenSupplyService { + /** + * Updates token supply data by fetching circulating supply from Hyperbridge chain via RPC + * @param blockTimestamp - Block timestamp for when this update occurs + */ + static async updateTokenSupply(blockTimestamp: bigint): Promise { + try { + // Get RPC URL for Hyperbridge chain + const hyperbridgeChain = getHostStateMachine(chainId) // Use current chain ID from the indexer context + const rpcUrl = replaceWebsocketWithHttp(ENV_CONFIG[hyperbridgeChain] || "") + if (!rpcUrl) { + throw new Error(`No RPC URL found for Hyperbridge chain: ${hyperbridgeChain}`) + } + + // Fetch total supply from substrate balances pallet + const totalSupplyResult = await this.getTotalSupply(rpcUrl) + if (totalSupplyResult instanceof Error) { + return totalSupplyResult + } + + // Fetch circulating supply by subtracting locked/staked amounts + const circulatingSupplyResult = await this.getCirculatingSupply(rpcUrl) + if (circulatingSupplyResult instanceof Error) { + return circulatingSupplyResult + } + + // Scale down values by 12 decimal places for storage (convert from smallest unit to token units) + // This converts from the raw blockchain units to human-readable token amounts + const scaleFactor = BigInt(10) ** BigInt(12) // 10^12 = 1,000,000,000,000 + const scaledTotalSupply = totalSupplyResult / scaleFactor + const scaledCirculatingSupply = circulatingSupplyResult / scaleFactor + + // Create or update the BridgeTokenSupply entity (single entity for Hyperbridge) + const entityId = "hyperbridge-token-supply" + let bridgeTokenSupply = await BridgeTokenSupply.get(entityId) + + const normalizedTimestamp = normalizeTimestamp(blockTimestamp) + + if (!bridgeTokenSupply) { + bridgeTokenSupply = BridgeTokenSupply.create({ + id: entityId, + totalSupply: scaledTotalSupply, + circulatingSupply: scaledCirculatingSupply, + lastUpdatedAt: normalizedTimestamp, + createdAt: timestampToDate(blockTimestamp), + }) + } else { + bridgeTokenSupply.totalSupply = scaledTotalSupply + bridgeTokenSupply.circulatingSupply = scaledCirculatingSupply + bridgeTokenSupply.lastUpdatedAt = normalizedTimestamp + } + + await bridgeTokenSupply.save() + + logger.info( + `[BridgeTokenSupplyService.updateTokenSupply] Updated Hyperbridge token supply: total=${scaledTotalSupply} (raw: ${totalSupplyResult}), circulating=${scaledCirculatingSupply} (raw: ${circulatingSupplyResult})`, + ) + + return bridgeTokenSupply + } catch (error) { + logger.error( + `[BridgeTokenSupplyService.updateTokenSupply] Failed to update Hyperbridge token supply`, + error, + ) + return error instanceof Error ? error : new Error(String(error)) + } + } + + /** + * Gets the total supply of the native token from substrate balances pallet + * @param rpcUrl - The RPC URL for the substrate chain + */ + private static async getTotalSupply(rpcUrl: string): Promise { + try { + // Storage key for balances.totalIssuance + const storageKey = "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80" + + const response = await fetch(rpcUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + id: 1, + method: "state_getStorage", + params: [storageKey, null], + }), + }) + + const result: SubstrateStorageResponse = await response.json() + + if (result.error) { + throw new Error(`RPC error: ${result.error.message}`) + } + + if (!result.result) { + throw new Error("No result returned from RPC call") + } + + // Convert hex string to Uint8Array using viem's hexToBytes + const bytes = hexToBytes(result.result as `0x${string}`) + + // Decode u128 using scale-ts + const totalSupply = u128.dec(bytes) + + return totalSupply + } catch (error) { + logger.error(`[BridgeTokenSupplyService.getTotalSupply] Failed to get total supply`, error) + return error instanceof Error ? error : new Error(String(error)) + } + } + + /** + * Calculates circulating supply by subtracting locked amounts from total supply + * Formula: Circulating Supply = Total Supply - (Sum of all account locks + Inactive Issuance) + * @param rpcUrl - The RPC URL for the substrate chain + */ + private static async getCirculatingSupply(rpcUrl: string): Promise { + try { + // Get total supply + const totalSupply = await this.getTotalSupply(rpcUrl) + if (totalSupply instanceof Error) { + return totalSupply + } + + // Get inactive issuance + const inactiveIssuance = await this.getInactiveIssuance(rpcUrl) + if (inactiveIssuance instanceof Error) { + return inactiveIssuance + } + + // Get team and foundation account + const teamTotal = await this.getTeamAndFoundationBalance(rpcUrl) + if (teamTotal instanceof Error) { + return teamTotal + } + + // Get sum of all account locks + const totalLocks = await this.getTotalAccountLocks(rpcUrl) + if (totalLocks instanceof Error) { + return totalLocks + } + + // Calculate circulating supply: Total Supply - (Inactive Issuance + Total Locks) + const circulatingSupply = totalSupply - (inactiveIssuance + totalLocks + teamTotal) + + logger.debug( + `[BridgeTokenSupplyService.getCirculatingSupply] Total: ${totalSupply}, Inactive: ${inactiveIssuance}, Locks: ${totalLocks}, Team and Foundation: ${teamTotal}, Circulating: ${circulatingSupply}`, + ) + + return circulatingSupply + } catch (error) { + logger.error(`[BridgeTokenSupplyService.getCirculatingSupply] Failed to get circulating supply`, error) + return error instanceof Error ? error : new Error(String(error)) + } + } + + /** + * Gets the inactive issuance from the balances pallet + * @param rpcUrl - The RPC URL for the substrate chain + */ + private static async getInactiveIssuance(rpcUrl: string): Promise { + try { + // Storage key for balances.inactiveIssuance + const storageKey = "0xc2261276cc9d1f8598ea4b6a74b15c2f1ccde6872881f893a21de93dfe970cd5" + + const response = await fetch(rpcUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + id: 1, + method: "state_getStorage", + params: [storageKey, null], + }), + }) + + const result: SubstrateStorageResponse = await response.json() + + if (result.error) { + throw new Error(`RPC error: ${result.error.message}`) + } + + // If no inactive issuance exists, return 0 + if (!result.result) { + return BigInt(0) + } + + // Convert hex string to Uint8Array using viem's hexToBytes + const bytes = hexToBytes(result.result as `0x${string}`) + + // Decode u128 using scale-ts + const inactiveIssuance = u128.dec(bytes) + + return inactiveIssuance + } catch (error) { + logger.error(`[BridgeTokenSupplyService.getInactiveIssuance] Failed to get inactive issuance`, error) + return error instanceof Error ? error : new Error(String(error)) + } + } + + /** + * Gets the inactive issuance from the balances pallet + * @param rpcUrl - The RPC URL for the substrate chain + */ + private static async getTeamAndFoundationBalance(rpcUrl: string): Promise { + try { + // Storage key for balances.inactiveIssuance + const foundation_account_key = + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9cc2c6dacd6a81b5cfa93c676700c2ccf1e3df2cbfa10ceadc854bd5aa305462c2f81bbc81cc7f6ef462ce857bd0c90b3" + const team_account_key = + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9a6f084e8a3b94abf6e45b5ee4bcc89db5525104d00c439213dcbf428b867f0930754f100b75873382f2103ce5f846163" + + // Query multiple storage keys at once + const response = await fetch(rpcUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + id: 1, + method: "state_queryStorageAt", + params: [[foundation_account_key, team_account_key], null], + }), + }) + + const result = await response.json() + + if (result.error) { + throw new Error(`RPC error querying team and foundation accounts: ${result.error.message}`) + } + + if (!result.result || !result.result.length) { + return BigInt(0) + } + + let batchTotal = BigInt(0) + + // Process each storage result + for (const storageResult of result.result) { + if (!storageResult.changes) continue + + for (const [key, value] of storageResult.changes) { + if (!value) continue + + try { + const amount = this.parseAccountBalance(value) + batchTotal += amount + } catch (parseError) { + logger.warn( + `[BridgeTokenSupplyService.processBatchLocks] Failed to parse lock data for key ${key}:`, + parseError, + ) + // Continue processing other locks even if one fails + } + } + } + + return batchTotal + } catch (error) { + logger.error(`[BridgeTokenSupplyService.getInactiveIssuance] Failed to get inactive issuance`, error) + return error instanceof Error ? error : new Error(String(error)) + } + } + + /** + * Gets the sum of all account locks from the balances pallet locks storage map + * @param rpcUrl - The RPC URL for the substrate chain + */ + private static async getTotalAccountLocks(rpcUrl: string): Promise { + try { + // Storage key prefix for balances.locks map + const storageKeyPrefix = "0xc2261276cc9d1f8598ea4b6a74b15c2f218f26c73add634897550b4003b26bc6" + + let totalLocks = BigInt(0) + let startKey: string | null = null + const pageSize = 1000 + const batchSize = 100 + + // Keep fetching keys until we get all of them (pagination) + while (true) { + const keysResponse = await fetch(rpcUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + id: 1, + method: "state_getKeysPaged", + params: [storageKeyPrefix, pageSize, startKey, null], + }), + }) + + const keysResult: SubstrateKeysResponse = await keysResponse.json() + + if (keysResult.error) { + throw new Error(`RPC error getting keys: ${keysResult.error.message}`) + } + + if (!keysResult.result || keysResult.result.length === 0) { + // No more keys to fetch + break + } + + logger.debug( + `[BridgeTokenSupplyService.getTotalAccountLocks] Fetched ${keysResult.result.length} keys in this page`, + ) + + // Process keys in batches to avoid overwhelming the RPC + for (let i = 0; i < keysResult.result.length; i += batchSize) { + const batch = keysResult.result.slice(i, i + batchSize) + const batchLocks = await this.processBatchLocks(rpcUrl, batch) + + if (batchLocks instanceof Error) { + logger.warn( + `[BridgeTokenSupplyService.getTotalAccountLocks] Failed to process batch ${i}-${i + batchSize}:`, + batchLocks, + ) + continue + } + + totalLocks += batchLocks + } + + // If we got less than pageSize results, we've reached the end + if (keysResult.result.length < pageSize) { + break + } + + // Set the start key for the next page (last key from current page) + startKey = keysResult.result[keysResult.result.length - 1] + } + + logger.debug(`[BridgeTokenSupplyService.getTotalAccountLocks] Total locks processed: ${totalLocks}`) + + return totalLocks + } catch (error) { + logger.error(`[BridgeTokenSupplyService.getTotalAccountLocks] Failed to get total account locks`, error) + return error instanceof Error ? error : new Error(String(error)) + } + } + + /** + * Processes a batch of lock storage keys and returns the sum of locked amounts + * @param rpcUrl - The RPC URL for the substrate chain + * @param keys - Array of storage keys to query + */ + private static async processBatchLocks(rpcUrl: string, keys: string[]): Promise { + try { + // Query multiple storage keys at once + const response = await fetch(rpcUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + id: 1, + method: "state_queryStorageAt", + params: [keys, null], + }), + }) + + const result = await response.json() + + if (result.error) { + throw new Error(`RPC error querying batch: ${result.error.message}`) + } + + if (!result.result || !result.result.length) { + return BigInt(0) + } + + let batchTotal = BigInt(0) + + // Process each storage result + for (const storageResult of result.result) { + if (!storageResult.changes) continue + + for (const [key, value] of storageResult.changes) { + if (!value) continue + // Don't count team and foundation locks + if (key.endsWith(FOUNDATION) || key.endsWith(TEAM)) { + logger.info(`Skipping locks on team and foundation account`) + continue + } + + try { + // Parse the encoded locks data + // Substrate stores locks as Vec> + // Each lock has an amount field we need to sum + const lockAmount = this.parseLockData(value) + if (lockAmount > 0) { + batchTotal += lockAmount + } + } catch (parseError) { + logger.warn( + `[BridgeTokenSupplyService.processBatchLocks] Failed to parse lock data for key ${key}:`, + parseError, + ) + // Continue processing other locks even if one fails + } + } + } + + return batchTotal + } catch (error) { + logger.error(`[BridgeTokenSupplyService.processBatchLocks] Failed to process batch locks`, error) + return error instanceof Error ? error : new Error(String(error)) + } + } + + /** + * Parses lock data from substrate storage to extract the locked amount using scale-ts + * BalanceLock struct format: + * - First 8 bytes: static byte array (lock ID) + * - Next 16 bytes: u128 lock amount (little-endian) + * - Next 1+ bytes: enum (reasons) + * @param hexData - Hex encoded lock data from substrate + */ + private static parseLockData(hexData: string): bigint { + try { + // Remove 0x prefix if present + const cleanHex = hexData.startsWith("0x") ? hexData.slice(2) : hexData + + if (cleanHex.length === 0) { + return BigInt(0) + } + + // Convert hex string to Uint8Array using viem's hexToBytes + const hexWithPrefix = cleanHex.startsWith("0x") ? cleanHex : `0x${cleanHex}` + const bytes = hexToBytes(hexWithPrefix as `0x${string}`) + + if (bytes.length === 0) { + return BigInt(0) + } + + // Decode the Vec using scale-ts + const decodedLocks = BalanceLocksVec.dec(bytes) + + // Sum all lock amounts + let totalLocked = BigInt(0) + for (const lock of decodedLocks) { + totalLocked += lock.amount + } + + logger.debug( + `[BridgeTokenSupplyService.parseLockData] Decoded ${decodedLocks.length} locks, total amount: ${totalLocked}`, + ) + + return totalLocked + } catch (error) { + logger.error(`[BridgeTokenSupplyService.parseLockData] Failed to parse lock data: ${hexData}`, error) + return BigInt(0) + } + } + + private static parseAccountBalance(hexData: string): bigint { + try { + // Remove 0x prefix if present + const cleanHex = hexData.startsWith("0x") ? hexData.slice(2) : hexData + + if (cleanHex.length === 0) { + return BigInt(0) + } + + // Convert hex string to Uint8Array using viem's hexToBytes + const hexWithPrefix = cleanHex.startsWith("0x") ? cleanHex : `0x${cleanHex}` + const bytes = hexToBytes(hexWithPrefix as `0x${string}`) + + if (bytes.length === 0) { + return BigInt(0) + } + + const account = AccountInfo.dec(bytes) + + return account.data.free + } catch (error) { + logger.error( + `[BridgeTokenSupplyService.parseAccountBalance] Failed to parse account info: ${hexData}`, + error, + ) + return BigInt(0) + } + } + + /** + * Gets the current Hyperbridge token supply data + */ + static async getTokenSupply(): Promise { + const entityId = "hyperbridge-token-supply" + return (await BridgeTokenSupply.get(entityId)) || null + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/dailyTreasuryReward.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/dailyTreasuryReward.service.ts new file mode 100644 index 00000000..8b6513ea --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/dailyTreasuryReward.service.ts @@ -0,0 +1,243 @@ +import { DailyTreasuryRelayerReward } from "@/configs/src/types" +import { replaceWebsocketWithHttp } from "@/utils/rpc.helpers" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { ENV_CONFIG } from "@/constants" +import { Struct, u32, u128, bool, _void, Enum, u8, Vector } from "scale-ts" +import { hexToBytes } from "viem" +import { xxhashAsHex, blake2AsU8a, decodeAddress, xxhashAsU8a } from "@polkadot/util-crypto" +import fetch from "node-fetch" +import { timestampToDate } from "@/utils/date.helpers" +import { AccountInfo } from "@/services/bridgeTokenSupply.service" +import { getStateId, StateMachine } from "@/utils/state-machine.helper" +import { retryPromise } from "@/utils/retry.utils" +import { compactAddLength } from "@polkadot/util" + +const REPUTATION_ASSET_ID = "0x0000000000000000000000000000000000000000000000000000000000000001" +export const TREASURY_ADDRESS = "13UVJyLkyUpEiXBx5p776dHQoBuuk3Y5PYp5Aa89rYWePWA3" +interface SubstrateStorageResponse { + jsonrpc: "2.0" + id: number + result?: string + error?: { message: string } +} + +const AssetAccount = Struct({ + balance: u128, + isFrozen: bool, + reason: _void, + extra: _void, +}) + +export class DailyTreasuryRewardService { + /** + * Finds the daily treasury reward record for a given date and adds to the amount + * Creates a new record if one doesn't exist. + */ + static async update(date: bigint, amount: bigint): Promise { + const day = timestampToDate(date) + day.setUTCHours(0, 0, 0, 0) + const id = day.toISOString().slice(0, 10) + + let record = await DailyTreasuryRelayerReward.get(id) + + if (!record) { + record = DailyTreasuryRelayerReward.create({ + id: id, + date: day, + dailyRewardAmount: BigInt(0), + }) + } + + record.dailyRewardAmount += amount + await record.save() + } + + private static async getStorage(storageKey: string, logMessage: string): Promise { + const operation = async (): Promise => { + const hyperbridgeChain = getHostStateMachine(chainId); + const rpcUrl = replaceWebsocketWithHttp(ENV_CONFIG[hyperbridgeChain] || ""); + if (!rpcUrl) { + throw new Error(`No RPC URL found for Hyperbridge chain: ${hyperbridgeChain}`); + } + + const response = await fetch(rpcUrl, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + jsonrpc: "2.0", + id: 1, + method: "state_getStorage", + params: [storageKey], + }), + }); + + if (!response.ok) { + throw new Error(`RPC request failed with status ${response.status}`); + } + + const result: SubstrateStorageResponse = await response.json(); + + if (result.error) { + throw new Error(result.error.message); + } + + return result.result || null; + }; + + try { + return await retryPromise(operation, { + maxRetries: 3, + backoffMs: 1000, + logMessage: `Fetch ${logMessage}`, + }); + } catch (e) { + const errorMessage = e instanceof Error ? e.message : String(e); + logger.error(`All retries failed for ${logMessage}: ${errorMessage}`); + return null; + } + } + + /** + * Fetches reputation asset balance for a given relayer account + */ + static async getReputationAssetBalance(accountId: string): Promise { + try { + const storageKey = this.generateAssetsAccountStorageKey(REPUTATION_ASSET_ID, accountId) + logger.info(`storage key is ${storageKey}`) + const result = await this.getStorage(storageKey, "reputation asset balance") + + if (!result) { + return BigInt(0) + } + + const bytes = hexToBytes(result as `0x${string}`) + const decoded = AssetAccount.dec(bytes) + + return decoded.balance + } catch (e) { + const errorMessage = e instanceof Error ? e.message : String(e) + logger.error(`Failed to fetch reputation asset balance for ${accountId}: ${errorMessage}`) + return BigInt(0) + } + } + + /** + * Fetches BRIDGE balance for the treasury + */ + static async getTreasuryBalance(): Promise { + try { + const storageKey = this.generateSystemAccountStorageKey(TREASURY_ADDRESS) + const result = await this.getStorage(storageKey, "treasury balance") + + if (!result) { + return BigInt(0) + } + + const bytes = hexToBytes(result as `0x${string}`) + const decoded = AccountInfo.dec(bytes) + + return decoded.data.free + } catch (e) { + const errorMessage = e instanceof Error ? e.message : String(e) + logger.error(`Failed to fetch treasury balance: ${errorMessage}`) + return BigInt(0) + } + } + + /** + * Get Fee Token Decimal stored on chain + */ + static async getFeeTokenDecimals(stateMachine: any): Promise { + try { + + const storageKey = this.generateFeeTokenDecimalsStorageKey(stateMachine) + logger.info(`storage key is ${storageKey}`) + const result = await this.getStorage(storageKey, "fee token decimals") + if (!result) { + logger.warn(`No fee token decimals found for state machine: ${JSON.stringify(stateMachine)}`) + return 18 + } + logger.info(`fee token decimal result is ${result}`) + + const bytes = hexToBytes(result as `0x${string}`) + return u8.dec(bytes) + } catch (e) { + const errorMessage = e instanceof Error ? e.message : String(e) + logger.error(`Failed to fetch fee token decimals: ${errorMessage}`) + return 18 + } + } + + /** + * Sorage Key for fee token decimal + */ + private static generateFeeTokenDecimalsStorageKey(stateMachine: any): string { + const palletHash = xxhashAsHex("HostExecutive", 128) + const storageHash = xxhashAsHex("FeeTokenDecimals", 128) + + logger.info(`trying to encode stateMachine: ${JSON.stringify(stateMachine)}`) + let stateId = getStateId(stateMachine) + const encodedKey = StateMachine.enc(stateId) + logger.info(`encoded stateMachine: ${encodedKey}`) + + const keyHash = blake2AsU8a(encodedKey, 128) + + logger.info(`encoded stateMachine keyHash: ${keyHash}`) + + const finalKey = new Uint8Array([ + ...hexToBytes(palletHash), + ...hexToBytes(storageHash), + ...keyHash, + ...encodedKey, + ]) + + logger.info(`encoded stateMachine finalKey: ${finalKey}`) + + return `0x${Buffer.from(finalKey).toString("hex")}` + } + + /** + * Generates the assets account stprage key + */ + private static generateAssetsAccountStorageKey(assetId: `0x${string}`, accountId: string): string { + const palletHash = xxhashAsHex("Assets", 128) + const storageHash = xxhashAsHex("Account", 128) + + const assetIdBytes = hexToBytes(assetId) + const accountIdBytes = decodeAddress(accountId) + + const assetIdHashed = blake2AsU8a(assetIdBytes, 128) + const accountIdHashed = blake2AsU8a(accountIdBytes, 128) + + const finalKey = new Uint8Array([ + ...hexToBytes(palletHash), + ...hexToBytes(storageHash), + ...assetIdHashed, + ...assetIdBytes, + ...accountIdHashed, + ...accountIdBytes, + ]) + + return `0x${Buffer.from(finalKey).toString("hex")}` + } + + /** + * + * Generates System Account storage Key + */ + private static generateSystemAccountStorageKey(accountId: string): string { + const palletHash = xxhashAsHex("System", 128) + const storageHash = xxhashAsHex("Account", 128) + const accountIdBytes = decodeAddress(accountId) + const accountIdHashed = blake2AsU8a(accountIdBytes, 128) + + const finalKey = new Uint8Array([ + ...hexToBytes(palletHash), + ...hexToBytes(storageHash), + ...accountIdHashed, + ...accountIdBytes, + ]) + + return `0x${Buffer.from(finalKey).toString("hex")}` + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/getRequest.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/getRequest.service.ts new file mode 100644 index 00000000..2845c0ac --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/getRequest.service.ts @@ -0,0 +1,208 @@ +import { GetRequest, GetRequestStatusMetadata, Status } from "@/configs/src/types" +import { ethers } from "ethers" +import { solidityKeccak256 } from "ethers/lib/utils" +import { timestampToDate } from "@/utils/date.helpers" + +export interface IGetRequestArgs { + id: string + source?: string + dest?: string + from?: string + keys?: string[] + nonce?: bigint + height?: bigint + context?: string + timeoutTimestamp?: bigint + fee?: bigint + blockNumber?: string + blockHash?: string + transactionHash?: string + blockTimestamp?: bigint + status?: Status + chain?: string + commitment?: string +} + +export interface IUpdateGetRequestStatusArgs { + commitment: string + blockNumber: string + blockHash: string + blockTimestamp: bigint + status: Status + transactionHash: string + chain: string +} + +export class GetRequestService { + static async createOrUpdate(args: IGetRequestArgs): Promise { + const { + id, + source, + dest, + from, + keys, + nonce, + height, + context, + timeoutTimestamp, + fee, + blockNumber, + blockHash, + blockTimestamp, + transactionHash, + status, + chain, + } = args + let getRequest = await GetRequest.get(id) + + logger.info( + `Processing Get Request: ${JSON.stringify({ + id, + transactionHash, + status, + })}`, + ) + + if (!getRequest) { + getRequest = GetRequest.create({ + id, + chain: chain || "", + source: source || "", + dest: dest || "", + from: from || "", + keys: keys || [""], + nonce: nonce || BigInt(0), + height: height || BigInt(0), + context: context || "", + timeoutTimestamp: timeoutTimestamp || BigInt(0), + fee: fee || BigInt(0), + blockNumber: blockNumber || "", + blockHash: blockHash || "", + transactionHash: transactionHash || "", + blockTimestamp: blockTimestamp || BigInt(0), + status: status || Status.SOURCE, + commitment: id, + }) + + await getRequest.save() + + logger.info( + `Saved GetRequest Event: ${JSON.stringify({ + id: getRequest.id, + })}`, + ) + } else { + if (source !== undefined) getRequest.source = source + if (dest !== undefined) getRequest.dest = dest + if (from !== undefined) getRequest.from = from + if (keys !== undefined) getRequest.keys = keys + if (nonce !== undefined) getRequest.nonce = nonce + if (height !== undefined) getRequest.height = height + if (context !== undefined) getRequest.context = context + if (timeoutTimestamp !== undefined) getRequest.timeoutTimestamp = timeoutTimestamp + if (fee !== undefined) getRequest.fee = fee + if (blockNumber !== undefined) getRequest.blockNumber = blockNumber + if (blockHash !== undefined) getRequest.blockHash = blockHash + if (transactionHash !== undefined) getRequest.transactionHash = transactionHash + if (blockTimestamp !== undefined) getRequest.blockTimestamp = blockTimestamp + if (status !== undefined) getRequest.status = status + if (chain !== undefined) getRequest.chain = chain + + await getRequest.save() + + logger.info( + `Updated GetRequest Event: ${JSON.stringify({ + id: getRequest.id, + })}`, + ) + } + + return getRequest + } + + /** + * Update the status of a get request + * Also adds a new entry to the get request status metadata + */ + static async updateStatus(args: IUpdateGetRequestStatusArgs): Promise { + const { commitment, blockNumber, blockHash, blockTimestamp, status, transactionHash, chain } = args + + logger.info( + `Updating Get Request Status: ${JSON.stringify({ + commitment, + transactionHash, + status, + })}`, + ) + + let getRequest = await this.createOrUpdate({ + id: commitment, + status, + }) + + await getRequest.save() + + logger.info( + `Created new get request while attempting get request update with details ${JSON.stringify({ + commitment, + transactionHash, + status, + })}`, + ) + + let getRequestStatusMetadata = GetRequestStatusMetadata.create({ + id: `${commitment}.${status}`, + requestId: commitment, + status, + chain, + timestamp: blockTimestamp, + blockNumber, + blockHash, + transactionHash, + createdAt: timestampToDate(blockTimestamp), + }) + + await getRequestStatusMetadata.save() + } + + /** + * Compute the getRequest commitment matching the solidity `encode` function for GetRequestEvent + */ + static computeRequestCommitment( + source: string, + dest: string, + nonce: bigint, + height: bigint, + timeoutTimestamp: bigint, + from: string, + keys: string[], + context: string, + ): string { + logger.info( + `Computing request commitment with details ${JSON.stringify({ + source, + dest, + nonce: nonce.toString(), + height: height.toString(), + timeoutTimestamp: timeoutTimestamp.toString(), + from, + keys, + context, + })}`, + ) + + let keysEncoding = "0x".concat(keys.map((key) => key.slice(2)).join("")) + + // Convert strings to bytes + const sourceBytes = ethers.utils.toUtf8Bytes(source) + const destBytes = ethers.utils.toUtf8Bytes(dest) + + // Pack the data in the same order as the Solidity code + const hash = solidityKeccak256( + ["bytes", "bytes", "uint64", "uint64", "uint64", "bytes", "bytes", "bytes"], + [sourceBytes, destBytes, nonce, height, timeoutTimestamp, from, keysEncoding, context], + ) + + return hash + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/getResponse.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/getResponse.service.ts new file mode 100644 index 00000000..a550be66 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/getResponse.service.ts @@ -0,0 +1,99 @@ +import { GetResponse, Status } from "@/configs/src/types" +import { timestampToDate } from "@/utils/date.helpers" + +export interface ICreateGetResponseArgs { + chain: string + commitment: string + response_message?: string[] + responseTimeoutTimestamp?: bigint | undefined + request?: string | undefined + status: Status + blockNumber: string + blockHash: string + transactionHash: string + blockTimestamp: bigint +} + +export class GetResponseService { + /** + * Finds a response enitity and creates a new one if it doesn't exist + */ + static async findOrCreate(args: ICreateGetResponseArgs): Promise { + const { + chain, + commitment, + request, + response_message, + responseTimeoutTimestamp, + status, + blockNumber, + blockHash, + blockTimestamp, + transactionHash, + } = args + let response = await GetResponse.get(commitment) + + logger.info( + `Creating GetResponse Event: ${JSON.stringify({ + commitment, + transactionHash, + status, + })}`, + ) + + if (typeof response === "undefined") { + response = GetResponse.create({ + id: commitment, + commitment, + chain, + requestId: request, + response_message: response_message || [""], + responseTimeoutTimestamp, + createdAt: timestampToDate(blockTimestamp), + blockNumber, + blockHash, + transactionHash, + }) + + await response.save() + + logger.info( + `Created new get response with details ${JSON.stringify({ + commitment, + transactionHash, + status, + })}`, + ) + } + + return response + } + + /** + * Find responses by chain + */ + static async findByChain(chain: string) { + return GetResponse.getByChain(chain, { + orderBy: "id", + limit: -1, + }) + } + + /** + * Find a response by commitment + */ + static async findByCommitment(commitment: string) { + // Since commitment is the ID, we can just use get() + return GetResponse.get(commitment) + } + + /** + * Find responses by request ID + */ + static async findByRequestId(requestId: string) { + return GetResponse.getByRequestId(requestId, { + orderBy: "id", + limit: -1, + }) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/hyperbridge.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/hyperbridge.service.ts new file mode 100644 index 00000000..653f142e --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/hyperbridge.service.ts @@ -0,0 +1,218 @@ +import { PostRequestEventLog, PostResponseEventLog } from "@/configs/src/types/abi-interfaces/EthereumHostAbi" +import { DailyProtocolFeesStats, Relayer, Transfer } from "@/configs/src/types/models" +import { HyperBridgeChainStatsService } from "@/services/hyperbridgeChainStats.service" +import { isHexString } from "ethers/lib/utils" +import { EthereumHostAbi__factory } from "@/configs/src/types/contracts" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import stringify from "safe-stable-stringify" +import { getDateFormatFromTimestamp, isWithin24Hours, timestampToDate } from "@/utils/date.helpers" +import { RelayerService } from "./relayer.service" +// import { +// HandlePostRequestsTransaction, +// HandlePostResponsesTransaction, +// } from "@/configs/src/types/abi-interfaces/HandlerV1Abi" + +export class HyperBridgeService { + /** + * Perform the necessary actions related to Hyperbridge stats when a PostRequest/PostResponse event is indexed + */ + static async handlePostRequestOrResponseEvent( + chain: string, + event: PostRequestEventLog | PostResponseEventLog, + ): Promise { + if (!event.args) return + + const { args, address } = event + let { body, dest } = args + + logger.info(`handlePostRequestOrResponseEvent: ${stringify({ chain, event })}`) + + try { + const protocolFee = await this.computeProtocolFeeFromHexData(address, body, dest) + await this.updateDailyProtocolFees(event.blockHash, protocolFee, chain) + await this.incrementProtocolFeesEarned(protocolFee, chain) + await this.incrementNumberOfSentMessages(chain) + } catch (error) { + logger.error( + `Error updating Hyperbridge stats related to PostRequest/PostResponse event: ${JSON.stringify({ + error, + address, + body, + })}`, + ) + return + } + } + + /** + * Perform the necessary actions related to Hyperbridge stats when a PostRequestHandled/PostResponseHandled event is indexed + */ + static async handlePostRequestOrResponseHandledEvent( + relayer_id: string, + chain: string, + timestamp: bigint, + ): Promise { + await this.incrementNumberOfDeliveredMessages(chain) + await RelayerService.updateMessageDelivered(relayer_id, chain, timestamp) + } + + /** + * Handle PostRequest or PostResponse transactions + */ + // static async handlePostRequestOrResponseTransaction( + // chain: string, + // transaction: HandlePostRequestsTransaction | HandlePostResponsesTransaction, + // ): Promise { + // logger.info( + // `Creating PostRequest or PostResponse transaction update: ${JSON.stringify({ + // transaction, + // })}`, + // ) + // const { status } = await transaction.receipt() + + // if (status === false) { + // await this.incrementNumberOfFailedDeliveries(chain) + // } + // } + + /** + * Increment the total number of messages sent on hyperbridge + */ + static async incrementNumberOfSentMessages(chain: string): Promise { + logger.info(`Incrementing number of messages sent on hyperbridge`) + // Update the specific chain stats + let chainStats = await HyperBridgeChainStatsService.findOrCreateChainStats(chain) + chainStats.numberOfMessagesSent += BigInt(1) + + await chainStats.save() + } + + /** + * Increment the number of successful messages handled by hyperbridge + */ + static async incrementNumberOfDeliveredMessages(chain: string): Promise { + // Update the specific chain stats + let chainStats = await HyperBridgeChainStatsService.findOrCreateChainStats(chain) + chainStats.numberOfDeliveredMessages += BigInt(1) + + await chainStats.save() + } + + /** + * Increment the number of failed deliveries by hyperbridge + */ + static async incrementNumberOfFailedDeliveries(chain: string): Promise { + // Update the specific chain stats + let chainStats = await HyperBridgeChainStatsService.findOrCreateChainStats(chain) + chainStats.numberOfFailedDeliveries += BigInt(1) + + await chainStats.save() + } + + /** + * Increment the number of timed-out messages handled by hyperbridge + */ + static async incrementNumberOfTimedOutMessagesSent(chain: string): Promise { + // Update the specific chain stats + let chainStats = await HyperBridgeChainStatsService.findOrCreateChainStats(chain) + chainStats.numberOfTimedOutMessages += BigInt(1) + + await chainStats.save() + } + + /** + * Increment the protocol fees earned by hyperbridge + */ + static async incrementProtocolFeesEarned(amount: bigint, chain: string): Promise { + logger.info(`Incrementing protocol fees earned by ${amount} on chain ${chain}`) + // Update the specific chain stats + let chainStats = await HyperBridgeChainStatsService.findOrCreateChainStats(chain) + chainStats.protocolFeesEarned += amount + + await chainStats.save() + } + + /** + * Handle transfers out of the host account, incrementing the fees payed out to relayers + */ + static async handleTransferOutOfHostAccounts(transfer: Transfer, chain: string): Promise { + let relayer = await Relayer.get(transfer.to) + + if (typeof relayer !== "undefined") { + let chainStats = await HyperBridgeChainStatsService.findOrCreateChainStats(chain) + + chainStats.feesPayedOutToRelayers += BigInt(transfer.amount) + + await chainStats.save() + } + } + + /** + * Increment the total amount transferred to hyperbridge (protocol fees + relayer fees) + */ + static async updateTotalTransfersIn(transfer: Transfer, chain: string): Promise { + // Update the specific chain metrics + let chainStats = await HyperBridgeChainStatsService.findOrCreateChainStats(chain) + chainStats.totalTransfersIn += BigInt(transfer.amount) + + await chainStats.save() + } + + static async computeProtocolFeeFromHexData( + contract_address: string, + data: string, + stateId: string, + ): Promise { + data = isHexString(data) ? data.slice(2) : data + const noOfBytesInData = data.length / 2 + const evmHostContract = EthereumHostAbi__factory.connect(contract_address, api) + logger.info( + `Computing protocol fee for data: ${JSON.stringify({ + data, + noOfBytesInData, + stateId, + })}`, + ) + const encoder = new TextEncoder() + const stateIdByte = encoder.encode(stateId) + const perByteFee = await evmHostContract.perByteFee(stateIdByte) + return perByteFee.mul(noOfBytesInData).toBigInt() + } + + static async updateDailyProtocolFees(blockHash: string, protocolFeeAmount: bigint, chain: string): Promise { + const stateMachineId = chain + + try { + const timestamp = await getBlockTimestamp(blockHash, chain) + + const dateString = getDateFormatFromTimestamp(timestamp) + const id = `${stateMachineId}.${dateString}` + + let dailyProtocolFees = await DailyProtocolFeesStats.get(id) + + if (!dailyProtocolFees) { + dailyProtocolFees = DailyProtocolFeesStats.create({ + id, + chain, + stateMachineId, + last24HoursProtocolFeesEarned: protocolFeeAmount, + lastUpdatedAt: timestamp, + createdAt: timestampToDate(timestamp), + }) + } + + if ( + isWithin24Hours(dailyProtocolFees.createdAt, timestamp) && + dailyProtocolFees.lastUpdatedAt !== timestamp + ) { + dailyProtocolFees.last24HoursProtocolFeesEarned += protocolFeeAmount + dailyProtocolFees.lastUpdatedAt = timestamp + } + + await dailyProtocolFees.save() + } catch (error) { + logger.error(`Error updating daily protocol fees for stateMachine: ${stateMachineId}`, error) + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/hyperbridgeChainStats.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/hyperbridgeChainStats.service.ts new file mode 100644 index 00000000..bd08f5cf --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/hyperbridgeChainStats.service.ts @@ -0,0 +1,86 @@ +import { HyperBridgeChainStats } from "@/configs/src/types" + +export class HyperBridgeChainStatsService { + /** + * Find the HyperBridgeChainStats record for a chain, create it if it doesn't exist + */ + static async findOrCreateChainStats(chain: string): Promise { + let chainStats = await HyperBridgeChainStats.get(chain) + + if (typeof chainStats === "undefined") { + chainStats = HyperBridgeChainStats.create({ + id: chain, + totalTransfersIn: BigInt(0), + protocolFeesEarned: BigInt(0), + feesPayedOutToRelayers: BigInt(0), + numberOfMessagesSent: BigInt(0), + numberOfDeliveredMessages: BigInt(0), + numberOfFailedDeliveries: BigInt(0), + numberOfTimedOutMessages: BigInt(0), + }) + await chainStats.save() + } + + return chainStats + } + + /** + * Get chains by number of messages sent + */ + static async getByNumberOfMessagesSent(numberOfMessagesSent: bigint) { + return HyperBridgeChainStats.getByNumberOfMessagesSent(numberOfMessagesSent, { + orderBy: "numberOfMessagesSent", + limit: -1, + }) + } + + /** + * Get chains by number of delivered messages + */ + static async getByNumberOfDeliveredMessages(numberOfDeliveredMessages: bigint) { + return HyperBridgeChainStats.getByNumberOfDeliveredMessages(numberOfDeliveredMessages, { + orderBy: "numberOfDeliveredMessages", + limit: -1, + }) + } + + /** + * Get chains by number of failed deliveries + */ + static async getByNumberOfFailedDeliveries(numberOfFailedDeliveries: bigint) { + return HyperBridgeChainStats.getByNumberOfFailedDeliveries(numberOfFailedDeliveries, { + orderBy: "numberOfFailedDeliveries", + limit: -1, + }) + } + + /** + * Get chains by total transfers in + */ + static async getByTotalTransfersIn(totalTransfersIn: bigint) { + return HyperBridgeChainStats.getByTotalTransfersIn(totalTransfersIn, { + orderBy: "totalTransfersIn", + limit: -1, + }) + } + + /** + * Get chains by protocol fees earned + */ + static async getByProtocolFeesEarned(protocolFeesEarned: bigint) { + return HyperBridgeChainStats.getByProtocolFeesEarned(protocolFeesEarned, { + orderBy: "protocolFeesEarned", + limit: -1, + }) + } + + /** + * Get chains by fees payed out to relayers + */ + static async getByFeesPayedOutToRelayers(feesPayedOutToRelayers: bigint) { + return HyperBridgeChainStats.getByFeesPayedOutToRelayers(feesPayedOutToRelayers, { + orderBy: "feesPayedOutToRelayers", + limit: -1, + }) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/intentGateway.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/intentGateway.service.ts new file mode 100644 index 00000000..1ac32625 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/intentGateway.service.ts @@ -0,0 +1,422 @@ +import Decimal from "decimal.js" +import { ethers } from "ethers" +import type { Hex } from "viem" +import { hexToBytes, bytesToHex, keccak256, encodeAbiParameters } from "viem" + +import { OrderStatus, OrderStatusMetadata, ProtocolParticipantType, PointsActivityType } from "@/configs/src/types" +import { ERC6160Ext20Abi__factory } from "@/configs/src/types/contracts" +import { Order as OrderPlaced } from "@/configs/src/types/models/Order" +import { timestampToDate } from "@/utils/date.helpers" + +import { PointsService } from "./points.service" +import { VolumeService } from "./volume.service" +import PriceHelper from "@/utils/price.helpers" +import { TokenPriceService } from "./token-price.service" +import stringify from "safe-stable-stringify" +import { getOrCreateUser } from "./userActivity.services" + +export interface TokenInfo { + token: Hex + amount: bigint +} + +export interface PaymentInfo extends TokenInfo { + beneficiary: Hex +} + +export interface Order { + id?: string + user: Hex + sourceChain: string + destChain: string + deadline: bigint + nonce: bigint + fees: bigint + outputs: PaymentInfo[] + inputs: TokenInfo[] + callData: Hex +} + +export const DEFAULT_REFERRER = "0x0000000000000000000000000000000000000000000000000000000000000000" as Hex + +export class IntentGatewayService { + static async getOrCreateOrder( + order: Order, + referrer: string, + logsData: { + transactionHash: string + blockNumber: number + timestamp: bigint + }, + ): Promise { + const { transactionHash, blockNumber, timestamp } = logsData + + let orderPlaced = await OrderPlaced.get(order.id!) + + if (!orderPlaced) { + const { inputUSD, inputValuesUSD } = await this.getOrderValue(order) + orderPlaced = await OrderPlaced.create({ + id: order.id!, + user: order.user, + sourceChain: order.sourceChain, + destChain: order.destChain, + commitment: order.id!, + deadline: order.deadline, + nonce: order.nonce, + fees: order.fees, + inputTokens: order.inputs.map((input) => input.token), + inputAmounts: order.inputs.map((input) => input.amount), + inputValuesUSD: inputValuesUSD, + inputUSD: inputUSD, + outputTokens: order.outputs.map((output) => output.token), + outputAmounts: order.outputs.map((output) => output.amount), + outputBeneficiaries: order.outputs.map((output) => output.beneficiary), + calldata: order.callData, + status: OrderStatus.PLACED, + referrer, + createdAt: timestampToDate(timestamp), + blockNumber: BigInt(blockNumber), + blockTimestamp: timestamp, + transactionHash, + }) + await orderPlaced.save() + + logger.info( + `Order Placed Event successfully saved: ${stringify({ + orderPlaced, + })}`, + ) + + logger.info("Now awarding points for the Order Placed Event") + + // Award points for order placement - using USD value directly + const orderValue = new Decimal(inputUSD) + const pointsToAward = orderValue.floor().toNumber() + + await PointsService.awardPoints( + order.user, + ethers.utils.toUtf8String(order.sourceChain), + BigInt(pointsToAward), + ProtocolParticipantType.USER, + PointsActivityType.ORDER_PLACED_POINTS, + transactionHash, + `Points awarded for placing order ${order.id} with value ${inputUSD} USD`, + timestamp, + ) + + await VolumeService.updateVolume("IntentGateway.USER", inputUSD, timestamp) + + let user = await getOrCreateUser(order.user, referrer, timestamp) + user.totalOrdersPlaced = user.totalOrdersPlaced + BigInt(1) + user.totalOrderPlacedVolumeUSD = new Decimal(user.totalOrderPlacedVolumeUSD) + .plus(new Decimal(inputUSD)) + .toString() + user.createdAt = user.createdAt === timestampToDate(BigInt(0)) ? timestampToDate(timestamp) : user.createdAt + await user.save() + } else { + // Handle race condition: Order already exists (e.g., was filled first) + // Update all fields except status and status-related metadata + logger.info( + `Order ${stringify({ order: order.id })} already exists with status ${stringify({ status: orderPlaced.status })}. Updating order details while preserving status.`, + ) + + const existingStatus = orderPlaced.status + const { inputUSD, inputValuesUSD } = await this.getOrderValue(order) + + orderPlaced.user = order.user + orderPlaced.sourceChain = order.sourceChain + orderPlaced.destChain = order.destChain + orderPlaced.deadline = order.deadline + orderPlaced.nonce = order.nonce + orderPlaced.fees = order.fees + orderPlaced.inputTokens = order.inputs.map((input) => input.token) + orderPlaced.inputAmounts = order.inputs.map((input) => input.amount) + orderPlaced.inputValuesUSD = inputValuesUSD + orderPlaced.inputUSD = inputUSD + orderPlaced.outputTokens = order.outputs.map((output) => output.token) + orderPlaced.outputAmounts = order.outputs.map((output) => output.amount) + orderPlaced.outputBeneficiaries = order.outputs.map((output) => output.beneficiary) + orderPlaced.calldata = order.callData + orderPlaced.referrer = referrer + // Keep existing status - don't overwrite it + + await orderPlaced.save() + + logger.info( + `Order ${stringify({ order })} updated with actual data. Status remains: ${stringify({ existingStatus })}`, + ) + + // Award points for order placement - using USD value directly + // Only award if status is not already FILLED (to avoid double awarding) + if (existingStatus !== OrderStatus.FILLED) { + logger.info("Now awarding points for the Order Placed Event") + + const orderValue = new Decimal(inputUSD) + const pointsToAward = orderValue.floor().toNumber() + + await PointsService.awardPoints( + order.user, + ethers.utils.toUtf8String(order.sourceChain), + BigInt(pointsToAward), + ProtocolParticipantType.USER, + PointsActivityType.ORDER_PLACED_POINTS, + transactionHash, + `Points awarded for placing order ${order.id} with value ${inputUSD} USD`, + timestamp, + ) + + await VolumeService.updateVolume("IntentGateway.USER", inputUSD, timestamp) + } + } + + return orderPlaced + } + + static async getByCommitment(commitment: string): Promise { + const orderPlaced = await OrderPlaced.get(commitment) + + if (!orderPlaced) return null + + return orderPlaced + } + + private static async getOrderValue(order: Order): Promise<{ inputUSD: string; inputValuesUSD: string[] }> { + const inputValuesUSD = await this.getInputValuesUSD(order) + + return { + inputUSD: inputValuesUSD.total, + inputValuesUSD: inputValuesUSD.values, + } + } + + private static async getInputValuesUSD(order: Order): Promise<{ total: string; values: string[] }> { + return this.getTokenValuesUSD(order.inputs) + } + + private static async getOutputValuesUSD(outputs: PaymentInfo[]): Promise<{ total: string; values: string[] }> { + return this.getTokenValuesUSD(outputs) + } + + private static async getTokenValuesUSD( + tokens: { token: string; amount: bigint }[], + ): Promise<{ total: string; values: string[] }> { + const valuesUSD = await Promise.all( + tokens.map(async (token) => { + const tokenAddress = this.bytes32ToBytes20(token.token) + let decimals = 18 + let symbol = "eth" + + if (tokenAddress != "0x0000000000000000000000000000000000000000") { + const tokenContract = ERC6160Ext20Abi__factory.connect(tokenAddress, api) + decimals = await tokenContract.decimals() + symbol = await tokenContract.symbol() + } + + const price = await TokenPriceService.getPrice(symbol) + return PriceHelper.getAmountValueInUSD(token.amount, decimals, price) + }), + ) + + const total = valuesUSD.reduce((acc, curr) => { + return acc.plus(new Decimal(curr.amountValueInUSD)) + }, new Decimal(0)) + + return { + total: total.toFixed(18), + values: valuesUSD.map((value) => value.amountValueInUSD), + } + } + + static async updateOrderStatus( + commitment: string, + status: OrderStatus, + logsData: { + transactionHash: string + blockNumber: number + timestamp: bigint + }, + filler?: string, + ): Promise { + const { transactionHash, blockNumber, timestamp } = logsData + + let orderPlaced = await OrderPlaced.get(commitment) + + // For race condtions, we create a placeholder order that will be updated when the PLACED event arrives + if (!orderPlaced && status != OrderStatus.PLACED) { + logger.warn( + `Order ${stringify({ commitment })} does not exist yet but FILLED event received. Creating placeholder order.`, + ) + + orderPlaced = await OrderPlaced.create({ + id: commitment, + user: "0x0000000000000000000000000000000000000000" as Hex, + sourceChain: "", + destChain: "", + commitment: commitment, + deadline: BigInt(0), + nonce: BigInt(0), + fees: BigInt(0), + inputTokens: [], + inputAmounts: [], + inputValuesUSD: [], + inputUSD: "0", + outputTokens: [], + outputAmounts: [], + outputBeneficiaries: [], + calldata: "0x", + status: OrderStatus.FILLED, + referrer: DEFAULT_REFERRER, + createdAt: timestampToDate(timestamp), + blockNumber: BigInt(blockNumber), + blockTimestamp: timestamp, + transactionHash, + }) + await orderPlaced.save() + + logger.info(`Placeholder order with status FILLED created for commitment ${stringify({ commitment })}`) + } + + if (orderPlaced) { + orderPlaced.status = status === OrderStatus.PLACED ? orderPlaced.status : status + await orderPlaced.save() + + // Award points for order filling - using USD value directly + if (status === OrderStatus.FILLED && filler) { + if (orderPlaced.outputTokens.length > 0) { + // Volume + let outputPaymentInfo: PaymentInfo[] = orderPlaced.outputTokens.map((token, index) => { + return { + token: token as Hex, + amount: orderPlaced.outputAmounts[index], + beneficiary: orderPlaced.outputBeneficiaries[index] as Hex, + } + }) + let outputUSD = await this.getOutputValuesUSD(outputPaymentInfo) + + await VolumeService.updateVolume(`IntentGateway.FILLER.${filler}`, outputUSD.total, timestamp) + + const orderValue = new Decimal(orderPlaced.inputUSD) + const pointsToAward = orderValue.floor().toNumber() + + // Rewards + await PointsService.awardPoints( + filler, + ethers.utils.toUtf8String(orderPlaced.destChain), + BigInt(pointsToAward), + ProtocolParticipantType.FILLER, + PointsActivityType.ORDER_FILLED_POINTS, + transactionHash, + `Points awarded for filling order ${commitment} with value ${orderPlaced.inputUSD} USD`, + timestamp, + ) + + // User + let user = await getOrCreateUser(orderPlaced.user, orderPlaced.referrer) + user.totalOrderFilledVolumeUSD = new Decimal(user.totalOrderFilledVolumeUSD) + .plus(new Decimal(orderPlaced.inputUSD)) + .toString() + user.totalFilledOrders = user.totalFilledOrders + BigInt(1) + await user.save() + + // Referrer + if (user.referrer) { + const referrerPointsToAward = Math.floor(pointsToAward / 2) + await PointsService.awardPoints( + user.referrer, + ethers.utils.toUtf8String(orderPlaced.sourceChain), + BigInt(referrerPointsToAward), + ProtocolParticipantType.REFERRER, + PointsActivityType.ORDER_REFERRED_POINTS, + transactionHash, + `Points awarded for filling order ${commitment} with value ${orderPlaced.inputUSD} USD`, + timestamp, + ) + } + } + } + } + + const orderStatusMetadata = await OrderStatusMetadata.create({ + id: `${commitment}.${status}`, + orderId: commitment, + status, + chain: chainId, + timestamp, + blockNumber: blockNumber.toString(), + filler, + transactionHash, + createdAt: timestampToDate(timestamp), + }) + + await orderStatusMetadata.save() + } + + static bytes32ToBytes20(bytes32: string): string { + if (bytes32.length === 42) { + return bytes32 + } + + const bytes = hexToBytes(bytes32 as Hex) + const addressBytes = bytes.slice(12) + return bytesToHex(addressBytes) as Hex + } + + static computeOrderCommitment(order: Order): string { + const encodedOrder = encodeAbiParameters( + [ + { + name: "order", + type: "tuple", + components: [ + { name: "user", type: "bytes32" }, + { name: "sourceChain", type: "bytes" }, + { name: "destChain", type: "bytes" }, + { name: "deadline", type: "uint256" }, + { name: "nonce", type: "uint256" }, + { name: "fees", type: "uint256" }, + { + name: "outputs", + type: "tuple[]", + components: [ + { name: "token", type: "bytes32" }, + { name: "amount", type: "uint256" }, + { name: "beneficiary", type: "bytes32" }, + ], + }, + { + name: "inputs", + type: "tuple[]", + components: [ + { name: "token", type: "bytes32" }, + { name: "amount", type: "uint256" }, + ], + }, + { name: "callData", type: "bytes" }, + ], + }, + ], + [ + { + user: order.user as Hex, + sourceChain: order.sourceChain as Hex, + destChain: order.destChain as Hex, + deadline: order.deadline, + nonce: order.nonce, + fees: order.fees, + outputs: order.outputs.map((output) => ({ + token: output.token as Hex, + amount: output.amount, + beneficiary: output.beneficiary as Hex, + })), + inputs: order.inputs.map((input) => ({ + token: input.token as Hex, + amount: input.amount, + })), + callData: order.callData as Hex, + }, + ], + ) + + return keccak256(encodedOrder) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/points.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/points.service.ts new file mode 100644 index 00000000..2a0517ad --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/points.service.ts @@ -0,0 +1,128 @@ +import { Rewards as RewardPoints, RewardsActivityLog as RewardPointsActivityLog } from "@/configs/src/types" +import { ProtocolParticipantType, PointsActivityType } from "@/configs/src/types" +import { timestampToDate } from "@/utils/date.helpers" + +export class PointsService { + private static async getOrCreate( + address: string, + chain: string, + earnerType: ProtocolParticipantType, + ): Promise { + const rewardPointsId = `${address}-${chain}-${earnerType}` + let rewardPoints = await RewardPoints.get(rewardPointsId) + + if (!rewardPoints) { + logger.info(`Creating Reward Points for ${address} on ${chain} with earner type ${earnerType}`) + rewardPoints = await RewardPoints.create({ + id: rewardPointsId, + address, + chain, + points: BigInt(0), + earnerType, + }) + } + + await rewardPoints.save() + + logger.info(`Reward Points for ${address} on ${chain} with earner type ${earnerType} saved`) + + return rewardPoints + } + + static async awardPoints( + address: string, + chain: string, + points: bigint, + earnerType: ProtocolParticipantType, + activityType: PointsActivityType, + transactionHash: string, + description: string, + timestamp: bigint, + ): Promise { + const rewardPoints = await this.getOrCreate(address, chain, earnerType) + + logger.info(`Awarding ${points} points to ${address} on ${chain} with earner type ${earnerType}`) + + rewardPoints.points = rewardPoints.points + points + await rewardPoints.save() + + const activityLog = await RewardPointsActivityLog.create({ + id: `${address}-${earnerType}-${transactionHash}`, + chain, + points, + transactionHash, + earnerAddress: address, + earnerType, + activityType, + description, + createdAt: timestampToDate(timestamp), + }) + await activityLog.save() + } + + static async deductPoints( + address: string, + chain: string, + points: bigint, + earnerType: ProtocolParticipantType, + activityType: PointsActivityType, + transactionHash: string, + description: string, + timestamp: bigint, + ): Promise { + const rewardPoints = await this.getOrCreate(address, chain, earnerType) + + logger.info(`Deducting ${points} points from ${address} on ${chain} with earner type ${earnerType}`) + + rewardPoints.points = rewardPoints.points - points + await rewardPoints.save() + + const activityLog = await RewardPointsActivityLog.create({ + id: `${address}-${earnerType}-${transactionHash}`, + chain, + points: -points, // Store as negative in activity log + transactionHash, + earnerAddress: address, + earnerType, + activityType, + description, + createdAt: timestampToDate(timestamp), + }) + await activityLog.save() + } + + static async getPoints(address: string, chain: string, earnerType: ProtocolParticipantType): Promise { + const rewardPoints = await RewardPoints.get(`${address}-${chain}-${earnerType}`) + return rewardPoints?.points || BigInt(0) + } + + /** + * Get reward points by address + */ + static async getByAddress(address: string) { + return RewardPoints.getByAddress(address, { + orderBy: "points", + limit: -1, + }) + } + + /** + * Get reward points by chain + */ + static async getByChain(chain: string) { + return RewardPoints.getByChain(chain, { + orderBy: "points", + limit: -1, + }) + } + + /** + * Get reward points by points amount + */ + static async getByPoints(points: bigint) { + return RewardPoints.getByPoints(points, { + orderBy: "points", + limit: -1, + }) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/relayer.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/relayer.service.ts new file mode 100644 index 00000000..e45d0197 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/relayer.service.ts @@ -0,0 +1,172 @@ +import { Relayer, RelayerActivity, Transfer } from "@/configs/src/types/models" +import { RelayerChainStatsService } from "@/services/relayerChainStats.service" +// import { +// HandlePostRequestsTransaction, +// HandlePostResponsesTransaction, +// } from "@/configs/src/types/abi-interfaces/HandlerV1Abi" +import PriceHelper from "@/utils/price.helpers" +import { PointsService } from "@/services/points.service" +import { PointsActivityType, ProtocolParticipantType } from "@/configs/src/types" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { getBlockTimestamp } from "@/utils/rpc.helpers" +import { GET_ETHEREUM_L2_STATE_MACHINES } from "@/utils/l2-state-machine.helper" + +export class RelayerService { + /** + * Find a relayer by its id or create a new one if it doesn't exist + */ + static async findOrCreate(relayer_id: string, chain: string, timestamp: bigint): Promise { + let relayer = await Relayer.get(relayer_id) + + if (typeof relayer === "undefined") { + relayer = Relayer.create({ id: relayer_id }) + await relayer.save() + } + + return relayer + } + + /** + * Update the total fees earned by a relayer + * Fees earned by a relayer == Sum of all transfers to the relayer from the hyperbridge host address + */ + static async updateFeesEarned(transfer: Transfer, timestamp: bigint): Promise { + const relayer = await this.findOrCreate(transfer.to, transfer.chain, timestamp) + const relayer_chain_stats = await RelayerChainStatsService.findOrCreate(relayer.id, transfer.chain) + + relayer_chain_stats.feesEarned += transfer.amount + await this.updateRelayerActivity(relayer.id, timestamp) + + await relayer.save() + await relayer_chain_stats.save() + } + + /** + * Update the total fees earned by a relayer via accumulation + */ + static async updateFeesEarnedViaAccumulation( + relayer_id: string, + fee: bigint, + chain: any, + timestamp: bigint, + ): Promise { + const relayer = await this.findOrCreate(relayer_id, chain, timestamp) + const relayer_chain_stats = await RelayerChainStatsService.findOrCreate(relayer.id, chain) + + relayer_chain_stats.feesEarned += fee + await this.updateRelayerActivity(relayer.id, timestamp) + + await relayer.save() + await relayer_chain_stats.save() + } + + /** + * Update message delivered by the relayer + * @param relayer_id The relayer address + * @param chain The chain identifier + */ + static async updateMessageDelivered(relayer_id: string, chain: string, timestamp: bigint): Promise { + const relayer = await this.findOrCreate(relayer_id, chain, timestamp) + const relayer_chain_stats = await RelayerChainStatsService.findOrCreate(relayer.id, chain) + + relayer_chain_stats.numberOfSuccessfulMessagesDelivered += BigInt(1) + await this.updateRelayerActivity(relayer.id, timestamp) + + await relayer.save() + await relayer_chain_stats.save() + } + + /** + * Update relayer activity + * @param relayerId The relayer address + * @param timestamp The timestamp of the activit + */ + static async updateRelayerActivity(relayerId: string, timestamp: bigint) { + let activity = await RelayerActivity.get(relayerId) + if (!activity) { + activity = RelayerActivity.create({ id: relayerId, relayerId, lastUpdatedAt: timestamp }) + } + + activity.lastUpdatedAt = timestamp + await activity.save() + } + + /** + * Computes relayer specific stats from the handlePostRequest/handlePostResponse transactions on the handlerV1 contract + */ + // static async handlePostRequestOrResponseTransaction( + // chain: string, + // transaction: HandlePostRequestsTransaction | HandlePostResponsesTransaction, + // ): Promise { + // const { from: relayer_id, hash: transaction_hash, blockHash } = transaction + // const receipt = await transaction.receipt() + // const { status, gasUsed, effectiveGasPrice } = receipt + + // const nativeCurrencyPrice = await PriceHelper.getNativeCurrencyPrice(chain) + + // let gasFee = BigInt(effectiveGasPrice) * BigInt(gasUsed) + + // // Add the L1 Gas Used for L2 chains + // if (GET_ETHEREUM_L2_STATE_MACHINES().includes(chain)) { + // if ((receipt as any).l1Fee) { + // const l1Fee = BigInt((receipt as any).l1Fee ?? 0) + // gasFee += l1Fee + // } else { + // logger.error( + // `Could not find l1Fee in transaction receipt: ${JSON.stringify({ + // chain, + // transactionHash: transaction.hash, + // })}`, + // ) + // } + // } + + // const usdFee = (gasFee * nativeCurrencyPrice) / (10n ** 18n); + // const gasFeeInEth = Number(gasFee) / 1e18; + + // try { + // const timestamp = await getBlockTimestamp(blockHash, chain) + + // let relayer = await RelayerService.findOrCreate(relayer_id, chain, timestamp) + // let relayer_chain_stats = await RelayerChainStatsService.findOrCreate(relayer_id, chain) + + // let pointsToAWard = 50; + // let description = "`Points awarded for successful message delivered`"; + // if (status === true) { + // relayer_chain_stats.numberOfSuccessfulMessagesDelivered += BigInt(1) + // relayer_chain_stats.gasUsedForSuccessfulMessages += BigInt(gasUsed) + // relayer_chain_stats.gasFeeForSuccessfulMessages += BigInt(gasFee) + // relayer_chain_stats.usdGasFeeForSuccessfulMessages += usdFee + // } else { + // relayer_chain_stats.numberOfFailedMessagesDelivered += BigInt(1) + // relayer_chain_stats.gasUsedForFailedMessages += BigInt(gasUsed) + // relayer_chain_stats.gasFeeForFailedMessages += BigInt(gasFee) + // relayer_chain_stats.usdGasFeeForFailedMessages += usdFee + + // pointsToAWard = pointsToAWard / 2; + // description = "`Points awarded for failed message delivery`" + // } + + // await PointsService.awardPoints( + // relayer_id, + // chain, + // BigInt(pointsToAWard), + // ProtocolParticipantType.RELAYER, + // PointsActivityType.REWARD_POINTS_EARNED, + // transaction_hash, + // description, + // timestamp, + // ) + + // await relayer.save() + // await relayer_chain_stats.save() + + // logger.info(`Relayer: ${relayer_id} updated successfully for chain: ${chain}`) + // } catch (e) { + // const errorMessage = e instanceof Error ? e.message : String(e) + // logger.error( + // `Error while handling PostRequest/PostResponse transaction relayer updates: ${errorMessage}`, + // ) + // } + // } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/relayerChainStats.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/relayerChainStats.service.ts new file mode 100644 index 00000000..91807ada --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/relayerChainStats.service.ts @@ -0,0 +1,41 @@ +import { RelayerStatsPerChain } from "@/configs/src/types" + +export class RelayerChainStatsService { + /* + * Find the RelayerChainMetrics record for a relayer on a chain, create it if it doesn't exist + */ + static async findOrCreate(relayer_id: string, chain: string): Promise { + let id = `${relayer_id}-${chain}` + let metrics = await RelayerStatsPerChain.get(id) + + if (!metrics) { + metrics = RelayerStatsPerChain.create({ + id, + relayerId: relayer_id, + chain, + numberOfFailedMessagesDelivered: BigInt(0), + numberOfSuccessfulMessagesDelivered: BigInt(0), + gasUsedForFailedMessages: BigInt(0), + gasUsedForSuccessfulMessages: BigInt(0), + gasFeeForFailedMessages: BigInt(0), + gasFeeForSuccessfulMessages: BigInt(0), + usdGasFeeForFailedMessages: BigInt(0), + usdGasFeeForSuccessfulMessages: BigInt(0), + feesEarned: BigInt(0), + }) + await metrics.save() + } + + return metrics + } + + /** + * Get stats by fees earned + */ + static async getByFeesEarned(fees: bigint) { + return RelayerStatsPerChain.getByFeesEarned(fees, { + orderBy: "feesEarned", + limit: -1, + }) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/request.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/request.service.ts new file mode 100644 index 00000000..7c87b2d4 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/request.service.ts @@ -0,0 +1,227 @@ +import { solidityKeccak256 } from "ethers/lib/utils" +import { Status } from "@/configs/src/types/enums" +import { Request, RequestStatusMetadata } from "@/configs/src/types/models" +import { ethers } from "ethers" +import { timestampToDate } from "@/utils/date.helpers" + +export interface ICreateRequestArgs { + chain: string + commitment: string + body?: string | undefined + dest?: string | undefined + fee?: bigint | undefined + from?: string | undefined + nonce?: bigint | undefined + source?: string | undefined + timeoutTimestamp?: bigint | undefined + to?: string | undefined + status: Status + blockNumber: string + blockHash: string + transactionHash: string + blockTimestamp: bigint + createdAt: Date +} + +export interface IUpdateRequestStatusArgs { + commitment: string + status: Status + blockNumber: string + blockHash: string + transactionHash: string + timeoutHash?: string + blockTimestamp: bigint + chain: string +} + +const REQUEST_STATUS_WEIGHTS = { + [Status.SOURCE]: 1, + [Status.HYPERBRIDGE_DELIVERED]: 2, + [Status.DESTINATION]: 3, + [Status.HYPERBRIDGE_TIMED_OUT]: 4, + [Status.TIMED_OUT]: 5, +} + +export class RequestService { + /** + * Finds a request entity and creates a new one if it doesn't exist + * If the request exists, it updates the request details + */ + static async createOrUpdate(args: ICreateRequestArgs): Promise { + const { + chain, + commitment, + body, + dest, + fee, + from, + nonce, + source, + status, + timeoutTimestamp, + to, + blockNumber, + blockHash, + transactionHash, + blockTimestamp, + } = args + let request = await Request.get(commitment) + + logger.info( + `Processing Request: ${JSON.stringify({ + commitment, + transactionHash, + status, + })}`, + ) + + if (typeof request === "undefined") { + // Create new request if it doesn't exist + request = Request.create({ + id: commitment, + chain, + body: body || "", + dest: dest || "", + fee: fee || BigInt(0), + from: from || "", + nonce: nonce || BigInt(0), + source: source || "", + status, + timeoutTimestamp: timeoutTimestamp || BigInt(0), + to: to || "", + commitment, + createdAt: timestampToDate(blockTimestamp), + }) + + await request.save() + + logger.info( + `Created new request with details ${JSON.stringify({ + commitment, + transactionHash, + status, + })}`, + ) + } else { + // Update existing request with new details if provided + if (body !== undefined) request.body = body + if (dest !== undefined) request.dest = dest + if (fee !== undefined) request.fee = fee + if (from !== undefined) request.from = from + if (nonce !== undefined) request.nonce = nonce + if (source !== undefined) request.source = source + if (timeoutTimestamp !== undefined) request.timeoutTimestamp = timeoutTimestamp + if (to !== undefined) request.to = to + + await request.save() + + logger.info( + `Updated existing request with details ${JSON.stringify({ + commitment, + transactionHash, + status, + })}`, + ) + } + + return request + } + + /** + * Update the status of a request + * Also adds a new entry to the request status metadata + */ + static async updateStatus(args: IUpdateRequestStatusArgs): Promise { + const { commitment, blockNumber, blockHash, blockTimestamp, status, transactionHash, chain } = args + + logger.info( + `Updating Request Status: ${JSON.stringify({ + commitment, + transactionHash, + status, + })}`, + ) + + let request = await Request.get(commitment) + + if (!request) { + // Create new request and request status metadata + + await this.createOrUpdate({ + commitment, + chain, + body: undefined, + dest: undefined, + fee: undefined, + from: undefined, + nonce: undefined, + source: undefined, + timeoutTimestamp: undefined, + to: undefined, + blockNumber: "", + blockHash: "", + blockTimestamp: 0n, + status, + transactionHash: "", + createdAt: timestampToDate(0n), + }) + + logger.info( + `Created new request while attempting request update with details ${JSON.stringify({ + commitment, + transactionHash, + status, + })}`, + ) + } + + let requestStatusMetadata = RequestStatusMetadata.create({ + id: `${commitment}.${status}`, + requestId: commitment, + status, + chain, + timestamp: blockTimestamp, + blockNumber, + blockHash, + transactionHash, + createdAt: timestampToDate(blockTimestamp), + }) + + await requestStatusMetadata.save() + } + + /** + * Compute the request commitment + */ + static computeRequestCommitment( + source: string, + dest: string, + nonce: bigint, + timeoutTimestamp: bigint, + from: string, + to: string, + body: string, + ): string { + logger.info( + `Computing request commitment with details ${JSON.stringify({ + source, + dest, + nonce: nonce.toString(), + timeoutTimestamp: timeoutTimestamp.toString(), + from, + to, + body, + })}`, + ) + + // Convert source, dest, from, to, body to bytes + const sourceByte = ethers.utils.toUtf8Bytes(source) + const destByte = ethers.utils.toUtf8Bytes(dest) + + let hash = solidityKeccak256( + ["bytes", "bytes", "uint64", "uint64", "bytes", "bytes", "bytes"], + [sourceByte, destByte, nonce, timeoutTimestamp, from, to, body], + ) + return hash + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/response.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/response.service.ts new file mode 100644 index 00000000..a3afbee0 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/response.service.ts @@ -0,0 +1,222 @@ +import { solidityKeccak256 } from "ethers/lib/utils" +import { Request, Response, ResponseStatusMetadata, Status } from "@/configs/src/types" +import { ethers } from "ethers" +import { timestampToDate } from "@/utils/date.helpers" + +export interface ICreateResponseArgs { + chain: string + commitment: string + response_message?: string | undefined + responseTimeoutTimestamp?: bigint | undefined + request?: Request | undefined + status: Status + blockNumber: string + blockHash: string + transactionHash: string + blockTimestamp: bigint +} + +export interface IUpdateResponseStatusArgs { + commitment: string + status: Status + blockNumber: string + blockHash: string + transactionHash: string + timeoutHash?: string + blockTimestamp: bigint + chain: string +} + +const RESPONSE_STATUS_WEIGHTS = { + [Status.SOURCE]: 1, + [Status.HYPERBRIDGE_DELIVERED]: 2, + [Status.DESTINATION]: 3, + [Status.HYPERBRIDGE_TIMED_OUT]: 4, + [Status.TIMED_OUT]: 5, +} + +export class ResponseService { + /** + * Finds a response enitity and creates a new one if it doesn't exist + */ + static async findOrCreate(args: ICreateResponseArgs): Promise { + const { + chain, + commitment, + request, + response_message, + responseTimeoutTimestamp, + status, + blockNumber, + blockHash, + blockTimestamp, + transactionHash, + } = args + let response = await Response.get(commitment) + + logger.info( + `Creating PostResponse Event: ${JSON.stringify({ + commitment, + transactionHash, + status, + })}`, + ) + + if (typeof response === "undefined") { + response = Response.create({ + id: commitment, + commitment, + chain, + response_message, + requestId: request?.id, + status, + responseTimeoutTimestamp, + createdAt: timestampToDate(blockTimestamp), + }) + + await response.save() + + logger.info( + `Created new response with details ${JSON.stringify({ + commitment, + transactionHash, + status, + })}`, + ) + + let responseStatusMetadata = ResponseStatusMetadata.create({ + id: `${commitment}.${status}`, + responseId: commitment, + status, + chain, + timestamp: blockTimestamp, + blockNumber, + blockHash, + transactionHash, + createdAt: timestampToDate(blockTimestamp), + }) + + await responseStatusMetadata.save() + } + + return response + } + + /** + * Update the status of a response + * Also adds a new entry to the response status metadata + */ + static async updateStatus(args: IUpdateResponseStatusArgs): Promise { + const { commitment, blockNumber, blockHash, blockTimestamp, status, transactionHash, chain } = args + + let response = await Response.get(commitment) + + if (response) { + let responseStatusMetadata = ResponseStatusMetadata.create({ + id: `${commitment}.${status}`, + responseId: commitment, + status, + chain, + timestamp: blockTimestamp, + blockNumber, + blockHash, + transactionHash, + createdAt: timestampToDate(blockTimestamp), + }) + + await responseStatusMetadata.save() + } else { + await this.findOrCreate({ + chain, + commitment, + blockHash, + blockNumber, + blockTimestamp, + status, + transactionHash, + request: undefined, + responseTimeoutTimestamp: undefined, + response_message: undefined, + }) + + logger.error( + `Attempted to update status of non-existent response with commitment: ${commitment} in transaction: ${transactionHash}`, + ) + + logger.info( + `Created new response while attempting response update with details: ${JSON.stringify({ + commitment, + transactionHash, + status, + })}`, + ) + } + } + + /** + * Compute the response commitment and return the hash + */ + static computeResponseCommitment( + source: string, + dest: string, + nonce: bigint, + timeoutTimestamp: bigint, + from: string, + to: string, + body: string, + response: string, + responseTimeoutTimestamp: bigint, + ): string { + logger.info( + `Computing response commitment with details ${JSON.stringify({ + source, + dest, + nonce: nonce.toString(), + timeoutTimestamp: timeoutTimestamp.toString(), + responseTimeoutTimestamp: responseTimeoutTimestamp.toString(), + response, + from, + to, + body, + })}`, + ) + + // Convert source, dest, from, to, body to bytes + const sourceByte = ethers.utils.toUtf8Bytes(source) + const destByte = ethers.utils.toUtf8Bytes(dest) + + let hash = solidityKeccak256( + ["bytes", "bytes", "uint64", "uint64", "bytes", "bytes", "bytes", "bytes", "uint64"], + [sourceByte, destByte, nonce, timeoutTimestamp, from, to, body, response, responseTimeoutTimestamp], + ) + return hash + } + + /** + * Find responses by chain + */ + static async findByChain(chain: string) { + return Response.getByChain(chain, { + orderBy: "id", + limit: -1, + }) + } + + /** + * Find a response by commitment + */ + static async findByCommitment(commitment: string) { + // Since commitment is the ID, we can just use get() + return Response.get(commitment) + } + + /** + * Find responses by request ID + */ + static async findByRequestId(requestId: string) { + return Response.getByRequestId(requestId, { + orderBy: "id", + limit: -1, + }) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/stateMachine.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/stateMachine.service.ts new file mode 100644 index 00000000..4a80a737 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/stateMachine.service.ts @@ -0,0 +1,165 @@ +import { StateMachineUpdateEvent } from "@/configs/src/types" +import { fetchStateCommitmentsEVM, fetchStateCommitmentsSubstrate, getStateId } from "@/utils/state-machine.helper" +import { timestampToDate } from "@/utils/date.helpers" + +// Arguments to functions that create StateMachineUpdated events +export interface ICreateStateMachineUpdatedEventArgs { + stateMachineId: string + height: number + blockHash: string + blockNumber: number + transactionHash: string + transactionIndex: number + timestamp: number + consensusStateId: string +} + +export class StateMachineService { + /** + * Create a new Evm Host StateMachineUpdated event entity + */ + static async createEvmStateMachineUpdatedEvent( + args: ICreateStateMachineUpdatedEventArgs, + chain: string, + ): Promise { + const { + blockHash, + blockNumber, + transactionHash, + transactionIndex, + timestamp, + stateMachineId, + height, + consensusStateId, + } = args + + logger.info( + `Creating StateMachineUpdated Event: ${JSON.stringify({ + args, + })}`, + ) + + logger.info(`Using Consensus State ID: ${consensusStateId}`) + + const stateCommitment = await fetchStateCommitmentsEVM({ + client: api, + stateMachineId, + consensusStateId, + height: BigInt(height.toString()), + }) + + if (!stateCommitment) { + logger.info(`State Commitment not found for ${stateMachineId}`) + return + } + + const event = StateMachineUpdateEvent.create({ + id: `${chain}_${transactionHash}_${stateMachineId}_${height}`, + stateMachineId, + height, + chain, + transactionHash, + transactionIndex: Number(transactionIndex), + blockHash, + blockNumber: Number(blockNumber), + commitmentTimestamp: stateCommitment.timestamp, + createdAt: timestampToDate(timestamp), + }) + + await event.save() + } + + /** + * Create a new Hyperbridge StateMachineUpdated event entity + */ + static async createSubstrateStateMachineUpdatedEvent( + args: ICreateStateMachineUpdatedEventArgs, + chain: string, + ): Promise { + const { + blockHash, + blockNumber, + transactionHash, + transactionIndex, + timestamp, + stateMachineId, + height, + consensusStateId, + } = args + + logger.info( + `Creating StateMachineUpdated Event: ${JSON.stringify({ + args, + })}`, + ) + + logger.info(`Using Consensus State ID: ${consensusStateId}`) + + const stateCommitment = await fetchStateCommitmentsSubstrate({ + api: api, + stateMachineId, + consensusStateId, + height: BigInt(height.toString()), + }) + + if (!stateCommitment) { + logger.info(`State Commitment not found for ${stateMachineId}`) + return + } + + const event = StateMachineUpdateEvent.create({ + id: `${stateMachineId}-${transactionHash}-${height}`, + stateMachineId, + height, + chain, + transactionHash, + transactionIndex: Number(transactionIndex), + blockHash, + blockNumber: Number(blockNumber), + commitmentTimestamp: stateCommitment.timestamp, + createdAt: timestampToDate(timestamp), + }) + + await event.save() + } + + /** + * Get updates by state machine ID + */ + static async getByStateMachineId(stateMachineId: string) { + return StateMachineUpdateEvent.getByStateMachineId(stateMachineId, { + orderBy: "height", + limit: -1, + }) + } + + /** + * Get updates by height + */ + static async getByHeight(height: number) { + return StateMachineUpdateEvent.getByHeight(height, { + orderBy: "blockNumber", + limit: -1, + }) + } + + /** + * Get updates by block number + */ + static async getByBlockNumber(blockNumber: number) { + return StateMachineUpdateEvent.getByBlockNumber(blockNumber, { + orderBy: "transactionIndex", + limit: -1, + }) + } + + /** + * Get updates by creation date + */ + static async getByCreatedAt(createdAt: Date) { + return StateMachineUpdateEvent.getByCreatedAt(createdAt, { + orderBy: "blockNumber", + limit: -1, + }) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/token-price.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/token-price.service.ts new file mode 100644 index 00000000..ff6add27 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/token-price.service.ts @@ -0,0 +1,209 @@ +import stringify from "safe-stable-stringify" +import { TokenPrice, TokenPriceLog } from "@/configs/src/types" +import { normalizeTimestamp, timestampToDate } from "@/utils/date.helpers" +import PriceHelper from "@/utils/price.helpers" +import { fulfilled } from "@/utils/data.helper" +import { ErrTokenPriceUnavailable } from "@/types/errors" +import { getHostStateMachine } from "@/utils/substrate.helpers" +import { TESTNET_STATE_MACHINE_IDS } from "@/testnet-state-machine-ids" + +import { TokenRegistryService } from "./token-registry.service" +import { TOKEN_REGISTRY, TokenConfig } from "@/addresses/token-registry.addresses" + +const DEFAULT_PROVIDER = "COINGECKO" as const + +/** + * Check if current chain is a testnet chain + */ +function isTestnetChain(): boolean { + try { + const currentStateMachineId = getHostStateMachine(chainId) + return TESTNET_STATE_MACHINE_IDS.includes(currentStateMachineId) + } catch (error) { + // If we can't determine the state machine ID, assume it's not testnet + return false + } +} + +/** + * Token Price Service fetches prices from CoinGecko adapter and stores them in the TokenPrice (current) and TokenPriceLog (historical). + */ +export class TokenPriceService { + /** + * getPrice fetches the current price for a token + * @param symbol - The symbol of the token to fetch the price for + * @returns A Promise that resolves to the price as a number + */ + static async getPrice(symbol: string, currentTimestamp = BigInt(Date.now())): Promise { + // Return zero price for testnet chains + if (isTestnetChain()) { + logger.info(`[TokenPriceService.getPrice] Returning zero price for testnet chain: ${symbol}`) + return 0 + } + + try { + const allowedConfig = TOKEN_REGISTRY.find((cfg) => cfg.symbol === symbol) + if (!allowedConfig) { + logger.warn(`[TokenPriceService.getPrice] Skipping dynamic price for non-whitelisted token: ${symbol}`) + return 0 + } + + let token = await TokenRegistryService.get(symbol) + if (!token) { + token = await TokenRegistryService.getOrCreateToken(allowedConfig as TokenConfig, currentTimestamp) + } + + let tokenPrice = await TokenPrice.get(symbol) + if (!tokenPrice) { + const updatedTokenPrices = await this.updateTokenPrices([symbol], currentTimestamp) + if (updatedTokenPrices instanceof Error) { + logger.error( + `[TokenPriceService.getPrice] Failed to update token price for ${symbol}`, + updatedTokenPrices, + ) + return 0 + } + if (updatedTokenPrices.length === 0) { + logger.error(`[TokenPriceService.getPrice] No token prices updated for ${symbol}`) + return 0 + } + tokenPrice = updatedTokenPrices[0] + } + + const stale = await TokenRegistryService.isStale(token, tokenPrice.lastUpdatedAt, currentTimestamp) + if (!stale) return parseFloat(tokenPrice.price) + + const updatedTokenPrices = await this.updateTokenPrices([symbol], currentTimestamp) + if (updatedTokenPrices instanceof Error) { + logger.error( + `[TokenPriceService.getPrice] Failed to update stale token price for ${symbol}`, + updatedTokenPrices, + ) + return 0 + } + if (updatedTokenPrices.length === 0) { + logger.error(`[TokenPriceService.getPrice] No token prices updated for stale ${symbol}`) + return 0 + } + + return parseFloat(tokenPrice.price) + } catch (error) { + if (ErrTokenPriceUnavailable.isError(error)) { + logger.warn(`[TokenPriceService.getPrice] Price unavailable for ${symbol}, returning 0`) + return 0 + } + + logger.error(`[TokenPriceService.getPrice] Failed to get token price for ${symbol}`, error) + return 0 + } + } + + /** + * storeTokenPrice creates or updates a TokenPrice entity and creates a TokenPriceLog entry + * @param symbol - Token symbol + * @param price - Price value + * @param blockTimestamp - Block timestamp + */ + static async storeTokenPrice(symbol: string, price: number, blockTimestamp: bigint): Promise { + const normalizedTimestamp = normalizeTimestamp(blockTimestamp) + + let tokenPrice = await TokenPrice.get(symbol) + if (!tokenPrice) { + tokenPrice = TokenPrice.create({ + id: symbol, + symbol, + currency: "USD", + price: price.toString(), + lastUpdatedAt: normalizedTimestamp, + }) + } + + tokenPrice.price = price.toString() + tokenPrice.lastUpdatedAt = normalizedTimestamp + logger.debug(`[TokenPriceService.storeTokenPrice] Updating price entry: ${symbol}`) + + const tokenPriceLog = TokenPriceLog.create({ + id: `${symbol}-${blockTimestamp}`, + symbol, + currency: "USD", + price: price.toString(), + provider: DEFAULT_PROVIDER, + timestamp: normalizedTimestamp, + createdAt: timestampToDate(blockTimestamp), + }) + + await tokenPrice.save() + await tokenPriceLog.save() + + return tokenPrice + } + + static async initializePriceIndexing(currentTimestamp: bigint): Promise { + await TokenRegistryService.initialize(currentTimestamp) + await this.syncAllTokenPrices(currentTimestamp) + } + + /** + * syncAllTokenPrices updates prices for all tokens that require updates + * @param currentTimestamp - Current timestamp + * @param currency - Currency to update (defaults to USD) + */ + static async syncAllTokenPrices(currentTimestamp: bigint): Promise { + const allowedConfigs = TOKEN_REGISTRY + + await Promise.all( + allowedConfigs.map((cfg) => TokenRegistryService.getOrCreateToken(cfg as TokenConfig, currentTimestamp)), + ) + + const tokensToUpdate = allowedConfigs.map(async (cfg) => { + const token = await TokenRegistryService.get(cfg.symbol) + if (!token) return null + + const tokenPrice = await TokenPrice.get(cfg.symbol) + if (!tokenPrice) { + return cfg.symbol + } + + const isStale = await TokenRegistryService.isStale(token, tokenPrice.lastUpdatedAt, currentTimestamp) + return isStale ? cfg.symbol : null + }) + + const checkResults = await Promise.allSettled(tokensToUpdate) + const symbolsNeedingUpdate = fulfilled(checkResults).filter((t) => t !== null) + if (symbolsNeedingUpdate.length === 0) { + return + } + + const result = await this.updateTokenPrices(symbolsNeedingUpdate, currentTimestamp) + if (result instanceof Error) { + logger.error(`[TokenPriceService.syncAllTokenPrices] Failed to update token prices`, result) + } + } + + /** + * updateTokenPrices fetches prices from CoinGecko and stores them + * @param symbols - Array of token symbols to update + * @param currencies - Currencies to store prices (optional) + * @param blockTimestamp - Timestamp of the block to update prices for (optional) + */ + static async updateTokenPrices(symbols: string[], blockTimestamp: bigint): Promise { + logger.info(`[TokenPriceService.updateTokenPrices] Syncing prices for: ${symbols}`) + + const response = await PriceHelper.getTokenPriceFromCoinGecko(symbols) + if (response instanceof Error) { + return response + } + + logger.info(`[TokenPriceService.updateTokenPrices] CoinGecko response: ${stringify(response)}`) + + const storePromises = symbols.flatMap((symbol) => { + const prices = (response[symbol.toLowerCase()] || response[symbol.toUpperCase()])?.usd + if (!prices) return [] + + return this.storeTokenPrice(symbol, prices, blockTimestamp) + }) + + const updatedTokensPromise = await Promise.allSettled(storePromises) + return fulfilled(updatedTokensPromise) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/token-registry.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/token-registry.service.ts new file mode 100644 index 00000000..8540d36a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/token-registry.service.ts @@ -0,0 +1,137 @@ +import { TOKEN_REGISTRY, TokenConfig } from "@/addresses/token-registry.addresses" +import { TokenRegistry } from "@/configs/src/types" +import { normalizeTimestamp, timestampToDate } from "@/utils/date.helpers" +import { fulfilled, safeArray } from "@/utils/data.helper" + +/** + * Token Registry Service manages token configurations and metadata, + * providing a centralized repository for token information. + */ +export class TokenRegistryService { + /** + * Initialize token registry with default tokens from TOKEN_REGISTRY. + * Only processes new tokens that don't exist in the database. + * @param currentTimestamp - Current timestamp + */ + static async initialize(currentTimestamp: bigint): Promise { + logger.info(`[TokenRegistryService.initialize] Initializing token registry`) + + try { + const storedTokens = await this.getTokens() + const tokenConfigs = safeArray(TOKEN_REGISTRY) + + const storedSymbols = new Set(storedTokens.map((token) => token.symbol)) + + const newTokenConfigs = tokenConfigs.filter((config) => !storedSymbols.has(config.symbol)) + if (newTokenConfigs.length === 0) { + return + } + + const promises = newTokenConfigs.map((config) => this.getOrCreateToken(config, currentTimestamp)) + + const results = await Promise.allSettled(promises) + const successful = fulfilled(results) + + logger.info(`[TokenRegistryService.initialize] Successfully registered ${successful.length} new tokens`) + } catch (error) { + // @ts-ignore + throw new Error(`Token registry initialization failed: ${error.message}`) + } + } + + /** + * Register or update a token in the registry + * @param tokenConfig - Token configuration + * @param currentTimestamp - Current timestamp + */ + static async getOrCreateToken(config: TokenConfig, currentTimestamp: bigint): Promise { + const { name, symbol, updateFrequencySeconds, address } = config + + let token = await this.get(symbol) + if (!token) { + token = TokenRegistry.create({ + id: symbol, + name, + symbol, + updateFrequencySeconds, + address, + lastUpdatedAt: normalizeTimestamp(currentTimestamp), + createdAt: timestampToDate(currentTimestamp), + }) + } + + token.name = name + token.address = address + token.updateFrequencySeconds = updateFrequencySeconds + token.lastUpdatedAt = normalizeTimestamp(currentTimestamp) + + await token.save() + + return token + } + + /** + * Check if the token needs price update based on its update frequency + * @param symbol - Token symbol + * @param lastPriceUpdate - Token price last updated timestamp in bigint + * @param currentTimestamp - Current timestamp in bigint + * @returns Boolean indicating if token needs update + */ + static async isStale(token: TokenRegistry, lastPriceUpdate: bigint, currentTimestamp: bigint): Promise { + const timeSinceUpdateMs = Number(normalizeTimestamp(currentTimestamp)) - Number(lastPriceUpdate) + const frequencyMs = token.updateFrequencySeconds * 1000 // Convert to milliseconds + const needsUpdate = timeSinceUpdateMs >= frequencyMs + + logger.debug( + `[TokenRegistryService.isStale] Token ${token.symbol}: timeSinceUpdate=${timeSinceUpdateMs}ms, frequency=${frequencyMs}ms, needsUpdate=${needsUpdate}`, + ) + + return needsUpdate + } + + /** + * getTokens fetches all tokens from the database with pagination. + * @param limit - Optional page size (defaults to 1000 for better performance) + * @returns Promise - Array of all tokens + */ + static async getTokens(limit: number = 100): Promise { + const allTokens: TokenRegistry[] = [] + let offset = 0 + let totalFetched = 0 + + try { + while (true) { + const startTime = Date.now() + const tokens = await TokenRegistry.getByFields([], { limit, offset }) + const fetchTime = Date.now() - startTime + + if (tokens.length === 0) { + break + } + + allTokens.push(...tokens) + totalFetched += tokens.length + offset += limit + + if (tokens.length < limit) { + break + } + } + + logger.info(`[TokenRegistryService.getTokens] Successfully fetched ${totalFetched} tokens total`) + return allTokens + } catch (error) { + logger.error(`[TokenRegistryService.getTokens] Error fetching tokens at offset ${offset}:`, error) + throw new Error(`Failed to fetch tokens: ${error instanceof Error ? error.message : "Unknown error"}`) + } + } + + /** + * get fetches a token by symbol + * @param symbol + * @returns + */ + static async get(symbol: string): ReturnType { + return TokenRegistry.get(symbol) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/tokenGateway.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/tokenGateway.service.ts new file mode 100644 index 00000000..7eaa0dab --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/tokenGateway.service.ts @@ -0,0 +1,180 @@ +import Decimal from "decimal.js" + +import { ERC6160Ext20Abi__factory, TokenGatewayAbi__factory } from "@/configs/src/types/contracts" +import { + TeleportStatus, + TeleportStatusMetadata, + TokenGatewayAssetTeleported, + ProtocolParticipantType, + PointsActivityType, +} from "@/configs/src/types" +import { timestampToDate } from "@/utils/date.helpers" +import { PointsService } from "./points.service" +import { TokenPriceService } from "./token-price.service" +import PriceHelper from "@/utils/price.helpers" +import { TOKEN_GATEWAY_ADDRESSES } from "@/token-gateway-addresses" +import { getOrCreateUser } from "./userActivity.services" + +export interface IAssetDetails { + erc20_address: string + erc6160_address: string + is_erc20: boolean + is_erc6160: boolean +} + +export interface ITeleportParams { + to: string + dest: string + amount: bigint + commitment: string + from: string + assetId: string + redeem: boolean +} + +export class TokenGatewayService { + /** + * Get asset details + */ + static async getAssetDetails(asset_id: string): Promise { + const TOKEN_GATEWAY_CONTRACT_ADDRESS = TOKEN_GATEWAY_ADDRESSES[`EVM-${chainId}`] + const tokenGatewayContract = TokenGatewayAbi__factory.connect(TOKEN_GATEWAY_CONTRACT_ADDRESS, api) + + const erc20Address = await tokenGatewayContract.erc20(asset_id) + const erc6160Address = await tokenGatewayContract.erc6160(asset_id) + + return { + erc20_address: erc20Address, + erc6160_address: erc6160Address, + is_erc20: !erc20Address.includes("0x" + "0".repeat(39)), + is_erc6160: !erc6160Address.includes("0x" + "0".repeat(39)), + } + } + + /** + * Get or create a teleport record + */ + static async getOrCreate( + teleportParams: ITeleportParams, + logsData: { + transactionHash: string + blockNumber: number + timestamp: bigint + }, + ): Promise { + const { transactionHash, blockNumber, timestamp } = logsData + + let teleport = await TokenGatewayAssetTeleported.get(teleportParams.commitment) + + const tokenDetails = await this.getAssetDetails(teleportParams.assetId.toString()) + const tokenAddress = tokenDetails.is_erc20 ? tokenDetails.erc20_address : tokenDetails.erc6160_address + + const tokenContract = ERC6160Ext20Abi__factory.connect(tokenAddress, api) + const decimals = await tokenContract.decimals() + const symbol = await tokenContract.symbol() + + const price = await TokenPriceService.getPrice(symbol, timestamp) + const { amountValueInUSD } = PriceHelper.getAmountValueInUSD(teleportParams.amount, decimals, price) + + if (!teleport) { + teleport = TokenGatewayAssetTeleported.create({ + id: teleportParams.commitment, + from: teleportParams.from, + sourceChain: chainId, + destChain: teleportParams.dest, + commitment: teleportParams.commitment, + amount: teleportParams.amount, + assetId: teleportParams.assetId.toString(), + to: teleportParams.to, + redeem: teleportParams.redeem, + status: TeleportStatus.TELEPORTED, + usdValue: amountValueInUSD, + createdAt: timestampToDate(timestamp), + blockNumber: BigInt(blockNumber), + blockTimestamp: timestamp, + transactionHash, + }) + await teleport.save() + + // Award points for token teleport - using USD value directly + const teleportValue = new Decimal(amountValueInUSD) + const pointsToAward = teleportValue.floor().toNumber() + + await PointsService.awardPoints( + teleportParams.from, + chainId, + BigInt(pointsToAward), + ProtocolParticipantType.USER, + PointsActivityType.TOKEN_TELEPORTED_POINTS, + transactionHash, + `Points awarded for teleporting token ${teleportParams.assetId} with value ${amountValueInUSD} USD`, + timestamp, + ) + + const user = await getOrCreateUser(teleportParams.from) + user.createdAt = user.createdAt === timestampToDate(BigInt(0)) ? timestampToDate(timestamp) : user.createdAt + user.totalTeleports = user.totalTeleports + BigInt(1) + user.totalTeleportedVolumeUSD = new Decimal(user.totalTeleportedVolumeUSD) + .plus(new Decimal(amountValueInUSD)) + .toString() + // Optimistically update the total successful teleports and volume + user.totalSuccessfulTeleports = user.totalSuccessfulTeleports + BigInt(1) + user.totalSuccessfulTeleportedVolumeUSD = new Decimal(user.totalSuccessfulTeleportedVolumeUSD) + .plus(new Decimal(amountValueInUSD)) + .toString() + await user.save() + } + + return teleport + } + + /** + * Get teleport by commitment + */ + static async getByCommitment(commitment: string): Promise { + const teleport = await TokenGatewayAssetTeleported.get(commitment) + return teleport + } + + /** + * Update teleport status + */ + static async updateTeleportStatus( + commitment: string, + status: TeleportStatus, + logsData: { + transactionHash: string + blockNumber: number + timestamp: bigint + }, + ): Promise { + const { transactionHash, blockNumber, timestamp } = logsData + + const teleport = await TokenGatewayAssetTeleported.get(commitment) + + if (teleport) { + teleport.status = status + await teleport.save() + + const teleportStatusMetadata = await TeleportStatusMetadata.create({ + id: `${commitment}.${status}`, + status, + chain: `EVM-${chainId}`, + timestamp, + blockNumber: blockNumber.toString(), + transactionHash, + teleportId: teleport?.id ?? "", + createdAt: timestampToDate(timestamp), + }) + + await teleportStatusMetadata.save() + } + } + + static async getAssetTokenContract(assetId: string) { + const tokenDetails = await TokenGatewayService.getAssetDetails(assetId.toString()) + const tokenAddress = tokenDetails.is_erc20 ? tokenDetails.erc20_address : tokenDetails.erc6160_address + + return ERC6160Ext20Abi__factory.connect(tokenAddress, api) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/transfer.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/transfer.service.ts new file mode 100644 index 00000000..46877ef6 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/transfer.service.ts @@ -0,0 +1,69 @@ +import { Transfer } from "@/configs/src/types/models" + +// Argument for storing transfer events +export interface IStoreTranferArgs { + from: string + to: string + value: BigInt + transactionHash: string + chain: string +} + +export class TransferService { + /** + * Increment the number of post requests handled by a relayer + */ + static async storeTransfer(arg: IStoreTranferArgs): Promise { + const { from, to, value, transactionHash, chain } = arg + let transfer = Transfer.create({ + id: transactionHash, + amount: BigInt(value.toString()), + from, + to, + chain, + }) + + await transfer.save() + return transfer + } + + /** + * Get transfers by amount + */ + static async getByAmount(amount: bigint) { + return Transfer.getByAmount(amount, { + orderBy: "id", + limit: -1, + }) + } + + /** + * Get transfers by sender address + */ + static async getByFrom(from: string) { + return Transfer.getByFrom(from, { + orderBy: "id", + limit: -1, + }) + } + + /** + * Get transfers by recipient address + */ + static async getByTo(to: string) { + return Transfer.getByTo(to, { + orderBy: "id", + limit: -1, + }) + } + + /** + * Get transfers by chain + */ + static async getByChain(chain: string) { + return Transfer.getByChain(chain, { + orderBy: "id", + limit: -1, + }) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/userActivity.services.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/userActivity.services.ts new file mode 100644 index 00000000..0c27ce41 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/userActivity.services.ts @@ -0,0 +1,28 @@ +import { UserActivity } from "@/configs/src/types" +import { timestampToDate } from "@/utils/date.helpers" + +export async function getOrCreateUser(address: string, referrer?: string, timestamp?: bigint): Promise { + const user = await UserActivity.get(address) + if (user) { + if (!user.referrer && referrer) { + user.referrer = referrer + await user.save() + } + return user + } + const newUser = UserActivity.create({ + id: address, + referrer, + totalOrdersPlaced: BigInt(0), + totalFilledOrders: BigInt(0), + totalTeleports: BigInt(0), + totalSuccessfulTeleports: BigInt(0), + totalOrderPlacedVolumeUSD: "0", + totalOrderFilledVolumeUSD: "0", + totalTeleportedVolumeUSD: "0", + totalSuccessfulTeleportedVolumeUSD: "0", + createdAt: timestampToDate(timestamp || BigInt(0)), + }) + await newUser.save() + return newUser +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/volume.service.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/volume.service.ts new file mode 100644 index 00000000..d5214191 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/services/volume.service.ts @@ -0,0 +1,101 @@ +import Decimal from "decimal.js" + +import { CumulativeVolumeUSD, DailyVolumeUSD } from "@/configs/src/types" +import { getDateFormatFromTimestamp, timestampToDate } from "@/utils/date.helpers" +import { getHostStateMachine } from "@/utils/substrate.helpers" + +export class VolumeService { + /** + * Update cumulative volume for a given identifier + * @param baseId - The identifier for the cumulative volume record + * @param volumeUSD - The volume in USD to add + * @param timestamp - The timestamp of the transaction + */ + static async updateCumulativeVolume(baseId: string, volumeUSD: string, timestamp: bigint): Promise { + const id = this.getChainTypeId(baseId) + let cumulativeVolumeUSD = await CumulativeVolumeUSD.get(id) + + if (!cumulativeVolumeUSD) { + cumulativeVolumeUSD = CumulativeVolumeUSD.create({ + id, + volumeUSD: new Decimal(volumeUSD).toFixed(18), + lastUpdatedAt: timestamp, + }) + } + + if (cumulativeVolumeUSD.lastUpdatedAt !== timestamp) { + cumulativeVolumeUSD.volumeUSD = new Decimal(cumulativeVolumeUSD.volumeUSD) + .plus(new Decimal(volumeUSD)) + .toFixed(18) + cumulativeVolumeUSD.lastUpdatedAt = timestamp + } + + await cumulativeVolumeUSD.save() + } + + /** + * Update daily volume for a given identifier + * Creates a new record every 24 hours + * @param baseId - The base identifier for the daily volume record + * @param volumeUSD - The volume in USD to add + * @param timestamp - The timestamp of the transaction + */ + static async updateDailyVolume(baseId: string, volumeUSD: string, timestamp: bigint): Promise { + const id = this.getChainTypeId(baseId) + const day = timestampToDate(timestamp) + day.setUTCHours(0, 0, 0, 0) + const dateString = day.toISOString().slice(0, 10) + const dailyRecordId = `${id}.${dateString}` + + let dailyVolumeUSD = await DailyVolumeUSD.get(dailyRecordId) + + if (!dailyVolumeUSD) { + dailyVolumeUSD = DailyVolumeUSD.create({ + id: dailyRecordId, + last24HoursVolumeUSD: "0", + lastUpdatedAt: timestamp, + createdAt: day, + }) + } + + dailyVolumeUSD.last24HoursVolumeUSD = new Decimal(dailyVolumeUSD.last24HoursVolumeUSD) + .plus(new Decimal(volumeUSD)) + .toFixed(18) + dailyVolumeUSD.lastUpdatedAt = timestamp + + await dailyVolumeUSD.save() + } + + /** + * Update both cumulative and daily volume in a single call + * @param id - The identifier for the volume records + * @param volumeUSD - The volume in USD to add + * @param timestamp - The timestamp of the transaction + */ + static async updateVolume(id: string, volumeUSD: string, timestamp: bigint): Promise { + await Promise.all([ + this.updateCumulativeVolume(id, volumeUSD, timestamp), + this.updateDailyVolume(id, volumeUSD, timestamp), + ]) + } + + /** + * Generate a entity record ID base on the base ID (getDailyRecordId inclusive) and chainId + * @param baseId - The identifier for the volume record + */ + static getChainTypeId(baseId: string): string { + const stateMachineId = getHostStateMachine(chainId) + return `${baseId}.${stateMachineId}` + } + + /** + * Generate a daily record ID based on the base ID and timestamp + * @param baseId - The base identifier + * @param timestamp - The timestamp + * @returns The daily record ID + */ + private static getDailyRecordId(baseId: string, timestamp: bigint): string { + const dateString = getDateFormatFromTimestamp(timestamp) + return `${baseId}.${dateString}` + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/substrate-chaintypes/hyperbridge.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/substrate-chaintypes/hyperbridge.ts new file mode 100644 index 00000000..7cec120f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/substrate-chaintypes/hyperbridge.ts @@ -0,0 +1,12 @@ +export default { + typesBundle: { + spec: { + gargantua: { + hasher: "keccakAsU8a", + }, + nexus: { + hasher: "keccakAsU8a", + }, + }, + }, +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/events/erc6160ext20/transfer.event.handler.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/events/erc6160ext20/transfer.event.handler.test.ts new file mode 100644 index 00000000..1b58b386 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/events/erc6160ext20/transfer.event.handler.test.ts @@ -0,0 +1,24 @@ +import { subqlTest } from "@subql/testing" +import { Relayer, Transfer } from "@/configs/src/types" + +const existingEntities = [ + Relayer.create({ + id: "0xbC50b90751bfCccbFa4c7220261909d0f528b00f", + }), +] + +subqlTest( + "transferEventHandler correctly computes totalTransfersIn & feesPayedOutToRelayers", + 5854079, + existingEntities, + [ + Transfer.create({ + id: "0xbf94293f2dbd11e71510d9add4338d5f362a67c69df6055c1c4c9bc965ac1f31", + chain: "EVM-11155111", + amount: BigInt("24000000000000000000000"), + from: "0x92F217a5e965EAa2aD356678D537A0A9ccC0AF41", + to: "0xbC50b90751bfCccbFa4c7220261909d0f528b00f", + }), + ], + "handleTransferEvent", +) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/units/state-commitment.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/units/state-commitment.test.ts new file mode 100644 index 00000000..bbaf1309 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/units/state-commitment.test.ts @@ -0,0 +1,65 @@ +import { ApiPromise, WsProvider } from "@polkadot/api" +import { fetchStateCommitmentsEVM, fetchStateCommitmentsSubstrate } from "@/utils/state-machine.helper" +import { JsonRpcProvider } from "@ethersproject/providers" +import { stringify } from "safe-stable-stringify" + +describe("fetchStateCommitmentsSubstrate Integration Test", () => { + let api: ApiPromise + + test("fetches real state commitment on Hyperbridge", async () => { + const provider = new WsProvider(process.env.HYPERBRIDGE_RPC_URL) + const api = await ApiPromise.create({ provider }) + const result = await fetchStateCommitmentsSubstrate({ + api, + stateMachineId: "EVM-10200", + consensusStateId: "GNO0", + height: 14803804n, + }) + + console.log("Gnosis commitment", stringify(result?.timestamp, null, 4)) + + expect(result).toBeDefined() + expect(result?.timestamp).toBeDefined() + expect(result?.state_root).toBeInstanceOf(Uint8Array) + + await api.disconnect() + }, 30000) // Increase timeout to 30 seconds +}) + +describe("fetchEvmStateCommitmentsFromHeight Integration Test", () => { + test("fetches real state commitment on EVM chain", async () => { + let client = new JsonRpcProvider(process.env.BSC_RPC_URL) + // @ts-ignore + global.chainId = 97 + const result = await fetchStateCommitmentsEVM({ + client, + stateMachineId: "KUSAMA-4009", + consensusStateId: "ETH0", + height: 4120654n, + }) + + console.log("Bsc testnet", stringify(result?.timestamp, null, 4)) + + expect(result).toBeDefined() + expect(result?.timestamp).toBeDefined() + expect(result?.state_root).toBeInstanceOf(Uint8Array) + }, 30000) // Increase timeout to 30 seconds + + test("fetches real state commitment on EVM chain", async () => { + let client = new JsonRpcProvider(process.env.BSC_RPC_URL) + // @ts-ignore + global.chainId = 56 + const result = await fetchStateCommitmentsEVM({ + client, + stateMachineId: "POLKADOT-3367", + consensusStateId: "ETH0", + height: 4432117n, + }) + + console.log("Bsc mainnet", stringify(result?.timestamp, null, 4)) + + expect(result).toBeDefined() + expect(result?.timestamp).toBeDefined() + expect(result?.state_root).toBeInstanceOf(Uint8Array) + }, 30000) // Increase timeout to 30 seconds +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/utils/helpers/date.helpers.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/utils/helpers/date.helpers.test.ts new file mode 100644 index 00000000..17709720 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/utils/helpers/date.helpers.test.ts @@ -0,0 +1,45 @@ +import { normalizeTimestamp } from "@/utils/date.helpers" + +describe("normalizeTimestamp", () => { + test("should convert a typical 10-digit seconds timestamp to milliseconds", () => { + const inputSeconds = 1713787200n + const expectedMilliseconds = 1713787200000n + expect(normalizeTimestamp(inputSeconds)).toBe(expectedMilliseconds) + }) + + test("should convert an 11-digit seconds timestamp (max seconds range) to milliseconds", () => { + const inputSeconds = 99999999999n + const expectedMilliseconds = 99999999999000n + expect(normalizeTimestamp(inputSeconds)).toBe(expectedMilliseconds) + }) + + test("should convert a small seconds timestamp to milliseconds", () => { + const inputSeconds = 123n + const expectedMilliseconds = 123000n + expect(normalizeTimestamp(inputSeconds)).toBe(expectedMilliseconds) + }) + + test("should handle zero timestamp correctly (treated as seconds)", () => { + const inputZero = 0n + const expectedZero = 0n + expect(normalizeTimestamp(inputZero)).toBe(expectedZero) + }) + + test("should return a typical 13-digit milliseconds timestamp unchanged", () => { + const inputMilliseconds = 1713787200000n + const expectedMilliseconds = 1713787200000n + expect(normalizeTimestamp(inputMilliseconds)).toBe(expectedMilliseconds) + }) + + test("should return a 12-digit timestamp unchanged (treated as milliseconds)", () => { + const inputMilliseconds = 100000000000n + const expectedMilliseconds = 100000000000n + expect(normalizeTimestamp(inputMilliseconds)).toBe(expectedMilliseconds) + }) + + test("should return a very large (e.g., 15-digit) milliseconds timestamp unchanged", () => { + const inputMilliseconds = 171378720012345n + const expectedMilliseconds = 171378720012345n + expect(normalizeTimestamp(inputMilliseconds)).toBe(expectedMilliseconds) + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/utils/helpers/rpc.helpers.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/utils/helpers/rpc.helpers.test.ts new file mode 100644 index 00000000..89a49738 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/test/utils/helpers/rpc.helpers.test.ts @@ -0,0 +1,75 @@ +import { ENV_CONFIG } from "@/constants" +import { + getBlockTimestamp, + getEvmBlockTimestamp, + getSubstrateBlockTimestamp, + replaceWebsocketWithHttp, +} from "@/utils/rpc.helpers" + +describe("Get Substrate Block Timestamp", () => { + const chain = "KUSAMA-4009" + const blockHash = "0xfc53c051dd3adc9b564fcf0e6bcfa00ecdb8faddcd5dfbd9e84f8e9c1c6f2f28" + + beforeAll(async () => { + const { ApiPromise, WsProvider } = await import("@polkadot/api") + ;(globalThis as any).api = await ApiPromise.create({ provider: new WsProvider(ENV_CONFIG[chain]) }) + }) + + test("should get a valid milliseconds timestamp from a substrate block", async () => { + const timestamp = await getSubstrateBlockTimestamp(blockHash) + + expect(new Date(Number(timestamp)).toISOString()).toBe("2025-04-30T17:38:18.000Z") + expect(timestamp).toBe(1746034698000n) + }) + + test("should handle API errors gracefully", async () => { + await expect(getSubstrateBlockTimestamp("0x00")).rejects.toThrow( + "RPC error: createType(BlockHash):: Expected input with 32 bytes (256 bits), found 1 bytes", + ) + }) +}) + +describe("Get Evm Block Timestamp", () => { + const chain = "EVM-97" + const blockHash = "0xcf2a760fab352596b2c3774658bdf57ffa34b7e8d8fe691732fffca29f98f5ef" + + test("should fetch the block timestamp by querying the block and extracing the timestamp", async () => { + const timestamp = await getEvmBlockTimestamp(blockHash, chain) + + expect(timestamp).toBe(1746112524n) + expect(new Date(Number(timestamp * 1000n)).toISOString()).toBe("2025-05-01T15:15:24.000Z") + }) + + test("should handle API errors gracefully", async () => { + await expect( + getEvmBlockTimestamp("0x0000000000000000000000000000000000000000000000000000000000000000", chain), + ).rejects.toThrow('Unexpected response: No timestamp found in response {"jsonrpc":"2.0","id":1,"result":null}') + }) + + test("should handle invalid chain parameter", async () => { + await expect(getEvmBlockTimestamp(blockHash, "UNKNOWN")).rejects.toThrow("No RPC URL found for chain: UNKNOWN") + }) +}) + +describe("Get Block Timestamp", () => { + const chain = "KUSAMA-4009" + const blockHash = "0xfc53c051dd3adc9b564fcf0e6bcfa00ecdb8faddcd5dfbd9e84f8e9c1c6f2f28" + + test("should use pick the appropriate function based on the chain and fetch the timestamp", async () => { + expect(await getBlockTimestamp(blockHash, chain)).toBe(1746034698000n) + }) +}) + +describe("replaceWebsocketWithHttp", () => { + test("should replace the websocket URL with an HTTP URL or throw an error", async () => { + expect(replaceWebsocketWithHttp(ENV_CONFIG["KUSAMA-4009"])).toBe( + "https://hyperbridge-paseo-rpc.blockops.network", + ) + expect(() => replaceWebsocketWithHttp(ENV_CONFIG["UNKNOWN"])).toThrow() + expect(replaceWebsocketWithHttp(ENV_CONFIG["EVM-97"])).toBe( + "https://wandering-delicate-silence.bsc-testnet.quiknode.pro/74d3977082e2021a0e005e12dbdcbb6732ed74ee", + ) + expect(replaceWebsocketWithHttp("https://")).toBe("https://") + expect(replaceWebsocketWithHttp("ws://")).toBe("http://") + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/errors.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/errors.ts new file mode 100644 index 00000000..b44c7a35 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/errors.ts @@ -0,0 +1,11 @@ +export class ErrTokenPriceUnavailable extends Error { + constructor(message: string) { + super() + this.name = "ErrTokenPriceUnavailable" + this.message = message + } + + static isError(error: unknown): error is ErrTokenPriceUnavailable { + return error instanceof ErrTokenPriceUnavailable + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/global.d.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/global.d.ts new file mode 100644 index 00000000..462ab8d8 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/global.d.ts @@ -0,0 +1,15 @@ +import { Store } from "@subql/types-core" +import { Provider, Signer } from "ethers" +import { Logger } from "@subql/types" +import { ApiPromise } from "@polkadot/api" + +import "@types/node-fetch" + +declare global { + const store: Store + const api: Provider | Signer | ApiPromise + const logger: Logger + const chainId: string +} + +export {} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/ismp.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/ismp.ts new file mode 100644 index 00000000..eabe600d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/ismp.ts @@ -0,0 +1,166 @@ +import { Hex } from "viem" + +/** + * Read-only storage query description for a cross-chain GET request. + */ +export interface GetRequest { + // The source state machine of this request. + source: string + // The destination state machine of this request. + dest: string + // Module Id of the sending module + from: Hex + // The nonce of this request on the source chain + nonce: bigint + // Height at which to read the state machine. + height: bigint + /// Raw Storage keys that would be used to fetch the values from the counterparty + /// For deriving storage keys for ink contract fields follow the guide in the link below + /// `` + /// The algorithms for calculating raw storage keys for different substrate pallet storage + /// types are described in the following links + /// `` + /// `` + /// `` + /// `` + /// For fetching keys from EVM contracts each key should be 52 bytes + /// This should be a concatenation of contract address and slot hash + keys: Hex[] + // Timestamp which this request expires in seconds. + timeoutTimestamp: bigint + context: Hex +} + +/** + * A single key/value pair returned in a GET response. + */ +export interface GetResponseStorageValues { + key: Hex + value: Hex +} + +/** + * Response payload to a prior {@link GetRequest}. + */ +export interface GetResponse { + /** + * The request that triggered this response. + */ + get: GetRequest + /** + * The response message. + */ + values: GetResponseStorageValues[] +} + +/** + * Executable POST request to a destination module. + */ +export interface PostRequest { + // The source state machine of this request. + source: string + // The destination state machine of this request. + dest: string + // Module Id of the sending module + from: Hex + // Module ID of the receiving module + to: Hex + // The nonce of this request on the source chain + nonce: bigint + // Encoded request body. + body: Hex + // Timestamp which this request expires in seconds. + timeoutTimestamp: bigint +} + +/** + * Response payload to a prior {@link PostRequest}. + */ +export interface PostResponse { + // The request that triggered this response. + post: PostRequest + // The response message. + response: string + // Timestamp at which this response expires in seconds. + timeoutTimestamp: bigint +} + +/** + * Batched GET request timeouts with proof for verification at a given height. + */ +export interface GetTimeoutMessage { + timeouts: GetRequest[] + height: StateMachineHeight + proof: Hex[] +} + +/** + * Batched POST request timeouts with proof for verification at a given height. + */ +export interface PostRequestTimeoutMessage { + timeouts: PostRequest[] + height: StateMachineHeight + proof: Hex[] +} + +/** + * Batched POST response timeouts with proof for verification at a given height. + */ +export interface PostResponseTimeoutMessage { + timeouts: PostResponse[] + height: StateMachineHeight + proof: Hex[] +} + +/** + * Chain-unique state machine identifier and block height. + */ +export interface StateMachineHeight { + stateMachineId: bigint + height: bigint +} + +/** + * Batch of GET responses accompanied by inclusion proof. + */ +export interface GetResponseMessage { + proof: Proof + responses: { + response: GetResponse + index: bigint + kIndex: bigint + }[] +} + +/** + * Batch of POST requests accompanied by inclusion proof. + */ +export interface PostRequestMessage { + proof: Proof + requests: { + request: PostRequest + index: bigint + kIndex: bigint + }[] +} + +/** + * Batch of POST responses accompanied by inclusion proof. + */ +export interface PostResponseMessage { + proof: Proof + responses: { + response: PostResponse + index: bigint + kIndex: bigint + }[] +} + +/** + * Merkle multiproof and metadata to verify inclusion at a specific height. + */ +export interface Proof { + height: StateMachineHeight + multiproof: Hex[] + leafCount: bigint +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/network.types.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/network.types.ts new file mode 100644 index 00000000..3c9240c6 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/types/network.types.ts @@ -0,0 +1,2 @@ +export type StateMachinePrefix = "POLKADOT" | "KUSAMA" | "SUBSTRATE" +export type StateMachineId = `${StateMachinePrefix}-${string}` diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/__tests__/data.helper.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/__tests__/data.helper.test.ts new file mode 100644 index 00000000..f4562e25 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/__tests__/data.helper.test.ts @@ -0,0 +1,30 @@ +import { fulfilled, safeArray } from "../data.helper" + +describe("safeArray", () => { + it("should return the array if input is an array", () => { + const input = [1, 2, 3] + expect(safeArray(input)).toEqual([1, 2, 3]) + }) + + it("should return empty array if input is undefined", () => { + expect(safeArray(undefined)).toEqual([]) + }) + + it("should return empty array if input is null", () => { + expect(safeArray(null)).toEqual([]) + }) +}) + +describe("fulfilled", () => { + it("should return only fulfilled values from promise settled results", async () => { + const results = await Promise.allSettled([ + Promise.resolve(1), + Promise.reject("error"), + Promise.resolve("hello"), + ]) + + const values = fulfilled(results) + + expect(values).toEqual([1, "hello"]) + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/__tests__/date.helpers.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/__tests__/date.helpers.test.ts new file mode 100644 index 00000000..803e2743 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/__tests__/date.helpers.test.ts @@ -0,0 +1,32 @@ +import { timestampToDate } from "../date.helpers" +describe("timestampToDate", () => { + it("should convert a Unix timestamp in seconds to a Date object", () => { + // Unix timestamp in seconds + const result = timestampToDate(1700000000) + expect(result).toBeInstanceOf(Date) + expect(result.getTime()).toBe(1700000000 * 1000) + }) + + it("should convert a Unix timestamp in milliseconds to a Date object", () => { + // Unix timestamp in milliseconds + const result = timestampToDate(1700000000000) + expect(result).toBeInstanceOf(Date) + expect(result.getTime()).toBe(1700000000000) + }) + + it("should convert a BigInt timestamp to a Date object", () => { + // BigInt timestamp + const result = timestampToDate(1700000000n) + expect(result).toBeInstanceOf(Date) + expect(result.getTime()).toBe(1700000000 * 1000) + }) + + it("should handle invalid inputs gracefully", () => { + // @ts-expect-error - testing invalid input + expect(() => timestampToDate("not a timestamp")).toThrow() + // @ts-expect-error - testing invalid input + expect(() => timestampToDate(null)).toThrow() + // @ts-expect-error - testing invalid input + expect(() => timestampToDate(undefined)).toThrow() + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/__tests__/price.helpers.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/__tests__/price.helpers.test.ts new file mode 100644 index 00000000..b763f360 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/__tests__/price.helpers.test.ts @@ -0,0 +1,54 @@ +import PriceHelper from "../price.helpers" + +describe.skip("PriceHelper.getTokenPriceInUSDCoingecko", () => { + beforeAll(() => { + ;(global as any).logger = console + }) + + it("should return correct price and amount value for CERE token", async () => { + const result = await PriceHelper.getTokenPriceInUSDCoingecko("CERE", BigInt("50000000000"), 10) + + expect(result).toHaveProperty("priceInUSD") + expect(result).toHaveProperty("amountValueInUSD") + + expect(parseFloat(result.priceInUSD)).toBeTruthy() + expect(parseFloat(result.amountValueInUSD)).toBeTruthy() + }) + + it("should return correct price and amount value for DOT token", async () => { + const result = await PriceHelper.getTokenPriceInUSDCoingecko("DOT", BigInt("100000000000"), 10) + + expect(result).toHaveProperty("priceInUSD") + expect(result).toHaveProperty("amountValueInUSD") + + expect(parseFloat(result.priceInUSD)).toBeTruthy() + expect(parseFloat(result.amountValueInUSD)).toBeTruthy() + }) + + it("should return correct price and amount value for ETH token", async () => { + const result = await PriceHelper.getTokenPriceInUSDCoingecko("eth", BigInt("1000000000000000000"), 18) + + expect(result).toHaveProperty("priceInUSD") + expect(result).toHaveProperty("amountValueInUSD") + + expect(parseFloat(result.priceInUSD)).toBeGreaterThan(1000) + expect(parseFloat(result.amountValueInUSD)).toBeGreaterThan(1000) + }) + + it("should return correct price and amount value for xDai", async () => { + const result = await PriceHelper.getTokenPriceInUSDCoingecko("xdai", BigInt("1000000000000000000"), 18) + + expect(result).toHaveProperty("priceInUSD") + expect(result).toHaveProperty("amountValueInUSD") + }) + + it("should return zero values when symbol empty string", async () => { + const result = await PriceHelper.getTokenPriceInUSDCoingecko("", BigInt("200000000000"), 18) + expect(result).toEqual({ priceInUSD: "0", amountValueInUSD: "0" }) + }) + + it("should handle invalid symbols properly", async () => { + const result = await PriceHelper.getTokenPriceInUSDCoingecko("+++", BigInt("100"), 18) + expect(result).toEqual({ priceInUSD: "0", amountValueInUSD: "0" }) + }) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/data.helper.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/data.helper.ts new file mode 100644 index 00000000..b741a509 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/data.helper.ts @@ -0,0 +1,28 @@ +/** + * safeArray is a utility function that returns an array from an array-like object or an empty array if the input is undefined or null. + * @param array - The array-like object to convert to an array. + */ +export const safeArray = (array: T[] | undefined | null) => { + return Array.isArray(array) ? array : [] +} + +/** + * A type-safe utility function that unwraps the values from an array of PromiseSettledResults. + * Supports full type inference. + * + * @param results - The array of PromiseSettledResults to unwrap + * @returns An array of unwrapped values + */ +export const fulfilled = []>( + results: T, +): Array ? U : never> => { + return results.reduce( + (acc, result) => { + if (result.status === "fulfilled") { + return [...acc, result.value] + } + return acc + }, + [] as Array ? U : never>, + ) +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/date.helpers.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/date.helpers.ts new file mode 100644 index 00000000..0cc1bf85 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/date.helpers.ts @@ -0,0 +1,72 @@ +/** + * Normalizes a BigInt timestamp value that might represent seconds or milliseconds. + * It uses a heuristic based on digit length to guess the unit. + * + * - Input timestamps with 11 or fewer digits (representing dates up to year 5138 if seconds) + * are assumed to be in SECONDS and are converted to milliseconds by multiplying by 1000n. + * - Input timestamps with more than 11 digits are assumed to already be in MILLISECONDS + * and are returned unchanged. + * + * IMPORTANT: This function is specifically designed for BigInt inputs where the unit + * (seconds vs milliseconds) is uncertain and precise BigInt arithmetic is desired + * for the conversion. Do NOT use this for standard JavaScript Date objects or + * the Number result of Date.prototype.getTime(), as those are already reliably + * in milliseconds. + * + * @param timestamp - A BigInt timestamp, potentially representing seconds or milliseconds. + * @returns A BigInt timestamp normalized to represent milliseconds. + * + * @example + * normalizeTimestamp(1700000000n) // Assumes seconds => returns 1700000000000n + * normalizeTimestamp(1700000000000n) // Assumes milliseconds => returns 1700000000000n + */ +export const normalizeTimestamp = (timestamp: bigint): bigint => { + if (timestamp.toString().length <= 11) { + return timestamp * 1000n + } + return timestamp +} + +/** + * Creates a Date object from a timestamp (either number or bigint). + * Ensures the timestamp is in milliseconds before creating the Date object. + * + * @param timestamp - A number or BigInt timestamp that might be in seconds or milliseconds + * @returns A Date object representing the timestamp + * + * @example + * timestampToDate(1700000000) // Converts seconds to ms, returns Date object + * timestampToDate(1700000000000) // Already in ms, returns Date object + * timestampToDate(1700000000n) // Converts BigInt seconds to ms, returns Date object + */ +export const timestampToDate = (timestamp: number | bigint): Date => { + if (typeof timestamp === "bigint") { + const normalizedTimestamp = normalizeTimestamp(timestamp) + return new Date(Number(normalizedTimestamp)) + } + + const normalizedTimestamp = normalizeTimestamp(BigInt(timestamp)) + return new Date(Number(normalizedTimestamp)) +} + +/** + * Check if a timestamp is within 24 hours of another timestamp + * @param createdAt - The date the record was created + * @param currentTimestamp - The current timestamp + * @returns True if within 24 hours, false otherwise + */ +export const isWithin24Hours = (createdAt: Date, currentTimestamp: bigint): boolean => { + const timestampDate = timestampToDate(currentTimestamp).toISOString().split("T")[0] + const createdDate = createdAt.toISOString().split("T")[0] + return timestampDate <= createdDate +} + +/** + * Get date YYYY-MM-DD format from bigint timestamp + * @param timestamp - The timestamp + * @returns YYYY-MM-DD + */ +export const getDateFormatFromTimestamp = (timestamp: bigint): string => { + const date = timestampToDate(timestamp) + return date.toISOString().split("T")[0] // Get YYYY-MM-DD format +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/enum.helpers.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/enum.helpers.ts new file mode 100644 index 00000000..abd4e653 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/enum.helpers.ts @@ -0,0 +1,24 @@ +/** + * Convert a postgres formatted enumList to an Array + * @example "{SEPOLIA, BSC}" => ['SEPOLIA', 'BSC'] + * @see https://stackoverflow.com/questions/18234946/postgresql-insert-into-an-array-of-enums + */ +export const convertEnumListStringToArray = (enumListString: string): Array => { + // Remove the wrapping brackets, e.g. {SEPOLIA, BSC} ==> SEPOLIA, BSC + if (["{", "["].includes(enumListString[0]) && ["}", "]"].includes(enumListString[enumListString.length - 1])) { + enumListString = enumListString.substring(1, enumListString.length - 1) + } + + let enumList = enumListString.split(",") + return enumList.map((item) => item.trim()) +} + +/** + * Convert an array to a postgres formatted enumList + * @example "[SEPOLIA, BSC]" => {'SEPOLIA', 'BSC'} + * @see https://stackoverflow.com/questions/18234946/postgresql-insert-into-an-array-of-enums + */ +export const convertArrayToEnumListString = (enumsArray: Array): string => { + const enumListString = enumsArray.join(",") + return `{${enumListString}}` +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/event.utils.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/event.utils.ts new file mode 100644 index 00000000..9cdbdf33 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/event.utils.ts @@ -0,0 +1,46 @@ +import stringify from "safe-stable-stringify" + +class EventDecodeError extends Error { + constructor(message: string) { + super(message) + this.name = "EventDecodeError" + } +} + +/** + * Creates a safe proxy wrapper around an event object that handles errors gracefully + * @param event - The event object to wrap + * @returns event | error + */ +export function getSafeEvent(event: T): T & { args: object } { + return new Proxy(event as T & { args: object }, { + get(target: T & { args: object }, prop: string | symbol, receiver: T) { + try { + const value = target[prop as keyof (T & { args: object })] + stringify(value) + + return value + } catch (error) { + logger.error(`Error accessing property '${String(prop)}' on event: ${stringify(error)}`) + + // @ts-expect-error + throw new EventDecodeError(error.message) + } + }, + }) +} + +export function wrap(handler: (event: T) => Promise) { + return async (event: T) => { + try { + await handler(getSafeEvent(event)) + } catch (error) { + if (error instanceof EventDecodeError) { + logger.error(`Error decoding event: ${error.message}`) + return + } + + throw error + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/price.helpers.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/price.helpers.ts new file mode 100644 index 00000000..c5e636d7 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/price.helpers.ts @@ -0,0 +1,402 @@ +import Decimal from "decimal.js" +import fetch from "node-fetch" +import type { Hex } from "viem" + +import { CHAINLINK_PRICE_FEED_CONTRACT_ADDRESSES } from "@/addresses/chainlink-price-feeds.addresses" +import { ENV_CONFIG, ITokenPriceFeedDetails } from "@/constants" +import { ChainLinkAggregatorV3Abi__factory } from "@/configs/src/types/contracts" +import { ethers } from "ethers" +import { UNISWAP_ADDRESSES } from "@/addresses/uniswap.addresses" +import uniswapV2Abi from "@/configs/abis/UniswapV2.abi.json" +import uniswapV3FactoryAbi from "@/configs/abis/UniswapV3Factory.abi.json" +import uniswapV3PoolAbi from "@/configs/abis/UniswapV3Pool.abi.json" +import uniswapV3QuoterV2Abi from "@/configs/abis/UniswapV3QuoterV2.abi.json" +import uniswapV4QuoterAbi from "@/configs/abis/UniswapV4Quoter.abi.json" +import { ErrTokenPriceUnavailable } from "@/types/errors" + +export interface CoinGeckoResponse { + [key: string]: { + usd: number + } +} + +export interface PriceResponse { + priceInUSD: string + amountValueInUSD: string +} + +export default class PriceHelper { + static async getNativeCurrencyPrice(stateMachineId: string): Promise { + const priceFeedAddress = CHAINLINK_PRICE_FEED_CONTRACT_ADDRESSES[stateMachineId] + + if (!priceFeedAddress) { + logger.warn(`Price feed address not found for state machine id: ${stateMachineId}`) + return BigInt(0) + } + + const priceFeedContract = ChainLinkAggregatorV3Abi__factory.connect(priceFeedAddress, api) + + const roundData = await priceFeedContract.latestRoundData() + const decimals = await priceFeedContract.decimals() + let exponent = 18 - decimals + + // Ensure we convert to the standard 18 decimals used by erc20. + return roundData.answer.toBigInt() * BigInt(10 ** exponent) + } + + /** + * Get the current price IN USD for an ERC20 token given it's contract address + */ + static async getTokenPriceInUsdChainlink(priceFeedDetails: ITokenPriceFeedDetails): Promise { + const priceFeedContract = ChainLinkAggregatorV3Abi__factory.connect(priceFeedDetails.chain_link_price_feed, api) + + const roundData = await priceFeedContract.latestRoundData() + const decimals = await priceFeedContract.decimals() + let exponent = 18 - decimals + + // Ensure we convert to the standard 18 decimals used by erc20. + return roundData.answer.toBigInt() * BigInt(10 ** exponent) + } + + static async getTokenPriceInUSDUniswap( + tokenAddress: string, + amount: bigint, + decimals: number, + ): Promise { + try { + const isNativeToken = tokenAddress.endsWith("0000000000000000000000000000000000000000") + + let priceInUSD: string + if (isNativeToken) { + const nativePrice = await this.getNativeCurrencyPrice(chainId) + priceInUSD = new Decimal(nativePrice.toString()).dividedBy(new Decimal(10).pow(18)).toFixed(18) + } else { + const uniswapPrice = await this.getUniswapPrice(tokenAddress, decimals) + priceInUSD = uniswapPrice.toFixed(18) + } + + const amountValueInUSD = new Decimal(amount.toString()) + .dividedBy(new Decimal(10).pow(decimals)) + .times(new Decimal(priceInUSD)) + .toFixed(18) + + return { + priceInUSD, + amountValueInUSD, + } + } catch (error) { + logger.error(`Error getting token price for ${tokenAddress}: ${error}`) + return { + priceInUSD: "0", + amountValueInUSD: "0", + } + } + } + + private static async getUniswapPrice(tokenAddress: string, decimals: number): Promise { + try { + const addresses = UNISWAP_ADDRESSES[`EVM-${chainId}`] + const { V2_FACTORY, WETH, USDC, USDT, DAI, V4_QUOTER, V3_FACTORY, V3_QUOTER } = addresses + + const amountIn = BigInt(10 ** decimals) + + const quoteTokens = [USDC, USDT, DAI, WETH] + + // Try V2 first + for (const quoteToken of quoteTokens) { + const pairAddress = await this.getUniswapV2PairAddress(V2_FACTORY, tokenAddress, quoteToken) + if (pairAddress) { + try { + const price = await this.getPriceFromPair(pairAddress, quoteToken) + // If we got a price from WETH pair, convert to USD + if (quoteToken === WETH) { + const wethUsdcPair = await this.getUniswapV2PairAddress(V2_FACTORY, WETH, USDC) + if (wethUsdcPair) { + const wethUsdPrice = await this.getPriceFromPair(wethUsdcPair, USDC) + return price.times(wethUsdPrice) + } + } + return price + } catch (error) { + logger.error(`Error getting price from V2 pair ${pairAddress}: ${error}`) + continue + } + } + } + + // If V2 fails, try V3 + + if (V3_FACTORY && V3_QUOTER) { + // Out of three tiers, we return the first one that works + const fees = [500, 3000, 10000] // 0.05%, 0.3%, 1% + + for (const quoteToken of quoteTokens) { + for (const fee of fees) { + try { + const factory = new ethers.Contract(V3_FACTORY, uniswapV3FactoryAbi, api) + const pool = await factory.getPool(tokenAddress, quoteToken, fee) + + if (pool && pool !== "0x0000000000000000000000000000000000000000") { + const poolContract = new ethers.Contract(pool, uniswapV3PoolAbi, api) + const liquidity = await poolContract.liquidity() + + if (liquidity > BigInt(0)) { + const quoter = new ethers.Contract(V3_QUOTER, uniswapV3QuoterV2Abi, api) + const quoteResult = await quoter.quoteExactInputSingle({ + tokenIn: tokenAddress, + tokenOut: quoteToken, + fee: fee, + amount: amountIn, + sqrtPriceLimitX96: BigInt(0), + }) + + const [amountOut] = quoteResult + let price = new Decimal(amountOut.toString()).dividedBy(new Decimal(10 ** decimals)) + + // If we got a price from WETH pair, convert to USD + if (quoteToken === WETH) { + const wethUsdcPool = await factory.getPool(WETH, USDC, 500) // Use 0.05% fee tier for stable pairs + + if ( + wethUsdcPool && + wethUsdcPool !== "0x0000000000000000000000000000000000000000" + ) { + const wethQuoteResult = await quoter.quoteExactInputSingle({ + tokenIn: WETH, + tokenOut: USDC, + fee: 500, + amount: BigInt(10 ** decimals), + sqrtPriceLimitX96: BigInt(0), + }) + + const [wethAmountOut] = wethQuoteResult + const wethUsdPrice = new Decimal(wethAmountOut.toString()).dividedBy( + new Decimal(10 ** decimals), + ) + price = price.times(wethUsdPrice) + } + } + + // Return the first valid price we find + return price + } + } + } catch (error) { + logger.error(`Error getting price from V3 pool for fee ${fee}: ${error}`) + continue + } + } + } + } + + // If V3 fails, try V4 + if (V4_QUOTER) { + for (const quoteToken of quoteTokens) { + for (const fee of [500, 3000, 10000]) { + // Same fee tiers as V3 + try { + const quoter = new ethers.Contract(V4_QUOTER, uniswapV4QuoterAbi, api) + + const [token0, token1] = + tokenAddress.toLowerCase() < quoteToken.toLowerCase() + ? [tokenAddress, quoteToken] + : [quoteToken, tokenAddress] + + const poolKey = { + currency0: token0, + currency1: token1, + fee: fee, + tickSpacing: fee === 500 ? 10 : fee === 3000 ? 60 : 200, // Tick spacing changes based on fee + hooks: "0x0000000000000000000000000000000000000000" as Hex, + } + + // Determine if token0 is the input token + const zeroForOne = tokenAddress.toLowerCase() === token0.toLowerCase() + + const quoteParams = { + poolKey, + zeroForOne, + exactAmount: amountIn, + hookData: "0x" as Hex, + } + + const quoteResult = await quoter.callStatic.quoteExactInputSingle(quoteParams) + const amountOut = quoteResult.amountOut + + let price = new Decimal(amountOut.toString()).dividedBy(new Decimal(10 ** decimals)) + + if (quoteToken === WETH) { + const wethUsdcPoolKey = { + currency0: WETH, + currency1: USDC, + fee: 500, + tickSpacing: 10, + hooks: "0x0000000000000000000000000000000000000000" as Hex, + } + + const wethQuoteParams = { + poolKey: wethUsdcPoolKey, + zeroForOne: true, + exactAmount: BigInt(10 ** decimals), + hookData: "0x" as Hex, + } + + const wethQuoteResult = await quoter.callStatic.quoteExactInputSingle(wethQuoteParams) + const wethAmountOut = wethQuoteResult.amountOut + const wethUsdPrice = new Decimal(wethAmountOut.toString()).dividedBy( + new Decimal(10 ** decimals), + ) + price = price.times(wethUsdPrice) + } + + return price + } catch (error) { + logger.error(`Error getting price from V4 pool for fee ${fee}: ${error}`) + continue + } + } + } + } + + throw new Error(`No Uniswap V2, V3, or V4 pair found for token ${tokenAddress}`) + } catch (error) { + logger.error(`Error getting Uniswap price for ${tokenAddress}: ${error}`) + return new Decimal(1) + } + } + + private static async getUniswapV2PairAddress( + factoryAddress: string, + token0: string, + token1: string, + ): Promise { + try { + const factory = new ethers.Contract(factoryAddress, uniswapV2Abi.factory, api) + + const pairAddress = await factory.callStatic.getPair(token0, token1) + logger.info(`Pair address for ${token0}/${token1}: ${pairAddress}`) + return pairAddress === "0x0000000000000000000000000000000000000000" ? null : pairAddress + } catch (error) { + logger.error(`Error getting pair address for ${token0}/${token1}: ${error}`) + return null + } + } + + private static async getPriceFromPair(pairAddress: string, quoteToken: string): Promise { + try { + const pair = new ethers.Contract(pairAddress, uniswapV2Abi.pair, api) + + const [token0, token1] = await Promise.all([pair.token0(), pair.token1()]) + + const [reserve0, reserve1] = await pair.getReserves() + + // Calculate price based on reserves + const reserveIn = token0.toLowerCase() === quoteToken.toLowerCase() ? reserve0 : reserve1 + const reserveOut = token0.toLowerCase() === quoteToken.toLowerCase() ? reserve1 : reserve0 + + if (reserveIn.eq(0) || reserveOut.eq(0)) { + throw new Error("Zero reserves") + } + + return new Decimal(reserveIn.toString()).dividedBy(new Decimal(reserveOut.toString())) + } catch (error) { + logger.error(`Error getting price from pair ${pairAddress}: ${error}`) + throw error + } + } + + /** + * Get Token Price From CoinGecko + * @param symbols - The token symbol or an array of token symbols + * @returns Price per token and total value in USD + */ + static async getTokenPriceFromCoinGecko(symbols: string | string[]): Promise { + try { + const _symbols = typeof symbols === "string" ? symbols : Array.from(symbols).join(",") + const headers = { accept: "application/json", "content-type": "application/json" } as Record + + const coingeckoApiKey = ENV_CONFIG["COIN_GECKGO_API_KEY"] + if (coingeckoApiKey) { + headers["x-cg-pro-api-key"] = coingeckoApiKey + } + + const baseUrl = coingeckoApiKey ? "https://pro-api.coingecko.com" : "https://api.coingecko.com" + + const response = await fetch(`${baseUrl}/api/v3/simple/price?symbols=${_symbols}&vs_currencies=usd`, { + method: "GET", + headers, + }) + + if (!response.ok) { + throw new Error(`CoinGecko API error: ${response.status} ${response.statusText}`) + } + + const data = (await response.json()) as CoinGeckoResponse + if (Object.keys(data).length === 0) { + return new ErrTokenPriceUnavailable(`No price found for symbols: ${symbols}`) + } + + return data + } catch (error) { + // @ts-ignore + return new Error(error.message) + } + } + + static getAmountValueInUSD(amount: bigint, decimals: number, price: string | number): PriceResponse { + const priceInUSD = new Decimal(price).toFixed(18) + const amountValueInUSD = new Decimal(amount.toString()) + .dividedBy(new Decimal(10).pow(decimals)) + .times(new Decimal(priceInUSD)) + .toFixed(18) + + return { + priceInUSD, + amountValueInUSD, + } + } + + /** + * Get token price in USD using CoinGecko API + * @param symbol - The token symbol + * @param amount - Amount in token's smallest unit (e.g., wei for ETH) + * @param decimals - Token decimals + * @returns Price per token and total value in USD + */ + static async getTokenPriceInUSDCoingecko(symbol: string, amount: bigint, decimals: number): Promise { + logger.info(`getTokenPriceInUSDCoingecko(${symbol}, BitInt(${amount.toString()}), ${decimals})`) + + if (!symbol) { + return { priceInUSD: "0", amountValueInUSD: "0" } + } + + try { + const response = await this.getTokenPriceFromCoinGecko(symbol) + if (response instanceof Error) { + return { priceInUSD: "0", amountValueInUSD: "0" } + } + + const price = response[symbol.toLowerCase()]?.usd || response[symbol.toUpperCase()]?.usd + if (!price || price <= 0) { + throw new Error(`Price not found for symbol: ${symbol}`) + } + + const { priceInUSD, amountValueInUSD } = this.getAmountValueInUSD(amount, decimals, price.toString()) + + logger.info( + `getTokenPriceInUSDCoingecko(${symbol}, BitInt(${amount.toString()}), ${decimals}) => ${priceInUSD}, ${amountValueInUSD}`, + ) + + return { + priceInUSD, + amountValueInUSD, + } + } catch (error) { + logger.error(`Error fetching token price for ${symbol}: ${error}`) + return { + priceInUSD: "0", + amountValueInUSD: "0", + } + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/retry.utils.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/retry.utils.ts new file mode 100644 index 00000000..f0d4b8a2 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/retry.utils.ts @@ -0,0 +1,22 @@ +export interface RetryConfig { + maxRetries: number; + backoffMs: number; + logMessage?: string; +} + +export async function retryPromise(operation: () => Promise, retryConfig: RetryConfig): Promise { + const { logMessage = "Retry operation failed" } = retryConfig + + let lastError: unknown + for (let i = 0; i < retryConfig.maxRetries; i++) { + try { + return await operation() + } catch (error) { + logger.trace(`Retrying(${i + 1}/${retryConfig.maxRetries}) > ${logMessage}`) + lastError = error + await new Promise((resolve) => setTimeout(resolve, retryConfig.backoffMs * 2 ** i)) + } + } + + throw lastError +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/rpc.helpers.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/rpc.helpers.ts new file mode 100644 index 00000000..fd09e6f1 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/rpc.helpers.ts @@ -0,0 +1,109 @@ +import fetch from "node-fetch" +import { u64 } from "scale-ts" +import { Hex, hexToBytes, keccak256, stringToBytes } from "viem" +import { Option as PolkadotOption } from "@polkadot/types" +import { Codec } from "@polkadot/types/types" +import { StorageData } from "@polkadot/types/interfaces" + +import { safeArray } from "./data.helper" +import { ENV_CONFIG } from "@/constants" + +/** + * Replace Websocket with HTTP is a function that replaces a websocket URL with an HTTP URL. + * @param url The URL to replace + */ +export function replaceWebsocketWithHttp(url: string): string { + if (url.startsWith("ws://")) { + return url.replace("ws://", "http://") + } else if (url.startsWith("wss://")) { + return url.replace("wss://", "https://") + } + return url +} + +/** + * Get Block Timestamp is a function that retrieves the timestamp of a block given its hash and chain. + * @param blockHash + */ +export async function getBlockTimestamp(blockhash: string, chain: string): Promise { + if (chain.startsWith("EVM")) { + return getEvmBlockTimestamp(blockhash, chain) + } + + return getSubstrateBlockTimestamp(blockhash) +} + +interface ETHGetBlockByHashResponse { + jsonrpc: "2.0" + id: 1 + error?: { + message: string + } + result: { + timestamp: bigint + hash: `0x${string}` + } +} + +/** + * Get EVM Block Timestamp is a function that retrieves the timestamp of a block given its hash and chain. + * @param blockHash The hash of the block + * @param chain The chain identifier + * @returns The timestamp as a bigint + * @throws Error if the RPC call fails or returns an unexpected response + */ +export async function getEvmBlockTimestamp(blockHash: string, chain: string): Promise { + const rpcUrl = replaceWebsocketWithHttp(ENV_CONFIG[chain] || "") + if (!rpcUrl) { + throw new Error(`No RPC URL found for chain: ${chain}`) + } + + const getBlockByHash = await fetch(rpcUrl, { + method: "POST", + headers: { accept: "application/json", "content-type": "application/json" }, + body: JSON.stringify({ + id: 1, + jsonrpc: "2.0", + method: "eth_getBlockByHash", + params: [blockHash, false], + }), + }) + + const block: ETHGetBlockByHashResponse = await getBlockByHash.json() + + // Check for JSON-RPC errors + if (block.error) { + throw new Error(`RPC error: ${block.error.message || JSON.stringify(block.error)}`) + } + + // Validate the response contains a result with a timestamp + if (!block.result || block.result.timestamp === undefined) { + throw new Error(`Unexpected response: No timestamp found in response ${JSON.stringify(block)}`) + } + + return BigInt(block.result.timestamp) +} + +/** + * Get Substrate Block Timestamp is a function that retrieves the timestamp of a block given its hash and chain. + * @param storageKey The storage key for the state item + * @param blockHash The hash of the block + * @param chain The chain identifier + * @returns The timestamp as a bigint + * @throws Error if the RPC call fails or returns an unexpected response + */ +export async function getSubstrateBlockTimestamp(blockHash: string): Promise { + const STORAGE_KEY = "0xf0c365c3cf59d671eb72da0e7a4113c49f1f0515f462cdcf84e0f1d6045dfcbb" + + try { + const storageValue = await api.rpc.state.getStorage>(STORAGE_KEY, blockHash) + + if (!storageValue.isSome) { + throw new Error(`Unexpected response: No storage found in response ${JSON.stringify(storageValue)}`) + } + + return u64.dec(hexToBytes(storageValue.value.toHex())) + } catch (err) { + throw new Error(`RPC error: ${(err as Error).message}`) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/state-machine.helper.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/state-machine.helper.ts new file mode 100644 index 00000000..87408913 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/state-machine.helper.ts @@ -0,0 +1,247 @@ +import { bytesToBigInt, bytesToHex, hexToBytes, keccak256, pad, toBytes, toHex } from "viem" +import { blake2AsU8a, xxhashAsU8a } from "@polkadot/util-crypto" +import { u64, Struct, Option, Bytes, u8, Vector, Enum, u32, u128, bool } from "scale-ts" +import type { ApiPromise } from "@polkadot/api" +import { Option as PolkadotOption } from "@polkadot/types" +import { logger } from "ethers" +import { TextEncoder } from "util" +import { CHAINS_BY_ISMP_HOST } from "@/constants" +import { Codec } from "@polkadot/types/types" +import { Provider } from "@ethersproject/providers" + +// Define ConsensusStateId as 4-byte array +const ConsensusStateId = Vector(u8, 4) + +// H256 is a 32-byte array +const H256 = Bytes(32) + +// Define StateCommitment +const StateCommitment = Struct({ + timestamp: u64, + overlay_root: Option(H256), + state_root: H256, +}) + +export const RequestMetadata = Struct({ + offchain: Struct({ + leaf_index: u64, + pos: u64, + }), + fee: Struct({ + payer: H256, + fee: u128, + }), + claimed: bool, +}) + +// Define StateMachine +const StateMachine = Enum({ + Evm: u32, + Polkadot: u32, + Kusama: u32, + Substrate: ConsensusStateId, + Tendermint: ConsensusStateId, +}) + +// Define StateMachineId +const StateMachineId = Struct({ + state_id: StateMachine, + consensus_state_id: ConsensusStateId, +}) + +// Define StateMachineHeight +const StateMachineHeight = Struct({ + id: StateMachineId, + height: u64, +}) + +type StateMachineHeight = { + id: { + state_id: + | { tag: "Evm"; value: number } + | { tag: "Polkadot"; value: number } + | { tag: "Kusama"; value: number } + | { tag: "Substrate"; value: number[] } + | { tag: "Tendermint"; value: number[] } + consensus_state_id: number[] + } + height: bigint +} +type StateCommitment = { + timestamp: bigint + overlay_root: Uint8Array | undefined + state_root: Uint8Array +} + +export async function fetchStateCommitmentsSubstrate(params: { + api: ApiPromise + stateMachineId: string + consensusStateId: string + height: bigint +}): Promise { + const { api, stateMachineId, consensusStateId, height } = params + + const state_machine_height: StateMachineHeight = { + id: { + state_id: getStateId(stateMachineId), + consensus_state_id: Array.from(new TextEncoder().encode(consensusStateId)), + }, + height: height, + } + + logger.info( + `Fetching state commitment for state machine height: ${JSON.stringify(state_machine_height, bigIntSerializer)}`, + ) + + const palletPrefix = xxhashAsU8a("Ismp", 128) + const storagePrefix = xxhashAsU8a("StateCommitments", 128) + + const encodedStateMachineHeight = StateMachineHeight.enc(state_machine_height) + const key = blake2AsU8a(encodedStateMachineHeight, 128) + + const full_key = new Uint8Array([...palletPrefix, ...storagePrefix, ...key, ...encodedStateMachineHeight]) + const hexKey = bytesToHex(full_key) + + const storageValue = await api.rpc.state.getStorage>(hexKey) + + if (storageValue.isSome) { + return StateCommitment.dec(hexToBytes(storageValue.value.toHex())) + } + + return null +} + +export async function fetchStateCommitmentsEVM(params: { + client: Provider + stateMachineId: string + consensusStateId: string + height: bigint +}): Promise { + const { client, stateMachineId, consensusStateId, height } = params + + const state_machine_height: StateMachineHeight = { + id: { + state_id: getStateId(stateMachineId), + consensus_state_id: Array.from(new TextEncoder().encode(consensusStateId)), + }, + height: height, + } + + logger.info( + `Fetching EVM state commitment for state machine height: ${JSON.stringify(state_machine_height, bigIntSerializer)}`, + ) + + // Add check for Kusama or Polkadot state machine type + const stateIdType = state_machine_height.id.state_id.tag + if (stateIdType !== "Kusama" && stateIdType !== "Polkadot") { + logger.info(`Unknown State Machine: ${stateIdType}. Expected Polkadot or Kusama state machine`) + return null + } + + const hostContractKey = `EVM-${chainId}` + const hostContract = CHAINS_BY_ISMP_HOST[hostContractKey] + + // Extract the paraId from the state machine ID + const paraId = BigInt(state_machine_height.id.state_id.value) + + // Generate keys for timestamp, overlay, and state root + const [timestampKey, overlayKey, stateRootKey] = generateStateCommitmentKeys(paraId, height) + + // Query the three storage values + const timestampValue = await client.getStorageAt(hostContract, bytesToHex(timestampKey)) + + if (!timestampValue) { + return null + } + + const overlayRootValue = await client.getStorageAt(hostContract, bytesToHex(overlayKey)) + + const stateRootValue = await client.getStorageAt(hostContract, bytesToHex(stateRootKey)) + + // Parse timestamp from big-endian bytes to BigInt + const timestamp = BigInt(timestampValue) / 1000n + + // Create the StateCommitment object + return { + timestamp, + overlay_root: overlayRootValue ? hexToBytes(overlayRootValue as `0x${string}`) : undefined, + state_root: stateRootValue ? hexToBytes(stateRootValue as `0x${string}`) : new Uint8Array(), + } +} + +function generateStateCommitmentKeys(paraId: bigint, height: bigint): [Uint8Array, Uint8Array, Uint8Array] { + // Constants + const STATE_COMMITMENT_SLOT = 5n + + // Convert to bytes using viem utilities + const stateIdBytes = toBytes(pad(`0x${paraId.toString(16)}`, { size: 32 })) + const slotBytes = toBytes(pad(`0x${STATE_COMMITMENT_SLOT.toString(16)}`, { size: 32 })) + + // Generate parent map key + const parentMapKeyData = new Uint8Array([...stateIdBytes, ...slotBytes]) + const parentMapKey = hexToBytes(keccak256(toHex(parentMapKeyData))) + + // Generate commitment key + const heightBytes = toBytes(pad(`0x${height.toString(16)}`, { size: 32 })) + const commitmentKeyData = new Uint8Array([...heightBytes, ...parentMapKey]) + + // Generate base slot + const baseSlotHash = keccak256(toHex(commitmentKeyData)) + const baseSlot = hexToBytes(baseSlotHash) + + // Calculate overlay and state root slots + const baseSlotBigInt = bytesToBigInt(baseSlot) + const overlaySlot = hexToBytes(pad(`0x${(baseSlotBigInt + 1n).toString(16)}`, { size: 32 })) + const stateRootSlot = hexToBytes(pad(`0x${(baseSlotBigInt + 2n).toString(16)}`, { size: 32 })) + + return [baseSlot, overlaySlot, stateRootSlot] +} + +const bigIntSerializer = (key: string, value: any) => { + if (typeof value === "bigint") { + return value.toString() + } + return value +} + +export const getStateMachineTag = (id: string): "Evm" | "Polkadot" | "Kusama" | "Substrate" | "Tendermint" => { + switch (id) { + case "EVM": + return "Evm" + case "POLKADOT": + return "Polkadot" + case "KUSAMA": + return "Kusama" + case "SUBSTRATE": + return "Substrate" + case "TENDERMINT": + return "Tendermint" + default: + throw new Error(`Unknown state machine type: ${id}`) + } +} + +export const getStateId = (id: string) => { + const [type, value] = id.split("-") + const tag = getStateMachineTag(type) + + switch (tag) { + case "Evm": + case "Polkadot": + case "Kusama": + return { + tag, + value: Number(value), + } + case "Substrate": + case "Tendermint": + return { + tag, + value: Array.from(new TextEncoder().encode(value)), + } + default: + throw new Error(`Unknown state machine type: ${type}`) + } +} + +export { StateMachineHeight, StateMachineId, StateMachine, StateCommitment } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/substrate.helpers.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/substrate.helpers.ts new file mode 100644 index 00000000..0a59833a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/substrate.helpers.ts @@ -0,0 +1,209 @@ +import { SubstrateEvent } from "@subql/types" +import { CHAIN_IDS_BY_GENESIS, HYPERBRIDGE } from "@/constants" +import { StateMachineId } from "@/types/network.types" + +/** + * Get the StateMachineID parsing the stringified object which substrate provides + */ +export const extractStateMachineIdFromSubstrateEventData = (substrateStateMachineId: string): string | undefined => { + try { + const parsed = JSON.parse(substrateStateMachineId) + let stateId + + // Handle array format with direct objects + if (Array.isArray(parsed)) { + // Find the object containing stateId or ethereum/bsc keys + const stateObject = parsed.find((item) => item?.stateId) + + if (!stateObject) return undefined + + // Extract stateId from different formats + stateId = stateObject.stateId || stateObject + } else { + // Handle object format + stateId = parsed.stateId + } + + if (!stateId) { + throw new Error(`StateId not present in stateMachineId: ${substrateStateMachineId}`) + } + + // Extract key and value + let main_key = "" + let value = "" + + Object.entries(stateId).forEach(([key, val]) => { + main_key = key.toUpperCase() + value = + val === null + ? "" + : typeof val === "string" && val.startsWith("0x") + ? Buffer.from(val.slice(2), "hex").toString() + : String(val) + }) + + switch (main_key) { + case "EVM": + return "EVM-".concat(value) + case "POLKADOT": + return "POLKADOT-".concat(value) + case "KUSAMA": + return "KUSAMA-".concat(value) + case "SUBSTRATE": + return "SUBSTRATE-".concat(value) + case "TENDERMINT": + return "TENDERMINT-".concat(value) + default: + throw new Error( + `Unknown state machine ID ${main_key} encountered in extractStateMachineIdFromSubstrateEventData. `, + ) + } + } catch (error) { + logger.error(error) + return undefined + } +} + +/** + * Checks if the given state machine ID represents a Substrate chain. + * @param stateMachineId The state machine ID to check. + */ +export function isSubstrateChain(stateMachineId: string): boolean { + return ( + stateMachineId.startsWith("POLKADOT") || + stateMachineId.startsWith("KUSAMA") || + stateMachineId.startsWith("SUBSTRATE") + ) +} + +/** + * Format chain data + */ + +// TODO: Fix any type :( +export const formatChain = (chain: any): StateMachineId => { + // Handle stringified JSON + const chainObj = typeof chain === "string" ? JSON.parse(chain) : chain + + // Get the first key of the object (evm, substrate, etc) + const chainType = Object.keys(chainObj)[0] + if (chainType) { + // Convert chainType to uppercase and combine with chain ID + const rawChainId = chainObj[chainType] + let id = String(rawChainId) + if (typeof rawChainId === "string" && rawChainId.startsWith?.("0x")) { + id = Buffer.from(rawChainId.slice(2), "hex").toString() + } + return `${chainType.toUpperCase()}-${id}` as StateMachineId + } + + return chain +} + +export function getHostStateMachine(chainId: string): StateMachineId { + const host = CHAIN_IDS_BY_GENESIS[chainId] + if (!host) { + throw new Error(`Unknown genesis hash: ${chainId}`) + } + return host +} + +export function isHyperbridge(host: StateMachineId): boolean { + return host === HYPERBRIDGE.mainnet || host === HYPERBRIDGE.testnet +} + +/** + * Error class for substrate indexing errors + */ +export class SubstrateIndexingError extends Error { + constructor( + message: string, + public chainId: string, + public blockNumber?: number, + public eventMethod?: string, + ) { + super(message) + this.name = "SubstrateIndexingError" + } +} + +/** + * Error class for state machine errors + */ +export class StateMachineError extends SubstrateIndexingError { + constructor(message: string, chainId: string, blockNumber?: number) { + super(message, chainId, blockNumber) + this.name = "StateMachineError" + } +} + +/** + * Error class for asset events + */ +export class AssetEventError extends SubstrateIndexingError { + constructor(message: string, chainId: string, blockNumber?: number) { + super(message, chainId, blockNumber) + this.name = "AssetEventError" + } +} + +export class SubstrateEventValidator { + /** + * Validate state machine event data + */ + static validateStateMachineEvent(event: SubstrateEvent): boolean { + const { data, method } = event.event + + switch (method) { + case "StateMachineUpdated": + // Check data array exists and has required elements + if (!Array.isArray(data) || data.length < 2) return false + + // Validate first element has stateId and consensusStateId + const stateData = data[0].toJSON() + if ( + typeof stateData !== "object" || + !stateData || + !("stateId" in stateData) || + !("consensusStateId" in stateData) + ) + return false + + // Validate second element is a number (height) + const height = Number(data[1].toString()) + return !isNaN(height) + + default: + return false + } + } + + /** + * Validate chain metadata + */ + static validateChainMetadata(chainId: string, stateMachineId: string): boolean { + return ( + typeof chainId === "string" && + chainId.length > 0 && + typeof stateMachineId === "string" && + stateMachineId.length > 0 + ) + } +} + +export interface Get { + get: { + source: string + dest: string + nonce: number + from: string + keys: string[] + height: number + context: string + timeoutTimestamp: number + } + values: { + key: string + value: string + }[] +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/transfer.helpers.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/transfer.helpers.ts new file mode 100644 index 00000000..d067203e --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/src/utils/transfer.helpers.ts @@ -0,0 +1,58 @@ +import { EthereumResult, EthereumLog } from "@subql/types-ethereum" + +import { ERC6160Ext20Abi__factory } from "@/configs/src/types/contracts" +import type { PriceResponse } from "./price.helpers" +import { TokenPriceService } from "@/services/token-price.service" +import PriceHelper from "./price.helpers" + +// ERC20 Transfer event signature: Transfer(address indexed from, address indexed to, uint256 value) +const ERC20_TRANSFER_TOPIC = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + +/** + * isERC20TransferEvent checks if the topic includes Transfer(address, address, uint256). + * @param log EthereumLog + * @returns boolean + */ +export const isERC20TransferEvent = (log: EthereumLog): boolean => { + return ( + log.topics && log.topics.length >= 3 && log.topics[0] === ERC20_TRANSFER_TOPIC // Check exact match for topics[0] + ) +} + +type GetPriceFromEthereumLogResponse = Promise + +/** + * getPriceDataFromEthereumLog retrieves price data from an Ethereum log. + * @param log EthereumLog + * @returns Promise + */ +export const getPriceDataFromEthereumLog = async ( + address: string, + amount: bigint, + currentTimestamp?: bigint, +): GetPriceFromEthereumLogResponse => { + const contract = ERC6160Ext20Abi__factory.connect(address.toLowerCase(), api) + + const symbol = await contract.symbol() + const decimals = await contract.decimals() + + const price = await TokenPriceService.getPrice(symbol, currentTimestamp) + const { amountValueInUSD, priceInUSD } = PriceHelper.getAmountValueInUSD(amount, decimals, price) + + return { + amountValueInUSD, + priceInUSD, + symbol, + decimals, + } +} + +/** + * extractAddressFromTopic converts a 32-byte indexed topic into a 20-byte EVM address + */ +export function extractAddressFromTopic(topic: string): string { + if (topic.startsWith("0x") && topic.length === 66) { + return ("0x" + topic.slice(26)).toLowerCase() + } + return topic.toLowerCase() +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/tsconfig.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/tsconfig.json new file mode 100644 index 00000000..ea3c8ca5 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/indexer/tsconfig.json @@ -0,0 +1,25 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "importHelpers": true, + "module": "commonjs", + "outDir": "dist", + "rootDirs": ["src"], + "noImplicitAny": false, + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + } + }, + "include": [ + "src/**/*", + "src/substrate-chaintypes/**/*", + "src/types/global.d.ts", + "node_modules/@subql/types-core/dist/global.d.ts", + "node_modules/@subql/types-ethereum/dist/global.d.ts", + "node_modules/@subql/types/dist/global.d.ts" + ], + "exclude": ["node_modules", "dist", "**/*.spec.ts"] +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/.eslintrc.js b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/.eslintrc.js new file mode 100644 index 00000000..7421961e --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/.eslintrc.js @@ -0,0 +1,9 @@ +module.exports = { + extends: ["../../.eslintrc.js"], + parserOptions: { + project: "./tsconfig.json", + }, + rules: { + // Any SDK-specific overrides + }, +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/.gitignore b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/.gitignore new file mode 100644 index 00000000..8f32107b --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/.gitignore @@ -0,0 +1,3 @@ +.env.testing +/node_modules +/.idea diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/CHANGELOG.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/CHANGELOG.md new file mode 100644 index 00000000..9018c73d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/CHANGELOG.md @@ -0,0 +1,91 @@ +# @hyperbridge/sdk + +## 1.4.7 + +### Patch Changes + +- Added Storage resolvers + +## 1.4.3 + +### Patch Changes + +- fix issue with copy wasm file and also added support for monorepo root package.json + +## 1.3.25 + +### Patch Changes + +- Add latest statemachine query to the indexer + +## 1.3.21 + +### Patch Changes + +- Updated relayer fee in estimate fill order + +## 1.3.20 + +### Patch Changes + +- Fix Indexer stream in cancel order not yielding SOURCE FINALIZED + +## 1.3.19 + +### Patch Changes + +- Fix message submit in cancel order method + +## 1.3.17 + +### Patch Changes + +- Update polygon config + +## 1.3.15 + +### Patch Changes + +- Add retry logic for source proof in cancel order + +## 1.3.14 + +### Patch Changes + +- Minor fix + +## 1.3.13 + +### Patch Changes + +- Minor patch + +## 1.3.12 + +### Patch Changes + +- Bump sdk + +## 1.3.11 + +### Patch Changes + +- Yield source proof from cancel order method + +## 1.3.10 + +### Patch Changes + +- Implemented cancel order method in Intent class + +## 1.3.4 + +### Patch Changes + +- Added queryGetRequestStatus method to the SDK + +## 1.3.0 + +### Minor Changes + +- Expose the calldata for estimateGasForPost() diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/README.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/README.md new file mode 100644 index 00000000..b5e47868 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/README.md @@ -0,0 +1,184 @@ +# @hyperbridge/sdk + +A JavaScript/TypeScript SDK for interacting with the Hyperbridge indexer and monitoring cross-chain messages. + +## Installation + +```bash +npm install @hyperbridge/sdk +# or +yarn add @hyperbridge/sdk +# or +pnpm add @hyperbridge/sdk +``` + +## Usage + +### Initialize Client + +```ts +import { IndexerClient, createQueryClient, EvmChain, SubstrateChain } from "@hyperbridge/sdk" + +const queryClient = createQueryClient({ + url: "http://localhost:3000", // URL of the Hyperbridge indexer API +}) + +// Create chain instances directly +const sourceChain = new EvmChain({ + chainId: 97, + rpcUrl: "https://data-seed-prebsc-1-s1.binance.org:8545", + host: "0x...", // Host contract address + consensusStateId: "BSC0" +}) + +const destChain = new EvmChain({ + chainId: 10200, + rpcUrl: "https://rpc.chiadochain.net", + host: "0x...", // Host contract address + consensusStateId: "GNO0" +}) + +const hyperbridgeChain = new SubstrateChain({ + stateMachineId: "KUSAMA-4009", + wsUrl: "wss://gargantua.polytope.technology", + hasher: "Keccak", + consensusStateId: "PAS0" +}) + +// Connect to Substrate chain +await hyperbridgeChain.connect() + +// Create the IndexerClient +const indexer = new IndexerClient({ + queryClient: queryClient, + pollInterval: 1_000, // Every second + source: sourceChain, + dest: destChain, + hyperbridge: hyperbridgeChain +}) +``` + + +### Monitor Post Request Status + +```ts +import { postRequestCommitment } from "@hyperbridge/sdk" + +// Get status stream for a commitment +const commitment = postRequestCommitment(request) +for await (const status of indexer.postRequestStatusStream(commitment)) { + switch (status.status) { + case RequestStatus.SOURCE_FINALIZED: + console.log("Request finalized on source chain") + break + case RequestStatus.HYPERBRIDGE_DELIVERED: + console.log("Request delivered to Hyperbridge") + break + // other statuses + } +} +``` + +### Monitor Timeout Status + +```ts +// Get timeout status stream +for await (const timeout of indexer.postRequestTimeoutStream(commitment)) { + switch (timeout.status) { + case TimeoutStatus.PENDING_TIMEOUT: + console.log("Request pending timeout") + break + case TimeoutStatus.HYPERBRIDGE_TIMED_OUT: + console.log("Request timed out on Hyperbridge") + break + // other timeout statuses + } +} +``` + +### Query Request Status + +```ts +// Get current status +const request = await indexer.queryRequestWithStatus(commitment) +console.log(request?.statuses) +``` + +Alternatively. You can use the `queryPostRequest` utility + +```ts +import { createQueryClient, queryPostRequest } from "@hyperbridge/sdk" + +const queryClient = createQueryClient({ + url: "http://localhost:3000", // URL of the Hyperbridge indexer API +}) + +const commitmentHash = "0x...." + +// Get request statuses +const request = await queryPostRequest({ commitmentHash, queryClient }) +console.log(request.statuses) // read transaction statuses +``` + +### Chain Utilities + +```ts +import { EvmChain, SubstrateChain } from "@hyperbridge/sdk" + +// Interact with EVM chains +const evmChain = new EvmChain({ + url: "https://rpc.chiadochain.net", + chainId: 10200, + host: "0x58A41B89F4871725E5D898d98eF4BF917601c5eB", +}) + +// Interact with Substrate chains +const hyperbridge = new SubstrateChain({ + ws: "wss://gargantua.dev.polytope.technology", + hasher: "Keccak", +}) + +const proof = await hyperbridge.queryStateProof(blockNumber, keys) +``` + +## Vite Integration + +If you're using Vite in your project, Hyperbridge SDK includes a plugin to handle WebAssembly dependencies correctly. + +### Using the Vite Plugin + +```ts +// vite.config.ts +import { defineConfig } from "vite" +import hyperbridge from "@hyperbridge/sdk/plugins/vite" + +export default defineConfig({ + plugins: [ + // ... other plugins + // Add the Hyperbridge WASM plugin + hyperbridge({ + logLevel: "trace" + }), + ], +}) +``` + +The plugin automatically copies the necessary WebAssembly files to the correct location in Vite's dependency cache during development. This ensures that any WASM dependencies required by Hyperbridge SDK are properly loaded when using Vite's dev server. + +## API Reference + +### Classes + +- IndexerClient - Main client for interacting with the indexer +- EvmChain - Utilities for EVM chain interaction +- SubstrateChain - Utilities for Substrate chain interaction + +### Types + +- RequestStatus - Enum of possible request statuses +- TimeoutStatus - Enum of possible timeout statuses +- HexString - Type for hex-encoded strings + +### Examples + +See the tests [directory](/packages/sdk/src/tests/postRequest.test.ts) for complete examples. diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/biome.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/biome.json new file mode 100644 index 00000000..8e9bad88 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/biome.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "vcs": { + "enabled": false, + "clientKind": "git", + "useIgnoreFile": false + }, + "files": { + "ignoreUnknown": false, + "ignore": ["./dist/*", "./src/utils/ckb-mmr-wasm/*"] + }, + "formatter": { + "enabled": false + }, + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + } + }, + "javascript": { + "formatter": { + "quoteStyle": "double" + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/package.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/package.json new file mode 100644 index 00000000..1eee4733 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/package.json @@ -0,0 +1,136 @@ +{ + "name": "@hyperbridge/sdk", + "version": "1.4.8", + "description": "The hyperclient SDK provides utilities for querying proofs and statuses for cross-chain requests from HyperBridge.", + "type": "module", + "types": "./dist/node/index.d.ts", + "exports": { + ".": { + "browser": "./dist/browser/index.js", + "import": "./dist/node/index.js" + }, + "./plugins/vite": { + "import": "./plugins/vite.js", + "types": "./plugins/vite.d.ts" + } + }, + "files": [ + "dist", + "plugins" + ], + "keywords": [ + "hyperbridge", + "indexer", + "subquery", + "graphql", + "substrate", + "blockchain", + "interoperability", + "cryptocurrency", + "evm" + ], + "homepage": "https://github.com/polytope-labs/hyperbridge-sdk#readme", + "bugs": { + "url": "https://github.com/polytope-labs/hyperbridge-sdk/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/polytope-labs/hyperbridge-sdk.git" + }, + "license": "ISC", + "author": "Polytope Labs", + "scripts": { + "build": "pnpm run build:browser && pnpm run build:node", + "build:node": "tsup --config tsup-node.config.ts", + "build:browser": "tsup --config tsup-browser.config.ts", + "prepublishOnly": "npm run build", + "test": "npm run test:concurrent && npm run test:sequence", + "test:file": "vitest --watch=false --maxConcurrency=1", + "test:concurrent": "vitest --watch=false --exclude=./src/tests/sequential", + "test:sequence": "vitest --watch=false --sequence.concurrent=false ./src/tests/sequential/**", + "test:requests": "vitest --watch=false --sequence.concurrent=false ./src/tests/sequential/requests.test.ts", + "test:intent-gateway": "vitest --watch=false --sequence.concurrent=false ./src/tests/sequential/intentGateway.test.ts", + "test:token-gateway": "vitest --watch=false --sequence.concurrent=false ./src/tests/tokenGateway.test.ts", + "test:evm-substrate": "vitest --watch=false --sequence.concurrent=false ./src/tests/sequential/evm-substrate.test.ts", + "test:watch": "vitest --exclude=./src/tests/sequential", + "lint": "biome lint .", + "lint:fix": "biome lint --write .", + "format": "prettier --write \"src/**/*.ts\"" + }, + "dependencies": { + "@async-generator/merge-race": "^1.0.3", + "@polkadot/api": "latest", + "@polkadot/types": "latest", + "@polkadot/util": "latest", + "@polkadot/util-crypto": "latest", + "@types/lodash-es": "^4.17.12", + "consola": "^3.4.2", + "decimal.js": "^10.5.0", + "graphql": "^16.10.0", + "graphql-request": "^7.1.2", + "idb-keyval": "^6.2.2", + "lodash-es": "^4.17.15", + "rpc-websocket-client": "^1.1.4", + "scale-ts": "^1.6.1", + "std-env": "^3.9.0", + "ts-pattern": "^5.6.2", + "unstorage": "^1.17.2", + "viem": "^2.34.0" + }, + "devDependencies": { + "@biomejs/biome": "^1.9.4", + "@iarna/toml": "^2.2.5", + "@polkadot/keyring": "latest", + "@polytope-labs/hyperclient": "1.2.0", + "@types/node": "^22.13.5", + "@vitest/coverage-v8": "^3.1.4", + "dotenv": "^16.4.7", + "jsdom": "^26.0.0", + "log-timestamp": "^0.3.0", + "tsup": "^8.4.0", + "vite-tsconfig-paths": "^5.1.4", + "vitest": "^3.1.4" + }, + "resolutions": { + "@polkadot/api": "^16.4.6", + "@polkadot/api-augment": "^16.4.6", + "@polkadot/api-base": "^16.4.6", + "@polkadot/api-contract": "^16.4.6", + "@polkadot/api-derive": "^16.4.6", + "@polkadot/hw-ledger": "^13.5.6", + "@polkadot/keyring": "^13.5.6", + "@polkadot/networks": "^13.5.6", + "@polkadot/phishing": "^0.25.18", + "@polkadot/rpc-augment": "^16.4.6", + "@polkadot/rpc-core": "^16.4.6", + "@polkadot/rpc-provider": "^16.4.6", + "@polkadot/typegen": "^16.4.6", + "@polkadot/types": "^16.4.6", + "@polkadot/types-augment": "^16.4.6", + "@polkadot/types-codec": "^16.4.6", + "@polkadot/types-create": "^16.4.6", + "@polkadot/types-known": "^16.4.6", + "@polkadot/types-support": "^16.4.6", + "@polkadot/util": "^13.5.6", + "@polkadot/util-crypto": "^13.5.6", + "@polkadot/wasm-crypto": "^7.5.1", + "@polkadot/x-bigint": "^13.5.6", + "@polkadot/x-fetch": "^13.5.6", + "@polkadot/x-global": "^13.5.6", + "@polkadot/x-randomvalues": "^13.5.6", + "@polkadot/x-textdecoder": "^13.5.6", + "@polkadot/x-textencoder": "^13.5.6", + "@polkadot/x-ws": "^13.5.6", + "typescript": "^5.9.3" + }, + "peerDependencies": { + "vite": "^5.0.0 || ^6.0.0" + }, + "publishConfig": { + "access": "public" + }, + "engineStrict": true, + "engines": { + "node": ">=22.x.x" + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/plugins/monorepo-helper.js b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/plugins/monorepo-helper.js new file mode 100644 index 00000000..949c3953 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/plugins/monorepo-helper.js @@ -0,0 +1,83 @@ +import fs from "node:fs"; +import path from "node:path"; + +function hasConventionalMonorepoLayout(dir) { + const candidates = ["packages", "apps"]; + for (const name of candidates) { + const p = path.join(dir, name); + if (fs.existsSync(p) && fs.lstatSync(p).isDirectory()) { + // Check if there are multiple subdirs with package.json + const subdirs = fs.readdirSync(p).filter(d => { + const full = path.join(p, d); + return fs.lstatSync(full).isDirectory() && + fs.existsSync(path.join(full, "package.json")); + }); + if (subdirs.length >= 2) return true; + } + } + return false; +} + +function hasWorkspaces(dir) { + const pkgPath = path.join(dir, "package.json"); + if (!fs.existsSync(pkgPath)) return false; + try { + const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8")); + if (Array.isArray(pkg.workspaces) && pkg.workspaces.length > 0) return true; + if (pkg.workspaces && Array.isArray(pkg.workspaces.packages) && pkg.workspaces.packages.length > 0) return true; + } catch { } + return false; +} + +function hasPnpmWorkspace(dir) { + return fs.existsSync(path.join(dir, "pnpm-workspace.yaml")); +} + +function hasLerna(dir) { + const lernaPath = path.join(dir, "lerna.json"); + if (!fs.existsSync(lernaPath)) return false; + try { + const lerna = JSON.parse(fs.readFileSync(lernaPath, "utf8")); + return Array.isArray(lerna.packages) && lerna.packages.length > 0; + } catch { return false; } +} + +function hasNx(dir) { + return fs.existsSync(path.join(dir, "nx.json")) || + fs.existsSync(path.join(dir, "workspace.json")); +} + +function hasTurbo(dir) { + return fs.existsSync(path.join(dir, "turbo.json")); +} + +function hasRush(dir) { + return fs.existsSync(path.join(dir, "rush.json")); +} + +function isMonorepoDir(dir) { + return hasWorkspaces(dir) || + hasPnpmWorkspace(dir) || + hasLerna(dir) || + hasNx(dir) || + hasTurbo(dir) || + hasRush(dir) || + hasConventionalMonorepoLayout(dir); +} + +/** + * Example it detects: starting at /repo/apps/web/src + * - finds nx.json at /repo → returns /repo + * Or starting at /repo/packages/lib/src + * - no tool configs, but finds multiple package.json under /repo/packages → returns /repo + */ +export function findMonorepoRootHeuristic(startDir = process.cwd()) { + let dir = path.resolve(startDir); + const { root } = path.parse(dir); + + while (true) { + if (isMonorepoDir(dir)) return dir; + if (dir === root) return null; + dir = path.dirname(dir); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/plugins/vite.d.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/plugins/vite.d.ts new file mode 100644 index 00000000..07b9cbd3 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/plugins/vite.d.ts @@ -0,0 +1,13 @@ +import type { Plugin } from "vite" + +/** + * A Vite plugin that copies the WebAssembly file from @hyperbridge/sdk to the Vite cache directory. + * This ensures the WASM file is available for browser imports when using Vite. + * + * @returns {Plugin} A Vite plugin + */ +export function copyWasm(config: { + logLevel?: "debug" | "default" | "silent" +}): Plugin + +export default copyWasm diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/plugins/vite.js b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/plugins/vite.js new file mode 100644 index 00000000..d19ce5b1 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/plugins/vite.js @@ -0,0 +1,134 @@ +import { existsSync } from "node:fs" +import { copyFile } from "node:fs/promises" +import path from "node:path" +import { colorize } from "consola/utils" +import { findMonorepoRootHeuristic } from "./monorepo-helper.js"; + +/** eg. silent | debug | default */ +let debug_mode = "default"; +const validLevels = new Set(['debug', 'default', 'silent']) + +const logMessage = (message) => { + if ('silent' === debug_mode) return; + + const time = new Date().toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + second: "2-digit", + hour12: true, + }) + + const timestamp = colorize("dim", time) + const tag = colorize("bold", colorize("magenta", "[hyperbridge]")) + + return console.log(timestamp + tag, message) +} + +const logDebug = (message) => { + if (debug_mode !== 'debug') return; + + const time = new Date().toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + second: "2-digit", + hour12: true, + }) + + const timestamp = colorize("dim", time) + const tag = colorize("bold", colorize("magenta", "[hyperbridge]")) + const debug = colorize("cyan", "[debug]"); + + return console.debug(timestamp, tag, debug, message) +} + +const findWasmSource = (projectDir) => { + const projectNodeModules = path.resolve(projectDir, "node_modules"); + let source = path.resolve(projectNodeModules, "@hyperbridge/sdk/dist/browser/web_bg.wasm"); + + if (existsSync(source)) return { source, tag: "Project Root" } + + logDebug("Could not find wasm dependency in project node_modules, checking monorepo root..."); + const monorepoRoot = findMonorepoRootHeuristic(projectDir); + + if (!monorepoRoot) return null; + + const monorepoNodeModules = path.resolve(monorepoRoot, "node_modules"); + source = path.resolve(monorepoNodeModules, "@hyperbridge/sdk/dist/browser/web_bg.wasm"); + + if (!existsSync(source)) return null; + + logDebug(`Found wasm dependency in monorepo root: ${source}`); + return { source, tag: "Monorepo Root" } +} + +const waitAndCopy = async ({ source, dest, destDir }) => { + const interval = 2000; // 2 seconds + const timeout = 60000; // 60 seconds + let elapsedTime = 0; + + while (elapsedTime < timeout) { + if (existsSync(destDir)) { + logMessage(`📦 Copying wasm dependency from ${source.tag}`); + try { + await copyFile(source.source, dest); + logMessage("✅ Copy complete"); + return; + } catch (error) { + logMessage(`❌ Error copying wasm file: ${error?.message}`); + return; + } + } else { + logMessage(`... waiting for ${destDir} to be created (retrying in 2s)`); + await new Promise(resolve => setTimeout(resolve, interval)); + elapsedTime += interval; + } + } + logMessage(`❌ Timed out waiting for ${destDir} to be created.`); +} + +/** + * + * @returns {import('vite').PluginContainer} + */ +const copyWasm = (params = {}) => { + const { logLevel = "default" } = params; + + if (!validLevels.has(logLevel)) { + throw new Error(`Invalid log level: ${logLevel}. Should be one of: ${Array.from(validLevels.values()).join(", ")}`); + } + + debug_mode = logLevel; + + let is_dev_server = false; + + + return { + name: "@hyperbridge/vite:wasm-deps", + configResolved(config) { + if (config.command === "serve") { + is_dev_server = true + } + }, + buildStart: function makeCopy() { + if (!is_dev_server) { + logMessage("⏭️ Skipping wasm dependency. Not neccessary for bundling step"); + return; + } + + const source = findWasmSource(process.cwd()); + + if (!source) { + logMessage("❌ Could not find wasm dependency."); + return; + } + + const projectNodeModules = path.resolve(process.cwd(), "node_modules"); + const destDir = path.resolve(projectNodeModules, "./.vite/deps"); + const dest = path.resolve(destDir, "web_bg.wasm"); + + waitAndCopy({ source, dest, destDir }); + } + } +} + +export default copyWasm diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/pnpm-lock.yaml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/pnpm-lock.yaml new file mode 100644 index 00000000..3bd539f5 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/pnpm-lock.yaml @@ -0,0 +1,3380 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@async-generator/merge-race': + specifier: ^1.0.3 + version: 1.0.3 + '@polkadot/api': + specifier: latest + version: 16.4.9 + '@polkadot/types': + specifier: latest + version: 16.4.9 + '@polkadot/util': + specifier: latest + version: 13.5.7 + '@polkadot/util-crypto': + specifier: latest + version: 13.5.7(@polkadot/util@13.5.7) + '@types/lodash-es': + specifier: ^4.17.12 + version: 4.17.12 + consola: + specifier: ^3.4.2 + version: 3.4.2 + decimal.js: + specifier: ^10.5.0 + version: 10.5.0 + graphql: + specifier: ^16.10.0 + version: 16.10.0 + graphql-request: + specifier: ^7.1.2 + version: 7.1.2(graphql@16.10.0) + idb-keyval: + specifier: ^6.2.2 + version: 6.2.2 + lodash-es: + specifier: ^4.17.15 + version: 4.17.21 + rpc-websocket-client: + specifier: ^1.1.4 + version: 1.1.4 + scale-ts: + specifier: ^1.6.1 + version: 1.6.1 + std-env: + specifier: ^3.9.0 + version: 3.9.0 + ts-pattern: + specifier: ^5.6.2 + version: 5.6.2 + unstorage: + specifier: ^1.17.2 + version: 1.17.2(idb-keyval@6.2.2) + viem: + specifier: ^2.34.0 + version: 2.34.0(typescript@5.9.3) + vite: + specifier: ^5.0.0 || ^6.0.0 + version: 6.3.5(@types/node@22.13.9) + devDependencies: + '@biomejs/biome': + specifier: ^1.9.4 + version: 1.9.4 + '@iarna/toml': + specifier: ^2.2.5 + version: 2.2.5 + '@polkadot/keyring': + specifier: latest + version: 13.5.7(@polkadot/util-crypto@13.5.7(@polkadot/util@13.5.7))(@polkadot/util@13.5.7) + '@polytope-labs/hyperclient': + specifier: 1.2.0 + version: 1.2.0 + '@types/node': + specifier: ^22.13.5 + version: 22.13.9 + '@vitest/coverage-v8': + specifier: ^3.1.4 + version: 3.1.4(vitest@3.1.4(@types/node@22.13.9)(jsdom@26.0.0)) + dotenv: + specifier: ^16.4.7 + version: 16.4.7 + jsdom: + specifier: ^26.0.0 + version: 26.0.0 + log-timestamp: + specifier: ^0.3.0 + version: 0.3.0 + tsup: + specifier: ^8.4.0 + version: 8.4.0(postcss@8.5.3)(typescript@5.9.3) + vite-tsconfig-paths: + specifier: ^5.1.4 + version: 5.1.4(typescript@5.9.3)(vite@6.3.5(@types/node@22.13.9)) + vitest: + specifier: ^3.1.4 + version: 3.1.4(@types/node@22.13.9)(jsdom@26.0.0) + +packages: + + '@adraffy/ens-normalize@1.11.0': + resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@asamuzakjp/css-color@2.8.3': + resolution: {integrity: sha512-GIc76d9UI1hCvOATjZPyHFmE5qhRccp3/zGfMPapK3jBi+yocEzp6BBB0UnfRYP9NP4FANqUZYb0hnfs3TM3hw==} + + '@async-generator/merge-race@1.0.3': + resolution: {integrity: sha512-6bbKfLJoRpMdqWhR8MuoSdgtqXZ0S1MnPv21QRi1BefOPBNCJJZJikk3U9LhZVEw9RuqIwd56AuLroTC+EeFgQ==} + + '@async-generator/subject@1.0.3': + resolution: {integrity: sha512-8aa17UMPPmhSEGcsjsoo7GqJvgw6L8um+8YQPeKYxK/zEZdSh1Mep/QoOo4/3sAYzFBtTwDSoib7J15SZAqfwg==} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.26.9': + resolution: {integrity: sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.26.9': + resolution: {integrity: sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@1.0.2': + resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} + engines: {node: '>=18'} + + '@biomejs/biome@1.9.4': + resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@1.9.4': + resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@1.9.4': + resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@1.9.4': + resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@1.9.4': + resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@1.9.4': + resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@1.9.4': + resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@1.9.4': + resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@1.9.4': + resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@csstools/color-helpers@5.0.2': + resolution: {integrity: sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==} + engines: {node: '>=18'} + + '@csstools/css-calc@2.1.2': + resolution: {integrity: sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/css-color-parser@3.0.8': + resolution: {integrity: sha512-pdwotQjCCnRPuNi06jFuP68cykU1f3ZWExLe/8MQ1LOs8Xq+fTkYgd+2V8mWUWMrOn9iS2HftPVaMZDaXzGbhQ==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-parser-algorithms': ^3.0.4 + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/css-parser-algorithms@3.0.4': + resolution: {integrity: sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==} + engines: {node: '>=18'} + peerDependencies: + '@csstools/css-tokenizer': ^3.0.3 + + '@csstools/css-tokenizer@3.0.3': + resolution: {integrity: sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==} + engines: {node: '>=18'} + + '@esbuild/aix-ppc64@0.25.0': + resolution: {integrity: sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.0': + resolution: {integrity: sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.0': + resolution: {integrity: sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.0': + resolution: {integrity: sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.0': + resolution: {integrity: sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.0': + resolution: {integrity: sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.0': + resolution: {integrity: sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.0': + resolution: {integrity: sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.0': + resolution: {integrity: sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.0': + resolution: {integrity: sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.0': + resolution: {integrity: sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.0': + resolution: {integrity: sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.0': + resolution: {integrity: sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.0': + resolution: {integrity: sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.0': + resolution: {integrity: sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.0': + resolution: {integrity: sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.0': + resolution: {integrity: sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.0': + resolution: {integrity: sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.0': + resolution: {integrity: sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.0': + resolution: {integrity: sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.0': + resolution: {integrity: sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.25.0': + resolution: {integrity: sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.0': + resolution: {integrity: sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.0': + resolution: {integrity: sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.0': + resolution: {integrity: sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@graphql-typed-document-node/core@3.2.0': + resolution: {integrity: sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==} + 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 + + '@iarna/toml@2.2.5': + resolution: {integrity: sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.6': + resolution: {integrity: sha512-GIKz/j99FRthB8icyJQA51E8Uk5hXmdyThjgQXRKiv9h0zeRlzSCLIzFw6K1LotZ3XuB7yzlf76qk7uBmTdFqA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@polkadot-api/json-rpc-provider-proxy@0.1.0': + resolution: {integrity: sha512-8GSFE5+EF73MCuLQm8tjrbCqlgclcHBSRaswvXziJ0ZW7iw3UEMsKkkKvELayWyBuOPa2T5i1nj6gFOeIsqvrg==} + + '@polkadot-api/json-rpc-provider@0.0.1': + resolution: {integrity: sha512-/SMC/l7foRjpykLTUTacIH05H3mr9ip8b5xxfwXlVezXrNVLp3Cv0GX6uItkKd+ZjzVPf3PFrDF2B2/HLSNESA==} + + '@polkadot-api/metadata-builders@0.3.2': + resolution: {integrity: sha512-TKpfoT6vTb+513KDzMBTfCb/ORdgRnsS3TDFpOhAhZ08ikvK+hjHMt5plPiAX/OWkm1Wc9I3+K6W0hX5Ab7MVg==} + + '@polkadot-api/observable-client@0.3.2': + resolution: {integrity: sha512-HGgqWgEutVyOBXoGOPp4+IAq6CNdK/3MfQJmhCJb8YaJiaK4W6aRGrdQuQSTPHfERHCARt9BrOmEvTXAT257Ug==} + peerDependencies: + '@polkadot-api/substrate-client': 0.1.4 + rxjs: '>=7.8.0' + + '@polkadot-api/substrate-bindings@0.6.0': + resolution: {integrity: sha512-lGuhE74NA1/PqdN7fKFdE5C1gNYX357j1tWzdlPXI0kQ7h3kN0zfxNOpPUN7dIrPcOFZ6C0tRRVrBylXkI6xPw==} + + '@polkadot-api/substrate-client@0.1.4': + resolution: {integrity: sha512-MljrPobN0ZWTpn++da9vOvt+Ex+NlqTlr/XT7zi9sqPtDJiQcYl+d29hFAgpaeTqbeQKZwz3WDE9xcEfLE8c5A==} + + '@polkadot-api/utils@0.1.0': + resolution: {integrity: sha512-MXzWZeuGxKizPx2Xf/47wx9sr/uxKw39bVJUptTJdsaQn/TGq+z310mHzf1RCGvC1diHM8f593KrnDgc9oNbJA==} + + '@polkadot/api-augment@16.4.9': + resolution: {integrity: sha512-3C5g6VUjs3cOwZmI2QDxZnwyLXI7554+fxQ/Mi5q12l7/5D5UrvDcDxFKUMALEUJRixGUvQ5T0f8s4mTHO/QsQ==} + engines: {node: '>=18'} + + '@polkadot/api-base@16.4.9': + resolution: {integrity: sha512-pv1n3bhMaA83+OBIw/tInfpuoRnpTBqzQKrkSYTVlbF+tlK0X3zl7iX0vxy1YJaL2vVQUiPR2tP3wnzz1mv7qg==} + engines: {node: '>=18'} + + '@polkadot/api-derive@16.4.9': + resolution: {integrity: sha512-3SgE7QOGy/G48hrz3rumzyJ2So875b/9pZXnp0b1Jm0c7p/nKwdcNK1nuWp/nMZ8RiEZpicVYmmkuytEXOwmkA==} + engines: {node: '>=18'} + + '@polkadot/api@16.4.9': + resolution: {integrity: sha512-bcJebd7RFWZYNL6hBwwLOq3jly3C5VL8BADqY2yu+ZfoFYQqdg7VrYhcmnl8O5IiG1DOpYIbuekRpKuBMkjNmw==} + engines: {node: '>=18'} + + '@polkadot/keyring@13.5.7': + resolution: {integrity: sha512-S75K2m2AoiTMnns7ko3t72jvyJRmrqdFFPldLdPdjRuds+E8OFewcwms/aXHGn9IwViWHFX6PSx0QAzWN/qWzQ==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': 13.5.7 + '@polkadot/util-crypto': 13.5.7 + + '@polkadot/networks@13.5.7': + resolution: {integrity: sha512-RdQcgaPy68NRSI7UTBdxr1aw66MXVdbpGhpWQpLf3/7puUdwkem6KxqFNnC9/kJSXRlyYGeYHN9Hsf4+CTWBSQ==} + engines: {node: '>=18'} + + '@polkadot/rpc-augment@16.4.9': + resolution: {integrity: sha512-J/6A2NgM92K8vHKGqUo877dPEOzYDoAm/8Ixrbq64obYnaVl5kAN+cctyRR0ywOTrY1wyRJmVa6Y83IPMgbX/A==} + engines: {node: '>=18'} + + '@polkadot/rpc-core@16.4.9': + resolution: {integrity: sha512-yOe0envLjrAffxL5NI1U9XaSt7bst93TVQdOyPw0HKCLc3uCJWnrnq8CKvdmR7IfHop+A1rkLaWyfY3tWcUMrA==} + engines: {node: '>=18'} + + '@polkadot/rpc-provider@16.4.9': + resolution: {integrity: sha512-1q+KVu2t2eTe5pLE+KaXXlU9itMc7LHFqssPFZi5VIZG+ORjAy2FmxwxWZmDlo/P12ZTD5CpJiJchtJ9Z6X0Zw==} + engines: {node: '>=18'} + + '@polkadot/types-augment@16.4.9': + resolution: {integrity: sha512-uTl3kJ01v3POJzIruzVtWshWjpd8nUmeREE0FSyYS6nb99mEk3nVy3w6V3dsHjEBF2X7FdU2ePTbr9mK0MI5AA==} + engines: {node: '>=18'} + + '@polkadot/types-codec@16.4.9': + resolution: {integrity: sha512-yw03qNA1QlXhvQ1zPE/+Km0t4tU3505chWJgR7m8sDehQkKXF0rNYURPuAVE+LpkzSyacJr9KU1X4Nkg42VfuQ==} + engines: {node: '>=18'} + + '@polkadot/types-create@16.4.9': + resolution: {integrity: sha512-428fwkPmQnENZdbX8bmc4dSqkVm328c1/Byxaa67gNsexeYi3XCFqjFC4toDECHNWW2YYN0XuPK6ieunPZuFpQ==} + engines: {node: '>=18'} + + '@polkadot/types-known@16.4.9': + resolution: {integrity: sha512-VzP0NZnthqz1hDXcF7VJbzMe/G589gaIVI5Y8NbGVYBwsR4BaxU3msLguM2MFlVCTOCCDlC8SJOezgaeWfg2DA==} + engines: {node: '>=18'} + + '@polkadot/types-support@16.4.9': + resolution: {integrity: sha512-NiSGYEVeyXo/8a/O5kIEZDpHE6zrcZtFeyrWLIPtjbIV0PfuJzl1Bc0i8rGZWcn/ZdZjnSYg++l33sTb2GaJOQ==} + engines: {node: '>=18'} + + '@polkadot/types@16.4.9': + resolution: {integrity: sha512-nfXIviIBohn603Q8t6vDQYrKDMeisVFN7EjDVOIYLXFMwbe9MvTW6i/NLyu9m42O8Z76O+yUisMazaE4046xJA==} + engines: {node: '>=18'} + + '@polkadot/util-crypto@13.5.7': + resolution: {integrity: sha512-SNzfAmtSSfUnQesrGLxc1RDg1arsvFSsAkH0xulffByqJfLugB3rZWJXIKqKNfcRZtomsMMURPeW7lfpAomSug==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': 13.5.7 + + '@polkadot/util@13.5.7': + resolution: {integrity: sha512-5Rhp6/FDI55iCJcGd/9bMQaF0E26OE+uZwz68JuRW75DW8v7zsN3bnjnVqk3KO/c4u5EgLSqbhXPuyW24BP1+Q==} + engines: {node: '>=18'} + + '@polkadot/wasm-bridge@7.5.1': + resolution: {integrity: sha512-E+N3CSnX3YaXpAmfIQ+4bTyiAqJQKvVcMaXjkuL8Tp2zYffClWLG5e+RY15Uh+EWfUl9If4y6cLZi3D5NcpAGQ==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': '*' + '@polkadot/x-randomvalues': '*' + + '@polkadot/wasm-crypto-asmjs@7.5.1': + resolution: {integrity: sha512-jAg7Uusk+xeHQ+QHEH4c/N3b1kEGBqZb51cWe+yM61kKpQwVGZhNdlWetW6U23t/BMyZArIWMsZqmK/Ij0PHog==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': '*' + + '@polkadot/wasm-crypto-init@7.5.1': + resolution: {integrity: sha512-Obu4ZEo5jYO6sN31eqCNOXo88rPVkP9TrUOyynuFCnXnXr8V/HlmY/YkAd9F87chZnkTJRlzak17kIWr+i7w3A==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': '*' + '@polkadot/x-randomvalues': '*' + + '@polkadot/wasm-crypto-wasm@7.5.1': + resolution: {integrity: sha512-S2yQSGbOGTcaV6UdipFVyEGanJvG6uD6Tg7XubxpiGbNAblsyYKeFcxyH1qCosk/4qf+GIUwlOL4ydhosZflqg==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': '*' + + '@polkadot/wasm-crypto@7.5.1': + resolution: {integrity: sha512-acjt4VJ3w19v7b/SIPsV/5k9s6JsragHKPnwoZ0KTfBvAFXwzz80jUzVGxA06SKHacfCUe7vBRlz7M5oRby1Pw==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': '*' + '@polkadot/x-randomvalues': '*' + + '@polkadot/wasm-util@7.5.1': + resolution: {integrity: sha512-sbvu71isFhPXpvMVX+EkRnUg/+54Tx7Sf9BEMqxxoPj7cG1I/MKeDEwbQz6MaU4gm7xJqvEWCAemLFcXfHQ/2A==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': '*' + + '@polkadot/x-bigint@13.5.7': + resolution: {integrity: sha512-NbN4EPbMBhjOXoWj0BVcT49/obzusFWPKbSyBxbZi8ITBaIIgpncgcCfXY4rII6Fqh74khx9jdevWge/6ycepQ==} + engines: {node: '>=18'} + + '@polkadot/x-fetch@13.5.7': + resolution: {integrity: sha512-ZlPtWJAq7xMMr8wo9API8l6mKRr/6kClF0Hm1CVhQgZruFTZd7A2XZfETMg49yaRouy16SRI85WhIw+pXfQd3g==} + engines: {node: '>=18'} + + '@polkadot/x-global@13.5.7': + resolution: {integrity: sha512-TkBxLfeKtj0laCzXp2lvRhwSIeXSxIu7LAWpfAUW4SYNFQvtgIS0x0Bq70CUW3lcy0wqTrSG2cqzfnbomB0Djw==} + engines: {node: '>=18'} + + '@polkadot/x-randomvalues@13.5.7': + resolution: {integrity: sha512-NEElpdu+Wqlr6USoh3abQfe0MaWlFlynPiqkA0/SJjK+0V0UOw0CyPwPgGrGa71/ju+1bsnu/ySshXqCR8HXTw==} + engines: {node: '>=18'} + peerDependencies: + '@polkadot/util': 13.5.7 + '@polkadot/wasm-util': '*' + + '@polkadot/x-textdecoder@13.5.7': + resolution: {integrity: sha512-wjSj+T2pBA1uW9dDYriZMAv4WgXl5zcWblxwOsZd3V/qxifMSlSLAy0WeC+08DD6TXGQYCOU0uOALsDivkUDZA==} + engines: {node: '>=18'} + + '@polkadot/x-textencoder@13.5.7': + resolution: {integrity: sha512-h6RsGUY8ZZrfqsbojD1VqTqmXcojDSfbXQHhVcAWqgceeh9JOOw8Q6yzhv+KpPelqKq/map3bobJaebQ8QNTMw==} + engines: {node: '>=18'} + + '@polkadot/x-ws@13.5.7': + resolution: {integrity: sha512-ZdmFhL3gDMRxJXqN7a88BIU1sm2IgAFnn+jMcjjJXwP5qEuP9ejwPHQL0EFOw6sqtylfQUFuWvahvIZT7MbQ5g==} + engines: {node: '>=18'} + + '@polytope-labs/hyperclient@1.2.0': + resolution: {integrity: sha512-HZH7lIg5MbUhrnS6pCIQgAvsFd5XnKuZ4Sg2xVbod2H/l/PWFXgH5eOaMfxEQIvzWo1r8Nl6kERDH/HpHvb+NQ==} + engines: {node: '>= 22.4.1'} + + '@rollup/rollup-android-arm-eabi@4.40.2': + resolution: {integrity: sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.40.2': + resolution: {integrity: sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.40.2': + resolution: {integrity: sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.40.2': + resolution: {integrity: sha512-47N4hxa01a4x6XnJoskMKTS8XZ0CZMd8YTbINbi+w03A2w4j1RTlnGHOz/P0+Bg1LaVL6ufZyNprSg+fW5nYQQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.40.2': + resolution: {integrity: sha512-8t6aL4MD+rXSHHZUR1z19+9OFJ2rl1wGKvckN47XFRVO+QL/dUSpKA2SLRo4vMg7ELA8pzGpC+W9OEd1Z/ZqoQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.40.2': + resolution: {integrity: sha512-C+AyHBzfpsOEYRFjztcYUFsH4S7UsE9cDtHCtma5BK8+ydOZYgMmWg1d/4KBytQspJCld8ZIujFMAdKG1xyr4Q==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.40.2': + resolution: {integrity: sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.40.2': + resolution: {integrity: sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.40.2': + resolution: {integrity: sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.40.2': + resolution: {integrity: sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.40.2': + resolution: {integrity: sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.40.2': + resolution: {integrity: sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.40.2': + resolution: {integrity: sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.40.2': + resolution: {integrity: sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.40.2': + resolution: {integrity: sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.40.2': + resolution: {integrity: sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.40.2': + resolution: {integrity: sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.40.2': + resolution: {integrity: sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.40.2': + resolution: {integrity: sha512-dt1llVSGEsGKvzeIO76HToiYPNPYPkmjhMHhP00T9S4rDern8P2ZWvWAQUEJ+R1UdMWJ/42i/QqJ2WV765GZcA==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.40.2': + resolution: {integrity: sha512-bwspbWB04XJpeElvsp+DCylKfF4trJDa2Y9Go8O6A7YLX2LIKGcNK/CYImJN6ZP4DcuOHB4Utl3iCbnR62DudA==} + cpu: [x64] + os: [win32] + + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + + '@substrate/connect-extension-protocol@2.2.2': + resolution: {integrity: sha512-t66jwrXA0s5Goq82ZtjagLNd7DPGCNjHeehRlE/gcJmJ+G56C0W+2plqOMRicJ8XGR1/YFnUSEqUFiSNbjGrAA==} + + '@substrate/connect-known-chains@1.9.2': + resolution: {integrity: sha512-uEmm+rKJQQhhbforvmcg74TsDHKFVBkstjPwblGT1RdHMxUKR7Gq7F8vbkGnr5ce9tMK2Ylil760Z7vtX013hw==} + + '@substrate/connect@0.8.11': + resolution: {integrity: sha512-ofLs1PAO9AtDdPbdyTYj217Pe+lBfTLltdHDs3ds8no0BseoLeAGxpz1mHfi7zB4IxI3YyAiLjH6U8cw4pj4Nw==} + deprecated: versions below 1.x are no longer maintained + + '@substrate/light-client-extension-helpers@1.0.0': + resolution: {integrity: sha512-TdKlni1mBBZptOaeVrKnusMg/UBpWUORNDv5fdCaJklP4RJiFOzBCrzC+CyVI5kQzsXBisZ+2pXm+rIjS38kHg==} + peerDependencies: + smoldot: 2.x + + '@substrate/ss58-registry@1.51.0': + resolution: {integrity: sha512-TWDurLiPxndFgKjVavCniytBIw+t4ViOi7TYp9h/D0NMmkEc9klFTo+827eyEJ0lELpqO207Ey7uGxUa+BS1jQ==} + + '@types/bn.js@5.1.6': + resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.16': + resolution: {integrity: sha512-HX7Em5NYQAXKW+1T+FiuG27NGwzJfCX3s1GjOa7ujxZa52kjJLOr4FUxT+giF6Tgxv1e+/czV/iTtBw27WTU9g==} + + '@types/node@22.13.9': + resolution: {integrity: sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==} + + '@vitest/coverage-v8@3.1.4': + resolution: {integrity: sha512-G4p6OtioySL+hPV7Y6JHlhpsODbJzt1ndwHAFkyk6vVjpK03PFsKnauZIzcd0PrK4zAbc5lc+jeZ+eNGiMA+iw==} + peerDependencies: + '@vitest/browser': 3.1.4 + vitest: 3.1.4 + peerDependenciesMeta: + '@vitest/browser': + optional: true + + '@vitest/expect@3.1.4': + resolution: {integrity: sha512-xkD/ljeliyaClDYqHPNCiJ0plY5YIcM0OlRiZizLhlPmpXWpxnGMyTZXOHFhFeG7w9P5PBeL4IdtJ/HeQwTbQA==} + + '@vitest/mocker@3.1.4': + resolution: {integrity: sha512-8IJ3CvwtSw/EFXqWFL8aCMu+YyYXG2WUSrQbViOZkWTKTVicVwZ/YiEZDSqD00kX+v/+W+OnxhNWoeVKorHygA==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@3.1.4': + resolution: {integrity: sha512-cqv9H9GvAEoTaoq+cYqUTCGscUjKqlJZC7PRwY5FMySVj5J+xOm1KQcCiYHJOEzOKRUhLH4R2pTwvFlWCEScsg==} + + '@vitest/runner@3.1.4': + resolution: {integrity: sha512-djTeF1/vt985I/wpKVFBMWUlk/I7mb5hmD5oP8K9ACRmVXgKTae3TUOtXAEBfslNKPzUQvnKhNd34nnRSYgLNQ==} + + '@vitest/snapshot@3.1.4': + resolution: {integrity: sha512-JPHf68DvuO7vilmvwdPr9TS0SuuIzHvxeaCkxYcCD4jTk67XwL45ZhEHFKIuCm8CYstgI6LZ4XbwD6ANrwMpFg==} + + '@vitest/spy@3.1.4': + resolution: {integrity: sha512-Xg1bXhu+vtPXIodYN369M86K8shGLouNjoVI78g8iAq2rFoHFdajNvJJ5A/9bPMFcfQqdaCpOgWKEoMQg/s0Yg==} + + '@vitest/utils@3.1.4': + resolution: {integrity: sha512-yriMuO1cfFhmiGc8ataN51+9ooHRuURdfAZfwFd3usWynjzpLslZdYnRegTv32qdgtJTsj15FoeZe2g15fY1gg==} + + abitype@1.0.8: + resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + agent-base@7.1.3: + resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} + engines: {node: '>= 14'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + bundle-require@5.1.0: + resolution: {integrity: sha512-3WrrOuZiyaaZPWiEt4G3+IffISVC9HYlWueJEBWED4ZH4aIAC2PnkdnuRrR94M+w6yGWn4AglWtJtBI8YqvgoA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.18' + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + chai@5.2.0: + resolution: {integrity: sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==} + engines: {node: '>=12'} + + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + consola@3.4.2: + resolution: {integrity: sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==} + engines: {node: ^14.18.0 || >=16.10.0} + + cookie-es@1.2.2: + resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + + cssstyle@4.2.1: + resolution: {integrity: sha512-9+vem03dMXG7gDmZ62uqmRiMRNtinIZ9ZyuF6BdxzfOD+FdN5hretzynkn0ReS2DO2GSw76RWHs0UmJPI2zUjw==} + engines: {node: '>=18'} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + data-urls@5.0.0: + resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==} + engines: {node: '>=18'} + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decimal.js@10.5.0: + resolution: {integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==} + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + dotenv@16.4.7: + resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==} + engines: {node: '>=12'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + esbuild@0.25.0: + resolution: {integrity: sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==} + engines: {node: '>=18'} + hasBin: true + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + expect-type@1.2.1: + resolution: {integrity: sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==} + engines: {node: '>=12.0.0'} + + fdir@6.4.4: + resolution: {integrity: sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + form-data@4.0.2: + resolution: {integrity: sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==} + engines: {node: '>= 6'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + globrex@0.1.2: + resolution: {integrity: sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graphql-request@7.1.2: + resolution: {integrity: sha512-+XE3iuC55C2di5ZUrB4pjgwe+nIQBuXVIK9J98wrVwojzDW3GMdSBZfxUk8l4j9TieIpjpggclxhNEU9ebGF8w==} + peerDependencies: + graphql: 14 - 16 + + graphql@16.10.0: + resolution: {integrity: sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + + h3@1.15.4: + resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + html-encoding-sniffer@4.0.0: + resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==} + engines: {node: '>=18'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + idb-keyval@6.2.2: + resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + + isows@1.0.7: + resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} + peerDependencies: + ws: '*' + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@5.0.6: + resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + + jsdom@26.0.0: + resolution: {integrity: sha512-BZYDGVAIriBWTpIxYzrXjv3E/4u8+/pSG5bQdIYCbNCGOvsPkDQfTVLAIXAf9ETdCpduCVTkDe2NNZ8NIwUVzw==} + engines: {node: '>=18'} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-tsconfig@0.2.5: + resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + + log-prefix@0.1.1: + resolution: {integrity: sha512-aP1Lst8OCdZKATqzXDN0JBissNVZuiKLyo6hOXDBxaQ1jHDsaxh2J1i5Pp0zMy6ayTKDWfUlLMXyLaQe1PJ48g==} + + log-timestamp@0.3.0: + resolution: {integrity: sha512-luRz6soxijd1aJh0GkLXFjKABihxthvTfWTzu3XhCgg5EivG2bsTpSd63QFbUgS+/KmFtL+0RfSpeaD2QvOV8Q==} + + loupe@3.1.3: + resolution: {integrity: sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + magic-string@0.30.17: + resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + + magicast@0.3.5: + resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + mock-socket@9.3.1: + resolution: {integrity: sha512-qxBgB7Qa2sEQgHFjj0dSigq7fX4k6Saisd5Nelwp2q8mlbAFh5dHV9JTTlF8viYJLSSWgMCZFUom8PJcMNBoJw==} + engines: {node: '>= 8'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nanoid@3.3.8: + resolution: {integrity: sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nock@13.5.6: + resolution: {integrity: sha512-o2zOYiCpzRqSzPj0Zt/dQ/DqZeYoaQ7TUonc/xUPjCGl9WeHpNbxgVvOquXYAaJzI0M9BXV3HTzG0p8IUAbBTQ==} + engines: {node: '>= 10.13'} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + node-mock-http@1.0.3: + resolution: {integrity: sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nwsapi@2.2.18: + resolution: {integrity: sha512-p1TRH/edngVEHVbwqWnxUViEmq5znDvyB+Sik5cmuLpGOIfDf/39zLiq3swPF8Vakqn+gvNiOQAZu8djYlQILA==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + ofetch@1.5.0: + resolution: {integrity: sha512-A7llJ7eZyziA5xq9//3ZurA8OhFqtS99K5/V1sLBJ5j137CM/OAjlbA/TEJXBuOWwOfLqih+oH5U3ran4za1FQ==} + + ox@0.8.7: + resolution: {integrity: sha512-W1f0FiMf9NZqtHPEDEAEkyzZDwbIKfmH2qmQx8NNiQ/9JhxrSblmtLJsSfTtQG5YKowLOnBlLVguCyxm/7ztxw==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parse5@7.2.1: + resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} + engines: {node: '>= 6'} + + postcss-load-config@6.0.1: + resolution: {integrity: sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g==} + engines: {node: '>= 18'} + peerDependencies: + jiti: '>=1.21.0' + postcss: '>=8.0.9' + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + jiti: + optional: true + postcss: + optional: true + tsx: + optional: true + yaml: + optional: true + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + propagate@2.0.1: + resolution: {integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==} + engines: {node: '>= 8'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + rollup@4.40.2: + resolution: {integrity: sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + rpc-websocket-client@1.1.4: + resolution: {integrity: sha512-UDMVcsNDJ3WET+0EFdmseYX+60MOCA3BpgpZ5dbtiGsqHo+9uWfgNbPZ4iGDtNcX+EUhCt/Y7C0fTmUU3CkkWA==} + engines: {node: '>=6.0.0'} + + rrweb-cssom@0.8.0: + resolution: {integrity: sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==} + + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scale-ts@1.6.1: + resolution: {integrity: sha512-PBMc2AWc6wSEqJYBDPcyCLUj9/tMKnLX70jLOSndMtcUoLQucP/DM0vnQo1wJAYjTrQiq8iG9rD0q6wFzgjH7g==} + + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + smoldot@2.0.26: + resolution: {integrity: sha512-F+qYmH4z2s2FK+CxGj8moYcd1ekSIKH8ywkdqlOz88Dat35iB1DIYL11aILN46YSGMzQW/lbJNS307zBSDN5Ig==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + deprecated: The work that was done in this beta branch won't be included in future versions + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + std-env@3.9.0: + resolution: {integrity: sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + sucrase@3.35.0: + resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + test-exclude@7.0.1: + resolution: {integrity: sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==} + engines: {node: '>=18'} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.13: + resolution: {integrity: sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==} + engines: {node: '>=12.0.0'} + + tinypool@1.0.2: + resolution: {integrity: sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.2: + resolution: {integrity: sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==} + engines: {node: '>=14.0.0'} + + tldts-core@6.1.83: + resolution: {integrity: sha512-I2wb9OJc6rXyh9d4aInhSNWChNI+ra6qDnFEGEwe9OoA68lE4Temw29bOkf1Uvwt8VZS079t1BFZdXVBmmB4dw==} + + tldts@6.1.83: + resolution: {integrity: sha512-FHxxNJJ0WNsEBPHyC1oesQb3rRoxpuho/z2g3zIIAhw1WHJeQsUzK1jYK8TI1/iClaa4fS3Z2TCA9mtxXsENSg==} + hasBin: true + + tough-cookie@5.1.2: + resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==} + engines: {node: '>=16'} + + tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + + tr46@5.0.0: + resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==} + engines: {node: '>=18'} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-interface-checker@0.1.13: + resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} + + ts-pattern@5.6.2: + resolution: {integrity: sha512-d4IxJUXROL5NCa3amvMg6VQW2HVtZYmUTPfvVtO7zJWGYLJ+mry9v2OmYm+z67aniQoQ8/yFNadiEwtNS9qQiw==} + + tsconfck@3.1.5: + resolution: {integrity: sha512-CLDfGgUp7XPswWnezWwsCRxNmgQjhYq3VXHM0/XIRxhVrKw0M1if9agzryh1QS3nxjCROvV+xWxoJO1YctzzWg==} + engines: {node: ^18 || >=20} + hasBin: true + peerDependencies: + typescript: ^5.0.0 + peerDependenciesMeta: + typescript: + optional: true + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsup@8.4.0: + resolution: {integrity: sha512-b+eZbPCjz10fRryaAA7C8xlIHnf8VnsaRqydheLIqwG/Mcpfk8Z5zp3HayX7GaTygkigHl5cBUs+IhcySiIexQ==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + '@microsoft/api-extractor': ^7.36.0 + '@swc/core': ^1 + postcss: ^8.4.12 + typescript: '>=4.5.0' + peerDependenciesMeta: + '@microsoft/api-extractor': + optional: true + '@swc/core': + optional: true + postcss: + optional: true + typescript: + optional: true + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + undici-types@6.20.0: + resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + + unstorage@1.17.2: + resolution: {integrity: sha512-cKEsD6iBWJgOMJ6vW1ID/SYuqNf8oN4yqRk8OYqaVQ3nnkJXOT1PSpaMh2QfzLs78UN5kSNRD2c/mgjT8tX7+w==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6.0.3 || ^7.0.0 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1.0.1 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + + uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + + viem@2.34.0: + resolution: {integrity: sha512-HJZG9Wt0DLX042MG0PK17tpataxtdAEhpta9/Q44FqKwy3xZMI5Lx4jF+zZPuXFuYjZ68R0PXqRwlswHs6r4gA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + vite-node@3.1.4: + resolution: {integrity: sha512-6enNwYnpyDo4hEgytbmc6mYWHXDHYEn0D1/rw4Q+tnHUGtKTJsn8T1YkX6Q18wI5LCrS8CTYlBaiCqxOy2kvUA==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite-tsconfig-paths@5.1.4: + resolution: {integrity: sha512-cYj0LRuLV2c2sMqhqhGpaO3LretdtMn/BVX4cPLanIZuwwrkVl+lK84E/miEXkCHWXuq65rhNN4rXsBcOB3S4w==} + peerDependencies: + vite: '*' + peerDependenciesMeta: + vite: + optional: true + + vite@6.3.5: + resolution: {integrity: sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@3.1.4: + resolution: {integrity: sha512-Ta56rT7uWxCSJXlBtKgIlApJnT6e6IGmTYxYcmxjJ4ujuZDI59GUQgVDObXXJujOmPDBYXHK1qmaGtneu6TNIQ==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.1.4 + '@vitest/ui': 3.1.4 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + + webidl-conversions@7.0.0: + resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==} + engines: {node: '>=12'} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-url@14.1.1: + resolution: {integrity: sha512-mDGf9diDad/giZ/Sm9Xi2YcyzaFpbdLpJPr+E9fSkyQ7KpQD4SdFcugkRQYzhmfI4KeV4Qpnn2sKPdo+kmsgRQ==} + engines: {node: '>=18'} + + whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + 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 + + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + 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 + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + +snapshots: + + '@adraffy/ens-normalize@1.11.0': {} + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@asamuzakjp/css-color@2.8.3': + dependencies: + '@csstools/css-calc': 2.1.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-color-parser': 3.0.8(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + lru-cache: 10.4.3 + + '@async-generator/merge-race@1.0.3': + dependencies: + '@async-generator/subject': 1.0.3 + + '@async-generator/subject@1.0.3': {} + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/parser@7.26.9': + dependencies: + '@babel/types': 7.26.9 + + '@babel/types@7.26.9': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@bcoe/v8-coverage@1.0.2': {} + + '@biomejs/biome@1.9.4': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.9.4 + '@biomejs/cli-darwin-x64': 1.9.4 + '@biomejs/cli-linux-arm64': 1.9.4 + '@biomejs/cli-linux-arm64-musl': 1.9.4 + '@biomejs/cli-linux-x64': 1.9.4 + '@biomejs/cli-linux-x64-musl': 1.9.4 + '@biomejs/cli-win32-arm64': 1.9.4 + '@biomejs/cli-win32-x64': 1.9.4 + + '@biomejs/cli-darwin-arm64@1.9.4': + optional: true + + '@biomejs/cli-darwin-x64@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64@1.9.4': + optional: true + + '@biomejs/cli-linux-x64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-x64@1.9.4': + optional: true + + '@biomejs/cli-win32-arm64@1.9.4': + optional: true + + '@biomejs/cli-win32-x64@1.9.4': + optional: true + + '@csstools/color-helpers@5.0.2': {} + + '@csstools/css-calc@2.1.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': + dependencies: + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + + '@csstools/css-color-parser@3.0.8(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3)': + dependencies: + '@csstools/color-helpers': 5.0.2 + '@csstools/css-calc': 2.1.2(@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3))(@csstools/css-tokenizer@3.0.3) + '@csstools/css-parser-algorithms': 3.0.4(@csstools/css-tokenizer@3.0.3) + '@csstools/css-tokenizer': 3.0.3 + + '@csstools/css-parser-algorithms@3.0.4(@csstools/css-tokenizer@3.0.3)': + dependencies: + '@csstools/css-tokenizer': 3.0.3 + + '@csstools/css-tokenizer@3.0.3': {} + + '@esbuild/aix-ppc64@0.25.0': + optional: true + + '@esbuild/android-arm64@0.25.0': + optional: true + + '@esbuild/android-arm@0.25.0': + optional: true + + '@esbuild/android-x64@0.25.0': + optional: true + + '@esbuild/darwin-arm64@0.25.0': + optional: true + + '@esbuild/darwin-x64@0.25.0': + optional: true + + '@esbuild/freebsd-arm64@0.25.0': + optional: true + + '@esbuild/freebsd-x64@0.25.0': + optional: true + + '@esbuild/linux-arm64@0.25.0': + optional: true + + '@esbuild/linux-arm@0.25.0': + optional: true + + '@esbuild/linux-ia32@0.25.0': + optional: true + + '@esbuild/linux-loong64@0.25.0': + optional: true + + '@esbuild/linux-mips64el@0.25.0': + optional: true + + '@esbuild/linux-ppc64@0.25.0': + optional: true + + '@esbuild/linux-riscv64@0.25.0': + optional: true + + '@esbuild/linux-s390x@0.25.0': + optional: true + + '@esbuild/linux-x64@0.25.0': + optional: true + + '@esbuild/netbsd-arm64@0.25.0': + optional: true + + '@esbuild/netbsd-x64@0.25.0': + optional: true + + '@esbuild/openbsd-arm64@0.25.0': + optional: true + + '@esbuild/openbsd-x64@0.25.0': + optional: true + + '@esbuild/sunos-x64@0.25.0': + optional: true + + '@esbuild/win32-arm64@0.25.0': + optional: true + + '@esbuild/win32-ia32@0.25.0': + optional: true + + '@esbuild/win32-x64@0.25.0': + optional: true + + '@graphql-typed-document-node/core@3.2.0(graphql@16.10.0)': + dependencies: + graphql: 16.10.0 + + '@iarna/toml@2.2.5': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.9.6': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.8.0': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@polkadot-api/json-rpc-provider-proxy@0.1.0': + optional: true + + '@polkadot-api/json-rpc-provider@0.0.1': + optional: true + + '@polkadot-api/metadata-builders@0.3.2': + dependencies: + '@polkadot-api/substrate-bindings': 0.6.0 + '@polkadot-api/utils': 0.1.0 + optional: true + + '@polkadot-api/observable-client@0.3.2(@polkadot-api/substrate-client@0.1.4)(rxjs@7.8.2)': + dependencies: + '@polkadot-api/metadata-builders': 0.3.2 + '@polkadot-api/substrate-bindings': 0.6.0 + '@polkadot-api/substrate-client': 0.1.4 + '@polkadot-api/utils': 0.1.0 + rxjs: 7.8.2 + optional: true + + '@polkadot-api/substrate-bindings@0.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@polkadot-api/utils': 0.1.0 + '@scure/base': 1.2.6 + scale-ts: 1.6.1 + optional: true + + '@polkadot-api/substrate-client@0.1.4': + dependencies: + '@polkadot-api/json-rpc-provider': 0.0.1 + '@polkadot-api/utils': 0.1.0 + optional: true + + '@polkadot-api/utils@0.1.0': + optional: true + + '@polkadot/api-augment@16.4.9': + dependencies: + '@polkadot/api-base': 16.4.9 + '@polkadot/rpc-augment': 16.4.9 + '@polkadot/types': 16.4.9 + '@polkadot/types-augment': 16.4.9 + '@polkadot/types-codec': 16.4.9 + '@polkadot/util': 13.5.7 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/api-base@16.4.9': + dependencies: + '@polkadot/rpc-core': 16.4.9 + '@polkadot/types': 16.4.9 + '@polkadot/util': 13.5.7 + rxjs: 7.8.2 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/api-derive@16.4.9': + dependencies: + '@polkadot/api': 16.4.9 + '@polkadot/api-augment': 16.4.9 + '@polkadot/api-base': 16.4.9 + '@polkadot/rpc-core': 16.4.9 + '@polkadot/types': 16.4.9 + '@polkadot/types-codec': 16.4.9 + '@polkadot/util': 13.5.7 + '@polkadot/util-crypto': 13.5.7(@polkadot/util@13.5.7) + rxjs: 7.8.2 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/api@16.4.9': + dependencies: + '@polkadot/api-augment': 16.4.9 + '@polkadot/api-base': 16.4.9 + '@polkadot/api-derive': 16.4.9 + '@polkadot/keyring': 13.5.7(@polkadot/util-crypto@13.5.7(@polkadot/util@13.5.7))(@polkadot/util@13.5.7) + '@polkadot/rpc-augment': 16.4.9 + '@polkadot/rpc-core': 16.4.9 + '@polkadot/rpc-provider': 16.4.9 + '@polkadot/types': 16.4.9 + '@polkadot/types-augment': 16.4.9 + '@polkadot/types-codec': 16.4.9 + '@polkadot/types-create': 16.4.9 + '@polkadot/types-known': 16.4.9 + '@polkadot/util': 13.5.7 + '@polkadot/util-crypto': 13.5.7(@polkadot/util@13.5.7) + eventemitter3: 5.0.1 + rxjs: 7.8.2 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/keyring@13.5.7(@polkadot/util-crypto@13.5.7(@polkadot/util@13.5.7))(@polkadot/util@13.5.7)': + dependencies: + '@polkadot/util': 13.5.7 + '@polkadot/util-crypto': 13.5.7(@polkadot/util@13.5.7) + tslib: 2.8.1 + + '@polkadot/networks@13.5.7': + dependencies: + '@polkadot/util': 13.5.7 + '@substrate/ss58-registry': 1.51.0 + tslib: 2.8.1 + + '@polkadot/rpc-augment@16.4.9': + dependencies: + '@polkadot/rpc-core': 16.4.9 + '@polkadot/types': 16.4.9 + '@polkadot/types-codec': 16.4.9 + '@polkadot/util': 13.5.7 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/rpc-core@16.4.9': + dependencies: + '@polkadot/rpc-augment': 16.4.9 + '@polkadot/rpc-provider': 16.4.9 + '@polkadot/types': 16.4.9 + '@polkadot/util': 13.5.7 + rxjs: 7.8.2 + tslib: 2.8.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/rpc-provider@16.4.9': + dependencies: + '@polkadot/keyring': 13.5.7(@polkadot/util-crypto@13.5.7(@polkadot/util@13.5.7))(@polkadot/util@13.5.7) + '@polkadot/types': 16.4.9 + '@polkadot/types-support': 16.4.9 + '@polkadot/util': 13.5.7 + '@polkadot/util-crypto': 13.5.7(@polkadot/util@13.5.7) + '@polkadot/x-fetch': 13.5.7 + '@polkadot/x-global': 13.5.7 + '@polkadot/x-ws': 13.5.7 + eventemitter3: 5.0.1 + mock-socket: 9.3.1 + nock: 13.5.6 + tslib: 2.8.1 + optionalDependencies: + '@substrate/connect': 0.8.11 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@polkadot/types-augment@16.4.9': + dependencies: + '@polkadot/types': 16.4.9 + '@polkadot/types-codec': 16.4.9 + '@polkadot/util': 13.5.7 + tslib: 2.8.1 + + '@polkadot/types-codec@16.4.9': + dependencies: + '@polkadot/util': 13.5.7 + '@polkadot/x-bigint': 13.5.7 + tslib: 2.8.1 + + '@polkadot/types-create@16.4.9': + dependencies: + '@polkadot/types-codec': 16.4.9 + '@polkadot/util': 13.5.7 + tslib: 2.8.1 + + '@polkadot/types-known@16.4.9': + dependencies: + '@polkadot/networks': 13.5.7 + '@polkadot/types': 16.4.9 + '@polkadot/types-codec': 16.4.9 + '@polkadot/types-create': 16.4.9 + '@polkadot/util': 13.5.7 + tslib: 2.8.1 + + '@polkadot/types-support@16.4.9': + dependencies: + '@polkadot/util': 13.5.7 + tslib: 2.8.1 + + '@polkadot/types@16.4.9': + dependencies: + '@polkadot/keyring': 13.5.7(@polkadot/util-crypto@13.5.7(@polkadot/util@13.5.7))(@polkadot/util@13.5.7) + '@polkadot/types-augment': 16.4.9 + '@polkadot/types-codec': 16.4.9 + '@polkadot/types-create': 16.4.9 + '@polkadot/util': 13.5.7 + '@polkadot/util-crypto': 13.5.7(@polkadot/util@13.5.7) + rxjs: 7.8.2 + tslib: 2.8.1 + + '@polkadot/util-crypto@13.5.7(@polkadot/util@13.5.7)': + dependencies: + '@noble/curves': 1.9.6 + '@noble/hashes': 1.8.0 + '@polkadot/networks': 13.5.7 + '@polkadot/util': 13.5.7 + '@polkadot/wasm-crypto': 7.5.1(@polkadot/util@13.5.7)(@polkadot/x-randomvalues@13.5.7(@polkadot/util@13.5.7)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.7))) + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.7) + '@polkadot/x-bigint': 13.5.7 + '@polkadot/x-randomvalues': 13.5.7(@polkadot/util@13.5.7)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.7)) + '@scure/base': 1.2.6 + tslib: 2.8.1 + + '@polkadot/util@13.5.7': + dependencies: + '@polkadot/x-bigint': 13.5.7 + '@polkadot/x-global': 13.5.7 + '@polkadot/x-textdecoder': 13.5.7 + '@polkadot/x-textencoder': 13.5.7 + '@types/bn.js': 5.1.6 + bn.js: 5.2.1 + tslib: 2.8.1 + + '@polkadot/wasm-bridge@7.5.1(@polkadot/util@13.5.7)(@polkadot/x-randomvalues@13.5.7(@polkadot/util@13.5.7)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.7)))': + dependencies: + '@polkadot/util': 13.5.7 + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.7) + '@polkadot/x-randomvalues': 13.5.7(@polkadot/util@13.5.7)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.7)) + tslib: 2.8.1 + + '@polkadot/wasm-crypto-asmjs@7.5.1(@polkadot/util@13.5.7)': + dependencies: + '@polkadot/util': 13.5.7 + tslib: 2.8.1 + + '@polkadot/wasm-crypto-init@7.5.1(@polkadot/util@13.5.7)(@polkadot/x-randomvalues@13.5.7(@polkadot/util@13.5.7)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.7)))': + dependencies: + '@polkadot/util': 13.5.7 + '@polkadot/wasm-bridge': 7.5.1(@polkadot/util@13.5.7)(@polkadot/x-randomvalues@13.5.7(@polkadot/util@13.5.7)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.7))) + '@polkadot/wasm-crypto-asmjs': 7.5.1(@polkadot/util@13.5.7) + '@polkadot/wasm-crypto-wasm': 7.5.1(@polkadot/util@13.5.7) + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.7) + '@polkadot/x-randomvalues': 13.5.7(@polkadot/util@13.5.7)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.7)) + tslib: 2.8.1 + + '@polkadot/wasm-crypto-wasm@7.5.1(@polkadot/util@13.5.7)': + dependencies: + '@polkadot/util': 13.5.7 + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.7) + tslib: 2.8.1 + + '@polkadot/wasm-crypto@7.5.1(@polkadot/util@13.5.7)(@polkadot/x-randomvalues@13.5.7(@polkadot/util@13.5.7)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.7)))': + dependencies: + '@polkadot/util': 13.5.7 + '@polkadot/wasm-bridge': 7.5.1(@polkadot/util@13.5.7)(@polkadot/x-randomvalues@13.5.7(@polkadot/util@13.5.7)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.7))) + '@polkadot/wasm-crypto-asmjs': 7.5.1(@polkadot/util@13.5.7) + '@polkadot/wasm-crypto-init': 7.5.1(@polkadot/util@13.5.7)(@polkadot/x-randomvalues@13.5.7(@polkadot/util@13.5.7)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.7))) + '@polkadot/wasm-crypto-wasm': 7.5.1(@polkadot/util@13.5.7) + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.7) + '@polkadot/x-randomvalues': 13.5.7(@polkadot/util@13.5.7)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.7)) + tslib: 2.8.1 + + '@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.7)': + dependencies: + '@polkadot/util': 13.5.7 + tslib: 2.8.1 + + '@polkadot/x-bigint@13.5.7': + dependencies: + '@polkadot/x-global': 13.5.7 + tslib: 2.8.1 + + '@polkadot/x-fetch@13.5.7': + dependencies: + '@polkadot/x-global': 13.5.7 + node-fetch: 3.3.2 + tslib: 2.8.1 + + '@polkadot/x-global@13.5.7': + dependencies: + tslib: 2.8.1 + + '@polkadot/x-randomvalues@13.5.7(@polkadot/util@13.5.7)(@polkadot/wasm-util@7.5.1(@polkadot/util@13.5.7))': + dependencies: + '@polkadot/util': 13.5.7 + '@polkadot/wasm-util': 7.5.1(@polkadot/util@13.5.7) + '@polkadot/x-global': 13.5.7 + tslib: 2.8.1 + + '@polkadot/x-textdecoder@13.5.7': + dependencies: + '@polkadot/x-global': 13.5.7 + tslib: 2.8.1 + + '@polkadot/x-textencoder@13.5.7': + dependencies: + '@polkadot/x-global': 13.5.7 + tslib: 2.8.1 + + '@polkadot/x-ws@13.5.7': + dependencies: + '@polkadot/x-global': 13.5.7 + tslib: 2.8.1 + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@polytope-labs/hyperclient@1.2.0': {} + + '@rollup/rollup-android-arm-eabi@4.40.2': + optional: true + + '@rollup/rollup-android-arm64@4.40.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.40.2': + optional: true + + '@rollup/rollup-darwin-x64@4.40.2': + optional: true + + '@rollup/rollup-freebsd-arm64@4.40.2': + optional: true + + '@rollup/rollup-freebsd-x64@4.40.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.40.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.40.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.40.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.40.2': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.40.2': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.40.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.40.2': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.40.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.40.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.40.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.40.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.40.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.40.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.40.2': + optional: true + + '@scure/base@1.2.6': {} + + '@scure/bip32@1.7.0': + dependencies: + '@noble/curves': 1.9.6 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@scure/bip39@1.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@substrate/connect-extension-protocol@2.2.2': + optional: true + + '@substrate/connect-known-chains@1.9.2': + optional: true + + '@substrate/connect@0.8.11': + dependencies: + '@substrate/connect-extension-protocol': 2.2.2 + '@substrate/connect-known-chains': 1.9.2 + '@substrate/light-client-extension-helpers': 1.0.0(smoldot@2.0.26) + smoldot: 2.0.26 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + optional: true + + '@substrate/light-client-extension-helpers@1.0.0(smoldot@2.0.26)': + dependencies: + '@polkadot-api/json-rpc-provider': 0.0.1 + '@polkadot-api/json-rpc-provider-proxy': 0.1.0 + '@polkadot-api/observable-client': 0.3.2(@polkadot-api/substrate-client@0.1.4)(rxjs@7.8.2) + '@polkadot-api/substrate-client': 0.1.4 + '@substrate/connect-extension-protocol': 2.2.2 + '@substrate/connect-known-chains': 1.9.2 + rxjs: 7.8.2 + smoldot: 2.0.26 + optional: true + + '@substrate/ss58-registry@1.51.0': {} + + '@types/bn.js@5.1.6': + dependencies: + '@types/node': 22.13.9 + + '@types/estree@1.0.7': {} + + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.16 + + '@types/lodash@4.17.16': {} + + '@types/node@22.13.9': + dependencies: + undici-types: 6.20.0 + + '@vitest/coverage-v8@3.1.4(vitest@3.1.4(@types/node@22.13.9)(jsdom@26.0.0))': + dependencies: + '@ampproject/remapping': 2.3.0 + '@bcoe/v8-coverage': 1.0.2 + debug: 4.4.0 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 5.0.6 + istanbul-reports: 3.1.7 + magic-string: 0.30.17 + magicast: 0.3.5 + std-env: 3.9.0 + test-exclude: 7.0.1 + tinyrainbow: 2.0.0 + vitest: 3.1.4(@types/node@22.13.9)(jsdom@26.0.0) + transitivePeerDependencies: + - supports-color + + '@vitest/expect@3.1.4': + dependencies: + '@vitest/spy': 3.1.4 + '@vitest/utils': 3.1.4 + chai: 5.2.0 + tinyrainbow: 2.0.0 + + '@vitest/mocker@3.1.4(vite@6.3.5(@types/node@22.13.9))': + dependencies: + '@vitest/spy': 3.1.4 + estree-walker: 3.0.3 + magic-string: 0.30.17 + optionalDependencies: + vite: 6.3.5(@types/node@22.13.9) + + '@vitest/pretty-format@3.1.4': + dependencies: + tinyrainbow: 2.0.0 + + '@vitest/runner@3.1.4': + dependencies: + '@vitest/utils': 3.1.4 + pathe: 2.0.3 + + '@vitest/snapshot@3.1.4': + dependencies: + '@vitest/pretty-format': 3.1.4 + magic-string: 0.30.17 + pathe: 2.0.3 + + '@vitest/spy@3.1.4': + dependencies: + tinyspy: 3.0.2 + + '@vitest/utils@3.1.4': + dependencies: + '@vitest/pretty-format': 3.1.4 + loupe: 3.1.3 + tinyrainbow: 2.0.0 + + abitype@1.0.8(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + + agent-base@7.1.3: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + assertion-error@2.0.1: {} + + asynckit@0.4.0: {} + + balanced-match@1.0.2: {} + + bn.js@5.2.1: {} + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + bundle-require@5.1.0(esbuild@0.25.0): + dependencies: + esbuild: 0.25.0 + load-tsconfig: 0.2.5 + + cac@6.7.14: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + chai@5.2.0: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.3 + pathval: 2.0.0 + + check-error@2.1.1: {} + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@4.1.1: {} + + consola@3.4.2: {} + + cookie-es@1.2.2: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + + cssstyle@4.2.1: + dependencies: + '@asamuzakjp/css-color': 2.8.3 + rrweb-cssom: 0.8.0 + + data-uri-to-buffer@4.0.1: {} + + data-urls@5.0.0: + dependencies: + whatwg-mimetype: 4.0.0 + whatwg-url: 14.1.1 + + debug@4.4.0: + dependencies: + ms: 2.1.3 + + decimal.js@10.5.0: {} + + deep-eql@5.0.2: {} + + defu@6.1.4: {} + + delayed-stream@1.0.0: {} + + destr@2.0.5: {} + + dotenv@16.4.7: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + entities@4.5.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@1.7.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + esbuild@0.25.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.0 + '@esbuild/android-arm': 0.25.0 + '@esbuild/android-arm64': 0.25.0 + '@esbuild/android-x64': 0.25.0 + '@esbuild/darwin-arm64': 0.25.0 + '@esbuild/darwin-x64': 0.25.0 + '@esbuild/freebsd-arm64': 0.25.0 + '@esbuild/freebsd-x64': 0.25.0 + '@esbuild/linux-arm': 0.25.0 + '@esbuild/linux-arm64': 0.25.0 + '@esbuild/linux-ia32': 0.25.0 + '@esbuild/linux-loong64': 0.25.0 + '@esbuild/linux-mips64el': 0.25.0 + '@esbuild/linux-ppc64': 0.25.0 + '@esbuild/linux-riscv64': 0.25.0 + '@esbuild/linux-s390x': 0.25.0 + '@esbuild/linux-x64': 0.25.0 + '@esbuild/netbsd-arm64': 0.25.0 + '@esbuild/netbsd-x64': 0.25.0 + '@esbuild/openbsd-arm64': 0.25.0 + '@esbuild/openbsd-x64': 0.25.0 + '@esbuild/sunos-x64': 0.25.0 + '@esbuild/win32-arm64': 0.25.0 + '@esbuild/win32-ia32': 0.25.0 + '@esbuild/win32-x64': 0.25.0 + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.7 + + eventemitter3@5.0.1: {} + + expect-type@1.2.1: {} + + fdir@6.4.4(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + form-data@4.0.2: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + mime-types: 2.1.35 + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-intrinsic@1.3.0: + 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 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + globrex@0.1.2: {} + + gopd@1.2.0: {} + + graphql-request@7.1.2(graphql@16.10.0): + dependencies: + '@graphql-typed-document-node/core': 3.2.0(graphql@16.10.0) + graphql: 16.10.0 + + graphql@16.10.0: {} + + h3@1.15.4: + dependencies: + cookie-es: 1.2.2 + crossws: 0.3.5 + defu: 6.1.4 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.3 + radix3: 1.1.2 + ufo: 1.6.1 + uncrypto: 0.1.3 + + has-flag@4.0.0: {} + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + html-encoding-sniffer@4.0.0: + dependencies: + whatwg-encoding: 3.1.1 + + html-escaper@2.0.2: {} + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.3 + debug: 4.4.0 + transitivePeerDependencies: + - supports-color + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + idb-keyval@6.2.2: {} + + iron-webcrypto@1.2.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-potential-custom-element-name@1.0.1: {} + + isexe@2.0.0: {} + + isomorphic-ws@4.0.1(ws@7.5.10): + dependencies: + ws: 7.5.10 + + isows@1.0.7(ws@8.18.3): + dependencies: + ws: 8.18.3 + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@5.0.6: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + debug: 4.4.0 + istanbul-lib-coverage: 3.2.2 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + joycon@3.1.1: {} + + jsdom@26.0.0: + dependencies: + cssstyle: 4.2.1 + data-urls: 5.0.0 + decimal.js: 10.5.0 + form-data: 4.0.2 + html-encoding-sniffer: 4.0.0 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.18 + parse5: 7.2.1 + rrweb-cssom: 0.8.0 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 5.1.2 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 7.0.0 + whatwg-encoding: 3.1.1 + whatwg-mimetype: 4.0.0 + whatwg-url: 14.1.1 + ws: 8.18.3 + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + json-stringify-safe@5.0.1: {} + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + load-tsconfig@0.2.5: {} + + lodash-es@4.17.21: {} + + lodash.sortby@4.7.0: {} + + log-prefix@0.1.1: {} + + log-timestamp@0.3.0: + dependencies: + log-prefix: 0.1.1 + + loupe@3.1.3: {} + + lru-cache@10.4.3: {} + + magic-string@0.30.17: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + magicast@0.3.5: + dependencies: + '@babel/parser': 7.26.9 + '@babel/types': 7.26.9 + source-map-js: 1.2.1 + + make-dir@4.0.0: + dependencies: + semver: 7.7.1 + + math-intrinsics@1.1.0: {} + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minipass@7.1.2: {} + + mock-socket@9.3.1: {} + + ms@2.1.3: {} + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nanoid@3.3.8: {} + + nock@13.5.6: + dependencies: + debug: 4.4.0 + json-stringify-safe: 5.0.1 + propagate: 2.0.1 + transitivePeerDependencies: + - supports-color + + node-domexception@1.0.0: {} + + node-fetch-native@1.6.7: {} + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + node-mock-http@1.0.3: {} + + normalize-path@3.0.0: {} + + nwsapi@2.2.18: {} + + object-assign@4.1.1: {} + + ofetch@1.5.0: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.1 + + ox@0.8.7(typescript@5.9.3): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.6 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.0.8(typescript@5.9.3) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + package-json-from-dist@1.0.1: {} + + parse5@7.2.1: + dependencies: + entities: 4.5.0 + + path-key@3.1.1: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + pathe@2.0.3: {} + + pathval@2.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + pirates@4.0.6: {} + + postcss-load-config@6.0.1(postcss@8.5.3): + dependencies: + lilconfig: 3.1.3 + optionalDependencies: + postcss: 8.5.3 + + postcss@8.5.3: + dependencies: + nanoid: 3.3.8 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + propagate@2.0.1: {} + + punycode@2.3.1: {} + + radix3@1.1.2: {} + + readdirp@4.1.2: {} + + resolve-from@5.0.0: {} + + rollup@4.40.2: + dependencies: + '@types/estree': 1.0.7 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.40.2 + '@rollup/rollup-android-arm64': 4.40.2 + '@rollup/rollup-darwin-arm64': 4.40.2 + '@rollup/rollup-darwin-x64': 4.40.2 + '@rollup/rollup-freebsd-arm64': 4.40.2 + '@rollup/rollup-freebsd-x64': 4.40.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.40.2 + '@rollup/rollup-linux-arm-musleabihf': 4.40.2 + '@rollup/rollup-linux-arm64-gnu': 4.40.2 + '@rollup/rollup-linux-arm64-musl': 4.40.2 + '@rollup/rollup-linux-loongarch64-gnu': 4.40.2 + '@rollup/rollup-linux-powerpc64le-gnu': 4.40.2 + '@rollup/rollup-linux-riscv64-gnu': 4.40.2 + '@rollup/rollup-linux-riscv64-musl': 4.40.2 + '@rollup/rollup-linux-s390x-gnu': 4.40.2 + '@rollup/rollup-linux-x64-gnu': 4.40.2 + '@rollup/rollup-linux-x64-musl': 4.40.2 + '@rollup/rollup-win32-arm64-msvc': 4.40.2 + '@rollup/rollup-win32-ia32-msvc': 4.40.2 + '@rollup/rollup-win32-x64-msvc': 4.40.2 + fsevents: 2.3.3 + + rpc-websocket-client@1.1.4: + dependencies: + isomorphic-ws: 4.0.1(ws@7.5.10) + uuid: 3.4.0 + ws: 7.5.10 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + rrweb-cssom@0.8.0: {} + + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + safer-buffer@2.1.2: {} + + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + scale-ts@1.6.1: {} + + semver@7.7.1: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + smoldot@2.0.26: + dependencies: + ws: 8.18.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + optional: true + + source-map-js@1.2.1: {} + + source-map@0.8.0-beta.0: + dependencies: + whatwg-url: 7.1.0 + + stackback@0.0.2: {} + + std-env@3.9.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + sucrase@3.35.0: + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + commander: 4.1.1 + glob: 10.4.5 + lines-and-columns: 1.2.4 + mz: 2.7.0 + pirates: 4.0.6 + ts-interface-checker: 0.1.13 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + symbol-tree@3.2.4: {} + + test-exclude@7.0.1: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 10.4.5 + minimatch: 9.0.5 + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinyglobby@0.2.13: + dependencies: + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + + tinypool@1.0.2: {} + + tinyrainbow@2.0.0: {} + + tinyspy@3.0.2: {} + + tldts-core@6.1.83: {} + + tldts@6.1.83: + dependencies: + tldts-core: 6.1.83 + + tough-cookie@5.1.2: + dependencies: + tldts: 6.1.83 + + tr46@1.0.1: + dependencies: + punycode: 2.3.1 + + tr46@5.0.0: + dependencies: + punycode: 2.3.1 + + tree-kill@1.2.2: {} + + ts-interface-checker@0.1.13: {} + + ts-pattern@5.6.2: {} + + tsconfck@3.1.5(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + + tslib@2.8.1: {} + + tsup@8.4.0(postcss@8.5.3)(typescript@5.9.3): + dependencies: + bundle-require: 5.1.0(esbuild@0.25.0) + cac: 6.7.14 + chokidar: 4.0.3 + consola: 3.4.2 + debug: 4.4.0 + esbuild: 0.25.0 + joycon: 3.1.1 + picocolors: 1.1.1 + postcss-load-config: 6.0.1(postcss@8.5.3) + resolve-from: 5.0.0 + rollup: 4.40.2 + source-map: 0.8.0-beta.0 + sucrase: 3.35.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.13 + tree-kill: 1.2.2 + optionalDependencies: + postcss: 8.5.3 + typescript: 5.9.3 + transitivePeerDependencies: + - jiti + - supports-color + - tsx + - yaml + + typescript@5.9.3: + optional: true + + ufo@1.6.1: {} + + uncrypto@0.1.3: {} + + undici-types@6.20.0: {} + + unstorage@1.17.2(idb-keyval@6.2.2): + dependencies: + anymatch: 3.1.3 + chokidar: 4.0.3 + destr: 2.0.5 + h3: 1.15.4 + lru-cache: 10.4.3 + node-fetch-native: 1.6.7 + ofetch: 1.5.0 + ufo: 1.6.1 + optionalDependencies: + idb-keyval: 6.2.2 + + uuid@3.4.0: {} + + viem@2.34.0(typescript@5.9.3): + dependencies: + '@noble/curves': 1.9.6 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.0.8(typescript@5.9.3) + isows: 1.0.7(ws@8.18.3) + ox: 0.8.7(typescript@5.9.3) + ws: 8.18.3 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + vite-node@3.1.4(@types/node@22.13.9): + dependencies: + cac: 6.7.14 + debug: 4.4.0 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 6.3.5(@types/node@22.13.9) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@6.3.5(@types/node@22.13.9)): + dependencies: + debug: 4.4.0 + globrex: 0.1.2 + tsconfck: 3.1.5(typescript@5.9.3) + optionalDependencies: + vite: 6.3.5(@types/node@22.13.9) + transitivePeerDependencies: + - supports-color + - typescript + + vite@6.3.5(@types/node@22.13.9): + dependencies: + esbuild: 0.25.0 + fdir: 6.4.4(picomatch@4.0.2) + picomatch: 4.0.2 + postcss: 8.5.3 + rollup: 4.40.2 + tinyglobby: 0.2.13 + optionalDependencies: + '@types/node': 22.13.9 + fsevents: 2.3.3 + + vitest@3.1.4(@types/node@22.13.9)(jsdom@26.0.0): + dependencies: + '@vitest/expect': 3.1.4 + '@vitest/mocker': 3.1.4(vite@6.3.5(@types/node@22.13.9)) + '@vitest/pretty-format': 3.1.4 + '@vitest/runner': 3.1.4 + '@vitest/snapshot': 3.1.4 + '@vitest/spy': 3.1.4 + '@vitest/utils': 3.1.4 + chai: 5.2.0 + debug: 4.4.0 + expect-type: 1.2.1 + magic-string: 0.30.17 + pathe: 2.0.3 + std-env: 3.9.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.13 + tinypool: 1.0.2 + tinyrainbow: 2.0.0 + vite: 6.3.5(@types/node@22.13.9) + vite-node: 3.1.4(@types/node@22.13.9) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.13.9 + jsdom: 26.0.0 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + + web-streams-polyfill@3.3.3: {} + + webidl-conversions@4.0.2: {} + + webidl-conversions@7.0.0: {} + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-mimetype@4.0.0: {} + + whatwg-url@14.1.1: + dependencies: + tr46: 5.0.0 + webidl-conversions: 7.0.0 + + whatwg-url@7.1.0: + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + ws@7.5.10: {} + + ws@8.18.3: {} + + xml-name-validator@5.0.0: {} + + xmlchars@2.2.0: {} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/IntentGateway.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/IntentGateway.ts new file mode 100644 index 00000000..12fa2ac5 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/IntentGateway.ts @@ -0,0 +1,1442 @@ +const ABI = [ + { + inputs: [ + { + internalType: "address", + name: "admin", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [], + name: "Expired", + type: "error", + }, + { + inputs: [], + name: "Filled", + type: "error", + }, + { + inputs: [], + name: "InsufficientNativeToken", + type: "error", + }, + { + inputs: [], + name: "InvalidInput", + type: "error", + }, + { + inputs: [], + name: "NotExpired", + type: "error", + }, + { + inputs: [], + name: "Unauthorized", + type: "error", + }, + { + inputs: [], + name: "UnauthorizedCall", + type: "error", + }, + { + inputs: [], + name: "UnexpectedCall", + type: "error", + }, + { + inputs: [], + name: "UnknownOrder", + type: "error", + }, + { + inputs: [], + name: "WrongChain", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "EscrowRefunded", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "EscrowReleased", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "bytes", + name: "stateMachineId", + type: "bytes", + }, + { + indexed: false, + internalType: "bytes32", + name: "gateway", + type: "bytes32", + }, + ], + name: "NewDeploymentAdded", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "address", + name: "filler", + type: "address", + }, + ], + name: "OrderFilled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "bytes32", + name: "user", + type: "bytes32", + }, + { + indexed: false, + internalType: "bytes", + name: "sourceChain", + type: "bytes", + }, + { + indexed: false, + internalType: "bytes", + name: "destChain", + type: "bytes", + }, + { + indexed: false, + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "fees", + type: "uint256", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + internalType: "bytes32", + name: "beneficiary", + type: "bytes32", + }, + ], + indexed: false, + internalType: "struct PaymentInfo[]", + name: "outputs", + type: "tuple[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + indexed: false, + internalType: "struct TokenInfo[]", + name: "inputs", + type: "tuple[]", + }, + { + indexed: false, + internalType: "bytes", + name: "callData", + type: "bytes", + }, + ], + name: "OrderPlaced", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + components: [ + { + internalType: "address", + name: "host", + type: "address", + }, + { + internalType: "address", + name: "dispatcher", + type: "address", + }, + ], + indexed: false, + internalType: "struct Params", + name: "previous", + type: "tuple", + }, + { + components: [ + { + internalType: "address", + name: "host", + type: "address", + }, + { + internalType: "address", + name: "dispatcher", + type: "address", + }, + ], + indexed: false, + internalType: "struct Params", + name: "current", + type: "tuple", + }, + ], + name: "ParamsUpdated", + type: "event", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "calculateCommitmentSlotHash", + outputs: [ + { + internalType: "bytes", + name: "", + type: "bytes", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes32", + name: "user", + type: "bytes32", + }, + { + internalType: "bytes", + name: "sourceChain", + type: "bytes", + }, + { + internalType: "bytes", + name: "destChain", + type: "bytes", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + internalType: "uint256", + name: "fees", + type: "uint256", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + internalType: "bytes32", + name: "beneficiary", + type: "bytes32", + }, + ], + internalType: "struct PaymentInfo[]", + name: "outputs", + type: "tuple[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct TokenInfo[]", + name: "inputs", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "callData", + type: "bytes", + }, + ], + internalType: "struct Order", + name: "order", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "relayerFee", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct CancelOptions", + name: "options", + type: "tuple", + }, + ], + name: "cancelOrder", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes32", + name: "user", + type: "bytes32", + }, + { + internalType: "bytes", + name: "sourceChain", + type: "bytes", + }, + { + internalType: "bytes", + name: "destChain", + type: "bytes", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + internalType: "uint256", + name: "fees", + type: "uint256", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + internalType: "bytes32", + name: "beneficiary", + type: "bytes32", + }, + ], + internalType: "struct PaymentInfo[]", + name: "outputs", + type: "tuple[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct TokenInfo[]", + name: "inputs", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "callData", + type: "bytes", + }, + ], + internalType: "struct Order", + name: "order", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "relayerFee", + type: "uint256", + }, + ], + internalType: "struct FillOptions", + name: "options", + type: "tuple", + }, + ], + name: "fillOrder", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [], + name: "host", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "stateMachineId", + type: "bytes", + }, + ], + name: "instance", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + internalType: "struct IncomingPostRequest", + name: "incoming", + type: "tuple", + }, + ], + name: "onAccept", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest", + name: "request", + type: "tuple", + }, + { + components: [ + { + internalType: "bytes", + name: "key", + type: "bytes", + }, + { + internalType: "bytes", + name: "value", + type: "bytes", + }, + ], + internalType: "struct StorageValue[]", + name: "values", + type: "tuple[]", + }, + ], + internalType: "struct GetResponse", + name: "response", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + internalType: "struct IncomingGetResponse", + name: "incoming", + type: "tuple", + }, + ], + name: "onGetResponse", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest", + name: "", + type: "tuple", + }, + ], + name: "onGetTimeout", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "", + type: "tuple", + }, + ], + name: "onPostRequestTimeout", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse", + name: "response", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + internalType: "struct IncomingPostResponse", + name: "", + type: "tuple", + }, + ], + name: "onPostResponse", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse", + name: "", + type: "tuple", + }, + ], + name: "onPostResponseTimeout", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "params", + outputs: [ + { + components: [ + { + internalType: "address", + name: "host", + type: "address", + }, + { + internalType: "address", + name: "dispatcher", + type: "address", + }, + ], + internalType: "struct Params", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes32", + name: "user", + type: "bytes32", + }, + { + internalType: "bytes", + name: "sourceChain", + type: "bytes", + }, + { + internalType: "bytes", + name: "destChain", + type: "bytes", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + internalType: "uint256", + name: "fees", + type: "uint256", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + internalType: "bytes32", + name: "beneficiary", + type: "bytes32", + }, + ], + internalType: "struct PaymentInfo[]", + name: "outputs", + type: "tuple[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "token", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + internalType: "struct TokenInfo[]", + name: "inputs", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "callData", + type: "bytes", + }, + ], + internalType: "struct Order", + name: "order", + type: "tuple", + }, + { + internalType: "bytes32", + name: "graffiti", + type: "bytes32", + }, + ], + name: "placeOrder", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "payer", + type: "address", + }, + ], + internalType: "struct DispatchPost", + name: "request", + type: "tuple", + }, + ], + name: "quote", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct DispatchGet", + name: "request", + type: "tuple", + }, + ], + name: "quote", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "payer", + type: "address", + }, + ], + internalType: "struct DispatchPostResponse", + name: "response", + type: "tuple", + }, + ], + name: "quote", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "payer", + type: "address", + }, + ], + internalType: "struct DispatchPost", + name: "request", + type: "tuple", + }, + ], + name: "quoteNative", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "payer", + type: "address", + }, + ], + internalType: "struct DispatchPostResponse", + name: "request", + type: "tuple", + }, + ], + name: "quoteNative", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct DispatchGet", + name: "request", + type: "tuple", + }, + ], + name: "quoteNative", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "address", + name: "host", + type: "address", + }, + { + internalType: "address", + name: "dispatcher", + type: "address", + }, + ], + internalType: "struct Params", + name: "p", + type: "tuple", + }, + ], + name: "setParams", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + stateMutability: "payable", + type: "receive", + }, +] as const + +export default { ABI } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/erc6160.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/erc6160.ts new file mode 100644 index 00000000..35d9e222 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/erc6160.ts @@ -0,0 +1,238 @@ +const ABI = [ + { + inputs: [ + { internalType: "address", name: "admin", type: "address" }, + { internalType: "string", name: "name", type: "string" }, + { internalType: "string", name: "symbol", type: "string" }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { inputs: [], name: "NotRoleAdmin", type: "error" }, + { inputs: [], name: "PermissionDenied", type: "error" }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "owner", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "spender", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "Approval", + type: "event", + }, + { + anonymous: false, + inputs: [ + { indexed: true, internalType: "address", name: "from", type: "address" }, + { indexed: true, internalType: "address", name: "to", type: "address" }, + { + indexed: false, + internalType: "uint256", + name: "value", + type: "uint256", + }, + ], + name: "Transfer", + type: "event", + }, + { + inputs: [], + name: "BURNER_ROLE", + outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "MINTER_ROLE", + outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "owner", type: "address" }, + { internalType: "address", name: "spender", type: "address" }, + ], + name: "allowance", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "spender", type: "address" }, + { internalType: "uint256", name: "amount", type: "uint256" }, + ], + name: "approve", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "address", name: "account", type: "address" }], + name: "balanceOf", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "_from", type: "address" }, + { internalType: "uint256", name: "_amount", type: "uint256" }, + { internalType: "bytes", name: "", type: "bytes" }, + ], + name: "burn", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "decimals", + outputs: [{ internalType: "uint8", name: "", type: "uint8" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "spender", type: "address" }, + { internalType: "uint256", name: "subtractedValue", type: "uint256" }, + ], + name: "decreaseAllowance", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "getBurnerRole", + outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "getMinterRole", + outputs: [{ internalType: "bytes32", name: "", type: "bytes32" }], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { internalType: "bytes32", name: "_role", type: "bytes32" }, + { internalType: "address", name: "_account", type: "address" }, + ], + name: "grantRole", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "bytes32", name: "_role", type: "bytes32" }, + { internalType: "address", name: "_account", type: "address" }, + ], + name: "hasRole", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "spender", type: "address" }, + { internalType: "uint256", name: "addedValue", type: "uint256" }, + ], + name: "increaseAllowance", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "_to", type: "address" }, + { internalType: "uint256", name: "_amount", type: "uint256" }, + { internalType: "bytes", name: "", type: "bytes" }, + ], + name: "mint", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "name", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "bytes32", name: "_role", type: "bytes32" }, + { internalType: "address", name: "_account", type: "address" }, + ], + name: "revokeRole", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "bytes4", name: "_interfaceId", type: "bytes4" }], + name: "supportsInterface", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "symbol", + outputs: [{ internalType: "string", name: "", type: "string" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "totalSupply", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "amount", type: "uint256" }, + ], + name: "transfer", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "from", type: "address" }, + { internalType: "address", name: "to", type: "address" }, + { internalType: "uint256", name: "amount", type: "uint256" }, + ], + name: "transferFrom", + outputs: [{ internalType: "bool", name: "", type: "bool" }], + stateMutability: "nonpayable", + type: "function", + }, +] as const + +export default { ABI } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/evmHost.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/evmHost.ts new file mode 100644 index 00000000..1441c258 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/evmHost.ts @@ -0,0 +1,2274 @@ +const ABI = [ + { + inputs: [], + name: "CannotChangeFeeToken", + type: "error", + }, + { + inputs: [], + name: "DuplicateResponse", + type: "error", + }, + { + inputs: [], + name: "FrozenHost", + type: "error", + }, + { + inputs: [], + name: "InvalidAddressLength", + type: "error", + }, + { + inputs: [], + name: "InvalidConsensusClient", + type: "error", + }, + { + inputs: [], + name: "InvalidHandler", + type: "error", + }, + { + inputs: [], + name: "InvalidHostManager", + type: "error", + }, + { + inputs: [], + name: "InvalidHyperbridgeId", + type: "error", + }, + { + inputs: [], + name: "InvalidStateMachinesLength", + type: "error", + }, + { + inputs: [], + name: "InvalidUnstakingPeriod", + type: "error", + }, + { + inputs: [], + name: "UnauthorizedAccount", + type: "error", + }, + { + inputs: [], + name: "UnauthorizedAction", + type: "error", + }, + { + inputs: [], + name: "UnauthorizedResponse", + type: "error", + }, + { + inputs: [], + name: "UnknownRequest", + type: "error", + }, + { + inputs: [], + name: "UnknownResponse", + type: "error", + }, + { + inputs: [], + name: "WithdrawalFailed", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "source", + type: "string", + }, + { + indexed: false, + internalType: "string", + name: "dest", + type: "string", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + indexed: false, + internalType: "uint256", + name: "height", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "timeoutTimestamp", + type: "uint256", + }, + { + indexed: false, + internalType: "bytes", + name: "context", + type: "bytes", + }, + { + indexed: false, + internalType: "uint256", + name: "fee", + type: "uint256", + }, + ], + name: "GetRequestEvent", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "address", + name: "relayer", + type: "address", + }, + ], + name: "GetRequestHandled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "string", + name: "dest", + type: "string", + }, + ], + name: "GetRequestTimeoutHandled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "enum FrozenStatus", + name: "status", + type: "uint8", + }, + ], + name: "HostFrozen", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "defaultTimeout", + type: "uint256", + }, + { + internalType: "uint256", + name: "defaultPerByteFee", + type: "uint256", + }, + { + internalType: "uint256", + name: "stateCommitmentFee", + type: "uint256", + }, + { + internalType: "address", + name: "feeToken", + type: "address", + }, + { + internalType: "address", + name: "admin", + type: "address", + }, + { + internalType: "address", + name: "handler", + type: "address", + }, + { + internalType: "address", + name: "hostManager", + type: "address", + }, + { + internalType: "address", + name: "uniswapV2", + type: "address", + }, + { + internalType: "uint256", + name: "unStakingPeriod", + type: "uint256", + }, + { + internalType: "uint256", + name: "challengePeriod", + type: "uint256", + }, + { + internalType: "address", + name: "consensusClient", + type: "address", + }, + { + internalType: "uint256[]", + name: "stateMachines", + type: "uint256[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "stateIdHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "perByteFee", + type: "uint256", + }, + ], + internalType: "struct PerByteFee[]", + name: "perByteFees", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "hyperbridge", + type: "bytes", + }, + ], + indexed: false, + internalType: "struct HostParams", + name: "oldParams", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "defaultTimeout", + type: "uint256", + }, + { + internalType: "uint256", + name: "defaultPerByteFee", + type: "uint256", + }, + { + internalType: "uint256", + name: "stateCommitmentFee", + type: "uint256", + }, + { + internalType: "address", + name: "feeToken", + type: "address", + }, + { + internalType: "address", + name: "admin", + type: "address", + }, + { + internalType: "address", + name: "handler", + type: "address", + }, + { + internalType: "address", + name: "hostManager", + type: "address", + }, + { + internalType: "address", + name: "uniswapV2", + type: "address", + }, + { + internalType: "uint256", + name: "unStakingPeriod", + type: "uint256", + }, + { + internalType: "uint256", + name: "challengePeriod", + type: "uint256", + }, + { + internalType: "address", + name: "consensusClient", + type: "address", + }, + { + internalType: "uint256[]", + name: "stateMachines", + type: "uint256[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "stateIdHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "perByteFee", + type: "uint256", + }, + ], + internalType: "struct PerByteFee[]", + name: "perByteFees", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "hyperbridge", + type: "bytes", + }, + ], + indexed: false, + internalType: "struct HostParams", + name: "newParams", + type: "tuple", + }, + ], + name: "HostParamsUpdated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + indexed: false, + internalType: "address", + name: "beneficiary", + type: "address", + }, + { + indexed: false, + internalType: "bool", + name: "native", + type: "bool", + }, + ], + name: "HostWithdrawal", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "source", + type: "string", + }, + { + indexed: false, + internalType: "string", + name: "dest", + type: "string", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + indexed: false, + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "timeoutTimestamp", + type: "uint256", + }, + { + indexed: false, + internalType: "bytes", + name: "body", + type: "bytes", + }, + { + indexed: false, + internalType: "uint256", + name: "fee", + type: "uint256", + }, + ], + name: "PostRequestEvent", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "address", + name: "relayer", + type: "address", + }, + ], + name: "PostRequestHandled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "string", + name: "dest", + type: "string", + }, + ], + name: "PostRequestTimeoutHandled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "source", + type: "string", + }, + { + indexed: false, + internalType: "string", + name: "dest", + type: "string", + }, + { + indexed: true, + internalType: "address", + name: "from", + type: "address", + }, + { + indexed: false, + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + indexed: false, + internalType: "uint256", + name: "nonce", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "timeoutTimestamp", + type: "uint256", + }, + { + indexed: false, + internalType: "bytes", + name: "body", + type: "bytes", + }, + { + indexed: false, + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + indexed: false, + internalType: "uint256", + name: "responseTimeoutTimestamp", + type: "uint256", + }, + { + indexed: false, + internalType: "uint256", + name: "fee", + type: "uint256", + }, + ], + name: "PostResponseEvent", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "uint256", + name: "newFee", + type: "uint256", + }, + ], + name: "PostResponseFunded", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "address", + name: "relayer", + type: "address", + }, + ], + name: "PostResponseHandled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "string", + name: "dest", + type: "string", + }, + ], + name: "PostResponseTimeoutHandled", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + indexed: false, + internalType: "uint256", + name: "newFee", + type: "uint256", + }, + ], + name: "RequestFunded", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "caller", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "fee", + type: "uint256", + }, + ], + name: "StateCommitmentRead", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "stateMachineId", + type: "string", + }, + { + indexed: false, + internalType: "uint256", + name: "height", + type: "uint256", + }, + { + components: [ + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "overlayRoot", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "stateRoot", + type: "bytes32", + }, + ], + indexed: false, + internalType: "struct StateCommitment", + name: "stateCommitment", + type: "tuple", + }, + { + indexed: true, + internalType: "address", + name: "fisherman", + type: "address", + }, + ], + name: "StateCommitmentVetoed", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "stateMachineId", + type: "string", + }, + { + indexed: false, + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + name: "StateMachineUpdated", + type: "event", + }, + { + inputs: [], + name: "admin", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "chainId", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "challengePeriod", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "consensusClient", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "consensusState", + outputs: [ + { + internalType: "bytes", + name: "", + type: "bytes", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "consensusUpdateTime", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "address", + name: "fisherman", + type: "address", + }, + ], + name: "deleteStateMachineCommitment", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "payer", + type: "address", + }, + ], + internalType: "struct DispatchPostResponse", + name: "post", + type: "tuple", + }, + ], + name: "dispatch", + outputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "payer", + type: "address", + }, + ], + internalType: "struct DispatchPost", + name: "post", + type: "tuple", + }, + ], + name: "dispatch", + outputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct DispatchGet", + name: "get", + type: "tuple", + }, + ], + name: "dispatch", + outputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse", + name: "response", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + name: "dispatchIncoming", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + name: "dispatchIncoming", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest", + name: "request", + type: "tuple", + }, + { + components: [ + { + internalType: "bytes", + name: "key", + type: "bytes", + }, + { + internalType: "bytes", + name: "value", + type: "bytes", + }, + ], + internalType: "struct StorageValue[]", + name: "values", + type: "tuple[]", + }, + ], + internalType: "struct GetResponse", + name: "response", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + name: "dispatchIncoming", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse", + name: "response", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + ], + internalType: "struct FeeMetadata", + name: "meta", + type: "tuple", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "dispatchTimeOut", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + ], + internalType: "struct FeeMetadata", + name: "meta", + type: "tuple", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "dispatchTimeOut", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest", + name: "request", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + ], + internalType: "struct FeeMetadata", + name: "meta", + type: "tuple", + }, + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "dispatchTimeOut", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "feeToken", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "frozen", + outputs: [ + { + internalType: "enum FrozenStatus", + name: "", + type: "uint8", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "fundRequest", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + ], + name: "fundResponse", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [], + name: "host", + outputs: [ + { + internalType: "bytes", + name: "", + type: "bytes", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "hostParams", + outputs: [ + { + components: [ + { + internalType: "uint256", + name: "defaultTimeout", + type: "uint256", + }, + { + internalType: "uint256", + name: "defaultPerByteFee", + type: "uint256", + }, + { + internalType: "uint256", + name: "stateCommitmentFee", + type: "uint256", + }, + { + internalType: "address", + name: "feeToken", + type: "address", + }, + { + internalType: "address", + name: "admin", + type: "address", + }, + { + internalType: "address", + name: "handler", + type: "address", + }, + { + internalType: "address", + name: "hostManager", + type: "address", + }, + { + internalType: "address", + name: "uniswapV2", + type: "address", + }, + { + internalType: "uint256", + name: "unStakingPeriod", + type: "uint256", + }, + { + internalType: "uint256", + name: "challengePeriod", + type: "uint256", + }, + { + internalType: "address", + name: "consensusClient", + type: "address", + }, + { + internalType: "uint256[]", + name: "stateMachines", + type: "uint256[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "stateIdHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "perByteFee", + type: "uint256", + }, + ], + internalType: "struct PerByteFee[]", + name: "perByteFees", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "hyperbridge", + type: "bytes", + }, + ], + internalType: "struct HostParams", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "hyperbridge", + outputs: [ + { + internalType: "bytes", + name: "", + type: "bytes", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + ], + name: "latestStateMachineHeight", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "nonce", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "stateId", + type: "bytes", + }, + ], + name: "perByteFee", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "requestCommitments", + outputs: [ + { + components: [ + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + ], + internalType: "struct FeeMetadata", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "requestReceipts", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "responded", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "responseCommitments", + outputs: [ + { + components: [ + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + { + internalType: "address", + name: "sender", + type: "address", + }, + ], + internalType: "struct FeeMetadata", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes32", + name: "commitment", + type: "bytes32", + }, + ], + name: "responseReceipts", + outputs: [ + { + components: [ + { + internalType: "bytes32", + name: "responseCommitment", + type: "bytes32", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + internalType: "struct ResponseReceipt", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "state", + type: "bytes", + }, + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "overlayRoot", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "stateRoot", + type: "bytes32", + }, + ], + internalType: "struct StateCommitment", + name: "commitment", + type: "tuple", + }, + ], + name: "setConsensusState", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "enum FrozenStatus", + name: "newState", + type: "uint8", + }, + ], + name: "setFrozenState", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "stateCommitmentFee", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + ], + name: "stateMachineCommitment", + outputs: [ + { + components: [ + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "overlayRoot", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "stateRoot", + type: "bytes32", + }, + ], + internalType: "struct StateCommitment", + name: "", + type: "tuple", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + ], + name: "stateMachineCommitmentUpdateTime", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "parachainId", + type: "bytes", + }, + { + internalType: "uint256", + name: "id", + type: "uint256", + }, + ], + name: "stateMachineId", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "state", + type: "bytes", + }, + ], + name: "storeConsensusState", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + components: [ + { + internalType: "uint256", + name: "timestamp", + type: "uint256", + }, + { + internalType: "bytes32", + name: "overlayRoot", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "stateRoot", + type: "bytes32", + }, + ], + internalType: "struct StateCommitment", + name: "commitment", + type: "tuple", + }, + ], + name: "storeStateMachineCommitment", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "timestamp", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "unStakingPeriod", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "uniswapV2Router", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "uint256", + name: "defaultTimeout", + type: "uint256", + }, + { + internalType: "uint256", + name: "defaultPerByteFee", + type: "uint256", + }, + { + internalType: "uint256", + name: "stateCommitmentFee", + type: "uint256", + }, + { + internalType: "address", + name: "feeToken", + type: "address", + }, + { + internalType: "address", + name: "admin", + type: "address", + }, + { + internalType: "address", + name: "handler", + type: "address", + }, + { + internalType: "address", + name: "hostManager", + type: "address", + }, + { + internalType: "address", + name: "uniswapV2", + type: "address", + }, + { + internalType: "uint256", + name: "unStakingPeriod", + type: "uint256", + }, + { + internalType: "uint256", + name: "challengePeriod", + type: "uint256", + }, + { + internalType: "address", + name: "consensusClient", + type: "address", + }, + { + internalType: "uint256[]", + name: "stateMachines", + type: "uint256[]", + }, + { + components: [ + { + internalType: "bytes32", + name: "stateIdHash", + type: "bytes32", + }, + { + internalType: "uint256", + name: "perByteFee", + type: "uint256", + }, + ], + internalType: "struct PerByteFee[]", + name: "perByteFees", + type: "tuple[]", + }, + { + internalType: "bytes", + name: "hyperbridge", + type: "bytes", + }, + ], + internalType: "struct HostParams", + name: "params", + type: "tuple", + }, + ], + name: "updateHostParams", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "paraId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + name: "vetoes", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "address", + name: "beneficiary", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + internalType: "bool", + name: "native", + type: "bool", + }, + ], + internalType: "struct WithdrawParams", + name: "params", + type: "tuple", + }, + ], + name: "withdraw", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + stateMutability: "payable", + type: "receive", + }, +] as const + +export default { ABI } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/handler.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/handler.ts new file mode 100644 index 00000000..062fcc6e --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/handler.ts @@ -0,0 +1,750 @@ +const ABI = [ + { + inputs: [], + name: "ChallengePeriodNotElapsed", + type: "error", + }, + { + inputs: [], + name: "ConsensusClientExpired", + type: "error", + }, + { + inputs: [], + name: "DuplicateMessage", + type: "error", + }, + { + inputs: [], + name: "HostFrozen", + type: "error", + }, + { + inputs: [], + name: "InvalidMessageDestination", + type: "error", + }, + { + inputs: [], + name: "InvalidProof", + type: "error", + }, + { + inputs: [], + name: "MessageNotTimedOut", + type: "error", + }, + { + inputs: [], + name: "MessageTimedOut", + type: "error", + }, + { + inputs: [], + name: "StateCommitmentNotFound", + type: "error", + }, + { + inputs: [], + name: "UnknownMessage", + type: "error", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + internalType: "bytes", + name: "proof", + type: "bytes", + }, + ], + name: "handleConsensus", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest[]", + name: "timeouts", + type: "tuple[]", + }, + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "bytes[]", + name: "proof", + type: "bytes[]", + }, + ], + internalType: "struct GetTimeoutMessage", + name: "message", + type: "tuple", + }, + ], + name: "handleGetRequestTimeouts", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "bytes32[]", + name: "multiproof", + type: "bytes32[]", + }, + { + internalType: "uint256", + name: "leafCount", + type: "uint256", + }, + ], + internalType: "struct Proof", + name: "proof", + type: "tuple", + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest", + name: "request", + type: "tuple", + }, + { + components: [ + { + internalType: "bytes", + name: "key", + type: "bytes", + }, + { + internalType: "bytes", + name: "value", + type: "bytes", + }, + ], + internalType: "struct StorageValue[]", + name: "values", + type: "tuple[]", + }, + ], + internalType: "struct GetResponse", + name: "response", + type: "tuple", + }, + { + internalType: "uint256", + name: "index", + type: "uint256", + }, + { + internalType: "uint256", + name: "kIndex", + type: "uint256", + }, + ], + internalType: "struct GetResponseLeaf[]", + name: "responses", + type: "tuple[]", + }, + ], + internalType: "struct GetResponseMessage", + name: "message", + type: "tuple", + }, + ], + name: "handleGetResponses", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest[]", + name: "timeouts", + type: "tuple[]", + }, + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "bytes[]", + name: "proof", + type: "bytes[]", + }, + ], + internalType: "struct PostRequestTimeoutMessage", + name: "message", + type: "tuple", + }, + ], + name: "handlePostRequestTimeouts", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "bytes32[]", + name: "multiproof", + type: "bytes32[]", + }, + { + internalType: "uint256", + name: "leafCount", + type: "uint256", + }, + ], + internalType: "struct Proof", + name: "proof", + type: "tuple", + }, + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "uint256", + name: "index", + type: "uint256", + }, + { + internalType: "uint256", + name: "kIndex", + type: "uint256", + }, + ], + internalType: "struct PostRequestLeaf[]", + name: "requests", + type: "tuple[]", + }, + ], + internalType: "struct PostRequestMessage", + name: "request", + type: "tuple", + }, + ], + name: "handlePostRequests", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse[]", + name: "timeouts", + type: "tuple[]", + }, + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "bytes[]", + name: "proof", + type: "bytes[]", + }, + ], + internalType: "struct PostResponseTimeoutMessage", + name: "message", + type: "tuple", + }, + ], + name: "handlePostResponseTimeouts", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "contract IIsmpHost", + name: "host", + type: "address", + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: "uint256", + name: "stateMachineId", + type: "uint256", + }, + { + internalType: "uint256", + name: "height", + type: "uint256", + }, + ], + internalType: "struct StateMachineHeight", + name: "height", + type: "tuple", + }, + { + internalType: "bytes32[]", + name: "multiproof", + type: "bytes32[]", + }, + { + internalType: "uint256", + name: "leafCount", + type: "uint256", + }, + ], + internalType: "struct Proof", + name: "proof", + type: "tuple", + }, + { + components: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse", + name: "response", + type: "tuple", + }, + { + internalType: "uint256", + name: "index", + type: "uint256", + }, + { + internalType: "uint256", + name: "kIndex", + type: "uint256", + }, + ], + internalType: "struct PostResponseLeaf[]", + name: "responses", + type: "tuple[]", + }, + ], + internalType: "struct PostResponseMessage", + name: "response", + type: "tuple", + }, + ], + name: "handlePostResponses", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes4", + name: "interfaceId", + type: "bytes4", + }, + ], + name: "supportsInterface", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, +] as const + +export default { ABI } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/permit2.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/permit2.ts new file mode 100644 index 00000000..3128cb7e --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/permit2.ts @@ -0,0 +1,29 @@ +export const PERMIT2_ABI = [ + { + inputs: [ + { internalType: "address", name: "token", type: "address" }, + { internalType: "address", name: "spender", type: "address" }, + { internalType: "uint160", name: "amount", type: "uint160" }, + { internalType: "uint48", name: "expiration", type: "uint48" }, + ], + name: "approve", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { internalType: "address", name: "owner", type: "address" }, + { internalType: "address", name: "token", type: "address" }, + { internalType: "address", name: "spender", type: "address" }, + ], + name: "allowance", + outputs: [ + { internalType: "uint160", name: "amount", type: "uint160" }, + { internalType: "uint48", name: "expiration", type: "uint48" }, + { internalType: "uint48", name: "nonce", type: "uint48" }, + ], + stateMutability: "view", + type: "function", + }, +] as const diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/pingModule.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/pingModule.ts new file mode 100644 index 00000000..1173dd5c --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/pingModule.ts @@ -0,0 +1,765 @@ +const ABI = [ + { + inputs: [ + { + internalType: "address", + name: "admin", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [], + name: "ExecutionFailed", + type: "error", + }, + { + inputs: [], + name: "NotIsmpHost", + type: "error", + }, + { + anonymous: false, + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "key", + type: "bytes", + }, + { + internalType: "bytes", + name: "value", + type: "bytes", + }, + ], + indexed: false, + internalType: "struct StorageValue[]", + name: "message", + type: "tuple[]", + }, + ], + name: "GetResponseReceived", + type: "event", + }, + { + anonymous: false, + inputs: [], + name: "GetTimeoutReceived", + type: "event", + }, + { + anonymous: false, + inputs: [], + name: "MessageDispatched", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "string", + name: "message", + type: "string", + }, + ], + name: "PostReceived", + type: "event", + }, + { + anonymous: false, + inputs: [], + name: "PostRequestTimeoutReceived", + type: "event", + }, + { + anonymous: false, + inputs: [], + name: "PostResponseReceived", + type: "event", + }, + { + anonymous: false, + inputs: [], + name: "PostResponseTimeoutReceived", + type: "event", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest", + name: "request", + type: "tuple", + }, + ], + name: "dispatch", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse", + name: "response", + type: "tuple", + }, + ], + name: "dispatchPostResponse", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "_paraId", + type: "uint256", + }, + ], + name: "dispatchToParachain", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "host", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + internalType: "struct IncomingPostRequest", + name: "incoming", + type: "tuple", + }, + ], + name: "onAccept", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest", + name: "request", + type: "tuple", + }, + { + components: [ + { + internalType: "bytes", + name: "key", + type: "bytes", + }, + { + internalType: "bytes", + name: "value", + type: "bytes", + }, + ], + internalType: "struct StorageValue[]", + name: "values", + type: "tuple[]", + }, + ], + internalType: "struct GetResponse", + name: "response", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + internalType: "struct IncomingGetResponse", + name: "response", + type: "tuple", + }, + ], + name: "onGetResponse", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "address", + name: "from", + type: "address", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes[]", + name: "keys", + type: "bytes[]", + }, + { + internalType: "uint64", + name: "height", + type: "uint64", + }, + { + internalType: "bytes", + name: "context", + type: "bytes", + }, + ], + internalType: "struct GetRequest", + name: "", + type: "tuple", + }, + ], + name: "onGetTimeout", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "", + type: "tuple", + }, + ], + name: "onPostRequestTimeout", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse", + name: "response", + type: "tuple", + }, + { + internalType: "address", + name: "relayer", + type: "address", + }, + ], + internalType: "struct IncomingPostResponse", + name: "", + type: "tuple", + }, + ], + name: "onPostResponse", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { + internalType: "bytes", + name: "response", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + ], + internalType: "struct PostResponse", + name: "", + type: "tuple", + }, + ], + name: "onPostResponseTimeout", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "address", + name: "module", + type: "address", + }, + { + internalType: "uint64", + name: "timeout", + type: "uint64", + }, + { + internalType: "uint256", + name: "count", + type: "uint256", + }, + { + internalType: "uint256", + name: "fee", + type: "uint256", + }, + ], + internalType: "struct PingMessage", + name: "pingMessage", + type: "tuple", + }, + ], + name: "ping", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "previousPostRequest", + outputs: [ + { + components: [ + { + internalType: "bytes", + name: "source", + type: "bytes", + }, + { + internalType: "bytes", + name: "dest", + type: "bytes", + }, + { + internalType: "uint64", + name: "nonce", + type: "uint64", + }, + { + internalType: "bytes", + name: "from", + type: "bytes", + }, + { + internalType: "bytes", + name: "to", + type: "bytes", + }, + { + internalType: "uint64", + name: "timeoutTimestamp", + type: "uint64", + }, + { + internalType: "bytes", + name: "body", + type: "bytes", + }, + ], + internalType: "struct PostRequest", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "hostAddr", + type: "address", + }, + { + internalType: "address", + name: "tokenFaucet", + type: "address", + }, + ], + name: "setIsmpHost", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +] as const + +export default { ABI } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/tokenGateway.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/tokenGateway.ts new file mode 100644 index 00000000..68230a55 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/tokenGateway.ts @@ -0,0 +1,471 @@ +const ABI = [ + { + inputs: [{ internalType: "address", name: "admin", type: "address" }], + stateMutability: "nonpayable", + type: "constructor", + }, + { inputs: [], name: "InconsistentState", type: "error" }, + { inputs: [], name: "InvalidAddressLength", type: "error" }, + { inputs: [], name: "InvalidAmount", type: "error" }, + { inputs: [], name: "UnauthorizedAction", type: "error" }, + { inputs: [], name: "UnauthorizedCall", type: "error" }, + { inputs: [], name: "UnexpectedCall", type: "error" }, + { inputs: [], name: "UnknownAsset", type: "error" }, + { inputs: [], name: "ZeroAddress", type: "error" }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: "address", name: "asset", type: "address" }, + { indexed: false, internalType: "address", name: "newAdmin", type: "address" }, + ], + name: "AssetAdminChanged", + type: "event", + }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: "uint256", name: "amount", type: "uint256" }, + { indexed: false, internalType: "bytes32", name: "commitment", type: "bytes32" }, + { indexed: true, internalType: "bytes32", name: "from", type: "bytes32" }, + { indexed: true, internalType: "address", name: "beneficiary", type: "address" }, + { indexed: true, internalType: "bytes32", name: "assetId", type: "bytes32" }, + ], + name: "AssetReceived", + type: "event", + }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: "uint256", name: "amount", type: "uint256" }, + { indexed: false, internalType: "bytes32", name: "commitment", type: "bytes32" }, + { indexed: true, internalType: "address", name: "beneficiary", type: "address" }, + { indexed: true, internalType: "bytes32", name: "assetId", type: "bytes32" }, + ], + name: "AssetRefunded", + type: "event", + }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: "address", name: "erc20", type: "address" }, + { indexed: false, internalType: "address", name: "erc6160", type: "address" }, + { indexed: false, internalType: "string", name: "name", type: "string" }, + { indexed: false, internalType: "string", name: "symbol", type: "string" }, + { indexed: false, internalType: "bytes32", name: "assetId", type: "bytes32" }, + { indexed: false, internalType: "uint256", name: "initialSupply", type: "uint256" }, + { indexed: false, internalType: "address", name: "beneficiary", type: "address" }, + ], + name: "AssetRegistered", + type: "event", + }, + { + anonymous: false, + inputs: [{ indexed: false, internalType: "bytes32", name: "assetId", type: "bytes32" }], + name: "AssetRemoved", + type: "event", + }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: "bytes32", name: "to", type: "bytes32" }, + { indexed: false, internalType: "string", name: "dest", type: "string" }, + { indexed: false, internalType: "uint256", name: "amount", type: "uint256" }, + { indexed: false, internalType: "bytes32", name: "commitment", type: "bytes32" }, + { indexed: true, internalType: "address", name: "from", type: "address" }, + { indexed: true, internalType: "bytes32", name: "assetId", type: "bytes32" }, + { indexed: false, internalType: "bool", name: "redeem", type: "bool" }, + ], + name: "AssetTeleported", + type: "event", + }, + { + anonymous: false, + inputs: [ + { indexed: false, internalType: "string", name: "chain", type: "string" }, + { indexed: false, internalType: "address", name: "moduleId", type: "address" }, + ], + name: "NewContractInstance", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + components: [ + { internalType: "address", name: "host", type: "address" }, + { internalType: "address", name: "dispatcher", type: "address" }, + ], + indexed: false, + internalType: "struct TokenGatewayParams", + name: "oldParams", + type: "tuple", + }, + { + components: [ + { internalType: "address", name: "host", type: "address" }, + { internalType: "address", name: "dispatcher", type: "address" }, + ], + indexed: false, + internalType: "struct TokenGatewayParams", + name: "newParams", + type: "tuple", + }, + ], + name: "ParamsUpdated", + type: "event", + }, + { + inputs: [{ internalType: "bytes32", name: "assetId", type: "bytes32" }], + name: "erc20", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [{ internalType: "bytes32", name: "assetId", type: "bytes32" }], + name: "erc6160", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "host", + outputs: [{ internalType: "address", name: "h", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { internalType: "address", name: "host", type: "address" }, + { internalType: "address", name: "dispatcher", type: "address" }, + ], + internalType: "struct TokenGatewayParams", + name: "params", + type: "tuple", + }, + { + components: [ + { internalType: "address", name: "erc20", type: "address" }, + { internalType: "address", name: "erc6160", type: "address" }, + { internalType: "string", name: "name", type: "string" }, + { internalType: "string", name: "symbol", type: "string" }, + { internalType: "uint256", name: "initialSupply", type: "uint256" }, + { internalType: "address", name: "beneficiary", type: "address" }, + ], + internalType: "struct AssetMetadata[]", + name: "assets", + type: "tuple[]", + }, + ], + internalType: "struct TokenGatewayParamsExt", + name: "teleportParams", + type: "tuple", + }, + ], + name: "init", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [{ internalType: "bytes", name: "destination", type: "bytes" }], + name: "instance", + outputs: [{ internalType: "address", name: "", type: "address" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { internalType: "bytes", name: "source", type: "bytes" }, + { internalType: "bytes", name: "dest", type: "bytes" }, + { internalType: "uint64", name: "nonce", type: "uint64" }, + { internalType: "bytes", name: "from", type: "bytes" }, + { internalType: "bytes", name: "to", type: "bytes" }, + { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" }, + { internalType: "bytes", name: "body", type: "bytes" }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { internalType: "address", name: "relayer", type: "address" }, + ], + internalType: "struct IncomingPostRequest", + name: "incoming", + type: "tuple", + }, + ], + name: "onAccept", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + components: [ + { internalType: "bytes", name: "source", type: "bytes" }, + { internalType: "bytes", name: "dest", type: "bytes" }, + { internalType: "uint64", name: "nonce", type: "uint64" }, + { internalType: "address", name: "from", type: "address" }, + { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" }, + { internalType: "bytes[]", name: "keys", type: "bytes[]" }, + { internalType: "uint64", name: "height", type: "uint64" }, + { internalType: "bytes", name: "context", type: "bytes" }, + ], + internalType: "struct GetRequest", + name: "request", + type: "tuple", + }, + { + components: [ + { internalType: "bytes", name: "key", type: "bytes" }, + { internalType: "bytes", name: "value", type: "bytes" }, + ], + internalType: "struct StorageValue[]", + name: "values", + type: "tuple[]", + }, + ], + internalType: "struct GetResponse", + name: "response", + type: "tuple", + }, + { internalType: "address", name: "relayer", type: "address" }, + ], + internalType: "struct IncomingGetResponse", + name: "", + type: "tuple", + }, + ], + name: "onGetResponse", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "bytes", name: "source", type: "bytes" }, + { internalType: "bytes", name: "dest", type: "bytes" }, + { internalType: "uint64", name: "nonce", type: "uint64" }, + { internalType: "address", name: "from", type: "address" }, + { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" }, + { internalType: "bytes[]", name: "keys", type: "bytes[]" }, + { internalType: "uint64", name: "height", type: "uint64" }, + { internalType: "bytes", name: "context", type: "bytes" }, + ], + internalType: "struct GetRequest", + name: "", + type: "tuple", + }, + ], + name: "onGetTimeout", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "bytes", name: "source", type: "bytes" }, + { internalType: "bytes", name: "dest", type: "bytes" }, + { internalType: "uint64", name: "nonce", type: "uint64" }, + { internalType: "bytes", name: "from", type: "bytes" }, + { internalType: "bytes", name: "to", type: "bytes" }, + { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" }, + { internalType: "bytes", name: "body", type: "bytes" }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + ], + name: "onPostRequestTimeout", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { + components: [ + { internalType: "bytes", name: "source", type: "bytes" }, + { internalType: "bytes", name: "dest", type: "bytes" }, + { internalType: "uint64", name: "nonce", type: "uint64" }, + { internalType: "bytes", name: "from", type: "bytes" }, + { internalType: "bytes", name: "to", type: "bytes" }, + { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" }, + { internalType: "bytes", name: "body", type: "bytes" }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { internalType: "bytes", name: "response", type: "bytes" }, + { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" }, + ], + internalType: "struct PostResponse", + name: "response", + type: "tuple", + }, + { internalType: "address", name: "relayer", type: "address" }, + ], + internalType: "struct IncomingPostResponse", + name: "", + type: "tuple", + }, + ], + name: "onPostResponse", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { internalType: "bytes", name: "source", type: "bytes" }, + { internalType: "bytes", name: "dest", type: "bytes" }, + { internalType: "uint64", name: "nonce", type: "uint64" }, + { internalType: "bytes", name: "from", type: "bytes" }, + { internalType: "bytes", name: "to", type: "bytes" }, + { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" }, + { internalType: "bytes", name: "body", type: "bytes" }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { internalType: "bytes", name: "response", type: "bytes" }, + { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" }, + ], + internalType: "struct PostResponse", + name: "", + type: "tuple", + }, + ], + name: "onPostResponseTimeout", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "params", + outputs: [ + { + components: [ + { internalType: "address", name: "host", type: "address" }, + { internalType: "address", name: "dispatcher", type: "address" }, + ], + internalType: "struct TokenGatewayParams", + name: "", + type: "tuple", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "bytes", name: "dest", type: "bytes" }, + { internalType: "bytes", name: "to", type: "bytes" }, + { internalType: "bytes", name: "body", type: "bytes" }, + { internalType: "uint64", name: "timeout", type: "uint64" }, + { internalType: "uint256", name: "fee", type: "uint256" }, + { internalType: "address", name: "payer", type: "address" }, + ], + internalType: "struct DispatchPost", + name: "post", + type: "tuple", + }, + ], + name: "quote", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { + components: [ + { internalType: "bytes", name: "source", type: "bytes" }, + { internalType: "bytes", name: "dest", type: "bytes" }, + { internalType: "uint64", name: "nonce", type: "uint64" }, + { internalType: "bytes", name: "from", type: "bytes" }, + { internalType: "bytes", name: "to", type: "bytes" }, + { internalType: "uint64", name: "timeoutTimestamp", type: "uint64" }, + { internalType: "bytes", name: "body", type: "bytes" }, + ], + internalType: "struct PostRequest", + name: "request", + type: "tuple", + }, + { internalType: "bytes", name: "response", type: "bytes" }, + { internalType: "uint64", name: "timeout", type: "uint64" }, + { internalType: "uint256", name: "fee", type: "uint256" }, + { internalType: "address", name: "payer", type: "address" }, + ], + internalType: "struct DispatchPostResponse", + name: "res", + type: "tuple", + }, + ], + name: "quote", + outputs: [{ internalType: "uint256", name: "", type: "uint256" }], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + components: [ + { internalType: "uint256", name: "amount", type: "uint256" }, + { internalType: "uint256", name: "relayerFee", type: "uint256" }, + { internalType: "bytes32", name: "assetId", type: "bytes32" }, + { internalType: "bool", name: "redeem", type: "bool" }, + { internalType: "bytes32", name: "to", type: "bytes32" }, + { internalType: "bytes", name: "dest", type: "bytes" }, + { internalType: "uint64", name: "timeout", type: "uint64" }, + { internalType: "uint256", name: "nativeCost", type: "uint256" }, + { internalType: "bytes", name: "data", type: "bytes" }, + ], + internalType: "struct TeleportParams", + name: "teleportParams", + type: "tuple", + }, + ], + name: "teleport", + outputs: [], + stateMutability: "payable", + type: "function", + }, +] as const + +export default { ABI } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapRouterV2.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapRouterV2.ts new file mode 100644 index 00000000..1396391e --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapRouterV2.ts @@ -0,0 +1,955 @@ +const ABI = [ + { + inputs: [], + name: "WETH", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "tokenA", + type: "address", + }, + { + internalType: "address", + name: "tokenB", + type: "address", + }, + { + internalType: "uint256", + name: "amountADesired", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountBDesired", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountAMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountBMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "addLiquidity", + outputs: [ + { + internalType: "uint256", + name: "amountA", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountB", + type: "uint256", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "token", + type: "address", + }, + { + internalType: "uint256", + name: "amountTokenDesired", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountTokenMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETHMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "addLiquidityETH", + outputs: [ + { + internalType: "uint256", + name: "amountToken", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETH", + type: "uint256", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [], + name: "factory", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + { + internalType: "uint256", + name: "reserveIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "reserveOut", + type: "uint256", + }, + ], + name: "getAmountIn", + outputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "reserveIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "reserveOut", + type: "uint256", + }, + ], + name: "getAmountOut", + outputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + ], + name: "getAmountsIn", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + ], + name: "getAmountsOut", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountA", + type: "uint256", + }, + { + internalType: "uint256", + name: "reserveA", + type: "uint256", + }, + { + internalType: "uint256", + name: "reserveB", + type: "uint256", + }, + ], + name: "quote", + outputs: [ + { + internalType: "uint256", + name: "amountB", + type: "uint256", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "tokenA", + type: "address", + }, + { + internalType: "address", + name: "tokenB", + type: "address", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountAMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountBMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "removeLiquidity", + outputs: [ + { + internalType: "uint256", + name: "amountA", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountB", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "token", + type: "address", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountTokenMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETHMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "removeLiquidityETH", + outputs: [ + { + internalType: "uint256", + name: "amountToken", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETH", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "token", + type: "address", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountTokenMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETHMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "removeLiquidityETHSupportingFeeOnTransferTokens", + outputs: [ + { + internalType: "uint256", + name: "amountETH", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "token", + type: "address", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountTokenMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETHMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + internalType: "bool", + name: "approveMax", + type: "bool", + }, + { + internalType: "uint8", + name: "v", + type: "uint8", + }, + { + internalType: "bytes32", + name: "r", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "s", + type: "bytes32", + }, + ], + name: "removeLiquidityETHWithPermit", + outputs: [ + { + internalType: "uint256", + name: "amountToken", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETH", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "token", + type: "address", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountTokenMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountETHMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + internalType: "bool", + name: "approveMax", + type: "bool", + }, + { + internalType: "uint8", + name: "v", + type: "uint8", + }, + { + internalType: "bytes32", + name: "r", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "s", + type: "bytes32", + }, + ], + name: "removeLiquidityETHWithPermitSupportingFeeOnTransferTokens", + outputs: [ + { + internalType: "uint256", + name: "amountETH", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "tokenA", + type: "address", + }, + { + internalType: "address", + name: "tokenB", + type: "address", + }, + { + internalType: "uint256", + name: "liquidity", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountAMin", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountBMin", + type: "uint256", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + { + internalType: "bool", + name: "approveMax", + type: "bool", + }, + { + internalType: "uint8", + name: "v", + type: "uint8", + }, + { + internalType: "bytes32", + name: "r", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "s", + type: "bytes32", + }, + ], + name: "removeLiquidityWithPermit", + outputs: [ + { + internalType: "uint256", + name: "amountA", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountB", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapETHForExactTokens", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOutMin", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapExactETHForTokens", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOutMin", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapExactETHForTokensSupportingFeeOnTransferTokens", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountOutMin", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapExactTokensForETH", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountOutMin", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapExactTokensForETHSupportingFeeOnTransferTokens", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountOutMin", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapExactTokensForTokens", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountOutMin", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapExactTokensForTokensSupportingFeeOnTransferTokens", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountInMax", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapTokensForExactETH", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountInMax", + type: "uint256", + }, + { + internalType: "address[]", + name: "path", + type: "address[]", + }, + { + internalType: "address", + name: "to", + type: "address", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "swapTokensForExactTokens", + outputs: [ + { + internalType: "uint256[]", + name: "amounts", + type: "uint256[]", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, +] as const + +export default { ABI } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapV2Factory.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapV2Factory.ts new file mode 100644 index 00000000..61621cc4 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapV2Factory.ts @@ -0,0 +1,256 @@ +const ABI = [ + { + inputs: [ + { + internalType: "address", + name: "_feeCollectorSetter", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + anonymous: false, + inputs: [ + { + indexed: true, + internalType: "address", + name: "token0", + type: "address", + }, + { + indexed: true, + internalType: "address", + name: "token1", + type: "address", + }, + { + indexed: false, + internalType: "address", + name: "pair", + type: "address", + }, + { + indexed: false, + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + name: "PairCreated", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "feeCollector_", + type: "address", + }, + ], + name: "SetFeeCollector", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "feeCollectorSetter_", + type: "address", + }, + ], + name: "SetFeeCollectorSetter", + type: "event", + }, + { + anonymous: false, + inputs: [ + { + indexed: false, + internalType: "address", + name: "migrator_", + type: "address", + }, + ], + name: "SetMigrator", + type: "event", + }, + { + inputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + name: "allPairs", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "allPairsLength", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "tokenA", + type: "address", + }, + { + internalType: "address", + name: "tokenB", + type: "address", + }, + ], + name: "createPair", + outputs: [ + { + internalType: "address", + name: "pair", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "feeCollector", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "feeCollectorSetter", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + { + internalType: "address", + name: "", + type: "address", + }, + ], + name: "getPair", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "migrator", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "pairCodeHash", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_feeCollector", + type: "address", + }, + ], + name: "setFeeCollector", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_feeCollectorSetter", + type: "address", + }, + ], + name: "setFeeCollectorSetter", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_migrator", + type: "address", + }, + ], + name: "setMigrator", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, +] as const + +export default { ABI } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapV3Quoter.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapV3Quoter.ts new file mode 100644 index 00000000..218d1547 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapV3Quoter.ts @@ -0,0 +1,204 @@ +const ABI = [ + { + inputs: [ + { + internalType: "bytes", + name: "path", + type: "bytes", + }, + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + ], + name: "quoteExactInput", + outputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + { + internalType: "uint160[]", + name: "sqrtPriceX96AfterList", + type: "uint160[]", + }, + { + internalType: "uint32[]", + name: "initializedTicksCrossedList", + type: "uint32[]", + }, + { + internalType: "uint256", + name: "gasEstimate", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "address", + name: "tokenIn", + type: "address", + }, + { + internalType: "address", + name: "tokenOut", + type: "address", + }, + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "uint24", + name: "fee", + type: "uint24", + }, + { + internalType: "uint160", + name: "sqrtPriceLimitX96", + type: "uint160", + }, + ], + internalType: "struct IQuoterV2.QuoteExactInputSingleParams", + name: "params", + type: "tuple", + }, + ], + name: "quoteExactInputSingle", + outputs: [ + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + { + internalType: "uint160", + name: "sqrtPriceX96After", + type: "uint160", + }, + { + internalType: "uint32", + name: "initializedTicksCrossed", + type: "uint32", + }, + { + internalType: "uint256", + name: "gasEstimate", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "path", + type: "bytes", + }, + { + internalType: "uint256", + name: "amountOut", + type: "uint256", + }, + ], + name: "quoteExactOutput", + outputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "uint160[]", + name: "sqrtPriceX96AfterList", + type: "uint160[]", + }, + { + internalType: "uint32[]", + name: "initializedTicksCrossedList", + type: "uint32[]", + }, + { + internalType: "uint256", + name: "gasEstimate", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + components: [ + { + internalType: "address", + name: "tokenIn", + type: "address", + }, + { + internalType: "address", + name: "tokenOut", + type: "address", + }, + { + internalType: "uint256", + name: "amount", + type: "uint256", + }, + { + internalType: "uint24", + name: "fee", + type: "uint24", + }, + { + internalType: "uint160", + name: "sqrtPriceLimitX96", + type: "uint160", + }, + ], + internalType: "struct IQuoterV2.QuoteExactOutputSingleParams", + name: "params", + type: "tuple", + }, + ], + name: "quoteExactOutputSingle", + outputs: [ + { + internalType: "uint256", + name: "amountIn", + type: "uint256", + }, + { + internalType: "uint160", + name: "sqrtPriceX96After", + type: "uint160", + }, + { + internalType: "uint32", + name: "initializedTicksCrossed", + type: "uint32", + }, + { + internalType: "uint256", + name: "gasEstimate", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, +] as const + +export default { ABI } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapV4Quoter.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapV4Quoter.ts new file mode 100644 index 00000000..01308a3e --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/uniswapV4Quoter.ts @@ -0,0 +1,294 @@ +export const UNISWAP_V4_QUOTER_ABI = [ + { + type: "constructor", + inputs: [{ name: "_poolManager", type: "address", internalType: "contract IPoolManager" }], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "_quoteExactInput", + inputs: [ + { + name: "params", + type: "tuple", + internalType: "struct IV4Quoter.QuoteExactParams", + components: [ + { name: "exactCurrency", type: "address", internalType: "Currency" }, + { + name: "path", + type: "tuple[]", + internalType: "struct PathKey[]", + components: [ + { name: "intermediateCurrency", type: "address", internalType: "Currency" }, + { name: "fee", type: "uint24", internalType: "uint24" }, + { name: "tickSpacing", type: "int24", internalType: "int24" }, + { name: "hooks", type: "address", internalType: "contract IHooks" }, + { name: "hookData", type: "bytes", internalType: "bytes" }, + ], + }, + { name: "exactAmount", type: "uint128", internalType: "uint128" }, + ], + }, + ], + outputs: [{ name: "", type: "bytes", internalType: "bytes" }], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "_quoteExactInputSingle", + inputs: [ + { + name: "params", + type: "tuple", + internalType: "struct IV4Quoter.QuoteExactSingleParams", + components: [ + { + name: "poolKey", + type: "tuple", + internalType: "struct PoolKey", + components: [ + { name: "currency0", type: "address", internalType: "Currency" }, + { name: "currency1", type: "address", internalType: "Currency" }, + { name: "fee", type: "uint24", internalType: "uint24" }, + { name: "tickSpacing", type: "int24", internalType: "int24" }, + { name: "hooks", type: "address", internalType: "contract IHooks" }, + ], + }, + { name: "zeroForOne", type: "bool", internalType: "bool" }, + { name: "exactAmount", type: "uint128", internalType: "uint128" }, + { name: "hookData", type: "bytes", internalType: "bytes" }, + ], + }, + ], + outputs: [{ name: "", type: "bytes", internalType: "bytes" }], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "_quoteExactOutput", + inputs: [ + { + name: "params", + type: "tuple", + internalType: "struct IV4Quoter.QuoteExactParams", + components: [ + { name: "exactCurrency", type: "address", internalType: "Currency" }, + { + name: "path", + type: "tuple[]", + internalType: "struct PathKey[]", + components: [ + { name: "intermediateCurrency", type: "address", internalType: "Currency" }, + { name: "fee", type: "uint24", internalType: "uint24" }, + { name: "tickSpacing", type: "int24", internalType: "int24" }, + { name: "hooks", type: "address", internalType: "contract IHooks" }, + { name: "hookData", type: "bytes", internalType: "bytes" }, + ], + }, + { name: "exactAmount", type: "uint128", internalType: "uint128" }, + ], + }, + ], + outputs: [{ name: "", type: "bytes", internalType: "bytes" }], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "_quoteExactOutputSingle", + inputs: [ + { + name: "params", + type: "tuple", + internalType: "struct IV4Quoter.QuoteExactSingleParams", + components: [ + { + name: "poolKey", + type: "tuple", + internalType: "struct PoolKey", + components: [ + { name: "currency0", type: "address", internalType: "Currency" }, + { name: "currency1", type: "address", internalType: "Currency" }, + { name: "fee", type: "uint24", internalType: "uint24" }, + { name: "tickSpacing", type: "int24", internalType: "int24" }, + { name: "hooks", type: "address", internalType: "contract IHooks" }, + ], + }, + { name: "zeroForOne", type: "bool", internalType: "bool" }, + { name: "exactAmount", type: "uint128", internalType: "uint128" }, + { name: "hookData", type: "bytes", internalType: "bytes" }, + ], + }, + ], + outputs: [{ name: "", type: "bytes", internalType: "bytes" }], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "msgSender", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "address" }], + stateMutability: "view", + }, + { + type: "function", + name: "poolManager", + inputs: [], + outputs: [{ name: "", type: "address", internalType: "contract IPoolManager" }], + stateMutability: "view", + }, + { + type: "function", + name: "quoteExactInput", + inputs: [ + { + name: "params", + type: "tuple", + internalType: "struct IV4Quoter.QuoteExactParams", + components: [ + { name: "exactCurrency", type: "address", internalType: "Currency" }, + { + name: "path", + type: "tuple[]", + internalType: "struct PathKey[]", + components: [ + { name: "intermediateCurrency", type: "address", internalType: "Currency" }, + { name: "fee", type: "uint24", internalType: "uint24" }, + { name: "tickSpacing", type: "int24", internalType: "int24" }, + { name: "hooks", type: "address", internalType: "contract IHooks" }, + { name: "hookData", type: "bytes", internalType: "bytes" }, + ], + }, + { name: "exactAmount", type: "uint128", internalType: "uint128" }, + ], + }, + ], + outputs: [ + { name: "amountOut", type: "uint256", internalType: "uint256" }, + { name: "gasEstimate", type: "uint256", internalType: "uint256" }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "quoteExactInputSingle", + inputs: [ + { + name: "params", + type: "tuple", + internalType: "struct IV4Quoter.QuoteExactSingleParams", + components: [ + { + name: "poolKey", + type: "tuple", + internalType: "struct PoolKey", + components: [ + { name: "currency0", type: "address", internalType: "Currency" }, + { name: "currency1", type: "address", internalType: "Currency" }, + { name: "fee", type: "uint24", internalType: "uint24" }, + { name: "tickSpacing", type: "int24", internalType: "int24" }, + { name: "hooks", type: "address", internalType: "contract IHooks" }, + ], + }, + { name: "zeroForOne", type: "bool", internalType: "bool" }, + { name: "exactAmount", type: "uint128", internalType: "uint128" }, + { name: "hookData", type: "bytes", internalType: "bytes" }, + ], + }, + ], + outputs: [ + { name: "amountOut", type: "uint256", internalType: "uint256" }, + { name: "gasEstimate", type: "uint256", internalType: "uint256" }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "quoteExactOutput", + inputs: [ + { + name: "params", + type: "tuple", + internalType: "struct IV4Quoter.QuoteExactParams", + components: [ + { name: "exactCurrency", type: "address", internalType: "Currency" }, + { + name: "path", + type: "tuple[]", + internalType: "struct PathKey[]", + components: [ + { name: "intermediateCurrency", type: "address", internalType: "Currency" }, + { name: "fee", type: "uint24", internalType: "uint24" }, + { name: "tickSpacing", type: "int24", internalType: "int24" }, + { name: "hooks", type: "address", internalType: "contract IHooks" }, + { name: "hookData", type: "bytes", internalType: "bytes" }, + ], + }, + { name: "exactAmount", type: "uint128", internalType: "uint128" }, + ], + }, + ], + outputs: [ + { name: "amountIn", type: "uint256", internalType: "uint256" }, + { name: "gasEstimate", type: "uint256", internalType: "uint256" }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "quoteExactOutputSingle", + inputs: [ + { + name: "params", + type: "tuple", + internalType: "struct IV4Quoter.QuoteExactSingleParams", + components: [ + { + name: "poolKey", + type: "tuple", + internalType: "struct PoolKey", + components: [ + { name: "currency0", type: "address", internalType: "Currency" }, + { name: "currency1", type: "address", internalType: "Currency" }, + { name: "fee", type: "uint24", internalType: "uint24" }, + { name: "tickSpacing", type: "int24", internalType: "int24" }, + { name: "hooks", type: "address", internalType: "contract IHooks" }, + ], + }, + { name: "zeroForOne", type: "bool", internalType: "bool" }, + { name: "exactAmount", type: "uint128", internalType: "uint128" }, + { name: "hookData", type: "bytes", internalType: "bytes" }, + ], + }, + ], + outputs: [ + { name: "amountIn", type: "uint256", internalType: "uint256" }, + { name: "gasEstimate", type: "uint256", internalType: "uint256" }, + ], + stateMutability: "nonpayable", + }, + { + type: "function", + name: "unlockCallback", + inputs: [{ name: "data", type: "bytes", internalType: "bytes" }], + outputs: [{ name: "", type: "bytes", internalType: "bytes" }], + stateMutability: "nonpayable", + }, + { + type: "error", + name: "NotEnoughLiquidity", + inputs: [{ name: "poolId", type: "bytes32", internalType: "PoolId" }], + }, + { type: "error", name: "NotPoolManager", inputs: [] }, + { type: "error", name: "NotSelf", inputs: [] }, + { + type: "error", + name: "QuoteSwap", + inputs: [{ name: "amount", type: "uint256", internalType: "uint256" }], + }, + { type: "error", name: "UnexpectedCallSuccess", inputs: [] }, + { + type: "error", + name: "UnexpectedRevertBytes", + inputs: [{ name: "revertData", type: "bytes", internalType: "bytes" }], + }, +] as const diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/universalRouter.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/universalRouter.ts new file mode 100644 index 00000000..a934fb93 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/universalRouter.ts @@ -0,0 +1,445 @@ +const ABI = [ + { + inputs: [ + { + components: [ + { + internalType: "address", + name: "permit2", + type: "address", + }, + { + internalType: "address", + name: "weth9", + type: "address", + }, + { + internalType: "address", + name: "v2Factory", + type: "address", + }, + { + internalType: "address", + name: "v3Factory", + type: "address", + }, + { + internalType: "bytes32", + name: "pairInitCodeHash", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "poolInitCodeHash", + type: "bytes32", + }, + { + internalType: "address", + name: "v4PoolManager", + type: "address", + }, + { + internalType: "address", + name: "v3NFTPositionManager", + type: "address", + }, + { + internalType: "address", + name: "v4PositionManager", + type: "address", + }, + ], + internalType: "struct RouterParameters", + name: "params", + type: "tuple", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + { + inputs: [], + name: "BalanceTooLow", + type: "error", + }, + { + inputs: [], + name: "ContractLocked", + type: "error", + }, + { + inputs: [ + { + internalType: "Currency", + name: "currency", + type: "address", + }, + ], + name: "DeltaNotNegative", + type: "error", + }, + { + inputs: [ + { + internalType: "Currency", + name: "currency", + type: "address", + }, + ], + name: "DeltaNotPositive", + type: "error", + }, + { + inputs: [], + name: "ETHNotAccepted", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "commandIndex", + type: "uint256", + }, + { + internalType: "bytes", + name: "message", + type: "bytes", + }, + ], + name: "ExecutionFailed", + type: "error", + }, + { + inputs: [], + name: "FromAddressIsNotOwner", + type: "error", + }, + { + inputs: [], + name: "InputLengthMismatch", + type: "error", + }, + { + inputs: [], + name: "InsufficientBalance", + type: "error", + }, + { + inputs: [], + name: "InsufficientETH", + type: "error", + }, + { + inputs: [], + name: "InsufficientToken", + type: "error", + }, + { + inputs: [ + { + internalType: "bytes4", + name: "action", + type: "bytes4", + }, + ], + name: "InvalidAction", + type: "error", + }, + { + inputs: [], + name: "InvalidBips", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "commandType", + type: "uint256", + }, + ], + name: "InvalidCommandType", + type: "error", + }, + { + inputs: [], + name: "InvalidEthSender", + type: "error", + }, + { + inputs: [], + name: "InvalidPath", + type: "error", + }, + { + inputs: [], + name: "InvalidReserves", + type: "error", + }, + { + inputs: [], + name: "LengthMismatch", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "tokenId", + type: "uint256", + }, + ], + name: "NotAuthorizedForToken", + type: "error", + }, + { + inputs: [], + name: "NotPoolManager", + type: "error", + }, + { + inputs: [], + name: "OnlyMintAllowed", + type: "error", + }, + { + inputs: [], + name: "SliceOutOfBounds", + type: "error", + }, + { + inputs: [], + name: "TransactionDeadlinePassed", + type: "error", + }, + { + inputs: [], + name: "UnsafeCast", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "action", + type: "uint256", + }, + ], + name: "UnsupportedAction", + type: "error", + }, + { + inputs: [], + name: "V2InvalidPath", + type: "error", + }, + { + inputs: [], + name: "V2TooLittleReceived", + type: "error", + }, + { + inputs: [], + name: "V2TooMuchRequested", + type: "error", + }, + { + inputs: [], + name: "V3InvalidAmountOut", + type: "error", + }, + { + inputs: [], + name: "V3InvalidCaller", + type: "error", + }, + { + inputs: [], + name: "V3InvalidSwap", + type: "error", + }, + { + inputs: [], + name: "V3TooLittleReceived", + type: "error", + }, + { + inputs: [], + name: "V3TooMuchRequested", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "minAmountOutReceived", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountReceived", + type: "uint256", + }, + ], + name: "V4TooLittleReceived", + type: "error", + }, + { + inputs: [ + { + internalType: "uint256", + name: "maxAmountInRequested", + type: "uint256", + }, + { + internalType: "uint256", + name: "amountRequested", + type: "uint256", + }, + ], + name: "V4TooMuchRequested", + type: "error", + }, + { + inputs: [], + name: "V3_POSITION_MANAGER", + outputs: [ + { + internalType: "contract INonfungiblePositionManager", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "V4_POSITION_MANAGER", + outputs: [ + { + internalType: "contract IPositionManager", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "commands", + type: "bytes", + }, + { + internalType: "bytes[]", + name: "inputs", + type: "bytes[]", + }, + ], + name: "execute", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "commands", + type: "bytes", + }, + { + internalType: "bytes[]", + name: "inputs", + type: "bytes[]", + }, + { + internalType: "uint256", + name: "deadline", + type: "uint256", + }, + ], + name: "execute", + outputs: [], + stateMutability: "payable", + type: "function", + }, + { + inputs: [], + name: "msgSender", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "poolManager", + outputs: [ + { + internalType: "contract IPoolManager", + name: "", + type: "address", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "int256", + name: "amount0Delta", + type: "int256", + }, + { + internalType: "int256", + name: "amount1Delta", + type: "int256", + }, + { + internalType: "bytes", + name: "data", + type: "bytes", + }, + ], + name: "uniswapV3SwapCallback", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [ + { + internalType: "bytes", + name: "data", + type: "bytes", + }, + ], + name: "unlockCallback", + outputs: [ + { + internalType: "bytes", + name: "", + type: "bytes", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + stateMutability: "payable", + type: "receive", + }, +] as const + +export default { ABI } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/weth.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/weth.ts new file mode 100644 index 00000000..c9833c1d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/abis/weth.ts @@ -0,0 +1,18 @@ +const ABI = [ + { + name: "deposit", + type: "function", + stateMutability: "payable", + inputs: [], + outputs: [], + }, + { + name: "withdraw", + type: "function", + stateMutability: "nonpayable", + inputs: [{ name: "wad", type: "uint256" }], + outputs: [], + }, +] as const + +export default { ABI } diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/chain.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/chain.ts new file mode 100644 index 00000000..ed97776d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/chain.ts @@ -0,0 +1,218 @@ +import { EvmChain, SubstrateChain } from "@/chain" +import type { + GetResponseStorageValues, + HexString, + IEvmConfig, + IGetRequest, + IMessage, + IPostRequest, + ISubstrateConfig, + StateMachineHeight, + StateMachineIdParams, +} from "@/types" +import { isEvmChain, isSubstrateChain } from "@/utils" +import { ExpectedError } from "./utils/exceptions" + +export * from "@/chains/evm" +export * from "@/chains/substrate" + +/** + * Type representing an ISMP message. + */ +export type IIsmpMessage = IRequestMessage | ITimeoutPostRequestMessage | IGetResponseMessage | IGetRequestMessage + +export interface IRequestMessage { + /** + * The kind of message. + */ + kind: "PostRequest" + /** + * The requests to be posted. + */ + requests: IPostRequest[] + /** + * The proof of the requests. + */ + proof: IProof + /** + * The signer of the message. + */ + signer: HexString +} + +export interface IGetRequestMessage { + /** + * The kind of message. + */ + kind: "GetRequest" + /** + * The requests to be posted. + */ + requests: IGetRequest[] + /** + * The proof of the requests from the source chain. + */ + source: IProof + /** + * The proof of the response from the target chain + */ + response: IProof + /** + * The signer of the message. + */ + signer: HexString +} + +export interface IGetResponse { + /** + * The request that triggered this response. + */ + get: IGetRequest + /** + * The response message. + */ + values: GetResponseStorageValues[] +} + +export interface IGetResponseMessage { + /** + * The kind of message. + */ + kind: "GetResponse" + /** + * The responses to be posted. + */ + responses: IGetResponse[] + /** + * The proof of the responses. + */ + proof: IProof + /** + * The signer of the message. + */ + signer: HexString +} + +export interface ITimeoutPostRequestMessage { + /** + * The kind of message. + */ + kind: "TimeoutPostRequest" + + /** + * The requests to be posted. + */ + requests: IPostRequest[] + + /** + * The proof of the requests. + */ + proof: IProof +} + +export interface IProof { + /** + * The height of the proof. + */ + height: bigint + /** + * The state machine identifier of the proof. + */ + stateMachine: string + + /** + * The associated consensus state identifier of the proof. + */ + consensusStateId: string + + /** + * The encoded storage proof + */ + proof: HexString +} + +/** + * Interface representing a chain. + */ +export interface IChain { + /** + * Returns the configuration for this chain + */ + get config(): IEvmConfig | ISubstrateConfig + + /* + * Returns the current timestamp of the chain in seconds. + */ + timestamp(): Promise + + /** + * Returns the state trie key for the request-receipt storage item for the given request commitment. + */ + requestReceiptKey(commitment: HexString): HexString + + /** + * Query and return the request-receipt for the given request commitment. + */ + queryRequestReceipt(commitment: HexString): Promise + + /** + * Query and return the encoded storage proof for the provided keys at the given height. + */ + queryStateProof(at: bigint, keys: HexString[]): Promise + + /* + * Query and return the encoded storage proof for requests + */ + queryProof(message: IMessage, counterparty: string, at?: bigint): Promise + + /* + * Encode an ISMP message into the appropriate calldata for this chain. + */ + encode(message: IIsmpMessage): HexString + + /** + * Get the latest state machine height for a given state machine ID. + */ + latestStateMachineHeight(stateMachineId: StateMachineIdParams): Promise + + /** + * Get the challenge period for a given state machine ID. + */ + challengePeriod(stateMachineId: StateMachineIdParams): Promise + + /** + * Get the update time for a statemachine height. + */ + stateMachineUpdateTime(stateMachineHeight: StateMachineHeight): Promise +} + +/** + * Returns the chain interface for a given state machine identifier + * @param chainConfig - Chain configuration + * @returns Chain interface + */ +export async function getChain(chainConfig: IEvmConfig | ISubstrateConfig): Promise { + if (isEvmChain(chainConfig.stateMachineId)) { + const config = chainConfig as IEvmConfig + const chainId = Number.parseInt(chainConfig.stateMachineId.split("-")[1]) + const evmChain = new EvmChain({ + chainId, + rpcUrl: config.rpcUrl, + host: config.host, + consensusStateId: config.consensusStateId, + }) + + return evmChain + } + + if (isSubstrateChain(chainConfig.stateMachineId)) { + const config = chainConfig as ISubstrateConfig + const substrateChain = new SubstrateChain(config) + + await substrateChain.connect() + + return substrateChain + } + + throw new ExpectedError(`Unsupported chain: ${chainConfig.stateMachineId}`) +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/chains/evm.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/chains/evm.ts new file mode 100644 index 00000000..0fb4f5c3 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/chains/evm.ts @@ -0,0 +1,795 @@ +import { + http, + type PublicClient, + bytesToBigInt, + bytesToHex, + createPublicClient, + encodeFunctionData, + erc20Abi, + hexToBytes, + keccak256, + pad, + toBytes, + toHex, + maxUint256, +} from "viem" +import { + arbitrum, + arbitrumSepolia, + base, + baseSepolia, + bsc, + bscTestnet, + gnosis, + gnosisChiado, + mainnet, + optimism, + optimismSepolia, + polygon, + unichain, + soneium, +} from "viem/chains" + +import { flatten, zip } from "lodash-es" +import { match } from "ts-pattern" +import type { GetProofParameters, Hex } from "viem" + +import EvmHost from "@/abis/evmHost" +import evmHost from "@/abis/evmHost" +import HandlerV1 from "@/abis/handler" +import type { IChain, IIsmpMessage } from "@/chain" +import { ChainConfigService } from "@/configs/ChainConfigService" +import type { + HexString, + IEvmConfig, + IGetRequest, + IMessage, + IPostRequest, + StateMachineHeight, + StateMachineIdParams, +} from "@/types" +import { + ADDRESS_ZERO, + EvmStateProof, + MmrProof, + SubstrateStateProof, + calculateMMRSize, + generateRootWithProof, + mmrPositionToKIndex, +} from "@/utils" + +import UniswapV2Factory from "@/abis/uniswapV2Factory" +import UniswapRouterV2 from "@/abis/uniswapRouterV2" + +const chains = { + [mainnet.id]: mainnet, + [arbitrum.id]: arbitrum, + [arbitrumSepolia.id]: arbitrumSepolia, + [optimism.id]: optimism, + [optimismSepolia.id]: optimismSepolia, + [base.id]: base, + [baseSepolia.id]: baseSepolia, + [soneium.id]: soneium, + [bsc.id]: bsc, + [bscTestnet.id]: bscTestnet, + [gnosis.id]: gnosis, + [gnosisChiado.id]: gnosisChiado, + [polygon.id]: polygon, + [unichain.id]: unichain, +} + +/** + * The default address used as fallback when no address is provided. + * This represents the zero address in EVM chains. + */ +export const DEFAULT_ADDRESS = "0x0000000000000000000000000000000000000000" + +/** + * Parameters for an EVM chain. + */ +export interface EvmChainParams { + /** + * The chain ID of the EVM chain + */ + chainId: number + /** + * The RPC URL of the EVM chain + */ + rpcUrl: string + /** + * The host address of the EVM chain (IsmpHost contract address) + */ + host: HexString + /** + * Consensus state identifier of this chain on hyperbridge + */ + consensusStateId?: string +} + +/** + * Encapsulates an EVM chain. + */ +export class EvmChain implements IChain { + private publicClient: PublicClient + private chainConfigService: ChainConfigService + + constructor(private readonly params: EvmChainParams) { + // Default consensus state IDs for known chains + const defaultConsensusStateIds: Record = { + 1: "ETH0", // Ethereum Mainnet + 11155111: "ETH0", // Sepolia + 42161: "ETH0", // Arbitrum One + 421614: "ETH0", // Arbitrum Sepolia + 10: "ETH0", // Optimism + 11155420: "ETH0", // Optimism Sepolia + 8453: "ETH0", // Base + 84532: "ETH0", // Base Sepolia + 137: "POLY", // Polygon Mainnet + 80002: "POLY", // Polygon Amoy + 56: "BSC0", // BSC + 97: "BSC0", // BSC Testnet + 100: "GNO0", // Gnosis + 10200: "GNO0", // Gnosis Chiado + } + + // Set default consensusStateId if not provided + if (!params.consensusStateId) { + params.consensusStateId = defaultConsensusStateIds[params.chainId] + } + + // @ts-ignore + this.publicClient = createPublicClient({ + // @ts-ignore + chain: chains[params.chainId], + transport: http(params.rpcUrl), + }) + this.chainConfigService = new ChainConfigService() + } + + // Expose minimal getters for external helpers/classes + get client(): PublicClient { + return this.publicClient + } + + get host(): HexString { + return this.params.host + } + + get config(): IEvmConfig { + return { + rpcUrl: this.params.rpcUrl, + stateMachineId: `EVM-${this.params.chainId}`, + host: this.params.host, + consensusStateId: this.params.consensusStateId!, + } + } + + get configService(): ChainConfigService { + return this.chainConfigService + } + + /** + * Derives the key for the request receipt. + * @param {HexString} commitment - The commitment to derive the key from. + * @returns {HexString} The derived key. + */ + requestReceiptKey(commitment: HexString): HexString { + return deriveMapKey(hexToBytes(commitment), REQUEST_RECEIPTS_SLOT) + } + + /** + * Queries the request receipt. + * @param {HexString} commitment - The commitment to query. + * @returns {Promise} The relayer address responsible for delivering the request. + */ + async queryRequestReceipt(commitment: HexString): Promise { + const relayer = await this.publicClient.readContract({ + address: this.params.host, + abi: EvmHost.ABI, + functionName: "requestReceipts", + args: [commitment], + }) + + // solidity returns zeroes if the storage slot is empty + return relayer === DEFAULT_ADDRESS ? undefined : relayer + } + + /** + * Queries the proof of the commitments. + * @param {IMessage} message - The message to query. + * @param {string} counterparty - The counterparty address. + * @param {bigint} [at] - The block number to query at. + * @returns {Promise} The proof. + */ + async queryProof(message: IMessage, counterparty: string, at?: bigint): Promise { + // for each request derive the commitment key collect into a new array + const commitmentKeys = + "Requests" in message + ? message.Requests.map((key) => requestCommitmentKey(key).slot1) + : message.Responses.map((key) => responseCommitmentKey(key)) + const config: GetProofParameters = { + address: this.params.host, + storageKeys: commitmentKeys, + } + if (!at) { + config.blockTag = "latest" + } else { + config.blockNumber = at + } + const proof = await this.publicClient.getProof(config) + const flattenedProof = Array.from(new Set(flatten(proof.storageProof.map((item) => item.proof)))) + + const encoded = EvmStateProof.enc({ + contractProof: proof.accountProof.map((item) => Array.from(hexToBytes(item))), + storageProof: [ + [Array.from(hexToBytes(this.params.host)), flattenedProof.map((item) => Array.from(hexToBytes(item)))], + ], + }) + + return toHex(encoded) + } + + /** + * Query and return the encoded storage proof for the provided keys at the given height. + * @param {bigint} at - The block height at which to query the storage proof. + * @param {HexString[]} keys - The keys for which to query the storage proof. + * @param {HexString} address - Optional contract address to fetch storage proof else default to host contract + * @returns {Promise} The encoded storage proof. + */ + async queryStateProof(at: bigint, keys: HexString[], address?: HexString): Promise { + const config: GetProofParameters = { + address: address ?? this.params.host, + storageKeys: keys, + } + if (!at) { + config.blockTag = "latest" + } else { + config.blockNumber = at + } + const proof = await this.publicClient.getProof(config) + const flattenedProof = Array.from(new Set(flatten(proof.storageProof.map((item) => item.proof)))) + + const encoded = EvmStateProof.enc({ + contractProof: proof.accountProof.map((item) => Array.from(hexToBytes(item))), + storageProof: [ + [Array.from(hexToBytes(config.address)), flattenedProof.map((item) => Array.from(hexToBytes(item)))], + ], + }) + + return toHex(encoded) + } + + /** + * Returns the current timestamp of the chain. + * @returns {Promise} The current timestamp. + */ + async timestamp(): Promise { + const data = await this.publicClient.readContract({ + address: this.params.host, + abi: EvmHost.ABI, + functionName: "timestamp", + }) + return BigInt(data) + } + + /** + * Get the latest state machine height for a given state machine ID. + * @param {StateMachineIdParams} stateMachineId - The state machine ID. + * @returns {Promise} The latest state machine height. + */ + async latestStateMachineHeight(stateMachineId: StateMachineIdParams): Promise { + if (!this.publicClient) throw new Error("API not initialized") + const id = stateMachineId.stateId.Polkadot || stateMachineId.stateId.Kusama + if (!id) + throw new Error( + "Expected Polakdot or Kusama State machine id when reading latest state machine height on evm", + ) + const data = await this.publicClient.readContract({ + address: this.params.host, + abi: EvmHost.ABI, + functionName: "latestStateMachineHeight", + args: [BigInt(id)], + }) + return data + } + + /** + * Get the state machine update time for a given state machine height. + * @param {StateMachineHeight} stateMachineHeight - The state machine height. + * @returns {Promise} The statemachine update time in seconds. + */ + async stateMachineUpdateTime(stateMachineHeight: StateMachineHeight): Promise { + if (!this.publicClient) throw new Error("API not initialized") + const id = stateMachineHeight.id.stateId.Polkadot || stateMachineHeight.id.stateId.Kusama + if (!id) throw new Error("Expected Polkadot or Kusama State machine id when reading state machine update time") + const data = await this.publicClient.readContract({ + address: this.params.host, + abi: EvmHost.ABI, + functionName: "stateMachineCommitmentUpdateTime", + args: [{ stateMachineId: BigInt(id), height: stateMachineHeight.height }], + }) + return data + } + + /** + * Get the challenge period for a given state machine id. + * @param {StateMachineIdParams} stateMachineId - The state machine ID. + * @returns {Promise} The challenge period in seconds. + */ + async challengePeriod(stateMachineId: StateMachineIdParams): Promise { + if (!this.publicClient) throw new Error("API not initialized") + const id = stateMachineId.stateId.Polkadot || stateMachineId.stateId.Kusama + if (!id) + throw new Error( + "Expected Polkadot or Kusama State machine id when reading latest state machine height on evm", + ) + const data = await this.publicClient.readContract({ + address: this.params.host, + abi: EvmHost.ABI, + functionName: "challengePeriod", + }) + return data + } + + /** + * Encodes an ISMP message for the EVM chain. + * @param {IIsmpMessage} message The ISMP message to encode. + * @returns {HexString} The encoded calldata. + */ + encode(message: IIsmpMessage): HexString { + const encoded = match(message) + .with({ kind: "PostRequest" }, (request) => { + const mmrProof = MmrProof.dec(request.proof.proof) + const requests = zip(request.requests, mmrProof.leafIndexAndPos) + .map(([req, leafIndexAndPos]) => { + if (!req || !leafIndexAndPos) return + const [[, kIndex]] = mmrPositionToKIndex( + [leafIndexAndPos?.pos], + calculateMMRSize(mmrProof.leafCount), + ) + return { + request: { + source: toHex(req.source), + dest: toHex(req.dest), + to: req.to, + from: req.from, + nonce: req.nonce, + timeoutTimestamp: req.timeoutTimestamp, + body: req.body, + } as any, + index: leafIndexAndPos?.leafIndex!, + kIndex, + } + }) + .filter((item) => !!item) + + const proof = { + height: { + stateMachineId: BigInt(Number.parseInt(request.proof.stateMachine.split("-")[1])), + height: request.proof.height, + }, + multiproof: mmrProof.items.map((item) => bytesToHex(new Uint8Array(item))), + leafCount: mmrProof.leafCount, + } + const encoded = encodeFunctionData({ + abi: HandlerV1.ABI, + functionName: "handlePostRequests", + args: [ + this.params.host, + { + proof, + requests, + }, + ], + }) + + return encoded + }) + .with({ kind: "TimeoutPostRequest" }, (timeout) => { + const proof = SubstrateStateProof.dec(timeout.proof.proof).value.storageProof.map((item) => + toHex(new Uint8Array(item)), + ) + const encoded = encodeFunctionData({ + abi: HandlerV1.ABI, + functionName: "handlePostRequestTimeouts", + args: [ + this.params.host, + { + height: { + stateMachineId: BigInt(Number.parseInt(timeout.proof.stateMachine.split("-")[1])), + height: timeout.proof.height, + }, + timeouts: timeout.requests.map((req) => ({ + source: toHex(req.source), + dest: toHex(req.dest), + to: req.to, + from: req.from, + nonce: req.nonce, + timeoutTimestamp: req.timeoutTimestamp, + body: req.body, + })), + proof, + }, + ], + }) + + return encoded + }) + .with({ kind: "GetResponse" }, (request) => { + const mmrProof = MmrProof.dec(request.proof.proof) + const responses = zip(request.responses, mmrProof.leafIndexAndPos) + .map(([req, leafIndexAndPos]) => { + if (!req || !leafIndexAndPos) return + const [[, kIndex]] = mmrPositionToKIndex( + [leafIndexAndPos?.pos], + calculateMMRSize(mmrProof.leafCount), + ) + return { + response: { + request: { + source: toHex(req.get.source), + dest: toHex(req.get.dest), + from: req.get.from, + nonce: req.get.nonce, + timeoutTimestamp: req.get.timeoutTimestamp, + keys: req.get.keys, + context: req.get.context, + height: req.get.height, + }, + + values: req.values, + } as any, + index: leafIndexAndPos?.leafIndex!, + kIndex, + } + }) + .filter((item) => !!item) + + const proof = { + height: { + stateMachineId: BigInt(Number.parseInt(request.proof.stateMachine.split("-")[1])), + height: request.proof.height, + }, + multiproof: mmrProof.items.map((item) => bytesToHex(new Uint8Array(item))), + leafCount: mmrProof.leafCount, + } + const encoded = encodeFunctionData({ + abi: HandlerV1.ABI, + functionName: "handleGetResponses", + args: [ + this.params.host, + { + proof, + responses, + }, + ], + }) + + return encoded + }) + .with({ kind: "GetRequest" }, (message) => { + throw new Error("GetResponse is not yet supported on Substrate chains") + }) + .exhaustive() + + return encoded + } + + /** + * Calculates the fee required to send a post request to the destination chain. + * The fee is calculated based on the per-byte fee for the destination chain + * multiplied by the size of the request body. + * + * @param request - The post request to calculate the fee for + * @returns The total fee in wei required to send the post request + */ + async quote(request: IPostRequest | IGetRequest): Promise { + // Exclude 0x prefix from the body length, and get the byte length + const bodyByteLength = + "body" in request ? Math.floor((request.body.length - 2) / 2) : Math.floor((request.context.length - 2) / 2) + + const args = "body" in request ? [toHex(request.dest)] : [toHex(request.source)] + + const perByteFee = await this.publicClient.readContract({ + address: this.params.host, + abi: EvmHost.ABI, + functionName: "perByteFee", + args: args as any, + }) + + const length = bodyByteLength < 32 ? 32 : bodyByteLength + + return perByteFee * BigInt(length) + } + + async quoteNative(request: IPostRequest | IGetRequest, fee: bigint): Promise { + const totalFee = (await this.quote(request)) + fee + const feeToken = await this.getFeeTokenWithDecimals() + return this.getAmountsIn(totalFee, feeToken.address, request.source) + } + + private async getAmountsIn(amountOut: bigint, tokenOutForQuote: HexString, chain: string): Promise { + const v2Router = this.configService.getUniswapRouterV2Address(chain) + const WETH = this.configService.getWrappedNativeAssetWithDecimals(chain).asset + const v2AmountIn = await this.publicClient.simulateContract({ + address: v2Router, + abi: UniswapRouterV2.ABI, + // @ts-ignore + functionName: "getAmountsIn", + // @ts-ignore + args: [amountOut, [WETH, tokenOutForQuote]], + }) + + return v2AmountIn.result[0] + } + /** + * Estimates the gas required for a post request execution on this chain. + * This function generates mock proofs for the post request, creates a state override + * with the necessary overlay root, and estimates the gas cost for executing the + * handlePostRequests transaction on the handler contract. + * + * @param request - The post request to estimate gas for + * @param paraId - The ID of the parachain (Hyperbridge) that will process the request + * @returns The estimated gas amount in gas units and the generated calldata + */ + async estimateGas(request: IPostRequest): Promise<{ gas: bigint; postRequestCalldata: HexString }> { + const hostParams = await this.publicClient.readContract({ + address: this.params.host, + abi: EvmHost.ABI, + functionName: "hostParams", + }) + + const { root, proof, index, kIndex, treeSize } = await generateRootWithProof(request, 2n ** 10n) + const latestStateMachineHeight = 6291991n + const paraId = 4009n + const overlayRootSlot = getStateCommitmentFieldSlot( + paraId, // Hyperbridge chain id + latestStateMachineHeight, // Hyperbridge chain height + 1, // For overlayRoot + ) + const postParams = { + height: { + stateMachineId: BigInt(paraId), + height: latestStateMachineHeight, + }, + multiproof: proof, + leafCount: treeSize, + } + + const formattedRequest = { + ...request, + source: toHex(request.source), + dest: toHex(request.dest), + } + + const contractArgs = [ + this.params.host, + { + proof: postParams, + requests: [ + { + request: formattedRequest, + index, + kIndex, + }, + ], + }, + ] as const + + const postRequestCalldata = encodeFunctionData({ + abi: HandlerV1.ABI, + functionName: "handlePostRequests", + args: contractArgs, + }) + + const gas = await this.publicClient.estimateContractGas({ + address: hostParams.handler, + abi: HandlerV1.ABI, + functionName: "handlePostRequests", + args: contractArgs, + stateOverride: [ + { + address: this.params.host, + stateDiff: [ + { + slot: overlayRootSlot, + value: root, + }, + ], + }, + ], + }) + + return { gas, postRequestCalldata } + } + + /** + * Gets the fee token address and decimals for the chain. + * This function gets the fee token address and decimals for the chain. + * + * @returns The fee token address and decimals + */ + async getFeeTokenWithDecimals(): Promise<{ address: HexString; decimals: number }> { + const hostParams = await this.publicClient.readContract({ + abi: EvmHost.ABI, + address: this.params.host, + functionName: "hostParams", + }) + const feeTokenAddress = hostParams.feeToken + const feeTokenDecimals = await this.publicClient.readContract({ + address: feeTokenAddress, + abi: erc20Abi, + functionName: "decimals", + }) + return { address: feeTokenAddress, decimals: feeTokenDecimals } + } + + /** + * Gets the nonce of the host. + * This function gets the nonce of the host. + * + * @returns The nonce of the host + */ + async getHostNonce(): Promise { + const nonce = await this.publicClient.readContract({ + abi: evmHost.ABI, + address: this.params.host, + functionName: "nonce", + }) + + return nonce + } +} + +/** + * Factory function for creating EVM chain instances with common defaults + * + * @param chainId - The EVM chain ID + * @param host - The IsmpHost contract address + * @param options - Optional configuration overrides + * @returns A new EvmChain instance + * + * @example + * ```typescript + * // Create with minimal config + * const ethChain = createEvmChain(1, "0x87ea45..", { + * rpcUrl: "https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY" + * }) + * + * // Create with custom consensus state ID + * const arbChain = createEvmChain(42161, "0x87ea42345..", { + * rpcUrl: "https://arb-mainnet.g.alchemy.com/v2/YOUR_KEY", + * consensusStateId: "ARB_CUSTOM" + * }) + * ``` + */ +export function createEvmChain( + chainId: number, + host: HexString, + options: { + rpcUrl: string + consensusStateId?: string + }, +): EvmChain { + return new EvmChain({ + chainId, + host, + rpcUrl: options.rpcUrl, + consensusStateId: options.consensusStateId, + }) +} + +/** + * Slot for storing request commitments. + */ +export const REQUEST_COMMITMENTS_SLOT = 0n + +/** + * Slot index for response commitments map + */ +export const RESPONSE_COMMITMENTS_SLOT = 1n + +/** + * Slot index for requests receipts map + */ +export const REQUEST_RECEIPTS_SLOT = 2n + +/** + * Slot index for response receipts map + */ +export const RESPONSE_RECEIPTS_SLOT = 3n + +/** + * Slot index for state commitment map + */ +export const STATE_COMMITMENTS_SLOT = 5n + +export function requestCommitmentKey(key: Hex): { slot1: Hex; slot2: Hex } { + // First derive the map key + const keyBytes = hexToBytes(key) + const slot = REQUEST_COMMITMENTS_SLOT + const mappedKey = deriveMapKey(keyBytes, slot) + + // Convert the derived key to BigInt and add 1 + const number = bytesToBigInt(hexToBytes(mappedKey)) + 1n + + // Convert back to 32-byte hex + return { + slot1: pad(`0x${number.toString(16)}`, { size: 32 }), + slot2: mappedKey, + } +} + +function responseCommitmentKey(key: Hex): Hex { + // First derive the map key + const keyBytes = hexToBytes(key) + const slot = RESPONSE_COMMITMENTS_SLOT + const mappedKey = deriveMapKey(keyBytes, slot) + + // Convert the derived key to BigInt and add 1 + const number = bytesToBigInt(hexToBytes(mappedKey)) + 1n + + // Convert back to 32-byte hex + return pad(`0x${number.toString(16)}`, { size: 32 }) +} + +function deriveMapKey(key: Uint8Array, slot: bigint): Hex { + // Convert slot to 32-byte big-endian representation + const slotBytes = pad(`0x${slot.toString(16)}`, { size: 32 }) + + // Combine key and slot bytes + const combined = new Uint8Array([...key, ...toBytes(slotBytes)]) + + // Calculate keccak256 hash + return keccak256(combined) +} + +/** + * Derives the storage slot for a specific field in the StateCommitment struct + * + * struct StateCommitment { + * uint256 timestamp; // slot + 0 + * bytes32 overlayRoot; // slot + 1 + * bytes32 stateRoot; // slot + 2 + * } + * + * @param stateMachineId - The state machine ID + * @param height - The block height + * @param field - The field index in the struct (0 for timestamp, 1 for overlayRoot, 2 for stateRoot) + * @returns The storage slot for the specific field + */ +export function getStateCommitmentFieldSlot(stateMachineId: bigint, height: bigint, field: 0 | 1 | 2): HexString { + const baseSlot = getStateCommitmentSlot(stateMachineId, height) + const slotNumber = bytesToBigInt(toBytes(baseSlot)) + BigInt(field) + return pad(`0x${slotNumber.toString(16)}`, { size: 32 }) +} + +export function getStateCommitmentSlot(stateMachineId: bigint, height: bigint): HexString { + // First level mapping: keccak256(stateMachineId . STATE_COMMITMENTS_SLOT) + const firstLevelSlot = deriveFirstLevelSlot(stateMachineId, STATE_COMMITMENTS_SLOT) + + // Second level mapping: keccak256(height . firstLevelSlot) + return deriveSecondLevelSlot(height, firstLevelSlot) +} + +function deriveFirstLevelSlot(key: bigint, slot: bigint): HexString { + const keyHex = pad(`0x${key.toString(16)}`, { size: 32 }) + const keyBytes = toBytes(keyHex) + + const slotBytes = toBytes(pad(`0x${slot.toString(16)}`, { size: 32 })) + + const combined = new Uint8Array([...keyBytes, ...slotBytes]) + + return keccak256(combined) +} + +function deriveSecondLevelSlot(key: bigint, firstLevelSlot: HexString): HexString { + const keyHex = pad(`0x${key.toString(16)}`, { size: 32 }) + const keyBytes = toBytes(keyHex) + + const slotBytes = toBytes(firstLevelSlot) + + const combined = new Uint8Array([...keyBytes, ...slotBytes]) + + return keccak256(combined) +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/chains/substrate.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/chains/substrate.ts new file mode 100644 index 00000000..6e2e3a79 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/chains/substrate.ts @@ -0,0 +1,692 @@ +import { ApiPromise, WsProvider } from "@polkadot/api" +import { capitalize } from "lodash-es" +import { Vector, u8 } from "scale-ts" +import { match } from "ts-pattern" +import { bytesToHex, hexToBytes, toBytes, toHex } from "viem" + +import type { IChain, IIsmpMessage, IProof } from "@/chain" +import type { + HexString, + IGetRequest, + IMessage, + IPostRequest, + ISubstrateConfig, + StateMachineHeight, + StateMachineIdParams, +} from "@/types" +import { + BasicProof, + GetRequestsWithProof, + type IStateMachine, + Message, + SubstrateStateProof, + isEvmChain, + isSubstrateChain, + replaceWebsocketWithHttp, +} from "@/utils" +import { ExpectedError } from "@/utils/exceptions" +import { keccakAsU8a } from "@polkadot/util-crypto" + +/** + * HTTP RPC Client for making JSON-RPC calls over HTTP + */ +class HttpRpcClient { + constructor(private readonly url: string) {} + + /** + * Make an RPC call over HTTP + * @param method - The RPC method name + * @param params - The parameters for the RPC call + * @returns Promise resolving to the RPC response + */ + async call(method: string, params: any[] = []): Promise { + const body = JSON.stringify({ + jsonrpc: "2.0", + id: Date.now(), + method, + params, + }) + + const response = await fetch(this.url, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body, + }) + + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`) + } + + const result = await response.json() + + if (result.error) { + throw new Error(`RPC error: ${result.error.message}`) + } + + return result.result + } +} + +export class SubstrateChain implements IChain { + /* + * api: The Polkadot API instance for the Substrate chain. + */ + api?: ApiPromise + private rpcClient: HttpRpcClient + + constructor(private readonly params: ISubstrateConfig) { + const url = this.params.wsUrl + + const httpUrl = replaceWebsocketWithHttp(url) + this.rpcClient = new HttpRpcClient(httpUrl) + } + + get config(): ISubstrateConfig { + return { + wsUrl: this.params.wsUrl, + consensusStateId: this.params.consensusStateId, + hasher: this.params.hasher, + stateMachineId: this.params.stateMachineId, + } + } + + /* + * connect: Connects to the Substrate chain using the provided WebSocket URL. + */ + public async connect() { + const wsProvider = new WsProvider(this.params.wsUrl) + + const typesBundle = + this.params.hasher === "Keccak" + ? { + spec: { + nexus: { + hasher: keccakAsU8a, + }, + gargantua: { + hasher: keccakAsU8a, + }, + }, + } + : {} + this.api = await ApiPromise.create({ + provider: wsProvider, + typesBundle, + }) + } + + /** + * Disconnects the Substrate chain connection. + */ + public async disconnect() { + if (this.api) { + await this.api.disconnect() + this.api = undefined + } + } + + /** + * Returns the storage key for a request receipt in the child trie + * The request commitment is the key + * @param key - The H256 hash key (as a 0x-prefixed hex string) + * @returns The storage key as a hex string + */ + requestReceiptKey(key: HexString): HexString { + const prefix = new TextEncoder().encode("RequestReceipts") + + const keyBytes = hexToBytes(key) + + // Concatenate the prefix and key bytes + return bytesToHex(new Uint8Array([...prefix, ...keyBytes])) + } + + /** + * Returns the storage key for a request commitment in the child trie + * The request commitment is the key + * @param key - The H256 hash key (as a 0x-prefixed hex string) + * @returns The storage key as a hex string + */ + requestCommitmentKey(key: HexString): HexString { + const prefix = new TextEncoder().encode("RequestCommitments") + + const keyBytes = hexToBytes(key) + + // Concatenate the prefix and key bytes + return bytesToHex(new Uint8Array([...prefix, ...keyBytes])) + } + + /** + * Queries a request commitment from the ISMP child trie storage. + * @param {HexString} commitment - The commitment hash to look up. + * @returns {Promise} The commitment data if found, undefined otherwise. + */ + async queryRequestCommitment(commitment: HexString): Promise { + const prefix = toHex(":child_storage:default:ISMP") + const key = this.requestCommitmentKey(commitment) + + const item: any = await this.rpcClient.call("childstate_getStorage", [prefix, key]) + + return item + } + + /** + * Queries the request receipt. + * @param {HexString} commitment - The commitment to query. + * @returns {Promise} The relayer address responsible for delivering the request. + */ + async queryRequestReceipt(commitment: HexString): Promise { + const prefix = toHex(":child_storage:default:ISMP") + const key = this.requestReceiptKey(commitment) + + const item: any = await this.rpcClient.call("childstate_getStorage", [prefix, key]) + + return item + } + + /** + * Returns the current timestamp of the chain. + * @returns {Promise} The current timestamp. + */ + async timestamp(): Promise { + if (!this.api) throw new Error("API not initialized") + + const now = await this.api.query.timestamp.now() + + return BigInt(now.toJSON() as number) / BigInt(1000) + } + + /** + * Queries the proof of the commitments. + * @param {IMessage} message - The message to query. + * @param {string} counterparty - The counterparty address. + * @param {bigint} [at] - The block number to query at. + * @returns {Promise} The proof. + */ + async queryProof(message: IMessage, counterparty: string, at?: bigint): Promise { + if (isEvmChain(counterparty)) { + // for evm chains, query the mmr proof + const proof: any = await this.rpcClient.call("mmr_queryProof", [Number(at), message]) + return toHex(proof.proof) + } + + if (isSubstrateChain(counterparty)) { + // for substrate chains, we use the child trie proof + const childTrieKeys = + "Requests" in message + ? message.Requests.map(requestCommitmentStorageKey) + : message.Responses.map(responseCommitmentStorageKey) + const proof: any = await this.rpcClient.call("ismp_queryChildTrieProof", [Number(at), childTrieKeys]) + const basicProof = BasicProof.dec(toHex(proof.proof)) + const encoded = SubstrateStateProof.enc({ + tag: "OverlayProof", + value: { + hasher: { + tag: this.params.hasher, + value: undefined, + }, + storageProof: basicProof, + }, + }) + return toHex(encoded) + } + + throw new ExpectedError(`Unsupported chain type for counterparty: ${counterparty}`) + } + + /** + * Submit an unsigned ISMP transaction to the chain. Resolves when the transaction is finalized. + * @param message - The message to be submitted. + * @returns A promise that resolves to an object containing the transaction hash, block hash, and block number. + */ + async submitUnsigned(message: IIsmpMessage): Promise<{ + transactionHash: string + blockHash: string + blockNumber: number + timestamp: number + }> { + if (!this.api) throw new Error("API not initialized") + const { api } = this + + const args = encodeISMPMessage(message) + let tx + if (message.kind === "GetRequest") { + tx = api.tx.stateCoprocessor.handleUnsigned(args) + } else { + tx = api.tx.ismp.handleUnsigned(args) + } + + return new Promise((resolve, reject) => { + let unsub = () => {} + + tx.send(async ({ isInBlock, isFinalized, isError, dispatchError, txHash, status }) => { + if (isFinalized || isInBlock) { + unsub() + const blockHash = isInBlock ? status.asInBlock.toHex() : status.asFinalized.toHex() + const header = await api.rpc.chain.getHeader(blockHash) + // Get a decorated api instance at a specific block + const apiAt = await api.at(blockHash) + const timestamp = await apiAt.query.timestamp.now() + resolve({ + transactionHash: txHash.toHex(), + blockHash: blockHash, + blockNumber: header.number.toNumber(), + timestamp: Number(timestamp.toJSON()) / 1000, + }) + } else if (isError) { + unsub() + console.error("Unsigned transaction failed: ", dispatchError) + reject(dispatchError) + } + }) + .then((unsubscribe) => { + unsub = unsubscribe + }) + .catch(reject) + }) + } + + /** + * Query the state proof for a given set of keys at a specific block height. + * @param at The block height to query the state proof at. + * @param keys The keys to query the state proof for. + * @returns The state proof as a hexadecimal string. + */ + async queryStateProof(at: bigint, keys: HexString[]): Promise { + const encodedKeys = keys.map((key) => Array.from(hexToBytes(key))) + const proof: any = await this.rpcClient.call("ismp_queryChildTrieProof", [Number(at), encodedKeys]) + const basicProof = BasicProof.dec(toHex(proof.proof)) + const encoded = SubstrateStateProof.enc({ + tag: "OverlayProof", + value: { + hasher: { + tag: this.params.hasher, + value: undefined, + }, + storageProof: basicProof, + }, + }) + return toHex(encoded) + } + + /** + * Get the latest state machine height for a given state machine ID. + * @param {StateMachineIdParams} stateMachineId - The state machine ID. + * @returns {Promise} The latest state machine height. + */ + async latestStateMachineHeight(stateMachineId: StateMachineIdParams): Promise { + const state_id = convertStateIdToStateMachineId(stateMachineId.stateId) + + const consensusStateIdToBytes = hexToBytes(stateMachineId.consensusStateId) + const decoder = new TextDecoder("utf-8") + const decodedConsensusStateId = decoder.decode(consensusStateIdToBytes) + + const payload = { + state_id, + consensus_state_id: decodedConsensusStateId, + } + + const latestHeight: number = await this.rpcClient.call("ismp_queryStateMachineLatestHeight", [payload]) + return BigInt(latestHeight) + } + + /** + * Get the state machine update time for a given state machine height. + * @param {StateMachineHeight} stateMachineHeight - The state machine height. + * @returns {Promise} The statemachine update time in seconds. + */ + async stateMachineUpdateTime(stateMachineHeight: StateMachineHeight): Promise { + const state_id = convertStateIdToStateMachineId(stateMachineHeight.id.stateId) + + const consensusStateIdToBytes = hexToBytes(stateMachineHeight.id.consensusStateId) + const decoder = new TextDecoder("utf-8") + const decodedConsensusStateId = decoder.decode(consensusStateIdToBytes) + + const stateMachineId = { + state_id, + consensus_state_id: decodedConsensusStateId, + } + + const payload = { + id: stateMachineId, + height: Number(stateMachineHeight.height), + } + + const updateTime: number = await this.rpcClient.call("ismp_queryStateMachineUpdateTime", [payload]) + return BigInt(updateTime) + } + + /** + * Get the challenge period for a given state machine id. + * @param {StateMachineIdParams} stateMachineId - The state machine ID. + * @returns {Promise} The challenge period in seconds. + */ + async challengePeriod(stateMachineId: StateMachineIdParams): Promise { + const state_id = convertStateIdToStateMachineId(stateMachineId.stateId) + + const consensusStateIdToBytes = hexToBytes(stateMachineId.consensusStateId) + const decoder = new TextDecoder("utf-8") + const decodedConsensusStateId = decoder.decode(consensusStateIdToBytes) + + const payload = { + state_id, + consensus_state_id: decodedConsensusStateId, + } + + const challengePeriod: number = await this.rpcClient.call("ismp_queryChallengePeriod", [payload]) + return BigInt(challengePeriod) + } + + /** + * Encode an ISMP calldata for a substrate chain. + * @param message The ISMP message to encode. + * @returns The encoded message as a hexadecimal string. + */ + encode(message: IIsmpMessage): HexString { + const palletIndex = this.getPalletIndex("Ismp") + const args = encodeISMPMessage(message) + + // Encoding the call enum and call index + const call = Vector(u8, 2).enc([palletIndex, 0]) + + return toHex(new Uint8Array([...call, ...args])) + } + + /** + * Returns the index of a pallet by its name, by looking up the pallets in the runtime metadata. + * @param {string} name - The name of the pallet. + * @returns {number} The index of the pallet. + */ + private getPalletIndex(name: string): number { + if (!this.api) throw new Error("API not initialized") + const pallets = this.api.runtimeMetadata.asLatest.pallets.entries() + + for (const p of pallets) { + if (p[1].name.toString() === name) { + const index = p[1].index.toNumber() + + return index + } + } + + throw new Error(`${name} not found in runtime`) + } +} + +function requestCommitmentStorageKey(key: HexString): number[] { + // Convert "RequestCommitments" to bytes + const prefix = new TextEncoder().encode("RequestCommitments") + + // Convert hex key to bytes + const keyBytes = hexToBytes(key) + + // Combine prefix and key bytes + return Array.from(new Uint8Array([...prefix, ...keyBytes])) +} + +function responseCommitmentStorageKey(key: HexString): number[] { + // Convert "ResponseCommitments" to bytes + const prefix = new TextEncoder().encode("ResponseCommitments") + + // Convert hex key to bytes + const keyBytes = hexToBytes(key) + + // Combine prefix and key bytes + return Array.from(new Uint8Array([...prefix, ...keyBytes])) +} + +/** + * Converts a state machine ID string to an enum value. + * @param {string} id - The state machine ID string. + * @returns {IStateMachine} The corresponding enum value. + */ +export function convertStateMachineIdToEnum(id: string): IStateMachine { + let [tag, value]: any = id.split("-") + tag = capitalize(tag) + if (["Evm", "Polkadot", "Kusama"].includes(tag)) { + value = Number.parseInt(value) + } else { + value = Array.from(toBytes(value)) + } + + return { tag, value } +} + +/** + * Converts a state machine enum representation to a string. + * @param {IStateMachine} stateMachine - The state machine enum object. + * @returns {string} The state machine ID string like "EVM-97" or "SUBSTRATE-cere". + */ +export function convertStateMachineEnumToString(stateMachine: { tag: string; value: number | number[] }): string { + const tag = stateMachine.tag.toUpperCase() + if (tag === "EVM" || tag === "POLKADOT" || tag === "KUSAMA") { + return `${tag}-${stateMachine.value}` + } else { + const bytes = new Uint8Array(stateMachine.value as number[]) + const decoder = new TextDecoder("utf-8") + const decoded = decoder.decode(bytes) + return `${tag}-${decoded}` + } +} + +/** + * Converts a stateId object back to the state_id format used by the RPC. + * @param stateId - The stateId object from StateMachineIdParams + * @returns The string representation like "EVM-11155111" or "SUBSTRATE-cere" + */ +export function convertStateIdToStateMachineId(stateId: { + Evm?: number + Substrate?: HexString + Polkadot?: number + Kusama?: number +}): string { + switch (true) { + case stateId.Evm !== undefined: + return `EVM-${stateId.Evm}` + case stateId.Polkadot !== undefined: + return `POLKADOT-${stateId.Polkadot}` + case stateId.Kusama !== undefined: + return `KUSAMA-${stateId.Kusama}` + case stateId.Substrate !== undefined: { + const bytes = hexToBytes(stateId.Substrate as HexString) + const decoder = new TextDecoder("utf-8") + const decoded = decoder.decode(bytes) + return `SUBSTRATE-${decoded}` + } + default: + throw new Error("Unsupported stateId variant") + } +} + +/** + * Converts an array of IPostRequest objects to a codec representation. + * @param {IPostRequest} request - The array of IPostRequest objects. + * @returns The codec representation of the requests. + */ +function convertIPostRequestToCodec(request: IPostRequest) { + return { + tag: "Post", + value: { + source: convertStateMachineIdToEnum(request.source), + dest: convertStateMachineIdToEnum(request.dest), + from: Array.from(hexToBytes(request.from)), + to: Array.from(hexToBytes(request.to)), + nonce: request.nonce, + body: Array.from(hexToBytes(request.body)), + timeoutTimestamp: request.timeoutTimestamp, + }, + } as const +} + +/** + * Converts an IGetRequest object to a codec representation. + * @param {IGetRequest} request - The IGetRequest object. + * @returns The codec representation of the request. + */ +export function convertIGetRequestToCodec(request: IGetRequest) { + return { + source: convertStateMachineIdToEnum(request.source), + dest: convertStateMachineIdToEnum(request.dest), + from: Array.from(hexToBytes(request.from)), + nonce: request.nonce, + keys: request.keys.map((key) => Array.from(hexToBytes(key))), + context: Array.from(hexToBytes(request.context)), + timeoutTimestamp: request.timeoutTimestamp, + height: request.height, + } as const +} + +/** + * Convert codec representation back to IGetRequest + */ +export function convertCodecToIGetRequest(codec: { + source: { tag: string; value: number | number[] } + dest: { tag: string; value: number | number[] } + from: number[] + nonce: bigint + keys: number[][] + height: bigint + context: number[] + timeoutTimestamp: bigint +}): IGetRequest { + return { + source: convertStateMachineEnumToString(codec.source), + dest: convertStateMachineEnumToString(codec.dest), + from: bytesToHex(new Uint8Array(codec.from)) as HexString, + nonce: codec.nonce, + keys: codec.keys.map((key) => bytesToHex(new Uint8Array(key)) as HexString), + height: codec.height, + context: bytesToHex(new Uint8Array(codec.context)) as HexString, + timeoutTimestamp: codec.timeoutTimestamp, + } +} + +/** + * Converts an IProof object to a codec representation. + * @param {IProof} proof - The IProof object. + * @returns The codec representation of the proof. + */ +export function convertIProofToCodec(proof: IProof) { + return { + height: { + height: proof.height, + id: { + consensusStateId: Array.from(toBytes(proof.consensusStateId)), + id: convertStateMachineIdToEnum(proof.stateMachine), + }, + }, + proof: Array.from(hexToBytes(proof.proof)), + } as const +} + +/** + * Converts a codec representation back to an IProof object. + * @param {any} codec - The codec representation of the proof. + * @returns {IProof} The IProof object. + */ +export function convertCodecToIProof(codec: { + height: { + height: bigint + id: { + consensusStateId: number[] + id: { tag: string; value: number | number[] } + } + } + proof: number[] +}): IProof { + const consensusStateIdBytes = new Uint8Array(codec.height.id.consensusStateId) + const decoder = new TextDecoder("utf-8") + const consensusStateId = decoder.decode(consensusStateIdBytes) + + return { + height: codec.height.height, + stateMachine: convertStateMachineEnumToString(codec.height.id.id), + consensusStateId, + proof: bytesToHex(new Uint8Array(codec.proof)) as HexString, + } +} + +export function encodeISMPMessage(message: IIsmpMessage): Uint8Array { + try { + return match(message) + .with({ kind: "PostRequest" }, (message) => { + return Vector(Message).enc([ + { + tag: "RequestMessage", + value: { + requests: message.requests.map( + (post_request) => convertIPostRequestToCodec(post_request).value, + ), + proof: { + height: { + height: message.proof.height, + id: { + consensusStateId: Array.from(toBytes(message.proof.consensusStateId)), + id: convertStateMachineIdToEnum(message.proof.stateMachine), + }, + }, + proof: Array.from(hexToBytes(message.proof.proof)), + }, + signer: Array.from(hexToBytes(message.signer)), + }, + }, + ]) + }) + .with({ kind: "GetResponse" }, (message) => { + throw new Error("GetResponse is not yet supported on Substrate chains") + }) + .with({ kind: "GetRequest" }, (message) => { + return GetRequestsWithProof.enc({ + requests: message.requests.map((request) => convertIGetRequestToCodec(request)), + source: { + height: { + height: message.source.height, + id: { + consensusStateId: Array.from(toBytes(message.source.consensusStateId)), + id: convertStateMachineIdToEnum(message.source.stateMachine), + }, + }, + proof: Array.from(hexToBytes(message.source.proof)), + }, + response: { + height: { + height: message.response.height, + id: { + consensusStateId: Array.from(toBytes(message.response.consensusStateId)), + id: convertStateMachineIdToEnum(message.response.stateMachine), + }, + }, + proof: Array.from(hexToBytes(message.response.proof)), + }, + signer: Array.from(hexToBytes(message.signer)), + }) + }) + .with({ kind: "TimeoutPostRequest" }, (message) => { + return Vector(Message).enc([ + { + tag: "TimeoutMessage", + value: { + tag: "Post", + value: { + requests: message.requests.map((r) => convertIPostRequestToCodec(r)), + proof: { + height: { + height: message.proof.height, + id: { + consensusStateId: Array.from(toBytes(message.proof.consensusStateId)), + id: convertStateMachineIdToEnum(message.proof.stateMachine), + }, + }, + proof: Array.from(hexToBytes(message.proof.proof)), + }, + }, + }, + }, + ]) + }) + .exhaustive() + } catch (error) { + throw new Error("Failed to encode ISMP message", { cause: error }) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/client.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/client.ts new file mode 100644 index 00000000..9ebf04db --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/client.ts @@ -0,0 +1,1946 @@ +import { type ConsolaInstance, LogLevels, createConsola } from "consola" +import { isNil, maxBy } from "lodash-es" +import { pad, toHex } from "viem" + +// @ts-ignore +import mergeRace from "@async-generator/merge-race" + +import type { + AssetTeleported, + AssetTeleportedResponse, + BlockMetadata, + ClientConfig, + GetRequestResponse, + GetRequestWithStatus, + GetResponseByRequestIdResponse, + HexString, + IEvmConfig, + IHyperbridgeConfig, + ISubstrateConfig, + OrderWithStatus, + PostRequestStatus, + PostRequestTimeoutStatus, + PostRequestWithStatus, + RequestStatusKey, + RequestStatusWithMetadata, + ResponseCommitmentWithValues, + RetryConfig, + StateMachineResponse, + StateMachineUpdate, + TimeoutStatusKey, + TokenGatewayAssetTeleportedWithStatus, +} from "@/types" + +import { type IChain, type SubstrateChain, getChain } from "@/chain" +import { + ASSET_TELEPORTED_BY_PARAMS, + GET_RESPONSE_BY_REQUEST_ID, + LATEST_STATE_MACHINE_UPDATE, + STATE_MACHINE_UPDATES_BY_HEIGHT, + STATE_MACHINE_UPDATES_BY_TIMESTAMP, +} from "@/queries" +import { + COMBINED_STATUS_WEIGHTS, + DEFAULT_POLL_INTERVAL, + REQUEST_STATUS_WEIGHTS, + TIMEOUT_STATUS_WEIGHTS, + dateStringtoTimestamp, + parseStateMachineId, + postRequestCommitment, + retryPromise, + sleep, + waitForChallengePeriod, +} from "@/utils" +import { + _queryGetRequestInternal, + _queryOrderInternal, + _queryRequestInternal, + _queryTokenGatewayAssetTeleportedInternal, +} from "./query-client" + +import { OrderStatus, RequestStatus, TeleportStatus, TimeoutStatus } from "@/types" + +import type { IndexerQueryClient } from "@/types" +import { AbortSignalInternal, ExpectedError } from "./utils/exceptions" + +/** + * Helper function to create chain configuration from legacy config format + * This helps migrate from the old config format to the new IChain-based format + * + * @param config - Legacy configuration object (IEvmConfig, ISubstrateConfig, or IHyperbridgeConfig) + * @returns Promise resolving to chain configuration with IChain instance + */ +export async function createChain(config: IEvmConfig | ISubstrateConfig | IHyperbridgeConfig): Promise { + // For hyperbridge config, we need to add the hasher + const chainConfig = "wsUrl" in config && !("hasher" in config) ? { ...config, hasher: "Keccak" as const } : config + + return await getChain(chainConfig as IEvmConfig | ISubstrateConfig) +} + +/** + * Helper function to create IndexerClient with legacy config format + * @deprecated Use the constructor with IChain instances directly for better performance + * + * @param config - Legacy configuration with IEvmConfig/ISubstrateConfig/IHyperbridgeConfig + * @returns Promise resolving to IndexerClient instance + */ +export async function createIndexerClient(config: { + pollInterval?: number + queryClient: IndexerQueryClient + tracing?: boolean + source: IEvmConfig | ISubstrateConfig + dest: IEvmConfig | ISubstrateConfig + hyperbridge: IHyperbridgeConfig +}): Promise { + const [source, dest, hyperbridge] = await Promise.all([ + createChain(config.source), + createChain(config.dest), + createChain(config.hyperbridge), + ]) + + return new IndexerClient({ + pollInterval: config.pollInterval, + queryClient: config.queryClient, + tracing: config.tracing, + source, + dest, + hyperbridge, + }) +} + +/** + * IndexerClient provides methods for interacting with the Hyperbridge indexer. + * + * This client facilitates querying and tracking cross-chain requests and their status + * through the Hyperbridge protocol. It supports: + * + * - Querying state machine updates by block height or timestamp + * - Retrieving request status information by transaction hash + * - Monitoring request status changes through streaming interfaces + * - Handling request timeout flows and related proof generation + * - Tracking request finalization across source and destination chains + * + * The client implements automatic retries with exponential backoff for network + * resilience and provides both simple query methods and advanced streaming + * interfaces for real-time status tracking. + * + * The URLs provided in the configuration must point to archive nodes to allow the client to query for storage proofs + * of potentially much older blocks. Regular nodes only store the state for recent blocks and will not be able + * to provide the necessary proofs for cross-chain verification, especially in timeout scenarios. + * + * @example + * ```typescript + * // New approach: Create IChain instances directly + * const sourceChain = new EvmChain({ + * chainId: 1, + * rpcUrl: "https://eth-rpc.com", + * host: "0x87ea45..", + * consensusStateId: "ETH0" + * }) + * const destChain = new EvmChain({ + * chainId: 42161, + * rpcUrl: "https://arb-rpc.com", + * host: "0x87ea42345..", + * consensusStateId: "ARB0" + * }) + * const hyperbridgeChain = new SubstrateChain({ + * stateMachineId: "POLKADOT-3367", + * wsUrl: "ws://localhost:9944", + * hasher: "Keccak", + * consensusStateId: "DOT0" + * }) + * await hyperbridgeChain.connect() + * + * const client = new IndexerClient({ + * queryClient: queryClient, + * pollInterval: 2000, + * source: sourceChain, + * dest: destChain, + * hyperbridge: hyperbridgeChain + * }); + * + * // Legacy approach: Use the helper function (deprecated) + * const client = await createIndexerClient({ + * queryClient: queryClient, + * pollInterval: 2000, + * source: { + * stateMachineId: "EVM-1", + * consensusStateId: "ETH0", + * rpcUrl: "https://eth-rpc.com", + * host: "0x87ea45.." + * }, + * dest: { + * stateMachineId: "EVM-42161", + * consensusStateId: "ETH0", + * rpcUrl: "https://arb-rpc.com", + * host: "0x87ea42345.." + * }, + * hyperbridge: { + * stateMachineId: "POLKADOT-3367", + * consensusStateId: "DOT0", + * wsUrl: "ws://localhost:9944" + * } + * }); + * + * // Query a request status + * const status = await client.queryRequestWithStatus("0x1234..."); + * + * // Stream status updates + * for await (const update of client.postRequestStatusStream("0x1234...")) { + * console.log(`Request status: ${update.status}`); + * } + * ``` + */ +export class IndexerClient { + /** + * GraphQL client used for making requests to the indexer + */ + private client: IndexerQueryClient + + /** + * Configuration for the IndexerClient including URLs, poll intervals, and chain-specific settings + */ + private config: ClientConfig + + private logger: ConsolaInstance + + /** + * Default configuration for retry behavior when network requests fail + * - maxRetries: Maximum number of retry attempts before failing + * - backoffMs: Initial backoff time in milliseconds (doubles with each retry) + */ + private defaultRetryConfig: RetryConfig = { + maxRetries: 3, + backoffMs: 1000, + } + + /** + * Creates a new IndexerClient instance + */ + constructor(config: PartialClientConfig) { + this.client = config.queryClient + this.config = { + pollInterval: DEFAULT_POLL_INTERVAL, + ...config, + } + this.logger = createConsola({ + level: LogLevels[config.tracing ? "trace" : "info"], + formatOptions: { + columns: 80, + colors: true, + compact: true, + date: false, + }, + }) + } + + /** + * Get the source chain instance + */ + get source(): IChain { + return this.config.source + } + + /** + * Get the destination chain instance + */ + get dest(): IChain { + return this.config.dest + } + + /** + * Get the hyperbridge chain instance + */ + get hyperbridge(): IChain { + return this.config.hyperbridge + } + + /** + * Query for a single state machine update event greater than or equal to the given height. + * @params statemachineId - ID of the state machine + * @params height - Starting block height + * @params chain - The identifier for the chain where the state machine update should be queried (corresponds to a stateMachineId) + * @returns Closest state machine update + */ + async queryStateMachineUpdateByHeight({ + statemachineId, + height, + chain, + }: { + statemachineId: string + chain: string + height: number + }): Promise { + const logger = this.logger.withTag("[queryStateMachineUpdateByHeight]()") + const message = `querying StateMachineId(${statemachineId}) update by Height(${height}) in chain Chain(${chain})` + + const response = await this.withRetry( + () => { + return this.client.request(STATE_MACHINE_UPDATES_BY_HEIGHT, { + statemachineId, + height, + chain, + }) + }, + { logger: logger, logMessage: message }, + ) + + const first_node = response?.stateMachineUpdateEvents?.nodes[0] + if (first_node?.createdAt) { + //@ts-ignore + first_node.timestamp = Math.floor(dateStringtoTimestamp(first_node.createdAt) / 1000) + } + logger.trace("Response >", first_node) + + //@ts-ignore + return first_node + } + + /** + * Query for a single state machine update event greater than or equal to the given timestamp. + * @params statemachineId - ID of the state machine + * @params timestamp - Starting block timestamp + * @params chain - The identifier for the chain where the state machine update should be queried (corresponds to a stateMachineId) + * @returns Closest state machine update + */ + async queryStateMachineUpdateByTimestamp({ + statemachineId, + commitmentTimestamp, + chain, + }: { + statemachineId: string + commitmentTimestamp: bigint + chain: string + }): Promise { + const logger = this.logger.withTag("[queryStateMachineUpdateByTimestamp]") + const message = `querying StateMachineId(${statemachineId}) update by Timestamp(${commitmentTimestamp}) in Chain(${chain})` + + const response = await this.withRetry( + () => + this.client.request(STATE_MACHINE_UPDATES_BY_TIMESTAMP, { + statemachineId, + commitmentTimestamp: commitmentTimestamp.toString(), + chain, + }), + { logger, logMessage: message }, + ) + + const first_node = response?.stateMachineUpdateEvents?.nodes[0] + if (first_node?.createdAt) { + //@ts-ignore + first_node.timestamp = Math.floor(dateStringtoTimestamp(first_node.createdAt) / 1000) + } + logger.trace("Response >", first_node) + + //@ts-ignore + return first_node + } + + /** + * Query for the latest state machine update height + * @params statemachineId - ID of the state machine + * @params chain - The identifier for the chain where the state machine update should be queried (corresponds to a stateMachineId) + * @returns Latest height or undefined if no updates found + */ + async queryLatestStateMachineHeight({ + statemachineId, + chain, + }: { + statemachineId: string + chain: string + }): Promise { + const logger = this.logger.withTag("[queryLatestStateMachineHeight]()") + const message = `querying latest StateMachineId(${statemachineId}) height in chain Chain(${chain})` + + const response = await this.withRetry( + () => { + return this.client.request(LATEST_STATE_MACHINE_UPDATE, { + statemachineId, + chain, + }) + }, + { logger: logger, logMessage: message }, + ) + + const first_node = response?.stateMachineUpdateEvents?.nodes[0] + if (!first_node) return undefined + + logger.trace("Latest height >", first_node.height) + return BigInt(first_node.height) + } + + /** + * Queries a request by CommitmentHash + * + * @param commitment_hash - Can be commitment + * @returns Latest status and block metadata of the request + */ + async queryPostRequest(commitment_hash: HexString): Promise { + return _queryRequestInternal({ + commitmentHash: commitment_hash, + queryClient: this.client, + logger: this.logger, + }) + } + + /** + * Queries a request by any of its associated hashes and returns it alongside its statuses + * Statuses will be one of SOURCE, HYPERBRIDGE_DELIVERED and DESTINATION + * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash + * @returns Latest status and block metadata of the request + */ + async queryGetRequest(hash: HexString): Promise { + return _queryGetRequestInternal({ + commitmentHash: hash, + queryClient: this.client, + logger: this.logger, + }) + } + + /** + * Queries the response associated with a specific request ID and returns its commitment + * @param requestId - The ID of the request to find the associated response for + * @returns The response associated with the given request ID, or undefined if not found + */ + async queryResponseByRequestId(requestId: string): Promise { + const response = await this.withRetry(() => + this.client.request(GET_RESPONSE_BY_REQUEST_ID, { + requestId, + }), + ) + + // If no responses are found or nodes array is empty, return undefined + if (!response.getResponses.nodes.length) return undefined + + // Return just the first response + const firstResponse = response.getResponses.nodes[0] + + return { + commitment: firstResponse.commitment, + values: firstResponse.responseMessage, + } + } + + /** + * Enhances a request with finality events by querying state machine updates. + * + * This method augments a request object with additional inferred status events + * that represent chain finality confirmations. It adds: + * - SOURCE_FINALIZED: When the source chain has finalized the request + * - HYPERBRIDGE_FINALIZED: When Hyperbridge has finalized the delivery confirmation + * + * The method also generates appropriate calldata for submitting cross-chain proofs + * when applicable. + * + * @param request - The request to enhance with finality events + * @returns The request with finality events added + * @private + */ + private async addRequestFinalityEvents(request: PostRequestWithStatus): Promise { + const events: RequestStatusWithMetadata[] = [] + + const addFinalityEvents = (request: PostRequestWithStatus) => { + this.logger.trace(`Added ${events.length} \`Request\` finality events`, events) + + request.statuses = [...request.statuses, ...events] + return request + } + + let hyperbridgeDelivered: RequestStatusWithMetadata | undefined + + if (request.source === this.config.hyperbridge.config.stateMachineId) { + // the first status contains the blocknumber of the initial request + hyperbridgeDelivered = request.statuses[0] + } else { + // we assume there's always a SOURCE event which contains the blocknumber of the initial request + const sourceFinality = await this.queryStateMachineUpdateByHeight({ + statemachineId: request.source, + height: request.statuses[0].metadata.blockNumber, + chain: this.config.hyperbridge.config.stateMachineId, + }) + + // no finality event found, return request as is + if (!sourceFinality) return addFinalityEvents(request) + + // Insert finality event into request.statuses at index 1 + events.push({ + status: RequestStatus.SOURCE_FINALIZED, + metadata: { + blockHash: sourceFinality.blockHash, + blockNumber: sourceFinality.height, + transactionHash: sourceFinality.transactionHash, + timestamp: sourceFinality.timestamp, + }, + }) + + // check if there's a hyperbridge delivered event + hyperbridgeDelivered = request.statuses.find((item) => item.status === RequestStatus.HYPERBRIDGE_DELIVERED) + + if (!hyperbridgeDelivered) return addFinalityEvents(request) + } + + // no need to query finality event if destination is hyperbridge + if (request.dest === this.config.hyperbridge.config.stateMachineId) { + return addFinalityEvents(request) + } + + const hyperbridgeFinality = await this.queryStateMachineUpdateByHeight({ + statemachineId: this.config.hyperbridge.config.stateMachineId, + height: hyperbridgeDelivered.metadata.blockNumber, + chain: request.dest, + }) + + if (!hyperbridgeFinality) return addFinalityEvents(request) + + // check if request receipt exists on destination chain + const destChain = this.config.dest + const hyperbridge = this.config.hyperbridge + + const proof = await hyperbridge.queryProof( + { Requests: [postRequestCommitment(request).commitment] }, + request.dest, + BigInt(hyperbridgeFinality.height), + ) + + const calldata = destChain.encode({ + kind: "PostRequest", + proof: { + stateMachine: this.config.hyperbridge.config.stateMachineId, + consensusStateId: this.config.hyperbridge.config.consensusStateId, + proof, + height: BigInt(hyperbridgeFinality.height), + }, + requests: [request], + signer: pad("0x"), + }) + + events.push({ + status: RequestStatus.HYPERBRIDGE_FINALIZED, + metadata: { + blockHash: hyperbridgeFinality.blockHash, + blockNumber: hyperbridgeFinality.height, + transactionHash: hyperbridgeFinality.transactionHash, + timestamp: hyperbridgeFinality.timestamp, + calldata, + }, + }) + + return addFinalityEvents(request) + } + + /** + * Adds timeout finality events to a request by querying for relevant timeout proofs and + * chain state necessary for timeout processing. + * + * This method enhances a request object with additional status events related to the + * timeout flow, including: + * - PENDING_TIMEOUT: When a request has passed its timeout timestamp + * - DESTINATION_FINALIZED: When the destination chain has finalized the timeout timestamp + * - HYPERBRIDGE_FINALIZED_TIMEOUT: When hyperbridge has finalized the timeout state + * + * The method also generates appropriate calldata for submitting timeout proofs. + * + * @param request - Request to fill timeout events for + * @returns Request with timeout events filled in, including any proof calldata for timeout submissions + * @private + */ + private async addTimeoutFinalityEvents(request: PostRequestWithStatus): Promise { + // check if request receipt exists on destination chain + const destChain = this.config.dest + const hyperbridge = this.config.hyperbridge + const events: RequestStatusWithMetadata[] = [] + const commitment = postRequestCommitment(request).commitment + const reciept = await destChain.queryRequestReceipt(commitment) + const destTimestamp = await destChain.timestamp() + + const addTimeoutEvents = (req: PostRequestWithStatus) => { + this.logger.trace(`Added ${events.length} timeout events`, events) + request.statuses = [...req.statuses, ...events] + return request + } + + if (request.timeoutTimestamp === 0n) { + // Early exit for requests with no timeout configured + // This prevents unnecessary timeout processing and expensive chain queries + // The events array is still empty at this point, so no timeout events are added + return addTimeoutEvents(request) + } + + // request not timed out + if (reciept || request.timeoutTimestamp > destTimestamp) { + return addTimeoutEvents(request) + } + + const is_finished = request.statuses.find((item) => item.status === RequestStatus.DESTINATION) + + if (!is_finished) { + events.push({ + status: TimeoutStatus.PENDING_TIMEOUT, + metadata: { blockHash: "0x", blockNumber: 0, transactionHash: "0x" }, + }) + } + + const delivered = request.statuses.find((item) => { + return item.status === RequestStatus.HYPERBRIDGE_DELIVERED + }) + + let hyperbridgeFinalized: StateMachineUpdate | undefined + if (!delivered) { + // either the request was never delivered to hyperbridge + // or hyperbridge was the destination of the request + hyperbridgeFinalized = await this.queryStateMachineUpdateByTimestamp({ + statemachineId: this.config.hyperbridge.config.stateMachineId, + commitmentTimestamp: request.timeoutTimestamp, + chain: request.source, + }) + } else { + const destFinalized = await this.queryStateMachineUpdateByTimestamp({ + statemachineId: request.dest, + commitmentTimestamp: request.timeoutTimestamp, + chain: this.config.hyperbridge.config.stateMachineId, + }) + + if (!destFinalized) return addTimeoutEvents(request) + + events.push({ + status: TimeoutStatus.DESTINATION_FINALIZED_TIMEOUT, + metadata: { + blockHash: destFinalized.blockHash, + blockNumber: destFinalized.blockNumber, + transactionHash: destFinalized.transactionHash, + timestamp: destFinalized.timestamp, + }, + }) + + // if the source is the hyperbridge state machine, no further action is needed + // use the timeout stream to timeout on hyperbridge + if (request.source === this.config.hyperbridge.config.stateMachineId) return request + + const hyperbridgeTimedOut = request.statuses.find( + (item) => item.status === TimeoutStatus.HYPERBRIDGE_TIMED_OUT, + ) + if (!hyperbridgeTimedOut) return addTimeoutEvents(request) + hyperbridgeFinalized = await this.queryStateMachineUpdateByHeight({ + statemachineId: this.config.hyperbridge.config.stateMachineId, + height: hyperbridgeTimedOut.metadata.blockNumber, + chain: request.source, + }) + } + + if (!hyperbridgeFinalized) return addTimeoutEvents(request) + + const proof = await hyperbridge.queryStateProof(BigInt(hyperbridgeFinalized.height), [ + hyperbridge.requestReceiptKey(commitment), + ]) + const sourceChain = this.config.source + const calldata = sourceChain.encode({ + kind: "TimeoutPostRequest", + proof: { + proof, + height: BigInt(hyperbridgeFinalized.height), + stateMachine: this.config.hyperbridge.config.stateMachineId, + consensusStateId: this.config.hyperbridge.config.consensusStateId, + }, + requests: [ + { + source: request.source, + dest: request.dest, + from: request.from, + to: request.to, + nonce: request.nonce, + body: request.body, + timeoutTimestamp: request.timeoutTimestamp, + }, + ], + }) + + events.push({ + status: TimeoutStatus.HYPERBRIDGE_FINALIZED_TIMEOUT, + metadata: { + blockHash: hyperbridgeFinalized.blockHash, + blockNumber: hyperbridgeFinalized.blockNumber, + transactionHash: hyperbridgeFinalized.transactionHash, + timestamp: hyperbridgeFinalized.timestamp, + calldata, + }, + }) + + return addTimeoutEvents(request) + } + + /** + * Queries a request returns it alongside its statuses, + * including any finalization events. + * @param hash - Commitment hash + * @returns Full request data with all inferred status events, including SOURCE_FINALIZED and HYPERBRIDGE_FINALIZED + * @remarks Unlike queryRequest(), this method adds derived finalization status events by querying state machine updates + */ + async queryRequestWithStatus(hash: HexString): Promise { + let request = await this.queryPostRequest(hash) + + if (!request) return + request = await this.addRequestFinalityEvents(request) + request = await this.addTimeoutFinalityEvents(request) + + // ensure all statuses are sorted by weight + request.statuses = request.statuses.sort( + (a, b) => COMBINED_STATUS_WEIGHTS[a.status] - COMBINED_STATUS_WEIGHTS[b.status], + ) + + return request + } + + /** + * Queries a GET request and returns it alongside its statuses, + * including any finalization events. + * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash + * @returns Full GET request data with all inferred status events, including SOURCE_FINALIZED and HYPERBRIDGE_FINALIZED + * @remarks Unlike queryGetRequest(), this method adds derived finalization status events by querying state machine updates + */ + async queryGetRequestWithStatus(hash: HexString): Promise { + let request = await this.queryGetRequest(hash) + + if (!request) return + + request = await this.addGetRequestFinalityEvents(request) + + request.statuses = request.statuses.sort( + (a, b) => COMBINED_STATUS_WEIGHTS[a.status] - COMBINED_STATUS_WEIGHTS[b.status], + ) + + return request + } + + /** + * Enhances a GET request with finality events by querying state machine updates. + * + * This method augments a GET request object with additional inferred status events + * that represent chain finality confirmations. It adds: + * - SOURCE_FINALIZED: When the source chain has finalized the request + * - HYPERBRIDGE_FINALIZED: When Hyperbridge has finalized the delivery confirmation and response is ready + * + * The method also generates appropriate calldata for submitting cross-chain proofs + * when applicable. + * + * @param request - The GET request to enhance with finality events + * @returns The request with finality events added + * @private + */ + private async addGetRequestFinalityEvents(request: GetRequestWithStatus): Promise { + const events: RequestStatusWithMetadata[] = [] + + const addFinalityEvents = (request: GetRequestWithStatus) => { + this.logger.trace(`Added ${events.length} \`GetRequest\` finality events`, events) + + request.statuses = [...request.statuses, ...events] + return request + } + + let hyperbridgeDelivered: RequestStatusWithMetadata | undefined + + if (request.source === this.config.hyperbridge.config.stateMachineId) { + hyperbridgeDelivered = request.statuses[0] + return addFinalityEvents(request) + } else { + const sourceFinality = await this.queryStateMachineUpdateByHeight({ + statemachineId: request.source, + height: request.statuses[0].metadata.blockNumber, + chain: this.config.hyperbridge.config.stateMachineId, + }) + + if (!sourceFinality) return addFinalityEvents(request) + + events.push({ + status: RequestStatus.SOURCE_FINALIZED, + metadata: { + blockHash: sourceFinality.blockHash, + blockNumber: sourceFinality.height, + transactionHash: sourceFinality.transactionHash, + timestamp: sourceFinality.timestamp, + }, + }) + + hyperbridgeDelivered = request.statuses.find((item) => item.status === RequestStatus.HYPERBRIDGE_DELIVERED) + + if (!hyperbridgeDelivered) return addFinalityEvents(request) + } + + const hyperbridgeFinality = await this.queryStateMachineUpdateByHeight({ + statemachineId: this.config.hyperbridge.config.stateMachineId, + height: hyperbridgeDelivered.metadata.blockNumber, + chain: request.source, + }) + + if (!hyperbridgeFinality) return addFinalityEvents(request) + + const sourceChain = this.config.source + const hyperbridge = this.config.hyperbridge + + try { + const response = await this.queryResponseByRequestId(request.commitment) + + if (!response) return addFinalityEvents(request) + + const proof = await hyperbridge.queryProof( + { Responses: [response.commitment as HexString] }, + request.source, + BigInt(hyperbridgeFinality.height), + ) + + const calldata = sourceChain.encode({ + kind: "GetResponse", + proof: { + stateMachine: this.config.hyperbridge.config.stateMachineId, + consensusStateId: this.config.hyperbridge.config.consensusStateId, + proof, + height: BigInt(hyperbridgeFinality.height), + }, + responses: [ + { + get: request, + values: request.keys.map((key, index) => ({ + key, + value: (response.values[index] as HexString) || "0x", + })), + }, + ], + signer: pad("0x"), + }) + + events.push({ + status: RequestStatus.HYPERBRIDGE_FINALIZED, + metadata: { + blockHash: hyperbridgeFinality.blockHash, + blockNumber: hyperbridgeFinality.height, + transactionHash: hyperbridgeFinality.transactionHash, + timestamp: hyperbridgeFinality.timestamp, + calldata, + }, + }) + } catch (error) { + this.logger.trace("Could not generate HYPERBRIDGE_FINALIZED event for GET request:", error) + } + + return addFinalityEvents(request) + } + + /** + * Create a Stream of status updates for a post request. + * Stream ends when either the request reaches the destination or times out. + * If the stream yields TimeoutStatus.PENDING_TIMEOUT, use postRequestTimeoutStream() to begin timeout processing. + * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash + * @returns AsyncGenerator that emits status updates until a terminal state is reached + * @example + * + * let client = new IndexerClient(config) + * let stream = client.postRequestStatusStream(hash) + * + * // you can use a for-await-of loop + * for await (const status of stream) { + * console.log(status) + * } + * + * // you can also use a while loop + * while (true) { + * const status = await stream.next() + * if (status.done) { + * break + * } + * console.log(status.value) + * } + * + */ + async *postRequestStatusStream(hash: HexString): AsyncGenerator { + const controller = new AbortController() + const logger = this.logger.withTag("[postRequestStatusStream]") + + try { + const request = await this.waitOrAbort({ + signal: controller.signal, + promise: () => this.queryPostRequest(hash), + }) + + logger.trace("`Request` found") + const chain = this.config.dest + const timeoutStream = + request.timeoutTimestamp > 0n ? this.timeoutStream(request.timeoutTimestamp, chain) : undefined + const statusStream = this.postRequestStatusStreamInternal(hash, controller.signal) + + logger.trace("Listening for events") + const combined = timeoutStream ? mergeRace(timeoutStream, statusStream) : statusStream + + logger.trace("Listening for events") + let item = await combined.next() + + while (!item.done) { + logger.trace(`Yielding Event(${item.value.status})`) + + yield item.value + item = await combined.next() + } + + logger.trace("Streaming complete") + } catch (error) { + if (!AbortSignalInternal.isError(error)) { + throw error + } + } + controller.abort() + return + } + + /* + * Returns a generator that will yield true if the request is timed out + * If the request does not have a timeout, it will never yield + * @param request - Request to timeout + */ + async *timeoutStream(timeoutTimestamp: bigint, chain: IChain): AsyncGenerator { + const logger = this.logger.withTag("[timeoutStream()]") + + if (timeoutTimestamp > 0n) { + let timestamp = await chain.timestamp() + + while (timestamp < timeoutTimestamp) { + logger.trace("Comparing timeout timestamps", { control: timeoutTimestamp, latest: timestamp }) + + const diff = BigInt(timeoutTimestamp) - BigInt(timestamp) + await this.sleep_for(Number(diff)) + timestamp = await chain.timestamp() + } + + yield { + status: TimeoutStatus.PENDING_TIMEOUT, + metadata: { blockHash: "0x", blockNumber: 0, transactionHash: "0x" }, + } + + return + } + } + + /** + * Create a Stream of status updates + * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash + * @returns AsyncGenerator that emits status updates until a terminal state is reached + */ + private async *postRequestStatusStreamInternal( + hash: HexString, + signal: AbortSignal, + ): AsyncGenerator { + let request = await this.waitOrAbort({ signal, promise: () => this.queryPostRequest(hash) }) + + let status: RequestStatusKey = + request.source === this.config.hyperbridge.config.stateMachineId + ? RequestStatus.HYPERBRIDGE_DELIVERED + : RequestStatus.SOURCE + + const latestMetadata = request.statuses[request.statuses.length - 1] + + const latest_request = maxBy( + [status, latestMetadata.status as RequestStatusKey], + (item) => REQUEST_STATUS_WEIGHTS[item], + ) + + if (!latest_request) return + + // start with the latest status + status = latest_request + + while (true) { + switch (status) { + // request has been dispatched from source chain + case RequestStatus.SOURCE: { + const sourceUpdate = await this.waitOrAbort({ + signal, + promise: () => + this.queryStateMachineUpdateByHeight({ + statemachineId: request.source, + height: request.statuses[0].metadata.blockNumber, + chain: this.config.hyperbridge.config.stateMachineId, + }), + }) + + yield { + status: RequestStatus.SOURCE_FINALIZED, + metadata: { + blockHash: sourceUpdate.blockHash, + blockNumber: sourceUpdate.height, + transactionHash: sourceUpdate.transactionHash, + timestamp: sourceUpdate.timestamp, + }, + } + + status = RequestStatus.SOURCE_FINALIZED + break + } + + // finality proofs for request has been verified on Hyperbridge + case RequestStatus.SOURCE_FINALIZED: { + // wait for the request to be delivered on Hyperbridge + request = await this.waitOrAbort({ + signal, + promise: () => this.queryPostRequest(hash), + predicate: (request) => !request || request.statuses.length < 2, + }) + + status = + request.dest === this.config.hyperbridge.config.stateMachineId + ? RequestStatus.DESTINATION + : RequestStatus.HYPERBRIDGE_DELIVERED + + yield { + status, + metadata: { + blockHash: request.statuses[1].metadata.blockHash, + blockNumber: request.statuses[1].metadata.blockNumber, + transactionHash: request.statuses[1].metadata.transactionHash, + // @ts-ignore + timestamp: request.statuses[1].metadata.timestamp, + }, + } + break + } + + // the request has been verified and aggregated on Hyperbridge + case RequestStatus.HYPERBRIDGE_DELIVERED: { + // Get the latest state machine update for hyperbridge on the destination chain + const hyperbridgeFinalized = await this.waitOrAbort({ + signal, + promise: () => { + const stateMachineId = this.config.hyperbridge.config.stateMachineId + const index = request.source === stateMachineId ? 0 : 1 + + return this.queryStateMachineUpdateByHeight({ + statemachineId: stateMachineId, + height: request.statuses[index].metadata.blockNumber, + chain: request.dest, + }) + }, + }) + + const destChain = this.config.dest + const hyperbridge = this.config.hyperbridge + + const safeFetchProof = async () => { + try { + const proof_hex = await hyperbridge.queryProof( + { Requests: [postRequestCommitment(request).commitment] }, + request.dest, + BigInt(hyperbridgeFinalized.height), + ) + return { data: proof_hex, error: null } + } catch (err) { + return { error: err as unknown, data: null } + } + } + + const proof = await this.waitOrAbort({ + signal, + promise: () => + this.withRetry(safeFetchProof, { + backoffMs: 2000, + maxRetries: 6, // <-- should fail after 2mins + }), + }) + + if (proof.data === null) { + this.logger.error("Failed to fetch proof:", proof.error) + + throw proof.error + } + + const calldata = destChain.encode({ + kind: "PostRequest", + proof: { + stateMachine: this.config.hyperbridge.config.stateMachineId, + consensusStateId: this.config.hyperbridge.config.consensusStateId, + proof: proof.data, + height: BigInt(hyperbridgeFinalized.height), + }, + requests: [request], + signer: pad("0x"), + }) + + const { stateId } = parseStateMachineId(this.config.hyperbridge.config.stateMachineId) + + await waitForChallengePeriod(destChain, { + height: BigInt(hyperbridgeFinalized.height), + id: { + stateId, + consensusStateId: toHex(this.config.hyperbridge.config.consensusStateId), + }, + }) + + yield { + status: RequestStatus.HYPERBRIDGE_FINALIZED, + metadata: { + blockHash: hyperbridgeFinalized.blockHash, + blockNumber: hyperbridgeFinalized.height, + transactionHash: hyperbridgeFinalized.transactionHash, + timestamp: hyperbridgeFinalized.timestamp, + calldata, + }, + } + status = RequestStatus.HYPERBRIDGE_FINALIZED + break + } + + // request has been finalized by hyperbridge + case RequestStatus.HYPERBRIDGE_FINALIZED: { + // wait for the request to be delivered to the destination + request = await this.waitOrAbort({ + signal, + promise: () => this.queryPostRequest(hash), + predicate: (request) => + !request || !request.statuses.find((s) => s.status === RequestStatus.DESTINATION), + }) + + const index = request.source === this.config.hyperbridge.config.stateMachineId ? 1 : 2 + + yield { + status: RequestStatus.DESTINATION, + metadata: { + blockHash: request.statuses[index].metadata.blockHash, + blockNumber: request.statuses[index].metadata.blockNumber, + transactionHash: request.statuses[index].metadata.transactionHash, + // @ts-ignore + timestamp: request.statuses[index].metadata.timestamp, + }, + } + status = RequestStatus.DESTINATION + break + } + + case RequestStatus.DESTINATION: + return + } + } + } + + private sleep_for(duration: number): Promise { + this.logger.trace(`Sleeping for ${duration}ms`) + return sleep(duration) + } + + private sleep_for_interval(): Promise { + return this.sleep_for(this.config.pollInterval) + } + + /** + * Create a Stream of status updates for a get request. + * Stream ends when either the request reaches the destination or times out. + * If the stream yields TimeoutStatus.PENDING_TIMEOUT, use postRequestTimeoutStream() to begin timeout processing. + * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash + * @returns AsyncGenerator that emits status updates until a terminal state is reached + * @example + * + * let client = new IndexerClient(config) + * let stream = client.getRequestStatusStream(hash) + * + * // you can use a for-await-of loop + * for await (const status of stream) { + * console.log(status) + * } + * + * // you can also use a while loop + * while (true) { + * const status = await stream.next() + * if (status.done) { + * break + * } + * console.log(status.value) + * } + * + */ + async *getRequestStatusStream(hash: HexString): AsyncGenerator { + const controller = new AbortController() + // wait for request to be created + try { + const request = await this.waitOrAbort({ + signal: controller.signal, + promise: () => this.queryGetRequest(hash), + }) + + const chain = this.config.dest + const timeoutStream = + request.timeoutTimestamp > 0n ? this.timeoutStream(request.timeoutTimestamp, chain) : undefined + const statusStream = this.getRequestStatusStreamInternal(hash, controller.signal) + const combined = timeoutStream ? mergeRace(timeoutStream, statusStream) : statusStream + + let item = await combined.next() + while (!item.done) { + yield item.value + item = await combined.next() + } + } catch (error) { + if (!AbortSignalInternal.isError(error)) { + throw error + } + } + controller.abort() + return + } + + /** + * Create a Stream of status updates + * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash + * @returns AsyncGenerator that emits status updates until a terminal state is reached + */ + private async *getRequestStatusStreamInternal( + hash: HexString, + signal: AbortSignal, + ): AsyncGenerator { + let request = await this.waitOrAbort({ signal, promise: () => this.queryGetRequest(hash) }) + + let status: RequestStatusKey | undefined = + request.source === this.config.hyperbridge.config.stateMachineId + ? RequestStatus.HYPERBRIDGE_DELIVERED + : RequestStatus.SOURCE + + const latestMetadata = request.statuses[request.statuses.length - 1] + + // start with the latest status + status = maxBy([status, latestMetadata.status as RequestStatusKey], (item) => REQUEST_STATUS_WEIGHTS[item]) + + if (!status) return + + while (true) { + switch (status) { + // request has been dispatched from source chain + case RequestStatus.SOURCE: { + const sourceUpdate = await this.waitOrAbort({ + signal, + promise: () => + this.queryStateMachineUpdateByHeight({ + statemachineId: request.source, + height: request.statuses[0].metadata.blockNumber, + chain: this.config.hyperbridge.config.stateMachineId, + }), + }) + + yield { + status: RequestStatus.SOURCE_FINALIZED, + metadata: { + blockHash: sourceUpdate.blockHash, + blockNumber: sourceUpdate.height, + transactionHash: sourceUpdate.transactionHash, + timestamp: sourceUpdate.timestamp, + }, + } + status = RequestStatus.SOURCE_FINALIZED + break + } + + // finality proofs for request has been verified on Hyperbridge + case RequestStatus.SOURCE_FINALIZED: { + // wait for the request to be delivered on Hyperbridge + request = await this.waitOrAbort({ + signal, + promise: () => this.queryGetRequest(hash), + predicate: (request) => !request || request.statuses.length < 2, + }) + + status = + request.source === this.config.hyperbridge.config.stateMachineId + ? RequestStatus.DESTINATION + : RequestStatus.HYPERBRIDGE_DELIVERED + + yield { + status, + metadata: { + blockHash: request.statuses[1].metadata.blockHash, + blockNumber: request.statuses[1].metadata.blockNumber, + transactionHash: request.statuses[1].metadata.transactionHash, + // @ts-ignore + timestamp: request.statuses[1].metadata.timestamp, + }, + } + break + } + + // the request has been verified and aggregated on Hyperbridge + case RequestStatus.HYPERBRIDGE_DELIVERED: { + // If Hyperbridge was the source, the request is already complete + if (request.source === this.config.hyperbridge.config.stateMachineId) { + return + } + // Get the latest state machine update for hyperbridge on the destination chain + const hyperbridgeFinalized = await this.waitOrAbort({ + signal, + promise: () => + this.queryStateMachineUpdateByHeight({ + statemachineId: this.config.hyperbridge.config.stateMachineId, + height: request.statuses[1].metadata.blockNumber, + chain: request.source, + }), + }) + + const sourceChain = this.config.source + const hyperbridge = this.config.hyperbridge + + const response = await this.queryResponseByRequestId(hash) + + const proof = await hyperbridge.queryProof( + { Responses: [response?.commitment as HexString] }, + request.source, + BigInt(hyperbridgeFinalized.height), + ) + + const calldata = sourceChain.encode({ + kind: "GetResponse", + proof: { + stateMachine: this.config.hyperbridge.config.stateMachineId, + consensusStateId: this.config.hyperbridge.config.consensusStateId, + proof, + height: BigInt(hyperbridgeFinalized.height), + }, + responses: [ + { + get: request, + values: request.keys.map((key, index) => ({ + key, + value: (response?.values[index] as HexString) || "0x", + })), + }, + ], + signer: pad("0x"), + }) + + yield { + status: RequestStatus.HYPERBRIDGE_FINALIZED, + metadata: { + blockHash: hyperbridgeFinalized.blockHash, + blockNumber: hyperbridgeFinalized.height, + transactionHash: hyperbridgeFinalized.transactionHash, + timestamp: hyperbridgeFinalized.timestamp, + calldata, + }, + } + status = RequestStatus.HYPERBRIDGE_FINALIZED + break + } + + // request has been finalized by hyperbridge + case RequestStatus.HYPERBRIDGE_FINALIZED: { + // If Hyperbridge was the source, the request is already complete + if (request.source === this.config.hyperbridge.config.stateMachineId) { + return + } + + // wait for the request to be delivered to the destination + request = await this.waitOrAbort({ + signal, + promise: () => this.queryGetRequest(hash), + predicate: (request) => + !request || !request.statuses.find((s) => s.status === RequestStatus.DESTINATION), + }) + + yield { + status: RequestStatus.DESTINATION, + metadata: { + blockHash: request.statuses[2].metadata.blockHash, + blockNumber: request.statuses[2].metadata.blockNumber, + transactionHash: request.statuses[2].metadata.transactionHash, + //@ts-ignore + timestamp: request.statuses[2].metadata.timestamp, + }, + } + status = RequestStatus.DESTINATION + break + } + + case RequestStatus.DESTINATION: + return + } + } + } + + /** + * Create a Stream of status updates for a timed out post request. + * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash + * @returns AsyncGenerator that emits status updates until a terminal state is reached + * @example + * + * let client = new IndexerClient(config) + * let stream = client.postRequestTimeoutStream(hash) + * + * // you can use a for-await-of loop + * for await (const status of stream) { + * console.log(status) + * } + * + * // you can also use a while loop + * while (true) { + * const status = await stream.next() + * if (status.done) { + * break + * } + * console.log(status.value) + * } + */ + async *postRequestTimeoutStream(hash: HexString): AsyncGenerator { + const controller = new AbortController() + const logger = this.logger.withTag("[postRequestTimeoutStream]") + + try { + const request = await this.queryPostRequest(hash) + if (!request) throw new Error("Request not found") + + logger.trace("`Request` found") + const timeoutStream = this.postRequestTimeoutStreamInternal(hash, controller.signal) + + logger.trace("Listening for timeout events") + let item = await timeoutStream.next() + while (!item.done) { + logger.trace(`Yielding Timeout Event(${item.value.status})`) + + yield item.value + item = await timeoutStream.next() + } + + logger.trace("Streaming complete") + } catch (error) { + if (!AbortSignalInternal.isError(error)) { + throw error + } + } + controller.abort() + return + } + + /** + * Create a Stream of status updates for a timed out post request. + * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash + * @returns AsyncGenerator that emits status updates until a terminal state is reached + */ + async *postRequestTimeoutStreamInternal( + hash: HexString, + signal: AbortSignal, + ): AsyncGenerator { + const request = await this.waitOrAbort({ + signal, + promise: () => this.queryPostRequest(hash), + }) + + const destChain = this.config.dest + + // if the destination is hyperbridge, then just wait for hyperbridge finality + let status: TimeoutStatusKey = + request.dest === this.config.hyperbridge.config.stateMachineId + ? TimeoutStatus.HYPERBRIDGE_TIMED_OUT + : TimeoutStatus.PENDING_TIMEOUT + + const commitment = postRequestCommitment(request).commitment + const hyperbridge = this.config.hyperbridge as SubstrateChain + + const latest = request.statuses[request.statuses.length - 1] + const latest_request = maxBy( + [status, latest.status as TimeoutStatusKey], + (item: TimeoutStatusKey) => TIMEOUT_STATUS_WEIGHTS[item], + ) + + if (!latest_request) { + return + } + + // we're always interested in the latest status + status = latest_request + + while (true) { + switch (status) { + case TimeoutStatus.PENDING_TIMEOUT: { + const receipt = await hyperbridge.queryRequestReceipt(commitment) + if (!receipt && request.source !== this.config.hyperbridge.config.stateMachineId) { + status = TimeoutStatus.HYPERBRIDGE_TIMED_OUT + break + } + + const update = await this.waitOrAbort({ + signal, + promise: () => + this.queryStateMachineUpdateByTimestamp({ + statemachineId: request.dest, + commitmentTimestamp: request.timeoutTimestamp, + chain: this.config.hyperbridge.config.stateMachineId, + }), + }) + + yield { + status: TimeoutStatus.DESTINATION_FINALIZED_TIMEOUT, + metadata: { + blockHash: update.blockHash, + blockNumber: update.height, + transactionHash: update.transactionHash, + timestamp: update.timestamp, + }, + } + status = TimeoutStatus.DESTINATION_FINALIZED_TIMEOUT + break + } + + case TimeoutStatus.DESTINATION_FINALIZED_TIMEOUT: { + if (request.source !== this.config.hyperbridge.config.stateMachineId) { + const receipt = await hyperbridge.queryRequestReceipt(commitment) + if (!receipt) { + status = TimeoutStatus.HYPERBRIDGE_TIMED_OUT + break + } + } + + const update = (await this.queryStateMachineUpdateByTimestamp({ + statemachineId: request.dest, + commitmentTimestamp: request.timeoutTimestamp, + chain: this.config.hyperbridge.config.stateMachineId, + }))! + + const proof = await destChain.queryStateProof(BigInt(update.height), [ + destChain.requestReceiptKey(commitment), + ]) + + const { stateId } = parseStateMachineId(request.dest) + + await waitForChallengePeriod(hyperbridge, { + height: BigInt(update.height), + id: { + stateId, + consensusStateId: toHex(this.config.dest.config.consensusStateId), + }, + }) + + const { blockHash, transactionHash, blockNumber, timestamp } = await hyperbridge.submitUnsigned({ + kind: "TimeoutPostRequest", + proof: { + proof, + height: BigInt(update.height), + stateMachine: request.dest, + consensusStateId: this.config.dest.config.consensusStateId, + }, + requests: [ + { + source: request.source, + dest: request.dest, + from: request.from, + to: request.to, + nonce: request.nonce, + body: request.body, + timeoutTimestamp: request.timeoutTimestamp, + }, + ], + }) + + status = + request.source === this.config.hyperbridge.config.stateMachineId + ? TimeoutStatus.TIMED_OUT + : TimeoutStatus.HYPERBRIDGE_TIMED_OUT + + yield { + status, + metadata: { + blockHash, + transactionHash, + blockNumber, + timestamp, + }, + } + break + } + + case TimeoutStatus.HYPERBRIDGE_TIMED_OUT: { + const hasDelivered = request.statuses.some( + (item) => item.status === RequestStatus.HYPERBRIDGE_DELIVERED, + ) + let update: StateMachineUpdate | undefined + if (!hasDelivered) { + // if request was never delivered to Hyperbridge + // then query for any state machine update > requestTimestamp + update = await this.waitOrAbort({ + signal, + promise: () => + this.queryStateMachineUpdateByTimestamp({ + statemachineId: this.config.hyperbridge.config.stateMachineId, + commitmentTimestamp: request.timeoutTimestamp, + chain: request.source, + }), + }) + } else { + const timeout = await this.waitOrAbort({ + signal, + promise: async () => { + const req = await this.queryPostRequest(hash) + return req?.statuses + .sort( + (a, b) => COMBINED_STATUS_WEIGHTS[a.status] - COMBINED_STATUS_WEIGHTS[b.status], + ) + .pop() + }, + predicate: (timeout) => !timeout || timeout?.status !== TimeoutStatus.HYPERBRIDGE_TIMED_OUT, + }) + + update = await this.waitOrAbort({ + signal, + promise: async () => + this.queryStateMachineUpdateByHeight({ + statemachineId: this.config.hyperbridge.config.stateMachineId, + height: timeout.metadata.blockNumber, + chain: request.source, + }), + }) + } + + const proof = await hyperbridge.queryStateProof(BigInt(update.height), [ + hyperbridge.requestReceiptKey(commitment), + ]) + + const sourceChain = this.config.source + const calldata = sourceChain.encode({ + kind: "TimeoutPostRequest", + proof: { + proof, + height: BigInt(update.height), + stateMachine: this.config.hyperbridge.config.stateMachineId, + consensusStateId: this.config.hyperbridge.config.consensusStateId, + }, + requests: [ + { + source: request.source, + dest: request.dest, + from: request.from, + to: request.to, + nonce: request.nonce, + body: request.body, + timeoutTimestamp: request.timeoutTimestamp, + }, + ], + }) + + const { stateId } = parseStateMachineId(this.config.hyperbridge.config.stateMachineId) + + await waitForChallengePeriod(sourceChain, { + height: BigInt(update.height), + id: { + stateId, + consensusStateId: toHex(this.config.hyperbridge.config.consensusStateId), + }, + }) + + yield { + status: TimeoutStatus.HYPERBRIDGE_FINALIZED_TIMEOUT, + metadata: { + transactionHash: update.transactionHash, + blockNumber: update.blockNumber, + blockHash: update.blockHash, + timestamp: update.timestamp, + calldata, + }, + } + status = TimeoutStatus.HYPERBRIDGE_FINALIZED_TIMEOUT + break + } + + case TimeoutStatus.HYPERBRIDGE_FINALIZED_TIMEOUT: { + // wait for the request to be timed out on the source + const delivered = await this.waitOrAbort({ + signal, + promise: async () => { + const req = await this.queryPostRequest(hash) + return req?.statuses.find((s) => s.status === RequestStatus.TIMED_OUT) + }, + }) + yield { + status: TimeoutStatus.TIMED_OUT, + metadata: { + transactionHash: delivered.metadata.transactionHash, + blockNumber: delivered.metadata.blockNumber, + blockHash: delivered.metadata.blockHash, + timestamp: delivered.metadata.timestamp, + }, + } + status = TimeoutStatus.TIMED_OUT + break + } + + case TimeoutStatus.TIMED_OUT: + return + } + } + } + + /** + * Executes an async operation with exponential backoff retry + * @param operation - Async function to execute + * @param retryConfig - Optional retry configuration + * @returns Result of the operation + * @throws Last encountered error after all retries are exhausted + * + * @example + * const result = await this.withRetry(() => this.queryStatus(hash)); + */ + private async withRetry(operation: () => Promise, retryConfig: Partial = {}): Promise { + return retryPromise(operation, { + ...this.defaultRetryConfig, + ...retryConfig, + }) + } + + /** + * Query for an order by its commitment hash + * @param commitment - The commitment hash of the order + * @returns The order with its status if found, undefined otherwise + */ + async queryOrder(commitment: HexString): Promise { + return _queryOrderInternal({ + commitmentHash: commitment, + queryClient: this.client, + logger: this.logger, + }) + } + + /** + * Create a Stream of status updates for an order. + * Stream ends when the order reaches a terminal state (FILLED, REDEEMED, or REFUNDED). + * @param commitment - The commitment hash of the order + * @returns AsyncGenerator that emits status updates until a terminal state is reached + * @example + * + * let client = new IndexerClient(config) + * let stream = client.orderStatusStream(commitment) + * + * // you can use a for-await-of loop + * for await (const status of stream) { + * console.log(status) + * } + * + * // you can also use a while loop + * while (true) { + * const status = await stream.next() + * if (status.done) { + * break + * } + * console.log(status.value) + * } + */ + async *orderStatusStream(commitment: HexString): AsyncGenerator< + { + status: OrderStatus + metadata: { + blockHash: string + blockNumber: number + transactionHash: string + timestamp: bigint + filler?: string + } + }, + void + > { + const logger = this.logger.withTag("[orderStatusStream]") + + let order: OrderWithStatus | undefined + + while (!order) { + await this.sleep_for_interval() + order = await _queryOrderInternal({ + commitmentHash: commitment, + queryClient: this.client, + logger: this.logger, + }) + } + + logger.trace("`Order` found") + // Yield initial status + const latestStatus = order.statuses[order.statuses.length - 1] + yield { + status: latestStatus.status, + metadata: latestStatus.metadata, + } + + // If we're already in a terminal state, end the stream + if ([OrderStatus.FILLED, OrderStatus.REDEEMED, OrderStatus.REFUNDED].includes(latestStatus.status)) { + return + } + + while (true) { + await this.sleep_for_interval() + const updatedOrder = await _queryOrderInternal({ + commitmentHash: commitment, + queryClient: this.client, + logger: this.logger, + }) + + if (!updatedOrder) continue + + const newLatestStatus = updatedOrder.statuses[updatedOrder.statuses.length - 1] + + if (newLatestStatus.status !== latestStatus.status) { + yield { + status: newLatestStatus.status, + metadata: newLatestStatus.metadata, + } + + if ([OrderStatus.FILLED, OrderStatus.REDEEMED, OrderStatus.REFUNDED].includes(newLatestStatus.status)) { + return + } + } + } + } + + async *tokenGatewayAssetTeleportedStatusStream(commitment: HexString): AsyncGenerator< + { + status: TeleportStatus + metadata: { + blockHash: string + blockNumber: number + transactionHash: string + timestamp: bigint + } + }, + void + > { + const logger = this.logger.withTag("[tokenGatewayAssetTeleportedStatusStream]") + logger.trace(`Starting stream for token gateway asset teleported with commitment ${commitment}`) + + let lastStatus: TeleportStatus | undefined + let lastBlockNumber: number | undefined + + while (true) { + try { + const teleport = await this.queryTokenGatewayAssetTeleported(commitment) + if (!teleport) { + logger.trace("No teleport found, waiting...") + await this.sleep_for_interval() + continue + } + + const statuses = teleport.statuses + if (statuses.length === 0) { + logger.trace("No statuses found, waiting...") + await this.sleep_for_interval() + continue + } + + // Find the latest status that we haven't seen yet + const latestStatus = statuses[statuses.length - 1] + if (lastStatus === latestStatus.status && lastBlockNumber === latestStatus.metadata.blockNumber) { + logger.trace("No new status, waiting...") + await this.sleep_for_interval() + continue + } + + lastStatus = latestStatus.status + lastBlockNumber = latestStatus.metadata.blockNumber + + yield latestStatus + + // If we've reached a final status, end the stream + if ( + latestStatus.status === TeleportStatus.RECEIVED || + latestStatus.status === TeleportStatus.REFUNDED + ) { + logger.trace("Final status reached, ending stream") + break + } + + await this.sleep_for_interval() + } catch (error) { + logger.error("Error in token gateway asset teleported status stream:", error) + await this.sleep_for_interval() + } + } + } + + private async queryTokenGatewayAssetTeleported( + commitment: HexString, + ): Promise { + return _queryTokenGatewayAssetTeleportedInternal({ + commitmentHash: commitment, + queryClient: this.client, + logger: this.logger, + }) + } + + /** + * Aggregate transactions with commitment. + * @param commitment + * @returns an object containing the transaction hash, block hash, block number, timestamp. + */ + async aggregateTransactionWithCommitment( + commitment: HexString, + ): Promise>> { + const logger = this.logger.withTag("aggregateTransactionWithCommitment") + + const { stateMachineId, consensusStateId } = this.config.source.config + + // check if request receipt exists on source chain + const sourceChain = this.config.source + const hyperbridge = this.config.hyperbridge as SubstrateChain + + logger.trace("Querying post request with commitment hash") + const request = await this.queryPostRequest(commitment) + if (!request) throw new Error("Request not found") + + logger.trace("Fetch latest stateMachineHeight") + const latestStateMachineHeight = await hyperbridge.latestStateMachineHeight({ + stateId: parseStateMachineId(stateMachineId).stateId, + consensusStateId: consensusStateId as HexString, + }) + + logger.trace("Query Request Proof from sourceChain") + const proof = await sourceChain.queryProof( + { Requests: [commitment] }, + this.config.hyperbridge.config.stateMachineId, + latestStateMachineHeight, + ) + + logger.trace("Construct Extrinsic and Submit Unsigned") + const calldata = await hyperbridge.submitUnsigned({ + kind: "PostRequest", + proof: { + stateMachine: this.config.source.config.stateMachineId, + consensusStateId: this.config.source.config.consensusStateId, + proof, + height: BigInt(latestStateMachineHeight), + }, + requests: [ + { + source: request.source, + dest: request.dest, + from: request.from, + to: request.to, + nonce: request.nonce, + body: request.body, + timeoutTimestamp: request.timeoutTimestamp, + }, + ], + signer: pad("0x"), + }) + + return calldata + } + + async waitOrAbort(params: { + signal: AbortSignal + promise: () => Promise + predicate?: (a: T) => boolean + }): Promise> { + const { predicate = (e) => isNil(e) } = params + + const _abort = () => { + if (params.signal.aborted) { + throw new AbortSignalInternal("Terminated request in 'waitOrAbort'") + } + } + + while (true) { + _abort() + await this.sleep_for_interval() + _abort() + const _data = await params.promise() + _abort() + + if (predicate(_data)) continue + return _data as NonNullable + } + } +} + +interface PartialClientConfig extends Omit { + pollInterval?: number +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/configs/ChainConfigService.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/configs/ChainConfigService.ts new file mode 100644 index 00000000..1971adae --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/configs/ChainConfigService.ts @@ -0,0 +1,111 @@ +import { toHex } from "viem" +import type { ChainConfig, HexString } from "@/types" +import { + addresses, + assets, + chainIds, + consensusStateIds, + coingeckoIds, + Chains, + WrappedNativeDecimals, + createRpcUrls, +} from "@/configs/chain" + +export class ChainConfigService { + private rpcUrls: Record + + constructor(env: NodeJS.ProcessEnv = process.env) { + this.rpcUrls = createRpcUrls(env) + } + + getChainConfig(chain: string): ChainConfig { + return { + chainId: chainIds[chain as keyof typeof chainIds], + rpcUrl: this.rpcUrls[chain as Chains], + intentGatewayAddress: addresses.IntentGateway[chain as keyof typeof addresses.IntentGateway]!, + } + } + + getIntentGatewayAddress(chain: string): `0x${string}` { + return addresses.IntentGateway[chain as keyof typeof addresses.IntentGateway]! as `0x${string}` + } + + getHostAddress(chain: string): `0x${string}` { + return addresses.Host[chain as keyof typeof addresses.Host]! as `0x${string}` + } + + getWrappedNativeAssetWithDecimals(chain: string): { asset: HexString; decimals: number } { + return { + asset: assets[chain as keyof typeof assets].WETH as HexString, + decimals: WrappedNativeDecimals[chain as keyof typeof WrappedNativeDecimals], + } + } + + getDaiAsset(chain: string): HexString { + return assets[chain as keyof typeof assets].DAI as HexString + } + + getUsdtAsset(chain: string): HexString { + return assets[chain as keyof typeof assets].USDT as HexString + } + + getUsdcAsset(chain: string): HexString { + return assets[chain as keyof typeof assets].USDC as HexString + } + + getChainId(chain: string): number { + return chainIds[chain as keyof typeof chainIds] + } + + getConsensusStateId(chain: string): HexString { + return toHex(consensusStateIds[chain as keyof typeof consensusStateIds]) + } + + getHyperbridgeChainId(): number { + return chainIds[Chains.HYPERBRIDGE_GARGANTUA] + } + + getRpcUrl(chain: string): string { + return this.rpcUrls[chain as Chains] + } + + getUniswapRouterV2Address(chain: string): HexString { + return addresses.UniswapRouter02[chain as keyof typeof addresses.UniswapRouter02]! as HexString + } + + getUniswapV2FactoryAddress(chain: string): HexString { + return addresses.UniswapV2Factory[chain as keyof typeof addresses.UniswapV2Factory]! as HexString + } + + getUniswapV3FactoryAddress(chain: string): HexString { + return addresses.UniswapV3Factory[chain as keyof typeof addresses.UniswapV3Factory]! as HexString + } + + getUniversalRouterAddress(chain: string): HexString { + return addresses.UniversalRouter[chain as keyof typeof addresses.UniversalRouter]! as HexString + } + + getUniswapV3QuoterAddress(chain: string): HexString { + return addresses.UniswapV3Quoter[chain as keyof typeof addresses.UniswapV3Quoter]! as HexString + } + + getUniswapV4QuoterAddress(chain: string): HexString { + return addresses.UniswapV4Quoter[chain as keyof typeof addresses.UniswapV4Quoter]! as HexString + } + + getPermit2Address(chain: string): HexString { + return addresses.Permit2[chain as keyof typeof addresses.Permit2]! as HexString + } + + getCoingeckoId(chain: string): string | undefined { + return coingeckoIds[chain as keyof typeof coingeckoIds] + } + + getEtherscanApiKey(): string | undefined { + return typeof process !== "undefined" ? (process as any)?.env?.ETHERSCAN_API_KEY : undefined + } + + getCalldispatcherAddress(chain: string): HexString { + return addresses.Calldispatcher[chain as keyof typeof addresses.Calldispatcher]! as HexString + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/configs/chain.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/configs/chain.ts new file mode 100644 index 00000000..25035721 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/configs/chain.ts @@ -0,0 +1,309 @@ +import { Chain, bscTestnet, gnosisChiado, sepolia, mainnet, bsc, base, arbitrum, polygon, unichain } from "viem/chains" + +export enum Chains { + BSC_CHAPEL = "EVM-97", + GNOSIS_CHIADO = "EVM-10200", + HYPERBRIDGE_GARGANTUA = "KUSAMA-4009", + SEPOLIA = "EVM-11155111", + MAINNET = "EVM-1", + BSC_MAINNET = "EVM-56", + ARBITRUM_MAINNET = "EVM-42161", + BASE_MAINNET = "EVM-8453", + POLYGON_MAINNET = "EVM-137", + UNICHAIN_MAINNET = "EVM-130", +} + +type AddressMap = { + [key: string]: { + [K in Chains]?: `0x${string}` + } +} + +type RpcMap = Record + +export const chainIds = { + [Chains.BSC_CHAPEL]: 97, + [Chains.GNOSIS_CHIADO]: 10200, + [Chains.HYPERBRIDGE_GARGANTUA]: 4009, + [Chains.SEPOLIA]: 11155111, + [Chains.MAINNET]: 1, + [Chains.BSC_MAINNET]: 56, + [Chains.ARBITRUM_MAINNET]: 42161, + [Chains.BASE_MAINNET]: 8453, + [Chains.POLYGON_MAINNET]: 137, + [Chains.UNICHAIN_MAINNET]: 130, +} as const + +export type ChainId = typeof chainIds + +export const viemChains: Record = { + "97": bscTestnet, + "10200": gnosisChiado, + "11155111": sepolia, + "1": mainnet, + "56": bsc, + "42161": arbitrum, + "8453": base, + "137": polygon, + "130": unichain, +} + +export const WrappedNativeDecimals = { + [Chains.BSC_CHAPEL]: 18, + [Chains.GNOSIS_CHIADO]: 18, + [Chains.SEPOLIA]: 18, + [Chains.MAINNET]: 18, + [Chains.BSC_MAINNET]: 18, + [Chains.ARBITRUM_MAINNET]: 18, + [Chains.BASE_MAINNET]: 18, + [Chains.POLYGON_MAINNET]: 18, + [Chains.UNICHAIN_MAINNET]: 18, +} + +export const assets = { + [Chains.BSC_CHAPEL]: { + WETH: "0xae13d989dac2f0debff460ac112a837c89baa7cd".toLowerCase(), + DAI: "0x1938165569A5463327fb206bE06d8D9253aa06b7".toLowerCase(), + USDC: "0xC625ec7D30A4b1AAEfb1304610CdAcD0d606aC92".toLowerCase(), + USDT: "0xc043f483373072f7f27420d6e7d7ad269c018e18".toLowerCase(), + }, + [Chains.GNOSIS_CHIADO]: { + WETH: "0x0000000000000000000000000000000000000000".toLowerCase(), + DAI: "0x50B1d3c7c073c9caa1Ef207365A2c9C976bD70b9".toLowerCase(), + USDC: "0x0000000000000000000000000000000000000000".toLowerCase(), + USDT: "0x0000000000000000000000000000000000000000".toLowerCase(), + }, + [Chains.SEPOLIA]: { + WETH: "0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9".toLowerCase(), + USDC: "0x0000000000000000000000000000000000000000".toLowerCase(), + USDT: "0x0000000000000000000000000000000000000000".toLowerCase(), + DAI: "0x0000000000000000000000000000000000000000".toLowerCase(), + }, + [Chains.MAINNET]: { + WETH: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2".toLowerCase(), + DAI: "0x6B175474E89094C44Da98b954EedeAC495271d0F".toLowerCase(), + USDC: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48".toLowerCase(), + USDT: "0xdAC17F958D2ee523a2206206994597C13D831ec7".toLowerCase(), + }, + [Chains.BSC_MAINNET]: { + WETH: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c".toLowerCase(), + DAI: "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3".toLowerCase(), + USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d".toLowerCase(), + USDT: "0x55d398326f99059fF775485246999027B3197955".toLowerCase(), + }, + [Chains.ARBITRUM_MAINNET]: { + WETH: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1".toLowerCase(), + DAI: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1".toLowerCase(), + USDC: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831".toLowerCase(), + USDT: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9".toLowerCase(), + }, + [Chains.BASE_MAINNET]: { + WETH: "0x4200000000000000000000000000000000000006".toLowerCase(), + DAI: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb".toLowerCase(), + USDC: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913".toLowerCase(), + USDT: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2".toLowerCase(), + }, + [Chains.POLYGON_MAINNET]: { + WETH: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270".toLowerCase(), + DAI: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063".toLowerCase(), + USDC: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359".toLowerCase(), + USDT: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F".toLowerCase(), + }, + [Chains.UNICHAIN_MAINNET]: { + WETH: "0x4200000000000000000000000000000000000006".toLowerCase(), + DAI: "0x0000000000000000000000000000000000000000".toLowerCase(), + USDC: "0x078d782b760474a361dda0af3839290b0ef57ad6".toLowerCase(), + USDT: "0x9151434b16b9763660705744891fa906f660ecc5".toLowerCase(), + }, +} + +export const addresses: AddressMap = { + IntentGateway: { + [Chains.BSC_CHAPEL]: "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509", + [Chains.GNOSIS_CHIADO]: "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509", + [Chains.SEPOLIA]: "0x016b6ffC9f890d1e28f9Fdb9eaDA776b02F89509", + [Chains.MAINNET]: "0x1a4ee689a004b10210a1df9f24a387ea13359acf", + [Chains.BSC_MAINNET]: "0x1a4ee689a004b10210a1df9f24a387ea13359acf", + [Chains.ARBITRUM_MAINNET]: "0x1a4ee689a004b10210a1df9f24a387ea13359acf", + [Chains.BASE_MAINNET]: "0x1a4ee689a004b10210a1df9f24a387ea13359acf", + [Chains.POLYGON_MAINNET]: "0x1a4ee689a004b10210a1df9f24a387ea13359acf", + [Chains.UNICHAIN_MAINNET]: "0x1a4ee689a004b10210a1df9f24a387ea13359acf", + }, + Host: { + [Chains.BSC_CHAPEL]: "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7", + [Chains.GNOSIS_CHIADO]: "0x58a41b89f4871725e5d898d98ef4bf917601c5eb", + [Chains.SEPOLIA]: "0x2EdB74C269948b60ec1000040E104cef0eABaae8", + [Chains.MAINNET]: "0x792A6236AF69787C40cF76b69B4c8c7B28c4cA20", + [Chains.BSC_MAINNET]: "0x24B5d421Ec373FcA57325dd2F0C074009Af021F7", + [Chains.ARBITRUM_MAINNET]: "0xE05AFD4Eb2ce6d65c40e1048381BD0Ef8b4B299e", + [Chains.BASE_MAINNET]: "0x6FFe92e4d7a9D589549644544780e6725E84b248", + [Chains.POLYGON_MAINNET]: "0xD8d3db17C1dF65b301D45C84405CcAC1395C559a", + [Chains.UNICHAIN_MAINNET]: "0x2A17C1c3616Bbc33FCe5aF5B965F166ba76cEDAf", + }, + UniswapRouter02: { + [Chains.BSC_CHAPEL]: "0x9639379819420704457B07A0C33B678D9E0F8Df0", + [Chains.GNOSIS_CHIADO]: "0x0000000000000000000000000000000000000000", + [Chains.SEPOLIA]: "0x0000000000000000000000000000000000000000", + [Chains.MAINNET]: "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D", + [Chains.BSC_MAINNET]: "0x10ED43C718714eb63d5aA57B78B54704E256024E", + [Chains.ARBITRUM_MAINNET]: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24", + [Chains.BASE_MAINNET]: "0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24", + [Chains.POLYGON_MAINNET]: "0xd2f9496824951D5237cC71245D659E48d0d5f9E8", + [Chains.UNICHAIN_MAINNET]: "0x284f11109359a7e1306c3e447ef14d38400063ff", + }, + UniswapV2Factory: { + [Chains.BSC_CHAPEL]: "0x12e036669DA18F4A2777853d6e2136b32AceEC86", + [Chains.GNOSIS_CHIADO]: "0x0000000000000000000000000000000000000000", + [Chains.SEPOLIA]: "0x0000000000000000000000000000000000000000", + [Chains.MAINNET]: "0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f", + [Chains.BSC_MAINNET]: "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73", + [Chains.ARBITRUM_MAINNET]: "0xf1D7CC64Fb4452F05c498126312eBE29f30Fbcf9", + [Chains.BASE_MAINNET]: "0x8909Dc15e40173Ff4699343b6eB8132c65e18eC6", + [Chains.POLYGON_MAINNET]: "0x5757371414417b8C6CAad45bAeF941aBc7d3Ab32", + [Chains.UNICHAIN_MAINNET]: "0x1F98400000000000000000000000000000000002", + }, + UniswapV3Factory: { + [Chains.BSC_CHAPEL]: "0x0000000000000000000000000000000000000000", + [Chains.GNOSIS_CHIADO]: "0x0000000000000000000000000000000000000000", + [Chains.SEPOLIA]: "0x0000000000000000000000000000000000000000", + [Chains.MAINNET]: "0x1F98431c8aD98523631AE4a59f267346ea31F984", + [Chains.BSC_MAINNET]: "0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865", + [Chains.ARBITRUM_MAINNET]: "0x1F98431c8aD98523631AE4a59f267346ea31F984", + [Chains.BASE_MAINNET]: "0x33128a8fC17869897dcE68Ed026d694621f6FDfD", + [Chains.POLYGON_MAINNET]: "0x1F98431c8aD98523631AE4a59f267346ea31F984", + [Chains.UNICHAIN_MAINNET]: "0x1F98431c8aD98523631AE4a59f267346ea31F984", + }, + UniversalRouter: { + [Chains.BSC_CHAPEL]: "0xcc6d5ece3d4a57245bf5a2f64f3ed9179b81f714", + [Chains.MAINNET]: "0x66a9893cc07d91d95644aedd05d03f95e1dba8af", + [Chains.BSC_MAINNET]: "0xd9C500DfF816a1Da21A48A732d3498Bf09dc9AEB", + [Chains.ARBITRUM_MAINNET]: "0xa51afafe0263b40edaef0df8781ea9aa03e381a3", + [Chains.BASE_MAINNET]: "0x6ff5693b99212da76ad316178a184ab56d299b43", + [Chains.POLYGON_MAINNET]: "0x1095692a6237d83c6a72f3f5efedb9a670c49223", + [Chains.UNICHAIN_MAINNET]: "0xef740bf23acae26f6492b10de645d6b98dc8eaf3", + }, + UniswapV3Quoter: { + [Chains.BSC_CHAPEL]: "0x0000000000000000000000000000000000000000", + [Chains.MAINNET]: "0x61fFE014bA17989E743c5F6cB21bF9697530B21e", + [Chains.BSC_MAINNET]: "0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997", + [Chains.ARBITRUM_MAINNET]: "0x61fFE014bA17989E743c5F6cB21bF9697530B21e", + [Chains.BASE_MAINNET]: "0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a", + [Chains.POLYGON_MAINNET]: "0x61fFE014bA17989E743c5F6cB21bF9697530B21e", + [Chains.UNICHAIN_MAINNET]: "0x385a5cf5f83e99f7bb2852b6a19c3538b9fa7658", + }, + UniswapV4Quoter: { + [Chains.BSC_CHAPEL]: "0x0000000000000000000000000000000000000000", + [Chains.MAINNET]: "0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203", + [Chains.BSC_MAINNET]: "0xd0737C9762912dD34c3271197E362Aa736Df0926", + [Chains.ARBITRUM_MAINNET]: "0x3972c00f7ed4885e145823eb7c655375d275a1c5", + [Chains.BASE_MAINNET]: "0x0d5e0f971ed27fbff6c2837bf31316121532048d", + [Chains.POLYGON_MAINNET]: "0xb3d5c3dfc3a7aebff71895a7191796bffc2c81b9", + [Chains.UNICHAIN_MAINNET]: "0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203", + }, + Calldispatcher: { + [Chains.SEPOLIA]: "0xC7f13b6D03A0A7F3239d38897503E90553ABe155", + [Chains.MAINNET]: "0xc71251c8b3e7b02697a84363eef6dce8dfbdf333", + [Chains.BSC_MAINNET]: "0xc71251c8b3e7b02697a84363eef6dce8dfbdf333", + [Chains.ARBITRUM_MAINNET]: "0xc71251c8b3e7b02697a84363eef6dce8dfbdf333", + [Chains.BASE_MAINNET]: "0xc71251c8b3e7b02697a84363eef6dce8dfbdf333", + [Chains.POLYGON_MAINNET]: "0xc71251c8b3e7b02697a84363eef6dce8dfbdf333", + [Chains.UNICHAIN_MAINNET]: "0xc71251c8b3e7b02697a84363eef6dce8dfbdf333", + }, + Permit2: { + [Chains.MAINNET]: "0x000000000022D473030F116dDEE9F6B43aC78BA3", + [Chains.BSC_MAINNET]: "0x000000000022D473030F116dDEE9F6B43aC78BA3", + [Chains.ARBITRUM_MAINNET]: "0x000000000022D473030F116dDEE9F6B43aC78BA3", + [Chains.BASE_MAINNET]: "0x000000000022D473030F116dDEE9F6B43aC78BA3", + [Chains.POLYGON_MAINNET]: "0x000000000022D473030F116dDEE9F6B43aC78BA3", + [Chains.UNICHAIN_MAINNET]: "0x000000000022D473030F116dDEE9F6B43aC78BA3", + }, +} + +export const createRpcUrls = (env: NodeJS.ProcessEnv): RpcMap => ({ + [Chains.BSC_CHAPEL]: env.BSC_CHAPEL || "https://bnb-testnet.api.onfinality.io/public", + [Chains.GNOSIS_CHIADO]: env.GNOSIS_CHIADO || "https://gnosis-chiado-rpc.publicnode.com", + [Chains.HYPERBRIDGE_GARGANTUA]: env.HYPERBRIDGE_GARGANTUA || "", + [Chains.SEPOLIA]: env.SEPOLIA || "https://1rpc.io/sepolia", + [Chains.MAINNET]: env.ETH_MAINNET || "https://eth-mainnet.g.alchemy.com/v2/demo", + [Chains.BSC_MAINNET]: env.BSC_MAINNET || "https://binance.llamarpc.com", + [Chains.ARBITRUM_MAINNET]: env.ARBITRUM_MAINNET || "https://arbitrum-one.public.blastapi.io", + [Chains.BASE_MAINNET]: env.BASE_MAINNET || "https://base-mainnet.public.blastapi.io", + [Chains.POLYGON_MAINNET]: env.POLYGON_MAINNET || "https://polygon-bor-rpc.publicnode.com", + [Chains.UNICHAIN_MAINNET]: env.UNICHAIN_MAINNET || "https://unichain.api.onfinality.io/public", +}) + +export const consensusStateIds = { + [Chains.BSC_CHAPEL]: "BSC0", + [Chains.GNOSIS_CHIADO]: "GNO0", + [Chains.HYPERBRIDGE_GARGANTUA]: "PAS0", + [Chains.SEPOLIA]: "ETH0", + [Chains.MAINNET]: "ETH0", + [Chains.BSC_MAINNET]: "BSC0", + [Chains.ARBITRUM_MAINNET]: "ETH0", + [Chains.BASE_MAINNET]: "ETH0", + [Chains.POLYGON_MAINNET]: "POLY", + [Chains.UNICHAIN_MAINNET]: "ETH0", +} + +export const coingeckoIds = { + [Chains.BSC_CHAPEL]: "binance-smart-chain", + [Chains.GNOSIS_CHIADO]: "gnosis", + [Chains.HYPERBRIDGE_GARGANTUA]: "hyperbridge", + [Chains.SEPOLIA]: "ethereum", + [Chains.MAINNET]: "ethereum", + [Chains.BSC_MAINNET]: "binance-smart-chain", + [Chains.ARBITRUM_MAINNET]: "arbitrum-one", + [Chains.BASE_MAINNET]: "base", + [Chains.POLYGON_MAINNET]: "polygon-pos", + [Chains.UNICHAIN_MAINNET]: "ethereum", +} + +export const popularTokens = { + [Chains.BSC_CHAPEL]: [ + "0xae13d989dac2f0debff460ac112a837c89baa7cd", + "0xC625ec7D30A4b1AAEfb1304610CdAcD0d606aC92", + "0xc043f483373072f7f27420d6e7d7ad269c018e18", + "0x1938165569A5463327fb206bE06d8D9253aa06b7", + ], + [Chains.GNOSIS_CHIADO]: ["0x50B1d3c7c073c9caa1Ef207365A2c9C976bD70b9"], + [Chains.SEPOLIA]: ["0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9"], + [Chains.MAINNET]: [ + "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", + "0xdAC17F958D2ee523a2206206994597C13D831ec7", + "0x6B175474E89094C44Da98b954EedeAC495271d0F", + ], + [Chains.BSC_MAINNET]: [ + "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82", + "0x000Ae314E2A2172a039B26378814C252734f556A", + "0x8d0d000ee44948fc98c9b98a4fa4921476f08b0d", + "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c", + "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d", + "0x55d398326f99059fF775485246999027B3197955", + "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3", + ], + [Chains.ARBITRUM_MAINNET]: [ + "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", + "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", + "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", + "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", + ], + [Chains.BASE_MAINNET]: [ + "0x4200000000000000000000000000000000000006", + "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2", + "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb", + ], + [Chains.POLYGON_MAINNET]: [ + "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270", + "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", + "0xc2132D05D31c914a87C6611C10748AEb04B58e8F", + "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063", + ], + [Chains.UNICHAIN_MAINNET]: [ + "0x4200000000000000000000000000000000000006", + "0x078d782b760474a361dda0af3839290b0ef57ad6", + "0x9151434b16b9763660705744891fa906f660ecc5", + "0x0000000000000000000000000000000000000000", + ], +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/helpers/data.helpers.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/helpers/data.helpers.ts new file mode 100644 index 00000000..56accd16 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/helpers/data.helpers.ts @@ -0,0 +1,3 @@ +export const bigIntReplacer = (_key: string, value: any) => { + return typeof value === "bigint" ? value.toString() : value +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/index.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/index.ts new file mode 100644 index 00000000..7b1962e6 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/index.ts @@ -0,0 +1,34 @@ +export { IndexerClient, createChain, createIndexerClient } from "@/client" +export { createQueryClient, queryGetRequest, queryPostRequest, queryAssetTeleported } from "@/query-client" +export { + __test, + postRequestCommitment, + getRequestCommitment, + orderCommitment, + DUMMY_PRIVATE_KEY, + ADDRESS_ZERO, + generateRootWithProof, + bytes32ToBytes20, + bytes20ToBytes32, + hexToString, + constructRedeemEscrowRequestBody, + estimateGasForPost, + getStorageSlot, + ERC20Method, + fetchPrice, + adjustFeeDecimals, + DEFAULT_GRAFFITI, + maxBigInt, + getGasPriceFromEtherscan, + USE_ETHERSCAN_CHAINS, + TESTNET_CHAINS, + retryPromise, +} from "@/utils" +export * from "@/protocols/intents" +export * from "@/utils/txEvents" +export * from "@/utils/tokenGateway" +export * from "@/utils/xcmGateway" +export * from "@/chain" +export * from "@/types" +export * from "@/configs/ChainConfigService" +export * from "@/configs/chain" diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/protocols/intents.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/protocols/intents.ts new file mode 100644 index 00000000..49e38e87 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/protocols/intents.ts @@ -0,0 +1,780 @@ +import { Decimal } from "decimal.js" +import { + concatHex, + encodeAbiParameters, + formatUnits, + hexToString, + maxUint256, + pad, + parseEventLogs, + parseUnits, + toHex, +} from "viem" +import EVM_HOST from "@/abis/evmHost" +import IntentGatewayABI from "@/abis/IntentGateway" +import { type IGetRequestMessage, type IProof, requestCommitmentKey, type SubstrateChain } from "@/chain" +import type { EvmChain } from "@/chains/evm" +import type { IndexerClient } from "@/client" +import { createCancellationStorage, STORAGE_KEYS } from "@/storage" +import { + type DispatchPost, + type FillOptions, + type HexString, + type IGetRequest, + type IPostRequest, + type Order, + RequestStatus, + type RequestStatusWithMetadata, +} from "@/types" +import { + ADDRESS_ZERO, + adjustFeeDecimals, + bytes20ToBytes32, + bytes32ToBytes20, + constructRedeemEscrowRequestBody, + ERC20Method, + fetchPrice, + getGasPriceFromEtherscan, + getRequestCommitment, + getStorageSlot, + MOCK_ADDRESS, + maxBigInt, + orderCommitment, + parseStateMachineId, + retryPromise, + sleep, + USE_ETHERSCAN_CHAINS, + waitForChallengePeriod, +} from "@/utils" +import { Swap } from "@/utils/swap" + +/** + * IntentGateway handles cross-chain intent operations between EVM chains. + * It provides functionality for estimating fill orders, finding optimal swap protocols, + * and checking order statuses across different chains. + */ +export class IntentGateway { + public readonly swap: Swap + private readonly storage = createCancellationStorage() + + /** + * Creates a new IntentGateway instance for cross-chain operations. + * @param source - The source EVM chain + * @param dest - The destination EVM chain + */ + constructor( + public readonly source: EvmChain, + public readonly dest: EvmChain, + ) { + this.swap = new Swap() + } + + /** + * Estimates the total cost required to fill an order, including gas fees, relayer fees, + * protocol fees, and swap operations. + * + * @param order - The order to estimate fill costs for + * @returns An object containing the estimated cost in both fee token and native token, plus the post request calldata + */ + async estimateFillOrder(order: Order): Promise<{ + order: Order + feeTokenAmount: bigint + nativeTokenAmount: bigint + postRequestCalldata: HexString + }> { + // Order with commitment and stringified chains + const orderWithCommitment = transformOrder(order) + + const postRequest: IPostRequest = { + source: orderWithCommitment.destChain, + dest: orderWithCommitment.sourceChain, + body: constructRedeemEscrowRequestBody(orderWithCommitment, MOCK_ADDRESS), + timeoutTimestamp: 0n, + nonce: await this.source.getHostNonce(), + from: this.source.configService.getIntentGatewayAddress(orderWithCommitment.destChain), + to: this.source.configService.getIntentGatewayAddress(orderWithCommitment.sourceChain), + } + + const { decimals: sourceChainFeeTokenDecimals } = await this.source.getFeeTokenWithDecimals() + + const { address: destChainFeeTokenAddress, decimals: destChainFeeTokenDecimals } = + await this.dest.getFeeTokenWithDecimals() + + const { gas: postGasEstimate, postRequestCalldata } = await this.source.estimateGas(postRequest) + + const postGasEstimateInSourceFeeToken = await this.convertGasToFeeToken( + postGasEstimate, + "source", + orderWithCommitment.sourceChain, + ) + + const minRelayerFee = 5n * 10n ** BigInt(sourceChainFeeTokenDecimals - 2) + const postGasWithIncentive = postGasEstimateInSourceFeeToken + (postGasEstimateInSourceFeeToken * 1n) / 100n + const relayerFeeInSourceFeeToken = maxBigInt(postGasWithIncentive, minRelayerFee) + + const relayerFeeInDestFeeToken = adjustFeeDecimals( + relayerFeeInSourceFeeToken, + sourceChainFeeTokenDecimals, + destChainFeeTokenDecimals, + ) + + const fillOptions: FillOptions = { + relayerFee: relayerFeeInDestFeeToken, + } + + const totalEthValue = orderWithCommitment.outputs + .filter((output) => bytes32ToBytes20(output.token) === ADDRESS_ZERO) + .reduce((sum, output) => sum + output.amount, 0n) + + const intentGatewayAddress = this.source.configService.getIntentGatewayAddress(orderWithCommitment.destChain) + const testValue = toHex(maxUint256 / 2n) + + const orderOverrides = await Promise.all( + orderWithCommitment.outputs.map(async (output) => { + const tokenAddress = bytes32ToBytes20(output.token) + + if (tokenAddress === ADDRESS_ZERO) { + return null + } + + try { + const stateDiffs = [] + + const balanceData = ERC20Method.BALANCE_OF + bytes20ToBytes32(MOCK_ADDRESS).slice(2) + const balanceSlot = await getStorageSlot(this.dest.client, tokenAddress, balanceData as HexString) + stateDiffs.push({ slot: balanceSlot as HexString, value: testValue }) + + try { + const allowanceData = + ERC20Method.ALLOWANCE + + bytes20ToBytes32(MOCK_ADDRESS).slice(2) + + bytes20ToBytes32(intentGatewayAddress).slice(2) + const allowanceSlot = await getStorageSlot( + this.dest.client, + tokenAddress, + allowanceData as HexString, + ) + stateDiffs.push({ + slot: allowanceSlot as HexString, + value: testValue, + }) + } catch (e) { + console.warn(`Could not find allowance slot for token ${tokenAddress}:`, e) + } + + return { address: tokenAddress, stateDiff: stateDiffs } + } catch (e) { + console.warn(`Could not find balance slot for token ${tokenAddress}:`, e) + return null + } + }), + ).then((results) => results.filter(Boolean)) + + const stateOverrides = [ + // Mock address with ETH balance so that any chain estimation runs + // even when the address doesn't hold any native token in that chain + { + address: MOCK_ADDRESS, + balance: maxUint256, + }, + ...orderOverrides.map((override) => ({ + address: override!.address, + stateDiff: override!.stateDiff, + })), + ] + + let destChainFillGas = 0n + try { + let protocolFeeInNativeToken = await this.quoteNative(postRequest, relayerFeeInDestFeeToken).catch(() => + this.dest.quoteNative(postRequest, relayerFeeInDestFeeToken).catch(() => 0n), + ) + protocolFeeInNativeToken = protocolFeeInNativeToken + (protocolFeeInNativeToken * 50n) / 10000n + + destChainFillGas = await this.dest.client.estimateContractGas({ + abi: IntentGatewayABI.ABI, + address: intentGatewayAddress, + functionName: "fillOrder", + args: [order as any, fillOptions as any], + account: MOCK_ADDRESS, + value: totalEthValue + protocolFeeInNativeToken, + stateOverride: stateOverrides as any, + }) + } catch { + console.warn( + `Could not estimate gas for fill order with native token as fees for chain ${orderWithCommitment.destChain}, now trying with fee token as fees`, + ) + + const destFeeTokenBalanceData = ERC20Method.BALANCE_OF + bytes20ToBytes32(MOCK_ADDRESS).slice(2) + const destFeeTokenBalanceSlot = await getStorageSlot( + this.dest.client, + destChainFeeTokenAddress, + destFeeTokenBalanceData as HexString, + ) + const destFeeTokenAllowanceData = + ERC20Method.ALLOWANCE + + bytes20ToBytes32(MOCK_ADDRESS).slice(2) + + bytes20ToBytes32(intentGatewayAddress).slice(2) + const destFeeTokenAllowanceSlot = await getStorageSlot( + this.dest.client, + destChainFeeTokenAddress, + destFeeTokenAllowanceData as HexString, + ) + const feeTokenStateDiffs = [ + { slot: destFeeTokenBalanceSlot, value: testValue }, + { slot: destFeeTokenAllowanceSlot, value: testValue }, + ] + + stateOverrides.push({ + address: destChainFeeTokenAddress, + stateDiff: feeTokenStateDiffs as any, + }) + + destChainFillGas = await this.dest.client.estimateContractGas({ + abi: IntentGatewayABI.ABI, + address: intentGatewayAddress, + functionName: "fillOrder", + args: [order as any, fillOptions as any], + account: MOCK_ADDRESS, + value: totalEthValue, + stateOverride: stateOverrides as any, + }) + } + + const fillGasInDestFeeToken = await this.convertGasToFeeToken( + destChainFillGas, + "dest", + orderWithCommitment.destChain, + ) + const fillGasInSourceFeeToken = adjustFeeDecimals( + fillGasInDestFeeToken, + destChainFeeTokenDecimals, + sourceChainFeeTokenDecimals, + ) + + const protocolFeeInSourceFeeToken = adjustFeeDecimals( + await this.dest.quote(postRequest), + destChainFeeTokenDecimals, + sourceChainFeeTokenDecimals, + ) + + let totalEstimateInSourceFeeToken = + fillGasInSourceFeeToken + protocolFeeInSourceFeeToken + relayerFeeInSourceFeeToken + + let totalNativeTokenAmount = await this.convertFeeTokenToNative( + totalEstimateInSourceFeeToken, + "source", + orderWithCommitment.sourceChain, + ) + + if ([orderWithCommitment.destChain, orderWithCommitment.sourceChain].includes("EVM-1")) { + totalEstimateInSourceFeeToken = + totalEstimateInSourceFeeToken + (totalEstimateInSourceFeeToken * 3000n) / 10000n + totalNativeTokenAmount = totalNativeTokenAmount + (totalNativeTokenAmount * 3200n) / 10000n + } else { + totalEstimateInSourceFeeToken = + totalEstimateInSourceFeeToken + (totalEstimateInSourceFeeToken * 250n) / 10000n + totalNativeTokenAmount = totalNativeTokenAmount + (totalNativeTokenAmount * 350n) / 10000n + } + return { + order: { + ...order, + fees: totalEstimateInSourceFeeToken, + }, + feeTokenAmount: totalEstimateInSourceFeeToken, + nativeTokenAmount: totalNativeTokenAmount, + postRequestCalldata, + } + } + + /** + * Converts fee token amounts back to the equivalent amount in native token. + * Uses USD pricing to convert between fee token amounts and native token costs. + * + * @param feeTokenAmount - The amount in fee token (DAI) + * @param getQuoteIn - Whether to use "source" or "dest" chain for the conversion + * @param evmChainID - The EVM chain ID in format "EVM-{id}" + * @returns The fee token amount converted to native token amount + * @private + */ + private async convertFeeTokenToNative( + feeTokenAmount: bigint, + getQuoteIn: "source" | "dest", + evmChainID: string, + ): Promise { + const client = this[getQuoteIn].client + const wethAsset = this[getQuoteIn].configService.getWrappedNativeAssetWithDecimals(evmChainID).asset + const feeToken = await this[getQuoteIn].getFeeTokenWithDecimals() + + try { + const { amountOut } = await this.swap.findBestProtocolWithAmountIn( + this[getQuoteIn].client, + feeToken.address, + wethAsset, + feeTokenAmount, + evmChainID, + { selectedProtocol: "v2" }, + ) + + if (amountOut === 0n) { + throw new Error() + } + return amountOut + } catch { + // Testnet block + const nativeCurrency = client.chain?.nativeCurrency + const chainId = Number.parseInt(evmChainID.split("-")[1]) + const feeTokenAmountDecimal = new Decimal(formatUnits(feeTokenAmount, feeToken.decimals)) + const nativeTokenPriceUsd = new Decimal(await fetchPrice(nativeCurrency?.symbol!, chainId)) + const totalCostInNativeToken = feeTokenAmountDecimal.dividedBy(nativeTokenPriceUsd) + return parseUnits(totalCostInNativeToken.toFixed(nativeCurrency?.decimals!), nativeCurrency?.decimals!) + } + } + + /** + * Converts gas costs to the equivalent amount in the fee token (DAI). + * Uses USD pricing to convert between native token gas costs and fee token amounts. + * + * @param gasEstimate - The estimated gas units + * @param gasEstimateIn - Whether to use "source" or "dest" chain for the conversion + * @param evmChainID - The EVM chain ID in format "EVM-{id}" + * @returns The gas cost converted to fee token amount + * @private + */ + private async convertGasToFeeToken( + gasEstimate: bigint, + gasEstimateIn: "source" | "dest", + evmChainID: string, + ): Promise { + const client = this[gasEstimateIn].client + const useEtherscan = USE_ETHERSCAN_CHAINS.has(evmChainID) + const etherscanApiKey = useEtherscan ? this[gasEstimateIn].configService.getEtherscanApiKey() : undefined + const gasPrice = + useEtherscan && etherscanApiKey + ? await retryPromise(() => getGasPriceFromEtherscan(evmChainID, etherscanApiKey), { + maxRetries: 3, + backoffMs: 250, + }).catch(async () => { + console.warn({ evmChainID }, "Error getting gas price from etherscan, using client's gas price") + return await client.getGasPrice() + }) + : await client.getGasPrice() + const gasCostInWei = gasEstimate * gasPrice + const wethAddr = this[gasEstimateIn].configService.getWrappedNativeAssetWithDecimals(evmChainID).asset + const feeToken = await this[gasEstimateIn].getFeeTokenWithDecimals() + + try { + const { amountOut } = await this.swap.findBestProtocolWithAmountIn( + this[gasEstimateIn].client, + wethAddr, + feeToken.address, + gasCostInWei, + evmChainID, + { selectedProtocol: "v2" }, + ) + if (amountOut === 0n) { + console.log("Amount out not found") + throw new Error() + } + return amountOut + } catch { + // Testnet block + const nativeCurrency = client.chain?.nativeCurrency + const chainId = Number.parseInt(evmChainID.split("-")[1]) + const gasCostInToken = new Decimal(formatUnits(gasCostInWei, nativeCurrency?.decimals!)) + const tokenPriceUsd = await fetchPrice(nativeCurrency?.symbol!, chainId) + const gasCostUsd = gasCostInToken.times(tokenPriceUsd) + const feeTokenPriceUsd = new Decimal(1) // stable coin + const gasCostInFeeToken = gasCostUsd.dividedBy(feeTokenPriceUsd) + return parseUnits(gasCostInFeeToken.toFixed(feeToken.decimals), feeToken.decimals) + } + } + + /** + * Gets a quote for the native token cost of dispatching a post request. + * + * @param postRequest - The post request to quote + * @param fee - The fee amount in fee token + * @returns The native token amount required + */ + async quoteNative(postRequest: IPostRequest, fee: bigint): Promise { + const dispatchPost: DispatchPost = { + dest: toHex(postRequest.dest), + to: postRequest.to, + body: postRequest.body, + timeout: postRequest.timeoutTimestamp, + fee: fee, + payer: postRequest.from, + } + + const quoteNative = await this.dest.client.readContract({ + address: this.dest.configService.getIntentGatewayAddress(postRequest.dest), + abi: IntentGatewayABI.ABI, + functionName: "quoteNative", + args: [dispatchPost] as any, + }) + + return quoteNative + } + + /** + * Checks if an order has been filled by verifying the commitment status on-chain. + * Reads the storage slot corresponding to the order's commitment hash. + * + * @param order - The order to check + * @returns True if the order has been filled, false otherwise + */ + async isOrderFilled(order: Order): Promise { + order = transformOrder(order) + const intentGatewayAddress = this.source.configService.getIntentGatewayAddress(order.destChain) + + const filledSlot = await this.dest.client.readContract({ + abi: IntentGatewayABI.ABI, + address: intentGatewayAddress, + functionName: "calculateCommitmentSlotHash", + args: [order.id as HexString], + }) + + const filledStatus = await this.dest.client.getStorageAt({ + address: intentGatewayAddress, + slot: filledSlot, + }) + return filledStatus !== "0x0000000000000000000000000000000000000000000000000000000000000000" + } + + private async submitAndConfirmReceipt( + hyperbridge: SubstrateChain, + commitment: HexString, + message: IGetRequestMessage, + ) { + let storageValue = await hyperbridge.queryRequestReceipt(commitment) + + if (!storageValue) { + console.log("No receipt found. Attempting to submit...") + try { + await hyperbridge.submitUnsigned(message) + } catch { + console.warn("Submission failed. Awaiting network confirmation...") + } + + console.log("Waiting for network state update...") + await sleep(30000) + + storageValue = await retryPromise( + async () => { + const value = await hyperbridge.queryRequestReceipt(commitment) + if (!value) throw new Error("Receipt not found") + return value + }, + { maxRetries: 10, backoffMs: 5000, logMessage: "Checking for receipt" }, + ) + } + + console.log("Hyperbridge Receipt confirmed.") + } + + /** + * Returns the native token amount required to dispatch a cancellation GET request for the given order. + * Internally constructs the IGetRequest and calls quoteNative. + */ + async quoteCancelNative(order: Order): Promise { + const orderWithCommitment = transformOrder(order) + + const height = (orderWithCommitment.deadline as bigint) + 1n + + const destIntentGateway = this.dest.configService.getIntentGatewayAddress(orderWithCommitment.destChain) + const slotHash = await this.dest.client.readContract({ + abi: IntentGatewayABI.ABI, + address: destIntentGateway, + functionName: "calculateCommitmentSlotHash", + args: [orderWithCommitment.id as HexString], + }) + const key = concatHex([destIntentGateway as HexString, slotHash as HexString]) as HexString + + const context = encodeAbiParameters( + [ + { + name: "requestBody", + type: "tuple", + components: [ + { name: "commitment", type: "bytes32" }, + { name: "beneficiary", type: "bytes32" }, + { + name: "tokens", + type: "tuple[]", + components: [ + { name: "token", type: "bytes32" }, + { name: "amount", type: "uint256" }, + ], + }, + ], + }, + ], + [ + { + commitment: orderWithCommitment.id as HexString, + beneficiary: orderWithCommitment.user as HexString, + tokens: orderWithCommitment.inputs, + }, + ], + ) as HexString + + const getRequest: IGetRequest = { + source: orderWithCommitment.sourceChain, + dest: orderWithCommitment.destChain, + from: this.source.configService.getIntentGatewayAddress(orderWithCommitment.destChain), + nonce: await this.source.getHostNonce(), + height, + keys: [key], + timeoutTimestamp: 0n, + context, + } + + return await this.source.quoteNative(getRequest, 0n) + } + + /** + * Cancels an order through the cross-chain protocol by generating and submitting proofs. + * This is an async generator function that yields status updates throughout the cancellation process. + * + * The cancellation process involves: + * 1. Fetching proof from the destination chain that the order exists + * 2. Creating a GET request to retrieve the order state + * 3. Waiting for the source chain to finalize the request + * 4. Fetching proof from the source chain + * 5. Waiting for the challenge period to complete + * 6. Submitting the request message to Hyperbridge + * 7. Monitoring until Hyperbridge finalizes the cancellation + * + * @param order - The order to cancel, containing source/dest chains, deadline, and other order details + * @param indexerClient - Client for querying the indexer and interacting with Hyperbridge + * + * @yields {CancelEvent} Status updates during the cancellation process: + * - DESTINATION_FINALIZED: Destination proof has been obtained + * - AWAITING_GET_REQUEST: Waiting for GET request to be provided + * - SOURCE_FINALIZED: Source chain has finalized the request + * - HYPERBRIDGE_DELIVERED: Hyperbridge has delivered the request + * - HYPERBRIDGE_FINALIZED: Cancellation is complete + * + * @throws {Error} If GET request is not provided when needed + * + * @example + * ```typescript + * const cancelStream = intentGateway.cancelOrder(order, indexerClient); + * + * for await (const event of cancelStream) { + * switch (event.status) { + * case 'SOURCE_FINALIZED': + * console.log('Source finalized at block:', event.data.metadata.blockNumber); + * break; + * case 'HYPERBRIDGE_FINALIZED': + * console.log('Cancellation complete'); + * break; + * } + * } + * ``` + */ + async *cancelOrder(order: Order, indexerClient: IndexerClient): AsyncGenerator { + const orderId = orderCommitment(order) + + const hyperbridge = indexerClient.hyperbridge as SubstrateChain + const sourceStateMachine = hexToString(order.sourceChain as HexString) + const sourceConsensusStateId = this.source.configService.getConsensusStateId(sourceStateMachine) + + let destIProof: IProof | null = await this.storage.getItem(STORAGE_KEYS.destProof(orderId)) + if (!destIProof) { + destIProof = yield* this.fetchDestinationProof(order, indexerClient) + await this.storage.setItem(STORAGE_KEYS.destProof(orderId), destIProof) + } else { + yield { status: "DESTINATION_FINALIZED", data: { proof: destIProof } } + } + + let getRequest: IGetRequest | null = await this.storage.getItem(STORAGE_KEYS.getRequest(orderId)) + if (!getRequest) { + const transactionHash = yield { + status: "AWAITING_GET_REQUEST", + data: undefined, + } + const receipt = await this.source.client.getTransactionReceipt({ + hash: transactionHash, + }) + + const events = parseEventLogs({ abi: EVM_HOST.ABI, logs: receipt.logs }) + const request = events.find((e) => e.eventName === "GetRequestEvent") + if (!request) throw new Error("GetRequest missing") + getRequest = request.args as unknown as IGetRequest + + await this.storage.setItem(STORAGE_KEYS.getRequest(orderId), getRequest) + } + + const commitment = getRequestCommitment({ + ...getRequest, + keys: [...getRequest.keys], + }) + const sourceStatusStream = indexerClient.getRequestStatusStream(commitment) + + for await (const statusUpdate of sourceStatusStream) { + if (statusUpdate.status === RequestStatus.SOURCE_FINALIZED) { + yield { + status: "SOURCE_FINALIZED", + data: { metadata: statusUpdate.metadata }, + } + + const sourceHeight = BigInt(statusUpdate.metadata.blockNumber) + let sourceIProof: IProof | null = await this.storage.getItem(STORAGE_KEYS.sourceProof(orderId)) + if (!sourceIProof) { + sourceIProof = await fetchSourceProof( + commitment, + this.source, + sourceStateMachine, + sourceConsensusStateId, + sourceHeight, + ) + await this.storage.setItem(STORAGE_KEYS.sourceProof(orderId), sourceIProof) + } + + await waitForChallengePeriod(hyperbridge, { + height: sourceIProof.height, + id: { + stateId: parseStateMachineId(sourceStateMachine).stateId, + consensusStateId: sourceConsensusStateId, + }, + }) + + const getRequestMessage: IGetRequestMessage = { + kind: "GetRequest", + requests: [getRequest], + source: sourceIProof, + response: destIProof, + signer: pad("0x"), + } + + await this.submitAndConfirmReceipt(hyperbridge, commitment, getRequestMessage) + continue + } + + if (statusUpdate.status === RequestStatus.HYPERBRIDGE_DELIVERED) { + yield { + status: "HYPERBRIDGE_DELIVERED", + data: statusUpdate as RequestStatusWithMetadata, + } + continue + } + + if (statusUpdate.status === RequestStatus.HYPERBRIDGE_FINALIZED) { + yield { + status: "HYPERBRIDGE_FINALIZED", + data: statusUpdate as RequestStatusWithMetadata, + } + await this.storage.removeItem(STORAGE_KEYS.destProof(orderId)) + await this.storage.removeItem(STORAGE_KEYS.getRequest(orderId)) + await this.storage.removeItem(STORAGE_KEYS.sourceProof(orderId)) + return + } + } + } + + /** + * Fetches proof for the destination chain. + */ + private async *fetchDestinationProof( + order: Order, + indexerClient: IndexerClient, + ): AsyncGenerator { + let latestHeight = 0n + let lastFailedHeight: bigint | null = null + + while (true) { + const height = await indexerClient.queryLatestStateMachineHeight({ + statemachineId: this.dest.config.stateMachineId, + chain: indexerClient.hyperbridge.config.stateMachineId, + }) + + latestHeight = height ?? 0n + const shouldFetch = + lastFailedHeight === null ? latestHeight > order.deadline : latestHeight > lastFailedHeight + + if (!shouldFetch) { + await sleep(10000) + continue + } + + try { + const intentGatewayAddress = this.dest.configService.getIntentGatewayAddress( + this.dest.config.stateMachineId, + ) + const orderId = orderCommitment(order) + const slotHash = await this.dest.client.readContract({ + abi: IntentGatewayABI.ABI, + address: intentGatewayAddress, + functionName: "calculateCommitmentSlotHash", + args: [orderId], + }) + + const proofHex = await this.dest.queryStateProof(latestHeight, [slotHash], intentGatewayAddress) + + const proof: IProof = { + consensusStateId: this.dest.config.consensusStateId, + height: latestHeight, + proof: proofHex, + stateMachine: this.dest.config.stateMachineId, + } + + yield { status: "DESTINATION_FINALIZED", data: { proof } } + return proof + } catch (e) { + lastFailedHeight = latestHeight + await sleep(10000) + } + } + } +} + +/** + * Transforms an Order object into the format expected by the smart contract. + * Converts chain IDs to hex format and restructures input/output arrays. + * + * @param order - The order to transform + * @returns The order in contract-compatible format + */ +function transformOrder(order: Order) { + return { + ...order, + id: orderCommitment(order), + sourceChain: hexToString(order.sourceChain as HexString), + destChain: hexToString(order.destChain as HexString), + } +} + +/** + * Fetches proof for the source chain. + */ +async function fetchSourceProof( + commitment: HexString, + source: EvmChain, + sourceStateMachine: string, + sourceConsensusStateId: string, + sourceHeight: bigint, +): Promise { + const { slot1, slot2 } = requestCommitmentKey(commitment) + const proofHex = await source.queryStateProof(sourceHeight, [slot1, slot2]) + + return { + height: sourceHeight, + stateMachine: sourceStateMachine, + consensusStateId: sourceConsensusStateId, + proof: proofHex, + } +} + +interface CancelEventMap { + DESTINATION_FINALIZED: { proof: IProof } + AWAITING_GET_REQUEST: undefined + SOURCE_FINALIZED: { metadata: { blockNumber: number } } + HYPERBRIDGE_DELIVERED: RequestStatusWithMetadata + HYPERBRIDGE_FINALIZED: RequestStatusWithMetadata + SOURCE_PROOF_RECEIVED: IProof +} + +type CancelEvent = { + [K in keyof CancelEventMap]: { status: K; data: CancelEventMap[K] } +}[keyof CancelEventMap] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/queries.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/queries.ts new file mode 100644 index 00000000..d6fdbe35 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/queries.ts @@ -0,0 +1,279 @@ +export const POST_REQUEST_STATUS = ` + query RequestStatusM($hash: String!) { + requests( + filter: { commitment: { equalTo: $hash } } + ) { + nodes { + commitment + timeoutTimestamp + source + dest + to + from + nonce + body + statusMetadata { + nodes { + blockHash + blockNumber + timestamp + chain + status + transactionHash + } + } + } + } +} +` + +export const GET_REQUEST_STATUS = ` +query GetRequestDetails($commitment: String!) { + getRequests( + filter: { commitment: { equalTo: $commitment } } + ) { + nodes { + id + source + dest + from + keys + nonce + height + context + timeoutTimestamp + fee + blockNumber + blockHash + transactionHash + blockTimestamp + status + chain + commitment + statusMetadata { + nodes { + status + chain + timestamp + blockNumber + blockHash + transactionHash + } + } + } + } +}` + +export const STATE_MACHINE_UPDATES_BY_HEIGHT = ` +query StateMachineUpdatesByHeight($statemachineId: String!, $height: Int!, $chain: String!) { + stateMachineUpdateEvents( + filter: { + and: [ + { stateMachineId: { equalTo: $statemachineId } } + { height: { greaterThanOrEqualTo: $height } } + { chain: { equalTo: $chain } } + ] + } + orderBy: HEIGHT_DESC + first: 1 + ) { + nodes { + height + stateMachineId + chain + blockHash + blockNumber + transactionHash + createdAt + } + } +} +` + +export const STATE_MACHINE_UPDATES_BY_TIMESTAMP = ` +query StateMachineUpdatesByTimestamp($statemachineId: String!, $commitmentTimestamp: BigFloat!, $chain: String!) { + stateMachineUpdateEvents( + filter: { + and: [ + { stateMachineId: { equalTo: $statemachineId } } + { commitmentTimestamp: { greaterThanOrEqualTo: $commitmentTimestamp } } + { chain: { equalTo: $chain } } + ] + } + orderBy: COMMITMENT_TIMESTAMP_DESC + first: 1 + ) { + nodes { + height + stateMachineId + chain + blockHash + blockNumber + transactionHash + commitmentTimestamp + createdAt + } + } + } +` + +export const LATEST_STATE_MACHINE_UPDATE = ` +query LatestStateMachineUpdate($statemachineId: String!, $chain: String!) { + stateMachineUpdateEvents( + filter: { + and: [ + { stateMachineId: { equalTo: $statemachineId } } + { chain: { equalTo: $chain } } + ] + } + orderBy: HEIGHT_DESC + first: 1 + ) { + nodes { + height + stateMachineId + chain + blockHash + blockNumber + transactionHash + createdAt + } + } +} +` + +export const ASSET_TELEPORTED_BY_PARAMS = ` +query AssetTeleportedByParams($id: String!) { + assetTeleported(id: $id) { + id + from + to + amount + dest + commitment + createdAt + blockNumber + } +} +` + +export const GET_RESPONSE_BY_REQUEST_ID = ` +query GetResponseByRequestId($requestId: String!) { + getResponses(filter: {requestId: {equalTo: $requestId}}) { + nodes { + id + commitment + responseMessage + } + } +} +` + +export const ORDER_STATUS = ` +query OrderStatus($commitment: String!) { + orders( + filter: { commitment: { equalTo: $commitment } } + ) { + nodes { + id + user + sourceChain + destChain + commitment + deadline + nonce + fees + inputTokens + inputAmounts + inputValuesUSD + inputUSD + outputTokens + outputAmounts + outputBeneficiaries + calldata + status + referrer + createdAt + blockNumber + blockTimestamp + transactionHash + statusMetadata { + nodes { + status + chain + timestamp + blockNumber + transactionHash + filler + } + } + } + } +}` + +export const TOKEN_GATEWAY_ASSET_TELEPORTED_STATUS = ` +query TokenGatewayAssetTeleportedStatus($commitment: String!) { + tokenGatewayAssetTeleporteds( + filter: { commitment: { equalTo: $commitment } } + ) { + nodes { + id + from + to + sourceChain + destChain + commitment + amount + usdValue + assetId + redeem + status + createdAt + blockNumber + blockTimestamp + transactionHash + statusMetadata { + nodes { + status + chain + timestamp + blockNumber + transactionHash + } + } + } + } +}` + +export const TOKEN_PRICE = ` +query TokenPrice($symbol: String!) { + tokenPrices( + filter: { symbol: { equalTo: $symbol } } + ) { + nodes { + id + symbol + address + currency + price + lastUpdatedAt + } + } +}` + +export const TOKEN_REGISTRY = ` +query TokenRegistry($symbol: String!) { + tokenRegistries( + filter: { symbol: { equalTo: $symbol } } + ) { + nodes { + id + name + symbol + address + updateFrequencySeconds + lastUpdatedAt + createdAt + } + } +}` diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/query-client.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/query-client.ts new file mode 100644 index 00000000..ffa77d5c --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/query-client.ts @@ -0,0 +1,417 @@ +import type { ConsolaInstance } from "consola" +import { GraphQLClient } from "graphql-request" +import { + ASSET_TELEPORTED_BY_PARAMS, + GET_REQUEST_STATUS, + ORDER_STATUS, + POST_REQUEST_STATUS, + TOKEN_GATEWAY_ASSET_TELEPORTED_STATUS, + TOKEN_PRICE, + TOKEN_REGISTRY, +} from "./queries" +import type { + AssetTeleported, + AssetTeleportedResponse, + GetRequestResponse, + GetRequestWithStatus, + HexString, + IndexerQueryClient, + OrderResponse, + OrderWithStatus, + PostRequestWithStatus, + RequestResponse, + RequestStatusKey, + TokenGatewayAssetTeleportedResponse, + TokenGatewayAssetTeleportedWithStatus, + TokenPrice, + TokenPricesResponse, + TokenRegistry, + TokenRegistryResponse, +} from "./types" +import { DEFAULT_LOGGER, REQUEST_STATUS_WEIGHTS, retryPromise, sleep } from "./utils" + +export function createQueryClient(config: { url: string }) { + return new GraphQLClient(config.url) +} + +/** + * Queries a request by CommitmentHash + * + * @example + * import { createQueryClient, queryRequest } from "@hyperbridge/sdk" + * + * const queryClient = createQueryClient({ + * url: "http://localhost:3000", // URL of the Hyperbridge indexer API + * }) + * const commitmentHash = "0x...." + * const request = await queryPostRequest({ commitmentHash, queryClient }) + */ +export function queryPostRequest(params: { commitmentHash: string; queryClient: IndexerQueryClient }) { + return _queryRequestInternal(params) +} + +/** + * Query for asset teleported events by sender, recipient, and destination chain + * @param id - Encoded Message Id + * @returns The asset teleported event if found, undefined otherwise + */ +export async function queryAssetTeleported(params: { + id: HexString + queryClient: IndexerQueryClient +}): Promise { + const { id, queryClient } = params + + return await retryPromise( + async () => { + const response = await queryClient.request(ASSET_TELEPORTED_BY_PARAMS, { id }) + + if (!response?.assetTeleported) { + throw new Error(`AssetTeleportedEvent not found for ${id}`) + } + + return response.assetTeleported + }, + { + logMessage: "queryingAssetTeleported", + backoffMs: 15000, + maxRetries: 15, + }, + ) +} + +/** + * Queries a GET Request by CommitmentHash + * + * @example + * import { createQueryClient, queryRequest } from "@hyperbridge/sdk" + * + * const queryClient = createQueryClient({ + * url: "http://localhost:3000", // URL of the Hyperbridge indexer API + * }) + * const commitmentHash = "0x...." + * const request = await queryGetRequest({ commitmentHash, queryClient }) + */ +export function queryGetRequest(params: { commitmentHash: string; queryClient: IndexerQueryClient }) { + return _queryGetRequestInternal(params) +} + +/** + * Queries an order by CommitmentHash + * + * @example + * import { createQueryClient, queryOrder } from "@hyperbridge/sdk" + * + * const queryClient = createQueryClient({ + * url: "http://localhost:3000", // URL of the Hyperbridge indexer API + * }) + * const commitmentHash = "0x...." + * const order = await queryOrder({ commitmentHash, queryClient }) + */ +export function queryOrder(params: { commitmentHash: string; queryClient: IndexerQueryClient }) { + return _queryOrderInternal(params) +} + +/** + * Internal function to query a token gateway asset teleported by CommitmentHash + * + * @param params - Parameters for querying the token gateway asset teleported + * @returns Latest status and block metadata of the token gateway asset teleported + */ +export async function _queryTokenGatewayAssetTeleportedInternal( + params: InternalQueryParams, +): Promise { + const { commitmentHash, queryClient: client, logger = DEFAULT_LOGGER } = params + + const response = await retryPromise( + () => { + return client.request(TOKEN_GATEWAY_ASSET_TELEPORTED_STATUS, { + commitment: commitmentHash, + }) + }, + { + maxRetries: 3, + backoffMs: 1000, + logger, + logMessage: `querying 'TokenGatewayAssetTeleported' with Statuses by CommitmentHash(${commitmentHash})`, + }, + ) + + const first_record = response.tokenGatewayAssetTeleporteds.nodes[0] + if (!first_record) return + + logger.trace("`TokenGatewayAssetTeleported` found") + const { statusMetadata, ...first_node } = first_record + + const statuses = structuredClone(statusMetadata.nodes).map((item) => ({ + status: item.status, + metadata: { + blockHash: item.blockHash, + blockNumber: Number.parseInt(item.blockNumber), + transactionHash: item.transactionHash, + timestamp: BigInt(item.timestamp), + }, + })) + + // sort by ascending order + const sorted = statuses.sort((a, b) => { + return Number(a.metadata.timestamp) - Number(b.metadata.timestamp) + }) + + return { + ...first_node, + amount: BigInt(first_node.amount), + blockNumber: BigInt(first_node.blockNumber), + blockTimestamp: BigInt(first_node.blockTimestamp), + createdAt: new Date(first_node.createdAt), + statuses: sorted, + } +} + +type InternalQueryParams = { + commitmentHash: string + queryClient: IndexerQueryClient + logger?: ConsolaInstance +} + +/** + * Queries a request by CommitmentHash + + * @param hash - Can be commitment + * @returns Latest status and block metadata of the request + */ +export async function _queryRequestInternal(params: InternalQueryParams): Promise { + const { commitmentHash: hash, queryClient: client, logger: logger_ = DEFAULT_LOGGER } = params + + const logger = logger_.withTag("[queryRequest]") + + const response = await retryPromise( + () => { + return client.request(POST_REQUEST_STATUS, { + hash, + }) + }, + { + maxRetries: 3, + backoffMs: 1000, + logger, + logMessage: `querying 'Request' with Statuses by CommitmentHash(${hash})`, + }, + ) + + const first_record = response.requests.nodes[0] + if (!first_record) return + + logger.trace("`Request` found") + const { statusMetadata, ...first_node } = first_record + + const statuses = structuredClone(statusMetadata.nodes).map((item) => ({ + status: item.status as any, + metadata: { + blockHash: item.blockHash, + blockNumber: Number.parseInt(item.blockNumber), + transactionHash: item.transactionHash, + timestamp: item?.timestamp, + }, + })) + + // sort by ascending order + const sorted = statuses.sort( + (a, b) => + REQUEST_STATUS_WEIGHTS[a.status as RequestStatusKey] - REQUEST_STATUS_WEIGHTS[b.status as RequestStatusKey], + ) + logger.trace("Statuses found", statuses) + + const request: PostRequestWithStatus = { + ...first_node, + timeoutTimestamp: BigInt(first_node.timeoutTimestamp), + statuses: sorted, + } + + return request +} + +/** + * Queries a request by any of its associated hashes and returns it alongside its statuses + * Statuses will be one of SOURCE, HYPERBRIDGE_DELIVERED and DESTINATION + * + * @param hash - Can be commitment, hyperbridge tx hash, source tx hash, destination tx hash, or timeout tx hash + * @returns Latest status and block metadata of the request + */ +export async function _queryGetRequestInternal(params: InternalQueryParams): Promise { + const { commitmentHash, queryClient: client, logger = DEFAULT_LOGGER } = params + + const response = await retryPromise( + () => { + return client.request(GET_REQUEST_STATUS, { + commitment: commitmentHash, + }) + }, + { + maxRetries: 3, + backoffMs: 1000, + logger, + logMessage: `query \`IGetRequest\` with commitment hash ${commitmentHash}`, + }, + ) + + if (!response.getRequests.nodes[0]) return + + logger.trace("`Request` found") + + const statuses = response.getRequests.nodes[0].statusMetadata.nodes.map((item) => ({ + status: item.status as any, + metadata: { + blockHash: item.blockHash, + blockNumber: Number.parseInt(item.blockNumber), + transactionHash: item.transactionHash, + timestamp: item?.timestamp, + }, + })) + + // sort by ascending order + const sorted = statuses.sort((a, b) => { + return ( + REQUEST_STATUS_WEIGHTS[a.status as RequestStatusKey] - REQUEST_STATUS_WEIGHTS[b.status as RequestStatusKey] + ) + }) + + const { statusMetadata, ...rest } = response.getRequests.nodes[0] + + return { + ...rest, + commitment: commitmentHash as HexString, + timeoutTimestamp: BigInt(rest.timeoutTimestamp), + nonce: BigInt(rest.nonce), + height: BigInt(rest.height), + statuses: sorted, + } +} + +/** + * Internal function to query an order by CommitmentHash + * + * @param params - Parameters for querying the order + * @returns Latest status and block metadata of the order + */ +export async function _queryOrderInternal(params: InternalQueryParams): Promise { + const { commitmentHash, queryClient: client, logger = DEFAULT_LOGGER } = params + + const response = await retryPromise( + () => { + return client.request(ORDER_STATUS, { + commitment: commitmentHash, + }) + }, + { + maxRetries: 3, + backoffMs: 1000, + logger, + logMessage: `querying 'Order' with Statuses by CommitmentHash(${commitmentHash})`, + }, + ) + + const first_record = response.orderPlaceds.nodes[0] + if (!first_record) return + + logger.trace("`Order` found") + const { statusMetadata, ...first_node } = first_record + + const statuses = structuredClone(statusMetadata.nodes).map((item) => ({ + status: item.status, + metadata: { + blockHash: item.blockHash, + blockNumber: Number.parseInt(item.blockNumber), + transactionHash: item.transactionHash, + timestamp: BigInt(item.timestamp), + filler: item.filler, + }, + })) + + // sort by ascending order + const sorted = statuses.sort((a, b) => { + // Since OrderStatus and RequestStatus are different enums, we'll just sort by timestamp + return Number(a.metadata.timestamp) - Number(b.metadata.timestamp) + }) + + const order: OrderWithStatus = { + ...first_node, + deadline: BigInt(first_node.deadline), + nonce: BigInt(first_node.nonce), + fees: BigInt(first_node.fees), + inputAmounts: first_node.inputAmounts.map(BigInt), + outputAmounts: first_node.outputAmounts.map(BigInt), + blockNumber: BigInt(first_node.blockNumber), + blockTimestamp: BigInt(first_node.blockTimestamp), + createdAt: new Date(first_node.createdAt), + statuses: sorted, + } + + return order +} + +type TokenPriceQueryParams = { + symbol: string + queryClient: IndexerQueryClient + logger?: ConsolaInstance +} + +export async function _queryTokenPriceInternal(params: TokenPriceQueryParams): Promise { + const { symbol, queryClient: client, logger = DEFAULT_LOGGER } = params + + const response = await retryPromise( + () => { + return client.request(TOKEN_PRICE, { symbol }) + }, + { + maxRetries: 3, + backoffMs: 1000, + logger, + logMessage: `querying 'TokenPrice' by Symbol(${symbol})`, + }, + ) + + const item = response.tokenPrices.nodes?.[0] + if (!item) return + + logger.trace("`TokenPrice` found") + return item +} + +type TokenRegistryQueryParams = { + symbol: string + queryClient: IndexerQueryClient + logger?: ConsolaInstance +} + +export async function _queryTokenRegistryInternal( + params: TokenRegistryQueryParams, +): Promise { + const { symbol, queryClient: client, logger = DEFAULT_LOGGER } = params + + const response = await retryPromise( + () => { + return client.request(TOKEN_REGISTRY, { symbol }) + }, + { + maxRetries: 3, + backoffMs: 1000, + logger, + logMessage: `querying 'TokenRegistry' by Symbol(${symbol})`, + }, + ) + + const item = response.tokenRegistries.nodes?.[0] + if (!item) return + + logger.trace("`TokenRegistry` found") + + return { + id: item.id, + name: item.name, + symbol: item.symbol, + address: item.address, + updateFrequencySeconds: item.updateFrequencySeconds, + lastUpdatedAt: item.lastUpdatedAt, + createdAt: new Date(item.createdAt), + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/drivers/browser.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/drivers/browser.ts new file mode 100644 index 00000000..c46752f0 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/drivers/browser.ts @@ -0,0 +1,23 @@ +// @ts-expect-error upstream driver types have export path resolution +import indexedDBDriver from "unstorage/drivers/indexedb" +// @ts-expect-error upstream driver types have export path resolution +import localStorageDriver from "unstorage/drivers/localstorage" +import type { LoadDriver } from "../types" + +const BASE_KEY = "hyperbridge/sdk/proof" + +export const loadDriver: LoadDriver = ({ key }) => { + if (key === "localstorage") { + return localStorageDriver({ base: BASE_KEY }) + } + + if (key === "indexeddb") { + return indexedDBDriver({ base: BASE_KEY }) + } + + console.warn( + `Hyperbridge/SDK/BrowserDriver: Unexpected storage driver: ${key}. Driver can't be loaded in the browser environment.`, + ) + + return null +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/drivers/node.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/drivers/node.ts new file mode 100644 index 00000000..f5117f68 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/drivers/node.ts @@ -0,0 +1,7 @@ +// @ts-expect-error Unable to resolve type +import fsDriver from "unstorage/drivers/fs" +import type { LoadDriver } from "../types" + +export const loadDriver: LoadDriver = ({ options }) => { + return fsDriver({ base: options?.basePath ?? "./.hyperbridge-cache" }) +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/index.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/index.ts new file mode 100644 index 00000000..5e69754f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/index.ts @@ -0,0 +1,114 @@ +import { createStorage } from "unstorage" +// @ts-expect-error failed to resolve types +import inMemoryDriver from "unstorage/drivers/memory" +import { loadDriver } from "@/storage/load-driver" +import { bytesToHex, hexToBytes } from "viem" +import { GetRequest, Proof } from "@/utils/substrate" +import { + convertCodecToIGetRequest, + convertIGetRequestToCodec, + convertCodecToIProof, + convertIProofToCodec, +} from "@/chains/substrate" +import type { IGetRequest, HexString } from "@/types" +import type { IProof } from "@/chain" +import type { CancellationStorageOptions, StorageDriverKey } from "@/storage/types" + +/** + * Encode IGetRequest to hex string using scale codec + */ +function encodeIGetRequest(request: IGetRequest): string { + const codec = convertIGetRequestToCodec(request) + const encoded = GetRequest.enc(codec) + return bytesToHex(encoded) +} + +/** + * Decode hex string back to IGetRequest using scale codec + */ +function decodeIGetRequest(hex: string): IGetRequest { + const bytes = hexToBytes(hex as HexString) + const decoded = GetRequest.dec(bytes) + return convertCodecToIGetRequest(decoded) +} + +/** + * Encode IProof to hex string using scale codec + */ +function encodeIProof(proof: IProof): string { + const codec = convertIProofToCodec(proof) + const encoded = Proof.enc(codec) + return bytesToHex(encoded) +} + +/** + * Decode hex string back to IProof using scale codec + */ +function decodeIProof(hex: string): IProof { + const bytes = hexToBytes(hex as HexString) + const decoded = Proof.dec(bytes) + return convertCodecToIProof(decoded) +} + +const detectEnvironment = (): StorageDriverKey => { + if (typeof process !== "undefined" && !!process.versions?.node) return "node" + if (typeof globalThis !== "undefined" && "localStorage" in globalThis) return "localstorage" + if (typeof globalThis !== "undefined" && "indexedDB" in globalThis) return "indexeddb" + return "memory" +} + +export function createCancellationStorage(options: CancellationStorageOptions = {}) { + const key = options.env ?? detectEnvironment() + const driver = loadDriver({ key, options }) ?? inMemoryDriver() + const baseStorage = createStorage({ driver }) + + const getItem = async (key: string): Promise => { + const value = await baseStorage.getItem(key) + if (!value) return null + + if (key.includes("getRequest")) { + const decoded = decodeIGetRequest(value) + return decoded as T + } + + if (key.includes("Proof")) { + const decoded = decodeIProof(value) + return decoded as T + } + + throw new Error(`Unknown storage key type: ${key}`) + } + + const setItem = async (key: string, value: unknown): Promise => { + if (key.includes("getRequest") && value && typeof value === "object") { + const encoded = encodeIGetRequest(value as IGetRequest) + await baseStorage.setItem(key, encoded) + return + } + + if (key.includes("Proof") && value && typeof value === "object") { + const encoded = encodeIProof(value as IProof) + await baseStorage.setItem(key, encoded) + return + } + + throw new Error(`Unknown storage key type: ${key}`) + } + + const removeItem = async (key: string): Promise => { + await baseStorage.removeItem(key) + } + + return Object.freeze({ + ...baseStorage, + getItem, + setItem, + removeItem, + }) +} + +export const STORAGE_KEYS = Object.freeze({ + destProof: (orderId: string) => `cancel-order:${orderId}:destProof`, + getRequest: (orderId: string) => `cancel-order:${orderId}:getRequest`, + sourceProof: (orderId: string) => `cancel-order:${orderId}:sourceProof`, +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/load-driver.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/load-driver.ts new file mode 100644 index 00000000..573a56d9 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/load-driver.ts @@ -0,0 +1,3 @@ +// Important: DO NOT REMOVE or RENAME this module +// Note: uses only Node driver during development. +export { loadDriver } from "./drivers/node" diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/types.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/types.ts new file mode 100644 index 00000000..e350b27a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/storage/types.ts @@ -0,0 +1,10 @@ +import type { Driver } from "unstorage" + +export type StorageDriverKey = "node" | "localstorage" | "indexeddb" | "memory" + +export interface CancellationStorageOptions { + env?: StorageDriverKey + basePath?: string +} + +export type LoadDriver = ({ key }: { key: StorageDriverKey; options?: CancellationStorageOptions }) => Driver | null diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/evm-substrate.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/evm-substrate.test.ts new file mode 100644 index 00000000..2458ec53 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/evm-substrate.test.ts @@ -0,0 +1,357 @@ +import { RequestStatus, TimeoutStatus, type HexString } from "@/types" +import EVM_HOST from "@/abis/evmHost" +import PING_MODULE from "@/abis/pingModule" +import ERC6160 from "@/abis/erc6160" +import HANDLER from "@/abis/handler" +import TOKEN_GATEWAY from "@/abis/tokenGateway" +import Keyring, { decodeAddress } from "@polkadot/keyring" +import { u8aToHex } from "@polkadot/util" +import { + type Chain, + createPublicClient, + createWalletClient, + getContract, + http, + keccak256, + parseEventLogs, + parseUnits, + type PrivateKeyAccount, + toHex, +} from "viem" +import { privateKeyToAccount } from "viem/accounts" +import { bscTestnet } from "viem/chains" +import { DEFAULT_LOGGER, normalizeTimestamp, postRequestCommitment } from "@/utils" +import { IndexerClient } from "@/client" +import { createQueryClient } from "@/query-client" +import { bigIntReplacer } from "@/helpers/data.helpers" + +const logger = DEFAULT_LOGGER.withTag("evm-substrate") + +const Source = { + name: "BSC Testnet", + chainId: 97, + stateMachineId: "EVM-97", + networkType: "testnet", + rpcUrls: [process.env.BSC_CHAPEL as string], + consensus: { layer: "BNB Testnet", stateId: "BSC0" }, + ismpHost: "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7", +} as const + +const Destination = { + group: "substrate", + name: "Cere Testnet", + networkType: "testnet", + chainId: "SUBSTRATE-cere", + consensus: { + layer: "Cere", + stateId: "CERE", + }, + rpcUrls: [process.env.CERE_LOCAL as string], + estimatedTransferTime: "10.4 minute", +} + +const Token = { + name: "Cere", + symbol: "CERE", + address: "0xf310641B4B6c032D0c88d72d712C020fCa9805A3", + decimals: 18, +} + +function assertIsToday(timestamp: bigint) { + const dateToCheck = new Date(Number(normalizeTimestamp(timestamp))) + const today = new Date() + + const isToday = + dateToCheck.getDate() === today.getDate() && + dateToCheck.getMonth() === today.getMonth() && + dateToCheck.getFullYear() === today.getFullYear() + + // Difference between timestamps and current timestamps must be less than an hour + let diff = (today.getTime() - dateToCheck.getTime()) / 1000 + expect(isToday).toBeTruthy() + expect(diff < 3600).toBeTruthy() +} + +test.skip("EVM -> Substrate token transfer", { timeout: 5_400_000 }, async () => { + // get token data + const token = Token + const indexer = getIndexer() + + // setup account + // setup EVM account + const sender_account = privateKeyToAccount(process.env.PRIVATE_KEY as HexString) + const recipient_account = getSubstrateAccount() + + const helper = await createHelpers({ + account: sender_account, + chain: bscTestnet, + rpc_url: process.env.BSC_CHAPEL as string, + }) + + // make transfer + const tx_hash = await initiateEvmTx({ + source: Source, + destination: Destination, + from: sender_account.address, + recipient: encodePolkaAddress(recipient_account.address) as HexString, + token: token, + amount: 0.02, + timeout: 3600, + relayerFee: 0, + account: sender_account, + helper: helper, + }) + + const postRequest = await getCommitment(helper, tx_hash) + const commitment = postRequest.commitment + + console.log("Post Request Commitment:", commitment) + const statusStream = indexer.postRequestStatusStream(commitment) + + for await (const status of statusStream) { + switch (status.status) { + case RequestStatus.SOURCE: { + assertIsToday(BigInt(status.metadata.timestamp!)) + break + } + case RequestStatus.SOURCE_FINALIZED: { + assertIsToday(BigInt(status.metadata.timestamp!)) + break + } + + case RequestStatus.HYPERBRIDGE_DELIVERED: { + assertIsToday(BigInt(status.metadata.timestamp!)) + break + } + + case RequestStatus.HYPERBRIDGE_FINALIZED: { + assertIsToday(BigInt(status.metadata.timestamp!)) + break + } + } + + console.log(JSON.stringify(status, null, 4)) + if (status.status === RequestStatus.HYPERBRIDGE_FINALIZED) { + break + } + } + + const req = await indexer.queryRequestWithStatus(commitment) + console.log("Full status", JSON.stringify(req, bigIntReplacer, 4)) + + if (!req) { + throw new Error("No RequestWithStatues") + } + + const statuses = new Set(req.statuses.map((status) => status.status)) + + expect(statuses).toContain(RequestStatus.HYPERBRIDGE_FINALIZED) +}) + +const singleton = (fn: () => T) => { + const EMPTY = "$EMPTY$" + + let output: T | typeof EMPTY = EMPTY + + return (): T => { + if (output !== EMPTY) return output + output = fn() + return output + } +} + +const getIndexer = singleton(() => { + const query_client = createQueryClient({ + url: process.env.INDEXER_URL as string, + }) + + return new IndexerClient({ + source: { + consensusStateId: Source.consensus.stateId, + rpcUrl: Source.rpcUrls[0], + stateMachineId: Source.stateMachineId, + host: Source.ismpHost, + }, + dest: { + hasher: "Blake2", + wsUrl: Destination.rpcUrls[0], + consensusStateId: Destination.consensus.stateId, + stateMachineId: Destination.chainId, + }, + hyperbridge: { + consensusStateId: "PAS0", + stateMachineId: "KUSAMA-4009", + wsUrl: process.env.HYPERBRIDGE_GARGANTUA as string, + }, + queryClient: query_client, + pollInterval: 1000, + }) +}) + +function getSubstrateAccount() { + const keyring = new Keyring({ type: "sr25519" }) + const bob = keyring.addFromUri(process.env.SECRET_PHRASE as string) + + return bob +} + +function encodePolkaAddress(polkaAddress?: string): string { + const keyring = new Keyring() + + return polkaAddress ? keyring.encodeAddress(polkaAddress, 0) : "" +} + +const readAssetId = (token_symbol: string) => { + const encoder = new TextEncoder() + return keccak256(encoder.encode(token_symbol)) +} + +async function initiateEvmTx(params: BridgeParams) { + const { account, helper } = params + const to: HexString = u8aToHex(decodeAddress(params.recipient, false)) + + const evm_token = params.token + const assetId = readAssetId(evm_token.symbol) + + if (!assetId) { + throw new Error(`Invalid assetId for token ${params.token.name}`) + } + + const nativeCost = 0n + + const transfer_params = { + amount: parseUnits(String(params.amount), params.token.decimals), + assetId: assetId, + data: "0x", + dest: toHex(params.destination.chainId), + nativeCost, + redeem: false, + relayerFee: parseUnits( + String(params.relayerFee), + 18, // todo: Fetch FeeToken decimal + ), + timeout: BigInt(params.timeout), + to, + } as const + + DEFAULT_LOGGER.debug("Initializing EVM transaction with params", { + token: params.token, + params: transfer_params, + }) + + const hash = await helper.tokenGateway.write.teleport([transfer_params], { + // chain: bscTestnet, + value: nativeCost, + account, + }) + + // add to store + return hash +} + +async function createHelpers(params: { chain: Chain; account: PrivateKeyAccount; rpc_url: string }) { + const { chain, account, rpc_url: rpc } = params + + const walletClient = createWalletClient({ + chain: chain, + account, + transport: http(rpc), + }) + + const publicClient = createPublicClient({ + chain: chain, + transport: http(process.env.BSC_CHAPEL), + }) + + const sharedClient = { public: publicClient, wallet: walletClient } + + const ping = getContract({ + address: process.env.PING_MODULE_ADDRESS as HexString, + abi: PING_MODULE.ABI, + client: sharedClient, + }) + + const hostAddress = await ping.read.host() + + const host = getContract({ + address: hostAddress, + abi: EVM_HOST.ABI, + client: publicClient, + }) + + const hostParams = await host.read.hostParams() + + const handler = getContract({ + address: hostParams.handler, + abi: HANDLER.ABI, + client: sharedClient, + }) + + const feeToken = getContract({ + address: hostParams.feeToken, + abi: ERC6160.ABI, + client: sharedClient, + }) + + const tokenGateway = getContract({ + abi: TOKEN_GATEWAY.ABI, + address: tokenGatewayAddress, + client: sharedClient, + }) + + return { + chain, + publicClient, + tokenGateway, + walletClient: walletClient, + host, + ping, + handler, + feeToken: feeToken, + } +} + +const tokenGatewayAddress = process.env.TOKEN_GATEWAY_ADDRESS as HexString + +async function getCommitment(helper: THelper, tx_hash: HexString) { + // wait for tx receipt to become available + await new Promise((resolve) => setTimeout(resolve, 5000)) + + const receipt = await helper.publicClient.waitForTransactionReceipt({ + hash: tx_hash, + confirmations: 1, + }) + + logger.log(`Transaction reciept: ${helper.chain.blockExplorers?.default?.url}/tx/${tx_hash}`) + logger.log("Block: ", receipt.blockNumber) + + // parse EvmHost PostRequestEvent emitted in the transcation logs + const event = parseEventLogs({ abi: EVM_HOST.ABI, logs: receipt.logs })[0] + + if (event.eventName !== "PostRequestEvent") { + throw new Error("Unexpected Event type") + } + + const request = event.args + + console.log("PostRequestEvent", { request }) + + const commitment = postRequestCommitment(request).commitment + + return { ...request, commitment } +} + +type THelper = Awaited> + +type BridgeParams = { + readonly source: typeof Source + readonly from: HexString + readonly destination: typeof Destination + readonly token: typeof Token + readonly amount: number + readonly timeout: number + readonly relayerFee: number + readonly recipient: HexString + readonly account: PrivateKeyAccount + readonly helper: Awaited> +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/hyperbridge.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/hyperbridge.test.ts new file mode 100644 index 00000000..d635f4fe --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/hyperbridge.test.ts @@ -0,0 +1,680 @@ +import "log-timestamp" + +import { type HexString, RequestStatus, TimeoutStatus } from "@/types" +import { + createWalletClient, + http, + createPublicClient, + getContract, + decodeFunctionData, + parseEventLogs, + parseUnits, + keccak256, + toHex, +} from "viem" +import { privateKeyToAccount } from "viem/accounts" +import { bscTestnet } from "viem/chains" +import PING_MODULE from "@/abis/pingModule" +import EVM_HOST from "@/abis/evmHost" +import HANDLER from "@/abis/handler" +import TOKEN_GATEWAY from "@/abis/tokenGateway" +import { WsProvider, ApiPromise, Keyring } from "@polkadot/api" +import type { Signer, SignerResult } from "@polkadot/api/types" +import { IndexerClient } from "@/client" +import { getChain } from "@/chain" +import { teleportDot } from "@/utils/xcmGateway" +import type { KeyringPair } from "@polkadot/keyring/types" +import type { SignerPayloadRaw } from "@polkadot/types/types" +import { u8aToHex, hexToU8a } from "@polkadot/util" +import { normalizeTimestamp, postRequestCommitment } from "@/utils" +import { createQueryClient, queryAssetTeleported } from "@/query-client" +import { keccakAsU8a } from "@polkadot/util-crypto" + +const query_client = createQueryClient({ + url: process.env.INDEXER_URL!, +}) + +function assertIsToday(timestamp: bigint) { + const dateToCheck = new Date(Number(normalizeTimestamp(timestamp))) + const today = new Date() + + const isToday = + dateToCheck.getDate() === today.getDate() && + dateToCheck.getMonth() === today.getMonth() && + dateToCheck.getFullYear() === today.getFullYear() + + // Difference between timestamps and current timestamps must be less than an hour + let diff = (today.getTime() - dateToCheck.getTime()) / 1000 + expect(isToday).toBeTruthy() + expect(diff < 3600).toBeTruthy() +} + +describe("Hyperbridge Requests", () => { + let indexer: IndexerClient + + beforeAll(async () => { + const { bscIsmpHost } = await bscSetup() + + // Create chain instances + const destChain = await getChain({ + consensusStateId: "BSC0", + rpcUrl: process.env.BSC_CHAPEL!, + stateMachineId: "EVM-97", + host: bscIsmpHost.address, + }) + + const sourceChain = await getChain({ + consensusStateId: "PAS0", + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + stateMachineId: "KUSAMA-4009", + hasher: "Keccak" as const, + }) + + const hyperbridgeChain = await getChain({ + consensusStateId: "PAS0", + stateMachineId: "KUSAMA-4009", + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + hasher: "Keccak" as const, + }) + + indexer = new IndexerClient({ + source: sourceChain, + dest: destChain, + hyperbridge: hyperbridgeChain, + queryClient: query_client, + pollInterval: 1_000, + }) + }) + + it("should teleport DOT using indexer client", async () => { + const params = { + destination: 97, + recipient: "0x742d35Cc6634C0532925a3b844Bc454e4438f44e" as HexString, + amount: 1, + timeout: BigInt(3600), + paraId: 4009, + } + + const { relayApi, bob, signer } = await hyperbridgeSetup() + + console.log("Api connected") + + try { + // Call the teleport function with indexer + console.log("Teleport Dot with Indexer started") + const result = await teleportDot({ + sourceApi: relayApi, + who: bob.address, + options: { signer }, + xcmGatewayParams: params, + }) + + for await (const event of result) { + console.log(event.kind) + if (event.kind === "Error") { + throw new Error(event.error as string) + } + + if (event.kind === "Ready") { + console.log(event) + } + + if (event.kind === "Finalized") { + // Verify that required fields are present + expect(event.message_id).toBeDefined() + console.log(event) + } + } + } catch (error) { + expect(error).toBeUndefined() + } + }, 300_000) + + it("It should correctly monitor requests that originate from hyperbridge", async () => { + const { bscTestnetClient, bscHandler, bscWalletClient } = await bscSetup() + const { hyperbridge, relayApi, bob, signer } = await hyperbridgeSetup() + const params = { + destination: 97, + recipient: bscWalletClient.account.address as HexString, + amount: 5, + timeout: BigInt(3600), + paraId: 4009, + } + + console.log("Beginning Hyperbridge Post Request Test") + + try { + // Call the teleport function + // + console.log("Teleport Dot started") + // Ensure indexer is defined + if (!indexer) { + throw new Error("Indexer client is not defined") + } + + const result = await teleportDot({ + sourceApi: relayApi, + who: bob.address, + options: { signer }, + xcmGatewayParams: params, + }) + + let commitment + for await (const event of result) { + if (event.kind === "Error") { + throw new Error(event.error as string) + } + + if (event.kind === "Ready") { + console.log(event) + } + + if (event.kind === "Finalized") { + console.log(event) + expect(event.message_id).toBeDefined() + commitment = (await queryAssetTeleported({ id: event.message_id!, queryClient: query_client })) + ?.commitment! as HexString + break + } + } + + expect(commitment).toBeDefined() + + console.log("Beginning Hyperbridge SDK tracking") + + let final_status + for await (const status of indexer.postRequestStatusStream(commitment!)) { + console.log(`Received status: ${status}`) + switch (status.status) { + case RequestStatus.HYPERBRIDGE_FINALIZED: { + console.log( + `Status ${status.status}, Transaction: https://testnet.bscscan.com/tx/${status.metadata.transactionHash}`, + ) + const { args, functionName } = decodeFunctionData({ + abi: HANDLER.ABI, + data: status.metadata.calldata, + }) + + console.log("\n\n\nRaw ABI call data:", status.metadata.calldata, "\n\n\n") + + expect(functionName).toBe("handlePostRequests") + assertIsToday(BigInt(status.metadata.timestamp!)) + + try { + const hash = await bscHandler.write.handlePostRequests(args as any) + await bscTestnetClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log(`Transaction submitted: https://testnet.bscscan.com/tx/${hash}`) + } catch (e) { + console.error("Error self-relaying: ", e) + } + + break + } + case RequestStatus.DESTINATION: { + final_status = RequestStatus.DESTINATION + console.log( + `Status ${status.status}, Transaction: https://testnet.bscscan.com/tx/${status.metadata.transactionHash}`, + ) + assertIsToday(BigInt(status.metadata.timestamp!)) + break + } + } + } + + console.log("Post request status stream has ended") + + expect(final_status).toEqual(RequestStatus.DESTINATION) + } catch (error) { + console.log(`Error ${error}`) + expect(error).toBeUndefined() + } finally { + await hyperbridge.disconnect() + await relayApi.disconnect() + } + }, 1_000_000) + + // non membership proofs are returning trie root mismatch errors due to the Erigon proof bug + it("It should correctly monitor requests that timeout from hyperbridge", async () => { + const { hyperbridge, relayApi, bob, signer } = await hyperbridgeSetup() + const params = { + destination: 97, + recipient: "0x742d35Cc6634C0532925a3b844Bc454e4438f44e" as HexString, + amount: 1, + timeout: BigInt(1), + paraId: 4009, + } + + console.log("Beginning Hyperbridge Post Request Timeout Test") + + try { + // Call the teleport function + // + console.log("Teleport Dot started") + // Ensure indexer is defined + if (!indexer) { + throw new Error("Indexer client is not defined") + } + const stream = await teleportDot({ + sourceApi: relayApi, + who: bob.address, + options: { signer }, + xcmGatewayParams: params, + }) + + let commitment + for await (const event of stream) { + if (event.kind === "Error") { + throw new Error(event.error as string) + } + + if (event.kind === "Ready") { + console.log(event) + } + + if (event.kind === "Finalized") { + console.log(event) + expect(event.message_id).toBeDefined() + commitment = (await queryAssetTeleported({ id: event.message_id!, queryClient: query_client })) + ?.commitment! as HexString + break + } + } + + expect(commitment).toBeDefined() + + console.log("Beginning Hyperbridge SDK Timeout tracking") + + // Wait for request to be indexed + for await (const status of indexer.postRequestStatusStream(commitment!)) { + if (status.status) { + // + console.log(`Request has been indexed: ${status.status}`) + break + } + } + + let final_status + for await (const status of indexer.postRequestTimeoutStream(commitment!)) { + final_status = status.status + switch (status.status) { + case TimeoutStatus.DESTINATION_FINALIZED_TIMEOUT: { + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/extrinsics/${status.metadata?.transactionHash}`, + ) + assertIsToday(BigInt(status.metadata!.timestamp!)) + break + } + case TimeoutStatus.TIMED_OUT: { + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/extrinsics/${status.metadata?.transactionHash}`, + ) + assertIsToday(BigInt(status.metadata!.timestamp!)) + break + } + } + } + + expect(final_status).toEqual(TimeoutStatus.TIMED_OUT) + } catch (error) { + expect(error).toBeUndefined() + } finally { + await hyperbridge.disconnect() + await relayApi.disconnect() + } + }, 1_200_000) + + it("should successfully deliver requests to Hyperbridge", async () => { + const { bscTestnetClient, bscTokenGateway, bscIsmpHost } = await bscSetup() + + // Create chain instances + const sourceChain = await getChain({ + consensusStateId: "BSC0", + rpcUrl: process.env.BSC_CHAPEL!, + stateMachineId: "EVM-97", + host: bscIsmpHost.address, + }) + + const destChain = await getChain({ + consensusStateId: "PAS0", + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + stateMachineId: "KUSAMA-4009", + hasher: "Keccak" as const, + }) + + const hyperbridgeChain = await getChain({ + consensusStateId: "PAS0", + stateMachineId: "KUSAMA-4009", + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + hasher: "Keccak" as const, + }) + + indexer = new IndexerClient({ + source: sourceChain, + dest: destChain, + hyperbridge: hyperbridgeChain, + queryClient: query_client, + pollInterval: 1_000, + }) + console.log("\n\nSending Post Request\n\n") + + const encoder = new TextEncoder() + const hash = await bscTokenGateway.write.teleport([ + { + amount: parseUnits("1", 18), + assetId: keccak256(encoder.encode("DOT")), + data: "0x", + dest: toHex("KUSAMA-4009"), + nativeCost: BigInt(0), + redeem: false, + relayerFee: parseUnits("0", 18), + timeout: BigInt(3600), + to: "0xe95696ab27a7ffc9c1a9969003787c8e3c7dcd87aa36238082eb22e67ec0e4ce", + }, + ]) + + const receipt = await bscTestnetClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log(`Transaction reciept: ${bscTestnet.blockExplorers.default.url}/tx/${hash}`) + console.log("Block: ", receipt.blockNumber) + + // parse EvmHost PostRequestEvent emitted in the transcation logs + const event = parseEventLogs({ abi: EVM_HOST.ABI, logs: receipt.logs })[0] + + if (event.eventName !== "PostRequestEvent") { + throw new Error("Unexpected Event type") + } + + const request = event.args + console.log("PostRequestEvent", { request }) + const commitment = postRequestCommitment(request).commitment + + let final_status + for await (const status of indexer.postRequestStatusStream(commitment)) { + switch (status.status) { + case RequestStatus.SOURCE_FINALIZED: { + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${status.metadata.transactionHash}`, + ) + assertIsToday(BigInt(status.metadata.timestamp!)) + break + } + + case RequestStatus.DESTINATION: { + final_status = status.status + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${status.metadata.transactionHash}`, + ) + assertIsToday(BigInt(status.metadata.timestamp!)) + break + } + } + } + + expect(final_status).toEqual(RequestStatus.DESTINATION) + }, 1_200_000) + + it("should successfully timeout requests sent to Hyperbridge", async () => { + const { bscTestnetClient, bscTokenGateway, bscHandler, bscIsmpHost } = await bscSetup() + + // Create chain instances + const sourceChain = await getChain({ + consensusStateId: "BSC0", + rpcUrl: process.env.BSC_CHAPEL!, + stateMachineId: "EVM-97", + host: bscIsmpHost.address, + }) + + const destChain = await getChain({ + consensusStateId: "PAS0", + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + stateMachineId: "KUSAMA-4009", + hasher: "Keccak" as const, + }) + + const hyperbridgeChain = await getChain({ + consensusStateId: "PAS0", + stateMachineId: "KUSAMA-4009", + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + hasher: "Keccak" as const, + }) + + indexer = new IndexerClient({ + source: sourceChain, + dest: destChain, + hyperbridge: hyperbridgeChain, + queryClient: query_client, + pollInterval: 1_000, + }) + + const { hyperbridge, relayApi, bob, signer } = await hyperbridgeSetup() + + console.log("\n\nSending Post Request\n\n") + + const encoder = new TextEncoder() + const hash = await bscTokenGateway.write.teleport([ + { + amount: parseUnits("1", 18), + assetId: keccak256(encoder.encode("DOT")), + data: "0x", + dest: toHex("KUSAMA-4009"), + nativeCost: BigInt(0), + redeem: false, + relayerFee: parseUnits("0", 18), + timeout: BigInt(1), + to: "0xe95696ab27a7ffc9c1a9969003787c8e3c7dcd87aa36238082eb22e67ec0e4ce", + }, + ]) + + const receipt = await bscTestnetClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log(`Transaction reciept: ${bscTestnet.blockExplorers.default.url}/tx/${hash}`) + console.log("Block: ", receipt.blockNumber) + + // parse EvmHost PostRequestEvent emitted in the transcation logs + const event = parseEventLogs({ abi: EVM_HOST.ABI, logs: receipt.logs })[0] + + if (event.eventName !== "PostRequestEvent") { + throw new Error("Unexpected Event type") + } + + const request = event.args + console.log("PostRequestEvent", { request }) + const commitment = postRequestCommitment(request).commitment + + console.log("PostRequestCommitment", { commitment }) + + // Wait for request to be indexed + for await (const status of indexer.postRequestStatusStream(commitment)) { + if (status.status) { + break + } + } + + // Call the teleport function + // + console.log("Teleport Dot to trigger state machine update event on BSC") + const params = { + destination: 97, + recipient: "0x742d35Cc6634C0532925a3b844Bc454e4438f44e" as HexString, + amount: 1, + timeout: BigInt(3600), + paraId: 4009, + } + // Ensure indexer is defined + if (!indexer) { + throw new Error("Indexer client is not defined") + } + const result = await teleportDot({ + sourceApi: relayApi, + who: bob.address, + options: { signer }, + xcmGatewayParams: params, + }) + + let hyp_commitment + for await (const event of result) { + if (event.kind === "Error") { + throw new Error(event.error as string) + } + + if (event.kind === "Ready") { + console.log(event) + } + + if (event.kind === "Finalized") { + console.log(event) + expect(event.message_id).toBeDefined() + hyp_commitment = (await queryAssetTeleported({ id: event.message_id!, queryClient: query_client })) + ?.commitment! as HexString + break + } + } + + expect(hyp_commitment).toBeDefined() + + let final_status + for await (const timeout of indexer.postRequestTimeoutStream(commitment!)) { + final_status = timeout.status + switch (timeout.status) { + case TimeoutStatus.HYPERBRIDGE_FINALIZED_TIMEOUT: { + console.log( + `Status ${timeout.status}, Transaction: https://testnet.bscscan.com/tx/${timeout.metadata?.transactionHash}`, + ) + const { args, functionName } = decodeFunctionData({ + abi: HANDLER.ABI, + data: timeout.metadata?.calldata! as any, + }) + assertIsToday(BigInt(timeout.metadata!.timestamp!)) + expect(functionName).toBe("handlePostRequestTimeouts") + + try { + const hash = await bscHandler.write.handlePostRequestTimeouts(args as any) + await bscTestnetClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log(`Transaction timeout submitted: https://testnet.bscscan.com/tx/${hash}`) + } catch (e) { + console.error("Error self-relaying: ", e) + } + + break + } + } + } + + expect(final_status).toEqual(TimeoutStatus.TIMED_OUT) + }, 1_200_000) +}) + +async function bscSetup() { + const account = privateKeyToAccount(process.env.PRIVATE_KEY as any) + + const bscWalletClient = createWalletClient({ + chain: bscTestnet, + account, + transport: http(process.env.BSC_CHAPEL), + }) + + const bscTestnetClient = createPublicClient({ + chain: bscTestnet, + transport: http(process.env.BSC_CHAPEL), + }) + + const bscPing = getContract({ + address: process.env.PING_MODULE_ADDRESS! as HexString, + abi: PING_MODULE.ABI, + client: { public: bscTestnetClient, wallet: bscWalletClient }, + }) + + const bscTokenGateway = getContract({ + address: process.env.TOKEN_GATEWAY_ADDRESS! as HexString, + abi: TOKEN_GATEWAY.ABI, + client: { public: bscTestnetClient, wallet: bscWalletClient }, + }) + + const bscIsmpHostAddress = await bscPing.read.host() + + const bscIsmpHost = getContract({ + address: bscIsmpHostAddress, + abi: EVM_HOST.ABI, + client: bscTestnetClient, + }) + + const bscHostParams = await bscIsmpHost.read.hostParams() + + const bscHandler = getContract({ + address: bscHostParams.handler, + abi: HANDLER.ABI, + client: { public: bscTestnetClient, wallet: bscWalletClient }, + }) + + return { + bscTestnetClient, + account, + bscHandler, + bscIsmpHost, + bscTokenGateway, + bscWalletClient, + } +} + +async function hyperbridgeSetup() { + // Set up the connection to a local node + const relayProvider = new WsProvider(process.env.PASEO_RPC_URL) + const relayApi = await ApiPromise.create({ provider: relayProvider }) + + const wsProvider = new WsProvider(process.env.HYPERBRIDGE_GARGANTUA) + const hyperbridge = await ApiPromise.create({ + provider: wsProvider, + typesBundle: { + spec: { + gargantua: { hasher: keccakAsU8a }, + nexus: { hasher: keccakAsU8a }, + }, + }, + }) + + // Set up BOB account from keyring + const keyring = new Keyring({ type: "sr25519" }) + const bob = keyring.addFromUri(process.env.SECRET_PHRASE!) + // Implement the Signer interface + const signer: Signer = createKeyringPairSigner(bob) + + console.log("Apis connected") + + return { + relayApi, + hyperbridge, + signer, + bob, + } +} + +function createKeyringPairSigner(pair: KeyringPair): Signer { + return { + /** + * Signs a raw payload + */ + async signRaw({ data }: SignerPayloadRaw): Promise { + // Sign the data + const signature = u8aToHex(pair.sign(hexToU8a(data), { withType: true })) + + return { + id: 1, + signature, + } + }, + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/intentGateway.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/intentGateway.test.ts new file mode 100644 index 00000000..5d12ffeb --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/intentGateway.test.ts @@ -0,0 +1,2329 @@ +import "log-timestamp" + +import { + createPublicClient, + createWalletClient, + getContract, + http, + maxUint256, + parseEventLogs, + PublicClient, + toHex, + WalletClient, + encodeFunctionData, + decodeFunctionResult, + parseUnits, + erc20Abi, + encodeAbiParameters, +} from "viem" +import { bsc, bscTestnet, mainnet, polygon, sepolia } from "viem/chains" +import { + ChainConfig, + FillerConfig, + type HexString, + IGetRequest, + IHyperbridgeConfig, + Order, + TokenInfo, + PaymentInfo, +} from "@/types" +import { + orderCommitment, + hexToString, + bytes20ToBytes32, + bytes32ToBytes20, + DEFAULT_GRAFFITI, + getStorageSlot, + ADDRESS_ZERO, + ERC20Method, + getGasPriceFromEtherscan, +} from "@/utils" +import EVM_HOST from "@/abis/evmHost" +import { EvmChain, EvmChainParams, IProof, SubstrateChain, getChain } from "@/chain" +import { IntentGateway } from "@/protocols/intents" +import { ChainConfigService } from "@/configs/ChainConfigService" +import { privateKeyToAccount, privateKeyToAddress } from "viem/accounts" +import IntentGatewayABI from "@/abis/IntentGateway" +import erc6160 from "@/abis/erc6160" +import handler from "@/abis/handler" +import { IndexerClient } from "@/client" +import { createQueryClient } from "@/query-client" +import { strict as assert } from "assert" +import { getOrderPlacedFromTx } from "@/utils/txEvents" + +describe.sequential("Intents protocol tests", () => { + it("Should generate the estimatedFee while doing bsc mainnet to eth mainnet", async () => { + const { chainConfigService, bscMainnetIsmpHost, mainnetIsmpHost } = await setUp() + const bscMainnetId = "EVM-56" + const mainnetId = "EVM-1" + const bscEvmChain = new EvmChain({ + chainId: 56, + host: chainConfigService.getHostAddress(bscMainnetId), + rpcUrl: process.env.BSC_MAINNET!, + }) + const mainnetEvmChain = new EvmChain({ + chainId: 1, + host: chainConfigService.getHostAddress(mainnetId), + rpcUrl: process.env.ETH_MAINNET!, + }) + + const bscIntentGateway = new IntentGateway(bscEvmChain, mainnetEvmChain) + + const bscUsdcAsset = chainConfigService.getUsdcAsset(bscMainnetId) + const mainnetUsdcAsset = chainConfigService.getUsdcAsset(mainnetId) + + const order = { + user: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + sourceChain: await bscMainnetIsmpHost.read.host(), + destChain: await mainnetIsmpHost.read.host(), + deadline: 65337297000n, + nonce: 0n, + fees: 0n, + outputs: [ + { + token: bytes20ToBytes32(mainnetUsdcAsset), + amount: 100n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + }, + ], + inputs: [ + { + token: bytes20ToBytes32(bscUsdcAsset), + amount: 100n, + }, + ], + callData: "0x" as HexString, + } + + const { + order: orderWithFee, + feeTokenAmount: estimatedFee, + nativeTokenAmount, + } = await bscIntentGateway.estimateFillOrder(order) + console.log("BSC => ETH") + console.log("Estimated fee:", estimatedFee) + console.log("Native token amount:", nativeTokenAmount) + + assert(estimatedFee > 0n) + assert(estimatedFee === orderWithFee.fees) + }, 1_000_000) + + it("Should generate the estimatedFee while doing bsc mainnet to arbitrum mainnet", async () => { + const { chainConfigService, bscMainnetIsmpHost, arbitrumMainnetIsmpHost } = await setUpBscToArbitrum() + const bscMainnetId = "EVM-56" + const arbitrumMainnetId = "EVM-42161" + const bscEvmChain = new EvmChain({ + chainId: 56, + host: chainConfigService.getHostAddress(bscMainnetId), + rpcUrl: process.env.BSC_MAINNET!, + }) + const arbitrumEvmChain = new EvmChain({ + chainId: 42161, + host: chainConfigService.getHostAddress(arbitrumMainnetId), + rpcUrl: process.env.ARBITRUM_MAINNET!, + }) + + const bscIntentGateway = new IntentGateway(bscEvmChain, arbitrumEvmChain) + + const bscUsdcAsset = chainConfigService.getUsdcAsset(bscMainnetId) + const arbitrumUsdcAsset = chainConfigService.getUsdcAsset(arbitrumMainnetId) + + const order = { + user: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + sourceChain: await bscMainnetIsmpHost.read.host(), + destChain: await arbitrumMainnetIsmpHost.read.host(), + deadline: 65337297000n, + nonce: 0n, + fees: 0n, + outputs: [ + { + token: bytes20ToBytes32(arbitrumUsdcAsset), + amount: 100n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + }, + ], + inputs: [ + { + token: bytes20ToBytes32(bscUsdcAsset), + amount: 100n, + }, + ], + callData: "0x" as HexString, + } + + const { + order: orderWithFee, + feeTokenAmount: estimatedFee, + nativeTokenAmount, + } = await bscIntentGateway.estimateFillOrder(order) + + console.log("BSC => Arbitrum") + console.log("Estimated Fee", estimatedFee) + console.log("Native Token Amount", nativeTokenAmount) + + assert(estimatedFee > 0n) + assert(estimatedFee === orderWithFee.fees) + }, 1_000_000) + + it("Should generate the estimatedFee while doing base mainnet to bsc mainnet", async () => { + const { chainConfigService, baseMainnetIsmpHost, bscMainnetIsmpHost } = await setUpBaseToBsc() + const baseMainnetId = "EVM-8453" + const bscMainnetId = "EVM-56" + const baseEvmChain = new EvmChain({ + chainId: 8453, + host: chainConfigService.getHostAddress(baseMainnetId), + rpcUrl: process.env.BASE_MAINNET!, + }) + const bscEvmChain = new EvmChain({ + chainId: 56, + host: chainConfigService.getHostAddress(bscMainnetId), + rpcUrl: process.env.BSC_MAINNET!, + }) + + const baseIntentGateway = new IntentGateway(baseEvmChain, bscEvmChain) + + const baseUsdcAsset = chainConfigService.getUsdcAsset(baseMainnetId) + const bscUsdcAsset = chainConfigService.getUsdcAsset(bscMainnetId) + + const order = { + user: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + sourceChain: await baseMainnetIsmpHost.read.host(), + destChain: await bscMainnetIsmpHost.read.host(), + deadline: 65337297000n, + nonce: 0n, + fees: 0n, + outputs: [ + { + token: bytes20ToBytes32(bscUsdcAsset), + amount: 100n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + }, + ], + inputs: [ + { + token: bytes20ToBytes32(baseUsdcAsset), + amount: 100n, + }, + ], + callData: "0x" as HexString, + } + + const { + order: orderWithFee, + feeTokenAmount: estimatedFee, + nativeTokenAmount, + } = await baseIntentGateway.estimateFillOrder(order) + + console.log("Base => BSC") + console.log("Estimated Fee", estimatedFee) + console.log("Native Token Amount", nativeTokenAmount) + + assert(estimatedFee > 0n) + assert(estimatedFee === orderWithFee.fees) + }, 1_000_000) + + it("Should generate the estimatedFee while doing bsc mainnet to polygon mainnet", async () => { + const { chainConfigService, bscMainnetIsmpHost, polygonMainnetIsmpHost } = await setUpBscToPolygon() + const bscMainnetId = "EVM-56" + const polygonMainnetId = "EVM-137" + const bscEvmChain = new EvmChain({ + chainId: 56, + host: chainConfigService.getHostAddress(bscMainnetId), + rpcUrl: process.env.BSC_MAINNET!, + }) + const polygonEvmChain = new EvmChain({ + chainId: 137, + host: chainConfigService.getHostAddress(polygonMainnetId), + rpcUrl: process.env.POLYGON_MAINNET!, + }) + + const bscIntentGateway = new IntentGateway(bscEvmChain, polygonEvmChain) + + const bscUsdcAsset = chainConfigService.getUsdcAsset(bscMainnetId) + const polygonUsdcAsset = chainConfigService.getUsdcAsset(polygonMainnetId) + + const order = { + user: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + sourceChain: await bscMainnetIsmpHost.read.host(), + destChain: await polygonMainnetIsmpHost.read.host(), + deadline: 65337297000n, + nonce: 0n, + fees: 0n, + outputs: [ + { + token: bytes20ToBytes32(polygonUsdcAsset), + amount: 100n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + }, + ], + inputs: [ + { + token: bytes20ToBytes32(bscUsdcAsset), + amount: 100n, + }, + ], + callData: "0x" as HexString, + } + + const { + order: orderWithFee, + feeTokenAmount: estimatedFee, + nativeTokenAmount, + } = await bscIntentGateway.estimateFillOrder(order) + + console.log("BSC => Polygon") + console.log("Estimated Fee", estimatedFee) + console.log("Native Token Amount", nativeTokenAmount) + + assert(estimatedFee > 0n) + assert(estimatedFee === orderWithFee.fees) + }, 1_000_000) +}) + +describe.sequential("Swap Tests", () => { + const mainnetId = "EVM-1" + + let intentGateway: IntentGateway + let chainConfigService: ChainConfigService + + beforeAll(async () => { + const setup = await setUp() + chainConfigService = setup.chainConfigService + + const chainId = Number.parseInt(mainnetId.split("-")[1]) + const mainnetEvmChain = new EvmChain({ + chainId: chainId, + host: chainConfigService.getHostAddress(mainnetId), + rpcUrl: process.env.ETH_MAINNET!, + }) + + intentGateway = new IntentGateway(mainnetEvmChain, mainnetEvmChain) + }) + + it("should get V2 quote and simulate swap with exact output", async () => { + const fillerWalletAddress = privateKeyToAccount(process.env.PRIVATE_KEY as HexString).address + const tokenIn = chainConfigService.getDaiAsset(mainnetId) + const tokenOut = chainConfigService.getUsdcAsset(mainnetId) + + const amountOut = parseUnits("1000", 6) + + const result = await intentGateway.swap.findBestProtocolWithAmountOut( + intentGateway.dest.client, + tokenIn, + tokenOut, + amountOut, + mainnetId, + { + selectedProtocol: "v2", + generateCalldata: true, + recipient: fillerWalletAddress, + }, + ) + + assert(result.protocol === "v2", "Should select V2 protocol") + assert(result.amountIn !== maxUint256, "Should return valid amount in") + assert(result.amountIn > parseUnits("1000", 18), "Amount in should be greater than 1000 DAI") + assert(result.transactions, "Should generate transactions") + assert(result.transactions.length > 0, "Should have at least one transaction") + + console.log("V2 Exact Output - Amount In:", result.amountIn) + console.log("V2 Exact Output - Protocol:", result.protocol) + console.log("V2 Exact Output - Number of transactions:", result.transactions.length) + + const calls = result.transactions.map((tx) => ({ + to: tx.to, + data: tx.data, + value: tx.value, + })) + + calls.push({ + to: tokenOut, + data: encodeFunctionData({ + abi: erc6160.ABI, + functionName: "balanceOf", + args: [fillerWalletAddress], + }), + value: 0n, + }) + + const client = intentGateway.dest.client + const slot = await getStorageSlot( + client as any, + tokenIn, + (ERC20Method.BALANCE_OF + bytes20ToBytes32(fillerWalletAddress).slice(2)) as `0x${string}`, + ) + + const simulationResult = await client.simulateCalls({ + account: fillerWalletAddress, + calls, + stateOverrides: [ + { + address: tokenIn, + stateDiff: [ + { + slot: slot as `0x${string}`, + value: toHex(maxUint256), + }, + ], + }, + ], + }) + + assert(simulationResult.results[1].status === "success", "Swap should succeed") + + const balanceResult = simulationResult.results[2] + assert(balanceResult.status === "success", "Balance check should succeed") + + const balance = decodeFunctionResult({ + abi: erc6160.ABI, + functionName: "balanceOf", + data: balanceResult.data, + }) + + assert(balance === amountOut, "Balance should equal expected output amount") + console.log("V2 simulation successful - Output balance:", balance) + }, 1_000_000) + + it("should get V3 quote and simulate swap with exact output", async () => { + const fillerWalletAddress = privateKeyToAccount(process.env.PRIVATE_KEY as HexString).address + const tokenIn = chainConfigService.getDaiAsset(mainnetId) + const tokenOut = chainConfigService.getUsdcAsset(mainnetId) + const amountOut = parseUnits("1000", 6) + + const result = await intentGateway.swap.findBestProtocolWithAmountOut( + intentGateway.dest.client, + tokenIn, + tokenOut, + amountOut, + mainnetId, + { + selectedProtocol: "v3", + generateCalldata: true, + recipient: fillerWalletAddress, + }, + ) + + assert(result.protocol === "v3", "Should select V3 protocol") + assert(result.amountIn !== maxUint256, "Should return valid amount in") + assert(result.fee !== undefined, "Should return fee tier") + assert(result.transactions, "Should generate transactions") + assert(result.transactions.length > 0, "Should have at least one transaction") + + const amountIn = result.amountIn + + const calls = result.transactions.map((tx) => ({ + to: tx.to, + data: tx.data, + value: tx.value, + })) + + calls.push({ + to: tokenOut, + data: encodeFunctionData({ + abi: erc6160.ABI, + functionName: "balanceOf", + args: [fillerWalletAddress], + }), + value: 0n, + }) + + const client = intentGateway.dest.client + const slot = await getStorageSlot( + client as any, + tokenIn, + (ERC20Method.BALANCE_OF + bytes20ToBytes32(fillerWalletAddress).slice(2)) as `0x${string}`, + ) + + const simulationResult = await client.simulateCalls({ + account: fillerWalletAddress, + calls, + stateOverrides: [ + { + address: tokenIn, + stateDiff: [ + { + slot: slot as `0x${string}`, + value: toHex(maxUint256), + }, + ], + }, + ], + }) + + assert(simulationResult.results[1].status === "success", "Swap should succeed") + + const balanceResult = simulationResult.results[2] + assert(balanceResult.status === "success", "Balance check should succeed") + + const balance = decodeFunctionResult({ + abi: erc6160.ABI, + functionName: "balanceOf", + data: balanceResult.data, + }) + + assert(balance === amountOut, "Balance should equal expected output amount") + console.log("V3 simulation successful - Fee tier:", result.fee, "Output balance:", balance) + }, 1_000_000) + + it("should get V2 quote and simulate ETH to USDC swap", async () => { + const fillerWalletAddress = privateKeyToAccount(process.env.PRIVATE_KEY as HexString).address + const tokenIn = ADDRESS_ZERO // ETH + const tokenOut = chainConfigService.getUsdcAsset(mainnetId) + const amountOut = parseUnits("1000", 6) + + const result = await intentGateway.swap.findBestProtocolWithAmountOut( + intentGateway.dest.client, + tokenIn, + tokenOut, + amountOut, + mainnetId, + { + selectedProtocol: "v2", + generateCalldata: true, + recipient: fillerWalletAddress, + }, + ) + + assert(result.protocol === "v2", "Should select V2 protocol") + assert(result.amountIn !== maxUint256, "Should return valid amount in") + assert(result.transactions, "Should generate transactions") + assert(result.transactions.length > 0, "Should have at least one transaction") + + console.log("V2 ETH => USDC - Amount In:", result.amountIn) + + const calls = result.transactions.map((tx) => ({ + to: tx.to, + data: tx.data, + value: tx.value, + })) + + calls.push({ + to: tokenOut, + data: encodeFunctionData({ + abi: erc6160.ABI, + functionName: "balanceOf", + args: [fillerWalletAddress], + }), + value: 0n, + }) + + const client = intentGateway.dest.client + + const simulationResult = await client.simulateCalls({ + account: fillerWalletAddress, + calls, + stateOverrides: [ + { + address: fillerWalletAddress, + balance: result.amountIn * 2n, + }, + ], + }) + + assert(simulationResult.results[0].status === "success", "Swap should succeed") + + const balanceResult = simulationResult.results[1] + assert(balanceResult.status === "success", "Balance check should succeed") + + const balance = decodeFunctionResult({ + abi: erc6160.ABI, + functionName: "balanceOf", + data: balanceResult.data, + }) + + assert(balance === amountOut, "Balance should equal expected output amount") + console.log("V2 ETH => USDC simulation successful - Output balance:", balance) + }, 1_000_000) + + it("should get V2 quote and simulate USDC to ETH swap", async () => { + const fillerWalletAddress = privateKeyToAccount(process.env.PRIVATE_KEY as HexString).address + const tokenIn = chainConfigService.getUsdcAsset(mainnetId) + const tokenOut = ADDRESS_ZERO // ETH + const amountOut = parseUnits("1", 18) + + const result = await intentGateway.swap.findBestProtocolWithAmountOut( + intentGateway.dest.client, + tokenIn, + tokenOut, + amountOut, + mainnetId, + { + selectedProtocol: "v2", + generateCalldata: true, + recipient: fillerWalletAddress, + }, + ) + + assert(result.protocol === "v2", "Should select V2 protocol") + assert(result.amountIn !== maxUint256, "Should return valid amount in") + assert(result.transactions, "Should generate transactions") + assert(result.transactions.length > 0, "Should have at least one transaction") + + console.log("V2 USDC => ETH - Amount In:", result.amountIn) + + const calls = result.transactions.map((tx) => ({ + to: tx.to, + data: tx.data, + value: tx.value, + })) + + const client = intentGateway.dest.client + const slot = await getStorageSlot( + client as any, + tokenIn, + (ERC20Method.BALANCE_OF + bytes20ToBytes32(fillerWalletAddress).slice(2)) as `0x${string}`, + ) + + const simulationResult = await client.simulateCalls({ + account: fillerWalletAddress, + calls, + stateOverrides: [ + { + address: tokenIn, + stateDiff: [ + { + slot: slot as `0x${string}`, + value: toHex(maxUint256 / 3n), + }, + ], + }, + ], + }) + + assert(simulationResult.results[1].status === "success", "Swap should succeed") + + console.log("V2 USDC => ETH simulation successful") + }, 1_000_000) + + it("should get V3 quote and simulate ETH to USDC swap", async () => { + const fillerWalletAddress = privateKeyToAccount(process.env.PRIVATE_KEY as HexString).address + const tokenIn = ADDRESS_ZERO // ETH + const tokenOut = chainConfigService.getUsdcAsset(mainnetId) + const amountOut = parseUnits("1000", 6) + + const result = await intentGateway.swap.findBestProtocolWithAmountOut( + intentGateway.dest.client, + tokenIn, + tokenOut, + amountOut, + mainnetId, + { + selectedProtocol: "v3", + generateCalldata: true, + recipient: fillerWalletAddress, + }, + ) + + assert(result.protocol === "v3", "Should select V3 protocol") + assert(result.amountIn !== maxUint256, "Should return valid amount in") + assert(result.fee !== undefined, "Should return fee tier") + assert(result.transactions, "Should generate transactions") + assert(result.transactions.length > 0, "Should have at least one transaction") + + console.log("V3 ETH => USDC - Amount In:", result.amountIn, "Fee tier:", result.fee) + + const calls = result.transactions.map((tx) => ({ + to: tx.to, + data: tx.data, + value: tx.value, + })) + + calls.push({ + to: tokenOut, + data: encodeFunctionData({ + abi: erc6160.ABI, + functionName: "balanceOf", + args: [fillerWalletAddress], + }), + value: 0n, + }) + + const client = intentGateway.dest.client + + const simulationResult = await client.simulateCalls({ + account: fillerWalletAddress, + calls, + stateOverrides: [ + { + address: fillerWalletAddress, + balance: result.amountIn * 2n, + }, + ], + }) + + assert(simulationResult.results[0].status === "success", "Swap should succeed") + + const balanceResult = simulationResult.results[1] + assert(balanceResult.status === "success", "Balance check should succeed") + + const balance = decodeFunctionResult({ + abi: erc6160.ABI, + functionName: "balanceOf", + data: balanceResult.data, + }) + + assert(balance === amountOut, "Balance should equal expected output amount") + console.log("V3 ETH => USDC simulation successful - Output balance:", balance) + }, 1_000_000) + + it("should get V3 quote and simulate USDC to ETH swap", async () => { + const fillerWalletAddress = privateKeyToAccount(process.env.PRIVATE_KEY as HexString).address + const tokenIn = chainConfigService.getUsdcAsset(mainnetId) + const tokenOut = ADDRESS_ZERO // ETH + const amountOut = parseUnits("1", 18) + + const result = await intentGateway.swap.findBestProtocolWithAmountOut( + intentGateway.dest.client, + tokenIn, + tokenOut, + amountOut, + mainnetId, + { + selectedProtocol: "v3", + generateCalldata: true, + recipient: fillerWalletAddress, + }, + ) + + assert(result.protocol === "v3", "Should select V3 protocol") + assert(result.amountIn !== maxUint256, "Should return valid amount in") + assert(result.fee !== undefined, "Should return fee tier") + assert(result.transactions, "Should generate transactions") + assert(result.transactions.length > 0, "Should have at least one transaction") + + console.log("V3 USDC => ETH - Amount In:", result.amountIn, "Fee tier:", result.fee) + + const calls = result.transactions.map((tx) => ({ + to: tx.to, + data: tx.data, + value: tx.value, + })) + + const client = intentGateway.dest.client + const slot = await getStorageSlot( + client as any, + tokenIn, + (ERC20Method.BALANCE_OF + bytes20ToBytes32(fillerWalletAddress).slice(2)) as `0x${string}`, + ) + + const simulationResult = await client.simulateCalls({ + account: fillerWalletAddress, + calls, + stateOverrides: [ + { + address: tokenIn, + stateDiff: [ + { + slot: slot as `0x${string}`, + value: toHex(maxUint256 / 3n), + }, + ], + }, + ], + }) + + assert(simulationResult.results[1].status === "success", "Swap should succeed") + + console.log("V3 USDC => ETH simulation successful") + }, 1_000_000) + + it("should get V4 quote and simulate ETH to USDC swap", async () => { + const fillerWalletAddress = privateKeyToAccount(process.env.PRIVATE_KEY as HexString).address + const tokenIn = ADDRESS_ZERO // ETH + const tokenOut = chainConfigService.getUsdcAsset(mainnetId) + const amountOut = parseUnits("1000", 6) + + const result = await intentGateway.swap.findBestProtocolWithAmountOut( + intentGateway.dest.client, + tokenIn, + tokenOut, + amountOut, + mainnetId, + + { + selectedProtocol: "v4", + generateCalldata: true, + recipient: fillerWalletAddress, + }, + ) + + assert(result.protocol === "v4", "Should select V4 protocol") + assert(result.amountIn !== maxUint256, "Should return valid amount in") + assert(result.fee !== undefined, "Should return fee tier") + assert(result.transactions, "Should generate transactions") + assert(result.transactions.length > 0, "Should have at least one transaction") + + const amountIn = result.amountIn + + const calls = result.transactions.map((tx) => ({ + to: tx.to, + data: tx.data, + value: 0n, + })) + calls.push({ + to: tokenOut, + data: encodeFunctionData({ + abi: erc6160.ABI, + functionName: "balanceOf", + args: [fillerWalletAddress], + }), + value: 0n, + }) + + const client = intentGateway.dest.client + + // Simulate with balance overrides for universal router + const simulationResult = await client.simulateCalls({ + account: fillerWalletAddress, + calls, + stateOverrides: [ + { + address: chainConfigService.getUniversalRouterAddress(mainnetId), + balance: amountIn, + }, + ], + }) + + assert(simulationResult.results[0].status === "success", "Swap should succeed") + + const balanceResult = simulationResult.results[1] + assert(balanceResult.status === "success", "Balance check should succeed") + + const balance = decodeFunctionResult({ + abi: erc6160.ABI, + functionName: "balanceOf", + data: balanceResult.data, + }) + + assert(balance === amountOut, "Balance should equal expected output amount") + console.log("V4 ETH/USDC simulation successful - Fee tier:", result.fee, "Output balance:", balance) + }, 1_000_000) + + it("should get V4 quote and simulate USDT to USDC swap with Permit2", async () => { + const fillerWalletAddress = privateKeyToAccount(process.env.PRIVATE_KEY as HexString).address + const tokenIn = chainConfigService.getUsdtAsset(mainnetId) + const tokenOut = chainConfigService.getUsdcAsset(mainnetId) + const amountOut = parseUnits("1000", 6) + + const result = await intentGateway.swap.findBestProtocolWithAmountOut( + intentGateway.dest.client, + tokenIn, + tokenOut, + amountOut, + mainnetId, + { + selectedProtocol: "v4", + generateCalldata: true, + recipient: fillerWalletAddress, + }, + ) + + assert(result.protocol === "v4", "Should select V4 protocol") + assert(result.amountIn !== maxUint256, "Should return valid amount in") + assert(result.transactions, "Should generate transactions") + assert(result.transactions.length > 0, "Should have at least one transaction") + + const calls = result.transactions.map((tx) => ({ + to: tx.to, + data: tx.data, + value: 0n, + })) + calls.push({ + to: tokenOut, + data: encodeFunctionData({ + abi: erc6160.ABI, + functionName: "balanceOf", + args: [fillerWalletAddress], + }), + value: 0n, + }) + + const client = intentGateway.dest.client + const slot = await getStorageSlot( + client as any, + tokenIn, + (ERC20Method.BALANCE_OF + bytes20ToBytes32(fillerWalletAddress).slice(2)) as `0x${string}`, + ) + + const simulationResult = await client.simulateCalls({ + account: fillerWalletAddress, + calls, + stateOverrides: [ + { + address: tokenIn, + stateDiff: [ + { + slot: slot as `0x${string}`, + value: toHex(maxUint256 / 3n), + }, + ], + }, + ], + }) + + const balanceResult = simulationResult.results[3] + assert(balanceResult.status === "success", "Balance check should succeed") + + const balance = decodeFunctionResult({ + abi: erc6160.ABI, + functionName: "balanceOf", + data: balanceResult.data, + }) + + assert(balance === amountOut, "Balance should equal expected output amount") + console.log("V4 USDT/USDC simulation successful - Fee tier:", result.fee, "Output balance:", balance) + }, 1_000_000) + + it("should get V2 quote with exact input and generate calldata", async () => { + const tokenIn = chainConfigService.getDaiAsset(mainnetId) + const tokenOut = chainConfigService.getUsdcAsset(mainnetId) + const amountIn = parseUnits("1000", 18) + + const result = await intentGateway.swap.findBestProtocolWithAmountIn( + intentGateway.dest.client, + tokenIn, + tokenOut, + amountIn, + mainnetId, + { + selectedProtocol: "v2", + generateCalldata: true, + recipient: ADDRESS_ZERO, + }, + ) + + assert(result.protocol === "v2", "Should select V2 protocol") + assert(result.amountOut !== BigInt(0), "Should return valid amount out") + assert(result.transactions, "Should generate transactions") + assert(result.transactions.length > 0, "Should have at least one transaction") + + console.log("V2 Exact Input - Amount Out:", result.amountOut) + console.log("V2 Exact Input - Protocol:", result.protocol) + console.log("V2 Exact Input - Number of transactions:", result.transactions.length) + }, 1_000_000) + + it("should get V3 quote with exact input and generate calldata", async () => { + const fillerWalletAddress = privateKeyToAddress(process.env.PRIVATE_KEY as HexString) + const tokenIn = chainConfigService.getDaiAsset(mainnetId) + const tokenOut = chainConfigService.getUsdcAsset(mainnetId) + const amountIn = parseUnits("1000", 18) + + const result = await intentGateway.swap.findBestProtocolWithAmountIn( + intentGateway.dest.client, + tokenIn, + tokenOut, + amountIn, + mainnetId, + { + selectedProtocol: "v3", + generateCalldata: true, + recipient: fillerWalletAddress, + }, + ) + + assert(result.protocol === "v3", "Should select V3 protocol") + assert(result.amountOut !== BigInt(0), "Should return valid amount out") + assert(result.fee !== undefined, "Should return fee tier") + assert(result.transactions, "Should generate transactions") + assert(result.transactions.length > 0, "Should have at least one transaction") + + console.log("V3 Exact Input - Amount Out:", result.amountOut) + console.log("V3 Exact Input - Fee tier:", result.fee) + console.log("V3 Exact Input - Number of transactions:", result.transactions.length) + }, 1_000_000) + + it("should get V4 quote and simulate ETH to USDC swap with exact input", async () => { + const fillerWalletAddress = privateKeyToAccount(process.env.PRIVATE_KEY as HexString).address + const tokenIn = ADDRESS_ZERO // ETH + const tokenOut = chainConfigService.getUsdcAsset(mainnetId) + const amountIn = parseUnits("1", 18) + + const result = await intentGateway.swap.findBestProtocolWithAmountIn( + intentGateway.dest.client, + tokenIn, + tokenOut, + amountIn, + mainnetId, + { + selectedProtocol: "v4", + generateCalldata: true, + recipient: fillerWalletAddress, + }, + ) + + assert(result.protocol === "v4", "Should select V4 protocol") + assert(result.amountOut !== BigInt(0), "Should return valid amount out") + assert(result.fee !== undefined, "Should return fee tier") + assert(result.transactions, "Should generate transactions") + assert(result.transactions.length > 0, "Should have at least one transaction") + + console.log("V4 Exact Input ETH/USDC - Amount Out:", result.amountOut) + console.log("V4 Exact Input ETH/USDC - Fee tier:", result.fee) + + const calls = result.transactions.map((tx) => ({ + to: tx.to, + data: tx.data, + value: 0n, + })) + calls.push({ + to: tokenOut, + data: encodeFunctionData({ + abi: erc6160.ABI, + functionName: "balanceOf", + args: [fillerWalletAddress], + }), + value: 0n, + }) + + const client = intentGateway.dest.client + + const simulationResult = await client.simulateCalls({ + account: fillerWalletAddress, + calls, + stateOverrides: [ + { + address: chainConfigService.getUniversalRouterAddress(mainnetId), + balance: amountIn, + }, + ], + }) + + assert(simulationResult.results[0].status === "success", "Swap should succeed") + + const balanceResult = simulationResult.results[1] + assert(balanceResult.status === "success", "Balance check should succeed") + + const balance = decodeFunctionResult({ + abi: erc6160.ABI, + functionName: "balanceOf", + data: balanceResult.data, + }) + + assert(balance >= result.amountOut, "Balance should be at least the quoted amount out") + console.log("V4 ETH/USDC exact input simulation successful - Output balance:", balance) + }, 1_000_000) + + it("should get V4 quote and simulate USDT to USDC swap with exact input", async () => { + const fillerWalletAddress = privateKeyToAccount(process.env.PRIVATE_KEY as HexString).address + const tokenIn = chainConfigService.getUsdtAsset(mainnetId) + const tokenOut = chainConfigService.getUsdcAsset(mainnetId) + const amountIn = parseUnits("1000", 6) + + const result = await intentGateway.swap.findBestProtocolWithAmountIn( + intentGateway.dest.client, + tokenIn, + tokenOut, + amountIn, + mainnetId, + { + selectedProtocol: "v4", + generateCalldata: true, + recipient: fillerWalletAddress, + }, + ) + + assert(result.protocol === "v4", "Should select V4 protocol") + assert(result.amountOut !== BigInt(0), "Should return valid amount out") + assert(result.fee !== undefined, "Should return fee tier") + assert(result.transactions, "Should generate transactions") + assert(result.transactions.length > 0, "Should have at least one transaction") + + console.log("V4 Exact Input USDT/USDC - Amount Out:", result.amountOut) + console.log("V4 Exact Input USDT/USDC - Fee tier:", result.fee) + + const calls = result.transactions.map((tx) => ({ + to: tx.to, + data: tx.data, + value: 0n, + })) + calls.push({ + to: tokenOut, + data: encodeFunctionData({ + abi: erc6160.ABI, + functionName: "balanceOf", + args: [fillerWalletAddress], + }), + value: 0n, + }) + + const client = intentGateway.dest.client + const slot = await getStorageSlot( + client as any, + tokenIn, + (ERC20Method.BALANCE_OF + bytes20ToBytes32(fillerWalletAddress).slice(2)) as `0x${string}`, + ) + + const simulationResult = await client.simulateCalls({ + account: fillerWalletAddress, + calls, + stateOverrides: [ + { + address: tokenIn, + stateDiff: [ + { + slot: slot as `0x${string}`, + value: toHex(maxUint256 / 3n), + }, + ], + }, + ], + }) + + const balanceResult = simulationResult.results[3] + assert(balanceResult.status === "success", "Balance check should succeed") + + const balance = decodeFunctionResult({ + abi: erc6160.ABI, + functionName: "balanceOf", + data: balanceResult.data, + }) + + assert(balance >= result.amountOut, "Balance should be at least the quoted amount out") + console.log("V4 USDT/USDC exact input simulation successful - Output balance:", balance) + }, 1_000_000) + + it("should find best protocol automatically without selection", async () => { + const tokenIn = chainConfigService.getDaiAsset(mainnetId) + const tokenOut = chainConfigService.getUsdcAsset(mainnetId) + const amountOut = parseUnits("1000", 6) + + // Test without specifying protocol - should auto-select best + const result = await intentGateway.swap.findBestProtocolWithAmountOut( + intentGateway.dest.client, + tokenIn, + tokenOut, + amountOut, + mainnetId, + { + generateCalldata: true, + recipient: ADDRESS_ZERO, + }, + ) + + assert(result.protocol !== null, "Should select a protocol") + assert(result.amountIn !== maxUint256, "Should return valid amount in") + assert(result.transactions, "Should generate transactions") + assert(result.transactions.length > 0, "Should have at least one transaction") + + console.log("Best Protocol Auto-Selected:", result.protocol) + console.log("Amount In:", result.amountIn) + console.log("Number of transactions:", result.transactions.length) + if (result.fee !== undefined) { + console.log("Fee tier:", result.fee) + } + }, 1_000_000) + + it("Should keep the input and output as usdc, but include the final calldata as usdc to a token", async () => { + const bscMainnetId = "EVM-56" + const bscEvmChain = new EvmChain({ + chainId: 56, + host: chainConfigService.getHostAddress(bscMainnetId), + rpcUrl: process.env.BSC_MAINNET!, + }) + + const mainnetEvmChain = new EvmChain({ + chainId: 1, + host: chainConfigService.getHostAddress(mainnetId), + rpcUrl: process.env.ETH_MAINNET!, + }) + const intentGateway = new IntentGateway(mainnetEvmChain, bscEvmChain) + const tokenIn = chainConfigService.getUsdcAsset(mainnetId) + const tokenOut = chainConfigService.getUsdcAsset(bscMainnetId) + const amountIn = parseUnits("5", 6) + const amountOut = parseUnits("5", 18) + const bscCalldispatcher = chainConfigService.getCalldispatcherAddress(bscMainnetId) + const memeToken = "0xEa7C32c66413C7F6DDD94c532594BcDF608Fe2c2" + const slippageinBps = 100n + + const { calldata } = await intentGateway.swap.createMultiHopSwapThroughPair( + intentGateway.dest.client, + tokenOut, + memeToken, + amountOut, + bscMainnetId, + "0x21426d68a9e5df153fe75ce0fed20173ebcb80ef", // User + "v3", + slippageinBps, + ) + + const encodedCalls = encodeAbiParameters( + [ + { + type: "tuple[]", + components: [ + { name: "to", type: "address" }, + { name: "value", type: "uint256" }, + { name: "data", type: "bytes" }, + ], + }, + ], + [calldata], + ) + + const { ethMainnetIsmpHost, bscMainnetIsmpHost } = await setUpEthToBsc() + + const order: Order = { + user: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + sourceChain: await ethMainnetIsmpHost.read.host(), + destChain: await bscMainnetIsmpHost.read.host(), + deadline: 65337297000n, + nonce: 0n, + fees: 0n, + outputs: [ + { + token: bytes20ToBytes32(tokenOut), + amount: amountOut, + beneficiary: bytes20ToBytes32(bscCalldispatcher), + }, + ], + inputs: [{ token: bytes20ToBytes32(tokenIn), amount: amountIn }], + callData: encodedCalls, + } + + const { feeTokenAmount: estimatedFee, nativeTokenAmount } = await intentGateway.estimateFillOrder(order) + console.log("ETH => BSC") + console.log("Estimated fee:", estimatedFee) + console.log("Native token amount:", nativeTokenAmount) + + assert(estimatedFee > 0n) + }, 1_000_000) + + it("Should be able to drop gas on the destination chain, through calldata", async () => { + const bscMainnetId = "EVM-56" + const bscEvmChain = new EvmChain({ + chainId: 56, + host: chainConfigService.getHostAddress(bscMainnetId), + rpcUrl: process.env.BSC_MAINNET!, + }) + + const mainnetEvmChain = new EvmChain({ + chainId: 1, + host: chainConfigService.getHostAddress(mainnetId), + rpcUrl: process.env.ETH_MAINNET!, + }) + const intentGateway = new IntentGateway(mainnetEvmChain, bscEvmChain) + const tokenIn = chainConfigService.getUsdcAsset(mainnetId) + const tokenOut = chainConfigService.getUsdcAsset(bscMainnetId) + + // The user gives 5 USDC, and expects 10c worth of gas, along with 4.9 USDC back + const amountIn = parseUnits("5", 6) + const firstAmountOut = parseUnits("4.9", 18) // This goes to the user + const gasDropUsdcAmount = parseUnits("0.1", 18) // Gets swapped to Native token + const bscCalldispatcher = chainConfigService.getCalldispatcherAddress(bscMainnetId) + + // Filler sends firstAmountOut + gasDropUsdcAmount to the calldispatcher which equals 5 USDC + // Calldispatcher sends firstAmountOut to the user, and gasDropUsdcAmount to universal router for swapping + + // This is the calldata for the calldispatcher sending the funds to the user + // Which is firstAmountout + + let firstCallData = { + to: tokenOut, + data: encodeFunctionData({ + abi: erc6160.ABI, + functionName: "transfer", + args: ["0xFbd87afA57268560ae4D820a5B73Db71916852a7", firstAmountOut], + }), + value: 0n, + } + + // This is the calldata for the calldispatcher using the rest of the amount to swap to native token and send to user + // Even though we are using createMultiHopSwapThroughPair, this is a simple swap to native token + const { calldata } = await intentGateway.swap.createMultiHopSwapThroughPair( + intentGateway.dest.client, + tokenOut, + ADDRESS_ZERO, + gasDropUsdcAmount, + bscMainnetId, + "0xFbd87afA57268560ae4D820a5B73Db71916852a7", // User + "v2", + 100n, // 1% slippage + ) + + const { ethMainnetIsmpHost, bscMainnetIsmpHost } = await setUpEthToBsc() + + const encodedCalls = encodeAbiParameters( + [ + { + type: "tuple[]", + components: [ + { name: "to", type: "address" }, + { name: "value", type: "uint256" }, + { name: "data", type: "bytes" }, + ], + }, + ], + [[firstCallData, ...calldata]], + ) + + const order: Order = { + user: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + sourceChain: await ethMainnetIsmpHost.read.host(), + destChain: await bscMainnetIsmpHost.read.host(), + deadline: 65337297000n, + nonce: 0n, + fees: 0n, + outputs: [ + { + token: bytes20ToBytes32(tokenOut), + amount: firstAmountOut + gasDropUsdcAmount, // 5 USDC` + beneficiary: bytes20ToBytes32(bscCalldispatcher), + }, + ], + inputs: [{ token: bytes20ToBytes32(tokenIn), amount: amountIn }], // 5 USDC + callData: encodedCalls, + } + + const { feeTokenAmount: estimatedFee, nativeTokenAmount } = await intentGateway.estimateFillOrder(order) + console.log("ETH => BSC") + console.log("Estimated fee:", estimatedFee) + console.log("Native token amount:", nativeTokenAmount) + + assert(estimatedFee > 0n) + }, 1_000_000) +}) + +describe.sequential("Order Cancellation tests", () => { + let indexer: IndexerClient + let hyperbridgeInstance: SubstrateChain + + beforeAll(async () => { + const { bscChapelIsmpHost, ethSepoliaIsmpHost, hyperbridge } = await setUpBscToSepoliaOrder() + + const query_client = createQueryClient({ + url: "https://gargantua.indexer.polytope.technology", + }) + + // Create chain instances + const sourceChain = await getChain({ + consensusStateId: "BSC0", + rpcUrl: process.env.BSC_CHAPEL!, + stateMachineId: "EVM-97", + host: bscChapelIsmpHost.address, + }) + + const destChain = await getChain({ + consensusStateId: "ETH0", + rpcUrl: process.env.SEPOLIA!, + stateMachineId: "EVM-11155111", + host: ethSepoliaIsmpHost.address, + }) + + const hyperbridgeChain = await getChain({ + consensusStateId: "PAS0", + stateMachineId: "KUSAMA-4009", + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + hasher: "Keccak" as const, + }) + + indexer = new IndexerClient({ + source: sourceChain, + dest: destChain, + hyperbridge: hyperbridgeChain, + queryClient: query_client, + pollInterval: 1_000, + }) + + await hyperbridge.connect() + hyperbridgeInstance = hyperbridge + }, 1_000_000) + + it("Should cancel order when deadline has reached and yield the necessary proofs", async () => { + const { + bscChapelId, + chainConfigService, + bscChapelIntentGateway, + feeTokenBscChapelAddress, + bscChapelWalletClient, + bscChapelPublicClient, + bscChapelIsmpHost, + ethSepoliaIsmpHost, + } = await setUpBscToSepoliaOrder() + + let bscChapelEvmStructParams: EvmChainParams = { + chainId: 97, + host: "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7", + rpcUrl: process.env.BSC_CHAPEL!, + } + + let ethSepoliaEvmStructParams: EvmChainParams = { + chainId: 11155111, + host: "0x2EdB74C269948b60ec1000040E104cef0eABaae8", + rpcUrl: process.env.SEPOLIA!, + } + + let bscEvmChain = new EvmChain(bscChapelEvmStructParams) // Source Chain + let ethSepoliaEvmChain = new EvmChain(ethSepoliaEvmStructParams) // Dest Chain + let intentGateway = new IntentGateway(bscEvmChain, ethSepoliaEvmChain) + + const daiAsset = chainConfigService.getDaiAsset(bscChapelId) + + const inputs: TokenInfo[] = [ + { + token: bytes20ToBytes32(daiAsset), + amount: 100n, + }, + ] + const outputs: PaymentInfo[] = [ + { + token: "0x0000000000000000000000000000000000000000000000000000000000000000", + amount: 100n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E", + }, + ] + + const order = { + user: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + sourceChain: await bscChapelIsmpHost.read.host(), + destChain: await ethSepoliaIsmpHost.read.host(), + deadline: 0n, // Expired deadline + nonce: 0n, + fees: 1000000n, + outputs, + inputs, + callData: "0x" as HexString, + } + + await approveTokens( + bscChapelWalletClient, + bscChapelPublicClient, + feeTokenBscChapelAddress, + bscChapelIntentGateway.address, + ) + + let hash = await bscChapelIntentGateway.write.placeOrder([order, DEFAULT_GRAFFITI], { + account: privateKeyToAccount(process.env.PRIVATE_KEY as HexString), + chain: bscTestnet, + }) + + let receipt = await bscChapelPublicClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log("Order placed on BSC") + + const orderPlacedEvent = await getOrderPlacedFromTx(bscChapelPublicClient, hash) + + if (!orderPlacedEvent) { + throw new Error("OrderPlaced event not found") + } + + console.log("orderPlacedEvent", orderPlacedEvent) + + const orderPlaced = orderPlacedEvent.args + + const hyperbridgeConfig: IHyperbridgeConfig = { + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + consensusStateId: "PAS0", + stateMachineId: "KUSAMA-4009", + } + + const cancelGenerator = intentGateway.cancelOrder(orderPlaced as Order, indexer) + + let result = await cancelGenerator.next() + + while (!result.done && result.value?.status !== "DESTINATION_FINALIZED") { + const status = result.value?.status + const data = result.value && "data" in result.value ? (result.value as any).data : undefined + + result = await cancelGenerator.next() + } + + expect(result.value?.status).toBe("DESTINATION_FINALIZED") + + if (result.value?.status === "DESTINATION_FINALIZED" && result.value && "data" in result.value) { + const data = (result.value as any).data as { proof: IProof } + expect(data.proof).toBeDefined() + } + const finalizedHeight = (result.value as any).data.proof.height as bigint + + result = await cancelGenerator.next() + expect(result.value?.status).toBe("AWAITING_GET_REQUEST") + + const cancelOptions = { + relayerFee: 10000000000n, + height: finalizedHeight, + } + + hash = await bscChapelIntentGateway.write.cancelOrder([orderPlaced, cancelOptions], { + account: privateKeyToAccount(process.env.PRIVATE_KEY as HexString), + chain: bscTestnet, + }) + + receipt = await bscChapelPublicClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log("Order cancelled on BSC") + + result = await cancelGenerator.next(hash) + + while (!result.done && result.value?.status !== "SOURCE_FINALIZED") { + result = await cancelGenerator.next() + } + expect(result.value?.status).toBe("SOURCE_FINALIZED") + + while (!result.done) { + const status = result.value?.status + + if (status === "HYPERBRIDGE_DELIVERED") { + console.log("Hyperbridge delivered") + result = await cancelGenerator.next() + continue + } + + if (status === "HYPERBRIDGE_FINALIZED") { + const data = (result.value as any).data + if (data?.metadata) { + console.log( + `Status ${result.value.status}, Transaction: https://sepolia.etherscan.io/tx/${data.metadata.transactionHash}`, + ) + } + break + } + + result = await cancelGenerator.next() + } + + expect(result.value?.status).toBe("HYPERBRIDGE_FINALIZED") + }, 1_000_000) + + it("Should quote native amount required for cancellation (BSC -> ETH)", async () => { + const { chainConfigService, bscMainnetIsmpHost, mainnetIsmpHost } = await setUp() + + const bscMainnetId = "EVM-56" + const ethMainnetId = "EVM-1" + + const source = new EvmChain({ + chainId: 56, + host: chainConfigService.getHostAddress(bscMainnetId), + rpcUrl: process.env.BSC_MAINNET!, + }) + + const dest = new EvmChain({ + chainId: 1, + host: chainConfigService.getHostAddress(ethMainnetId), + rpcUrl: process.env.ETH_MAINNET!, + }) + + const intentGateway = new IntentGateway(source, dest) + + const sourceDaiAsset = chainConfigService.getDaiAsset(bscMainnetId) + const destDaiAsset = chainConfigService.getDaiAsset(ethMainnetId) + const user = "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString + + const order: Order = { + user, + sourceChain: await bscMainnetIsmpHost.read.host(), + destChain: await mainnetIsmpHost.read.host(), + deadline: 0n, + nonce: 0n, + fees: 0n, + outputs: [ + { + token: bytes20ToBytes32(destDaiAsset), + amount: 100n, + beneficiary: user, + }, + ], + inputs: [ + { + token: bytes20ToBytes32(sourceDaiAsset), + amount: 100n, + }, + ], + callData: "0x" as HexString, + } + + const nativeRequired = await intentGateway.quoteCancelNative(order) + console.log("Native required for cancellation (BSC -> ETH):", nativeRequired) + expect(nativeRequired >= 0n).toBe(true) + }, 1_000_000) + + it.skip("Should resume order cancellation from stored destProof", async () => { + const { + bscChapelId, + chainConfigService, + bscChapelIntentGateway, + feeTokenBscChapelAddress, + bscChapelWalletClient, + bscChapelPublicClient, + bscChapelIsmpHost, + ethSepoliaIsmpHost, + } = await setUpBscToSepoliaOrder() + + let bscChapelEvmStructParams: EvmChainParams = { + chainId: 97, + host: "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7", + rpcUrl: process.env.BSC_CHAPEL!, + } + + let ethSepoliaEvmStructParams: EvmChainParams = { + chainId: 11155111, + host: "0x2EdB74C269948b60ec1000040E104cef0eABaae8", + rpcUrl: process.env.SEPOLIA!, + } + + let bscEvmChain = new EvmChain(bscChapelEvmStructParams) + let ethSepoliaEvmChain = new EvmChain(ethSepoliaEvmStructParams) + let intentGateway = new IntentGateway(bscEvmChain, ethSepoliaEvmChain) + + const daiAsset = chainConfigService.getDaiAsset(bscChapelId) + + const inputs: TokenInfo[] = [ + { + token: bytes20ToBytes32(daiAsset), + amount: 100n, + }, + ] + const outputs: PaymentInfo[] = [ + { + token: "0x0000000000000000000000000000000000000000000000000000000000000000", + amount: 100n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E", + }, + ] + + const order = { + user: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + sourceChain: await bscChapelIsmpHost.read.host(), + destChain: await ethSepoliaIsmpHost.read.host(), + deadline: 0n, + nonce: 0n, + fees: 1000000n, + outputs, + inputs, + callData: "0x" as HexString, + } + + await approveTokens( + bscChapelWalletClient, + bscChapelPublicClient, + feeTokenBscChapelAddress, + bscChapelIntentGateway.address, + ) + + let hash = await bscChapelIntentGateway.write.placeOrder([order, DEFAULT_GRAFFITI], { + account: privateKeyToAccount(process.env.PRIVATE_KEY as HexString), + chain: bscTestnet, + }) + + await bscChapelPublicClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + const orderPlacedEvent = await getOrderPlacedFromTx(bscChapelPublicClient, hash) + if (!orderPlacedEvent) { + throw new Error("OrderPlaced event not found") + } + + const orderPlaced = orderPlacedEvent.args + + // First attempt: fetch and store destProof + console.log("Test 1: Storing destProof...") + const firstCancelGenerator = intentGateway.cancelOrder(orderPlaced as Order, indexer) + let result = await firstCancelGenerator.next() + + while (!result.done && result.value?.status !== "DESTINATION_FINALIZED") { + result = await firstCancelGenerator.next() + } + + expect(result.value?.status).toBe("DESTINATION_FINALIZED") + const firstProof = (result.value as any).data.proof as IProof + console.log("destProof stored at height", firstProof.height) + + // Second attempt: should resume from stored destProof + console.log("Test 1: Resuming from stored destProof...") + const secondCancelGenerator = intentGateway.cancelOrder(orderPlaced as Order, indexer) + result = await secondCancelGenerator.next() + + expect(result.value?.status).toBe("DESTINATION_FINALIZED") + const resumedProof = (result.value as any).data.proof as IProof + expect(resumedProof.height).toBe(firstProof.height) + expect(resumedProof.stateMachine).toBe(firstProof.stateMachine) + console.log("Successfully resumed from stored destProof") + + // Continue to completion + result = await secondCancelGenerator.next() + expect(result.value?.status).toBe("AWAITING_GET_REQUEST") + + const finalizedHeight = resumedProof.height + const cancelOptions = { + relayerFee: 10000000000n, + height: finalizedHeight, + } + + hash = await bscChapelIntentGateway.write.cancelOrder([orderPlaced, cancelOptions], { + account: privateKeyToAccount(process.env.PRIVATE_KEY as HexString), + chain: bscTestnet, + }) + + await bscChapelPublicClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + result = await secondCancelGenerator.next(hash) + + while (!result.done && result.value?.status !== "SOURCE_FINALIZED") { + result = await secondCancelGenerator.next() + } + expect(result.value?.status).toBe("SOURCE_FINALIZED") + + while (!result.done) { + const status = result.value?.status + if (status === "HYPERBRIDGE_DELIVERED") { + result = await secondCancelGenerator.next() + continue + } + if (status === "HYPERBRIDGE_FINALIZED") { + break + } + result = await secondCancelGenerator.next() + } + + expect(result.value?.status).toBe("HYPERBRIDGE_FINALIZED") + }, 1_000_000) + + it.skip("Should resume order cancellation from stored destProof and getRequest", async () => { + const { + bscChapelId, + chainConfigService, + bscChapelIntentGateway, + feeTokenBscChapelAddress, + bscChapelWalletClient, + bscChapelPublicClient, + bscChapelIsmpHost, + ethSepoliaIsmpHost, + } = await setUpBscToSepoliaOrder() + + let bscChapelEvmStructParams: EvmChainParams = { + chainId: 97, + host: "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7", + rpcUrl: process.env.BSC_CHAPEL!, + } + + let ethSepoliaEvmStructParams: EvmChainParams = { + chainId: 11155111, + host: "0x2EdB74C269948b60ec1000040E104cef0eABaae8", + rpcUrl: process.env.SEPOLIA!, + } + + let bscEvmChain = new EvmChain(bscChapelEvmStructParams) + let ethSepoliaEvmChain = new EvmChain(ethSepoliaEvmStructParams) + let intentGateway = new IntentGateway(bscEvmChain, ethSepoliaEvmChain) + + const daiAsset = chainConfigService.getDaiAsset(bscChapelId) + + const inputs: TokenInfo[] = [ + { + token: bytes20ToBytes32(daiAsset), + amount: 100n, + }, + ] + const outputs: PaymentInfo[] = [ + { + token: "0x0000000000000000000000000000000000000000000000000000000000000000", + amount: 100n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E", + }, + ] + + const order = { + user: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + sourceChain: await bscChapelIsmpHost.read.host(), + destChain: await ethSepoliaIsmpHost.read.host(), + deadline: 0n, + nonce: 0n, + fees: 1000000n, + outputs, + inputs, + callData: "0x" as HexString, + } + + await approveTokens( + bscChapelWalletClient, + bscChapelPublicClient, + feeTokenBscChapelAddress, + bscChapelIntentGateway.address, + ) + + let hash = await bscChapelIntentGateway.write.placeOrder([order, DEFAULT_GRAFFITI], { + account: privateKeyToAccount(process.env.PRIVATE_KEY as HexString), + chain: bscTestnet, + }) + + await bscChapelPublicClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + const orderPlacedEvent = await getOrderPlacedFromTx(bscChapelPublicClient, hash) + if (!orderPlacedEvent) { + throw new Error("OrderPlaced event not found") + } + + const orderPlaced = orderPlacedEvent.args + + // First attempt: store destProof and getRequest + console.log("Test 2: Storing destProof and getRequest...") + const firstCancelGenerator = intentGateway.cancelOrder(orderPlaced as Order, indexer) + let result = await firstCancelGenerator.next() + + while (!result.done && result.value?.status !== "DESTINATION_FINALIZED") { + result = await firstCancelGenerator.next() + } + + expect(result.value?.status).toBe("DESTINATION_FINALIZED") + const finalizedHeight = (result.value as any).data.proof.height as bigint + + result = await firstCancelGenerator.next() + expect(result.value?.status).toBe("AWAITING_GET_REQUEST") + + const cancelOptions = { + relayerFee: 10000000000n, + height: finalizedHeight, + } + + hash = await bscChapelIntentGateway.write.cancelOrder([orderPlaced, cancelOptions], { + account: privateKeyToAccount(process.env.PRIVATE_KEY as HexString), + chain: bscTestnet, + }) + + await bscChapelPublicClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + result = await firstCancelGenerator.next(hash) + console.log("destProof and getRequest stored") + + console.log("Test 2: Resuming from stored destProof and getRequest...") + const secondCancelGenerator = intentGateway.cancelOrder(orderPlaced as Order, indexer) + + result = await secondCancelGenerator.next() + expect(result.value?.status).toBe("DESTINATION_FINALIZED") + + result = await secondCancelGenerator.next() + expect(result.value?.status).not.toBe("AWAITING_GET_REQUEST") + console.log("Successfully resumed from stored destProof and getRequest, next status:", result.value?.status) + + while (!result.done && result.value?.status !== "SOURCE_FINALIZED") { + const status = result.value?.status + if (status === "HYPERBRIDGE_DELIVERED") { + console.log("Received HYPERBRIDGE_DELIVERED, continuing...") + result = await secondCancelGenerator.next() + continue + } + result = await secondCancelGenerator.next() + } + expect(result.value?.status).toBe("SOURCE_FINALIZED") + + while (!result.done) { + const status = result.value?.status + if (status === "HYPERBRIDGE_DELIVERED") { + result = await secondCancelGenerator.next() + continue + } + if (status === "HYPERBRIDGE_FINALIZED") { + break + } + result = await secondCancelGenerator.next() + } + + expect(result.value?.status).toBe("HYPERBRIDGE_FINALIZED") + }, 1_000_000) + + it("Should resume order cancellation from stored destProof, getRequest, and sourceProof", async () => { + const { + bscChapelId, + chainConfigService, + bscChapelIntentGateway, + feeTokenBscChapelAddress, + bscChapelWalletClient, + bscChapelPublicClient, + bscChapelIsmpHost, + ethSepoliaIsmpHost, + } = await setUpBscToSepoliaOrder() + + let bscChapelEvmStructParams: EvmChainParams = { + chainId: 97, + host: "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7", + rpcUrl: process.env.BSC_CHAPEL!, + } + + let ethSepoliaEvmStructParams: EvmChainParams = { + chainId: 11155111, + host: "0x2EdB74C269948b60ec1000040E104cef0eABaae8", + rpcUrl: process.env.SEPOLIA!, + } + + let bscEvmChain = new EvmChain(bscChapelEvmStructParams) + let ethSepoliaEvmChain = new EvmChain(ethSepoliaEvmStructParams) + let intentGateway = new IntentGateway(bscEvmChain, ethSepoliaEvmChain) + + const daiAsset = chainConfigService.getDaiAsset(bscChapelId) + + const inputs: TokenInfo[] = [ + { + token: bytes20ToBytes32(daiAsset), + amount: 100n, + }, + ] + const outputs: PaymentInfo[] = [ + { + token: "0x0000000000000000000000000000000000000000000000000000000000000000", + amount: 100n, + beneficiary: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E", + }, + ] + + const order = { + user: "0x000000000000000000000000Ea4f68301aCec0dc9Bbe10F15730c59FB79d237E" as HexString, + sourceChain: await bscChapelIsmpHost.read.host(), + destChain: await ethSepoliaIsmpHost.read.host(), + deadline: 0n, + nonce: 0n, + fees: 1000000n, + outputs, + inputs, + callData: "0x" as HexString, + } + + await approveTokens( + bscChapelWalletClient, + bscChapelPublicClient, + feeTokenBscChapelAddress, + bscChapelIntentGateway.address, + ) + + let hash = await bscChapelIntentGateway.write.placeOrder([order, DEFAULT_GRAFFITI], { + account: privateKeyToAccount(process.env.PRIVATE_KEY as HexString), + chain: bscTestnet, + }) + + await bscChapelPublicClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + const orderPlacedEvent = await getOrderPlacedFromTx(bscChapelPublicClient, hash) + if (!orderPlacedEvent) { + throw new Error("OrderPlaced event not found") + } + + const orderPlaced = orderPlacedEvent.args + + console.log("Test 3: Storing destProof, getRequest, and sourceProof...") + const firstCancelGenerator = intentGateway.cancelOrder(orderPlaced as Order, indexer) + let result = await firstCancelGenerator.next() + + while (!result.done && result.value?.status !== "DESTINATION_FINALIZED") { + result = await firstCancelGenerator.next() + } + + expect(result.value?.status).toBe("DESTINATION_FINALIZED") + const finalizedHeight = (result.value as any).data.proof.height as bigint + + result = await firstCancelGenerator.next() + expect(result.value?.status).toBe("AWAITING_GET_REQUEST") + + const cancelOptions = { + relayerFee: 10000000000n, + height: finalizedHeight, + } + + hash = await bscChapelIntentGateway.write.cancelOrder([orderPlaced, cancelOptions], { + account: privateKeyToAccount(process.env.PRIVATE_KEY as HexString), + chain: bscTestnet, + }) + + await bscChapelPublicClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + result = await firstCancelGenerator.next(hash) + + while (!result.done && result.value?.status !== "SOURCE_FINALIZED") { + result = await firstCancelGenerator.next() + } + + expect(result.value?.status).toBe("SOURCE_FINALIZED") + const firstSourceHeight = BigInt((result.value as any).data.metadata.blockNumber) + console.log("destProof, getRequest, and sourceProof stored at source height", firstSourceHeight) + + console.log("Test 3: Resuming from stored destProof, getRequest, and sourceProof...") + const secondCancelGenerator = intentGateway.cancelOrder(orderPlaced as Order, indexer) + + result = await secondCancelGenerator.next() + expect(result.value?.status).toBe("DESTINATION_FINALIZED") + + result = await secondCancelGenerator.next() + expect(result.value?.status).not.toBe("AWAITING_GET_REQUEST") + + while (!result.done && result.value?.status !== "SOURCE_FINALIZED") { + result = await secondCancelGenerator.next() + } + + expect(result.value?.status).toBe("SOURCE_FINALIZED") + const resumedSourceHeight = BigInt((result.value as any).data.metadata.blockNumber) + expect(resumedSourceHeight).toBe(firstSourceHeight) + console.log("Successfully resumed from all stored values (destProof, getRequest, sourceProof)") + + while (!result.done) { + const status = result.value?.status + if (status === "HYPERBRIDGE_DELIVERED") { + result = await secondCancelGenerator.next() + continue + } + if (status === "HYPERBRIDGE_FINALIZED") { + break + } + result = await secondCancelGenerator.next() + } + + expect(result.value?.status).toBe("HYPERBRIDGE_FINALIZED") + }, 1_000_000) +}) + +async function setUp() { + const bscMainnetId = "EVM-56" + const mainnetId = "EVM-1" + const chains = [bscMainnetId, mainnetId] + + let chainConfigService = new ChainConfigService() + let chainConfigs: ChainConfig[] = chains.map((chain) => chainConfigService.getChainConfig(chain)) + + const bscMainnetPublicClient = createPublicClient({ + chain: bsc, + transport: http(process.env.BSC_MAINNET!), + }) + + const mainnetPublicClient = createPublicClient({ + chain: mainnet, + transport: http(process.env.ETH_MAINNET!), + }) + + const bscMainnetIsmpHostAddress = "0x24B5d421Ec373FcA57325dd2F0C074009Af021F7" as HexString + const mainnetIsmpHostAddress = "0x792A6236AF69787C40cF76b69B4c8c7B28c4cA20" as HexString + + const bscMainnetIsmpHost = getContract({ + address: bscMainnetIsmpHostAddress, + abi: EVM_HOST.ABI, + client: bscMainnetPublicClient, + }) + + const mainnetIsmpHost = getContract({ + address: mainnetIsmpHostAddress, + abi: EVM_HOST.ABI, + client: mainnetPublicClient, + }) + + return { + chainConfigs, + chainConfigService, + bscMainnetIsmpHost, + mainnetIsmpHost, + } +} + +async function setUpBscToArbitrum() { + const bscMainnetId = "EVM-56" + const arbitrumMainnetId = "EVM-42161" + const chains = [bscMainnetId, arbitrumMainnetId] + + let chainConfigService = new ChainConfigService() + let chainConfigs: ChainConfig[] = chains.map((chain) => chainConfigService.getChainConfig(chain)) + + const bscMainnetPublicClient = createPublicClient({ + chain: bsc, + transport: http(process.env.BSC_MAINNET!), + }) + + const arbitrumPublicClient = createPublicClient({ + chain: { + id: 42161, + name: "arbitrum", + nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, + rpcUrls: { default: { http: [process.env.ARBITRUM_MAINNET!] } }, + }, + transport: http(process.env.ARBITRUM_MAINNET!), + }) + + const bscMainnetIsmpHostAddress = "0x24B5d421Ec373FcA57325dd2F0C074009Af021F7" as HexString + const arbitrumIsmpHostAddress = "0xE05AFD4Eb2ce6d65c40e1048381BD0Ef8b4B299e" as HexString + + const bscMainnetIsmpHost = getContract({ + address: bscMainnetIsmpHostAddress, + abi: EVM_HOST.ABI, + client: bscMainnetPublicClient, + }) + + const arbitrumMainnetIsmpHost = getContract({ + address: arbitrumIsmpHostAddress, + abi: EVM_HOST.ABI, + client: arbitrumPublicClient, + }) + + return { + chainConfigs, + chainConfigService, + bscMainnetIsmpHost, + arbitrumMainnetIsmpHost, + } +} + +async function setUpBaseToBsc() { + const baseMainnetId = "EVM-8453" + const bscMainnetId = "EVM-56" + const chains = [baseMainnetId, bscMainnetId] + + let chainConfigService = new ChainConfigService() + let chainConfigs: ChainConfig[] = chains.map((chain) => chainConfigService.getChainConfig(chain)) + + const basePublicClient = createPublicClient({ + chain: { + id: 8453, + name: "base", + nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, + rpcUrls: { default: { http: [process.env.BASE_MAINNET!] } }, + }, + transport: http(process.env.BASE_MAINNET!), + }) + + const bscMainnetPublicClient = createPublicClient({ + chain: bsc, + transport: http(process.env.BSC_MAINNET!), + }) + + const baseIsmpHostAddress = "0x6FFe92e4d7a9D589549644544780e6725E84b248" as HexString + const bscMainnetIsmpHostAddress = "0x24B5d421Ec373FcA57325dd2F0C074009Af021F7" as HexString + + const baseMainnetIsmpHost = getContract({ + address: baseIsmpHostAddress, + abi: EVM_HOST.ABI, + client: basePublicClient, + }) + + const bscMainnetIsmpHost = getContract({ + address: bscMainnetIsmpHostAddress, + abi: EVM_HOST.ABI, + client: bscMainnetPublicClient, + }) + + return { + chainConfigs, + chainConfigService, + baseMainnetIsmpHost, + bscMainnetIsmpHost, + } +} + +async function setUpEthToBsc() { + const ethMainnetId = "EVM-1" + const bscMainnetId = "EVM-56" + const chains = [ethMainnetId, bscMainnetId] + + let chainConfigService = new ChainConfigService() + let chainConfigs: ChainConfig[] = chains.map((chain) => chainConfigService.getChainConfig(chain)) + + const ethMainnetPublicClient = createPublicClient({ + chain: mainnet, + transport: http(process.env.ETH_MAINNET!), + }) + + const bscMainnetPublicClient = createPublicClient({ + chain: bsc, + transport: http(process.env.BSC_MAINNET!), + }) + + const ethMainnetIsmpHostAddress = "0x792A6236AF69787C40cF76b69B4c8c7B28c4cA20" as HexString + const bscMainnetIsmpHostAddress = "0x24B5d421Ec373FcA57325dd2F0C074009Af021F7" as HexString + + const ethMainnetIsmpHost = getContract({ + address: ethMainnetIsmpHostAddress, + abi: EVM_HOST.ABI, + client: ethMainnetPublicClient, + }) + + const bscMainnetIsmpHost = getContract({ + address: bscMainnetIsmpHostAddress, + abi: EVM_HOST.ABI, + client: bscMainnetPublicClient, + }) + + return { + chainConfigs, + chainConfigService, + ethMainnetIsmpHost, + bscMainnetIsmpHost, + } +} + +async function setUpBscToSepoliaOrder() { + const bscChapelId = "EVM-97" + const ethSepoliaId = "EVM-11155111" + + const chains = [bscChapelId, ethSepoliaId] + + let chainConfigService = new ChainConfigService() + let chainConfigs: ChainConfig[] = chains.map((chain) => chainConfigService.getChainConfig(chain)) + + const account = privateKeyToAccount(process.env.PRIVATE_KEY as any) + + const bscChapelWalletClient = createWalletClient({ + chain: bscTestnet, + account, + transport: http(process.env.BSC_CHAPEL), + }) + + const bscChapelPublicClient = createPublicClient({ + chain: bscTestnet, + transport: http(process.env.BSC_CHAPEL), + }) + + const ethSepoliaPublicClient = createPublicClient({ + chain: sepolia, + transport: http(process.env.SEPOLIA!), + }) + + const bscChapelIntentGateway = getContract({ + address: chainConfigService.getIntentGatewayAddress(bscChapelId), + abi: IntentGatewayABI.ABI, + client: { public: bscChapelPublicClient, wallet: bscChapelWalletClient }, + }) + + const bscChapelIsmpHostAddress = "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7" as HexString + const ethSepoliaIsmpHostAddress = "0x2EdB74C269948b60ec1000040E104cef0eABaae8" as HexString + + const bscChapelIsmpHost = getContract({ + address: bscChapelIsmpHostAddress, + abi: EVM_HOST.ABI, + client: bscChapelPublicClient, + }) + + const ethSepoliaIsmpHost = getContract({ + address: ethSepoliaIsmpHostAddress, + abi: EVM_HOST.ABI, + client: ethSepoliaPublicClient, + }) + + const bscChapelHostParams = await bscChapelIsmpHost.read.hostParams() + + const bscChapelHandler = getContract({ + address: bscChapelHostParams.handler, + abi: handler.ABI, + client: { public: bscChapelPublicClient, wallet: bscChapelWalletClient }, + }) + + const bscChapelFeeToken = getContract({ + address: bscChapelHostParams.feeToken, + abi: erc6160.ABI, + client: { public: bscChapelPublicClient, wallet: bscChapelWalletClient }, + }) + + const hyperbridge = new SubstrateChain({ + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + hasher: "Keccak", + stateMachineId: "KUSAMA-4009", + consensusStateId: "PAS0", + }) + + const feeTokenBscChapelAddress = bscChapelHostParams.feeToken + + return { + account, + hyperbridge, + chainConfigs, + chainConfigService, + bscChapelId, + ethSepoliaIsmpHost, + bscChapelIntentGateway, + bscChapelWalletClient, + bscChapelPublicClient, + feeTokenBscChapelAddress, + bscChapelIsmpHost, + bscChapelFeeToken, + bscChapelHandler, + } +} + +async function setUpBscToPolygon() { + const bscMainnetId = "EVM-56" + const polygonMainnetId = "EVM-137" + const chains = [bscMainnetId, polygonMainnetId] + + let chainConfigService = new ChainConfigService() + let chainConfigs: ChainConfig[] = chains.map((chain) => chainConfigService.getChainConfig(chain)) + + const bscMainnetPublicClient = createPublicClient({ + chain: bsc, + transport: http(process.env.BSC_MAINNET!), + }) + + const polygonPublicClient = createPublicClient({ + chain: { + id: 137, + name: "polygon", + nativeCurrency: { name: "MATIC", symbol: "MATIC", decimals: 18 }, + rpcUrls: { default: { http: [process.env.POLYGON_MAINNET!] } }, + }, + transport: http(process.env.POLYGON_MAINNET!), + }) + + const bscMainnetIsmpHostAddress = "0x24B5d421Ec373FcA57325dd2F0C074009Af021F7" as HexString + const polygonIsmpHostAddress = "0xD8d3db17C1dF65b301D45C84405CcAC1395C559a" as HexString + + const bscMainnetIsmpHost = getContract({ + address: bscMainnetIsmpHostAddress, + abi: EVM_HOST.ABI, + client: bscMainnetPublicClient, + }) + + const polygonMainnetIsmpHost = getContract({ + address: polygonIsmpHostAddress, + abi: EVM_HOST.ABI, + client: polygonPublicClient, + }) + + return { + chainConfigs, + chainConfigService, + bscMainnetIsmpHost, + polygonMainnetIsmpHost, + } +} + +export async function approveTokens( + walletClient: WalletClient, + publicClient: PublicClient, + tokenAddress: HexString, + spender: HexString, +) { + const approval = await publicClient.readContract({ + abi: erc6160.ABI, + address: tokenAddress, + functionName: "allowance", + args: [walletClient.account?.address as HexString, spender], + account: walletClient.account, + }) + + if (approval == 0n) { + console.log("Approving tokens for test") + const tx = await walletClient.writeContract({ + abi: erc6160.ABI, + address: tokenAddress, + functionName: "approve", + args: [spender, maxUint256], + chain: walletClient.chain, + account: walletClient.account!, + }) + + const receipt = await publicClient.waitForTransactionReceipt({ hash: tx }) + console.log("Approved tokens for test:", receipt) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/requests.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/requests.test.ts new file mode 100644 index 00000000..905f2e10 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/requests.test.ts @@ -0,0 +1,607 @@ +import "log-timestamp" + +import { + createPublicClient, + createWalletClient, + decodeFunctionData, + getContract, + hexToBytes, + http, + parseAbi, + parseEventLogs, + toHex, +} from "viem" +import { privateKeyToAccount } from "viem/accounts" +import { bscTestnet, gnosisChiado, sepolia } from "viem/chains" + +import { IndexerClient } from "@/client" +import { type HexString, RequestStatus, TimeoutStatus } from "@/types" +import { getRequestCommitment, postRequestCommitment } from "@/utils" + +import ERC6160 from "@/abis/erc6160" +import PING_MODULE from "@/abis/pingModule" +import EVM_HOST from "@/abis/evmHost" +import HANDLER from "@/abis/handler" +import { EvmChain, SubstrateChain, getChain } from "@/chain" +import { createQueryClient } from "@/query-client" +import { bigIntReplacer } from "@/helpers/data.helpers" + +describe.sequential("Get and Post Requests", () => { + let indexer: IndexerClient + let hyperbridgeInstance: SubstrateChain + + beforeAll(async () => { + const { gnosisChiadoHost, bscIsmpHost, hyperbridge } = await setUp() + + const query_client = createQueryClient({ + url: process.env.INDEXER_URL!, + }) + + // Create chain instances + const sourceChain = await getChain({ + consensusStateId: "BSC0", + rpcUrl: process.env.BSC_CHAPEL!, + stateMachineId: "EVM-97", + host: bscIsmpHost.address, + }) + + const destChain = await getChain({ + consensusStateId: "GNO0", + rpcUrl: process.env.GNOSIS_CHIADO!, + stateMachineId: "EVM-10200", + host: gnosisChiadoHost.address, + }) + + const hyperbridgeChain = await getChain({ + consensusStateId: "PAS0", + stateMachineId: "KUSAMA-4009", + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + hasher: "Keccak" as const, + }) + + indexer = new IndexerClient({ + source: sourceChain, + dest: destChain, + hyperbridge: hyperbridgeChain, + queryClient: query_client, + pollInterval: 1_000, + }) + + await hyperbridge.connect() + hyperbridgeInstance = hyperbridge + }) + + afterAll(async () => { + await hyperbridgeInstance.disconnect() + }) + + describe.sequential("Post Request", () => { + it.skip("should stream and query the timeout status", async () => { + const { bscTestnetClient, bscHandler, bscPing, gnosisChiadoHost } = await setUp() + console.log("\n\nSending Post Request\n\n") + + const hash = await bscPing.write.ping([ + { + dest: await gnosisChiadoHost.read.host(), + count: BigInt(1), + fee: BigInt(0), + module: process.env.PING_MODULE_ADDRESS! as HexString, + timeout: BigInt(150), // so it can timeout + }, + ]) + + // wait for tx receipt to become available + await new Promise((resolve) => setTimeout(resolve, 5000)) + + const receipt = await bscTestnetClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log(`Transaction reciept: ${bscTestnet.blockExplorers.default.url}/tx/${hash}`) + console.log("Block: ", receipt.blockNumber) + + // parse EvmHost PostRequestEvent emitted in the transcation logs + const event = parseEventLogs({ abi: EVM_HOST.ABI, logs: receipt.logs })[0] + + if (event.eventName !== "PostRequestEvent") { + throw new Error("Unexpected Event type") + } + + const request = event.args + + console.log("PostRequestEvent", { request }) + + const commitment = postRequestCommitment(request).commitment + + console.log("Post Request Commitment:", commitment) + const statusStream = indexer.postRequestStatusStream(commitment) + + for await (const status of statusStream) { + console.log(JSON.stringify(status, null, 4)) + + if (status.status === TimeoutStatus.PENDING_TIMEOUT) { + console.log("Request is now timed out", request.timeoutTimestamp) + } + } + + console.log("Starting timeout stream") + + for await (const timeout of indexer.postRequestTimeoutStream(commitment)) { + console.log(JSON.stringify(timeout, null, 4)) + switch (timeout.status) { + case TimeoutStatus.DESTINATION_FINALIZED_TIMEOUT: + console.log( + `Status ${timeout.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${timeout.metadata?.transactionHash}`, + ) + break + case TimeoutStatus.HYPERBRIDGE_TIMED_OUT: + console.log( + `Status ${timeout.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${timeout.metadata?.transactionHash}`, + ) + break + case TimeoutStatus.HYPERBRIDGE_FINALIZED_TIMEOUT: { + console.log( + `Status ${timeout.status}, Transaction: https://testnet.bscscan.com/tx/${timeout.metadata?.transactionHash}`, + ) + const { args, functionName } = decodeFunctionData({ + abi: HANDLER.ABI, + data: timeout.metadata?.calldata! as any, + }) + + expect(functionName).toBe("handlePostRequestTimeouts") + + try { + const hash = await bscHandler.write.handlePostRequestTimeouts(args as any) + await bscTestnetClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log(`Transaction timeout submitted: https://testnet.bscscan.com/tx/${hash}`) + } catch (e) { + console.error("Error self-relaying: ", e) + } + + break + } + default: + console.log("Unknown timeout status") + break + } + } + + const req = await indexer.queryRequestWithStatus(commitment) + console.log("Full status", JSON.stringify(req, null, 4)) + + const hyperbridgeFinalizedStatus = req?.statuses.find( + (status) => status.status === TimeoutStatus.HYPERBRIDGE_FINALIZED_TIMEOUT, + ) + expect(hyperbridgeFinalizedStatus).toBeDefined() + expect(hyperbridgeFinalizedStatus?.metadata.calldata).toBeDefined() + }, 1200_000) + + it("Should scale encode the ISMP message correctly", async () => { + const tx = hyperbridgeInstance.encode({ + kind: "TimeoutPostRequest", + proof: { + consensusStateId: "GNO0", + height: 14521611n, + proof: "0x1c5108f90211a0948c6c60ecc8a4c5b52abc1dd10f443ebb8260026b0d612bca6b9a109212b3b9a0dca88b1cb7af156a5ab839733fba6f5e453f79ae6e9b562d842e79b306f8ecb3a04ad21a053a57b8e4809e4784a1ff1a8c88c8df8aa390a6e564d95c5453b7c77ea05a35d3990b8c0aba736489c26a60d92e05af997ba7650e1634c5c2be8072154aa08341930c3f806f141a6f466a943081d21075cc11bb8d8581ff713fd6a83e0295a00f4c53e27af241636913b27be4e1ab580e581da0ea9d7d0a11c3ba8b73a4df81a08305b1e68ad37a0a002c581a22226a750ea111309034eecf3be7877256cbe10aa098e0f88044865234a7b764acbe97dfdcc346c64f2d63fbea3af8b896d37b865fa083050f2c1090ac0019a31dd6e84003021efc47f5a3c4dedbd169d91be7919a83a0c1faf279cc5357f52d599c445ba348878526d800608cedc27dd895c089c6a057a026c8da47d503c7fec2d87a3f85566fadf6c63df1dd6ec1dda2afa26ea577decda086815dd8cf3128abc904157125d8267f8a4e9ee1e861c56948fa6b6168f3ae91a0a81e2e30cd6cde88f964bcc7c899fd32d407af2a8468edcae84a54bb8fc9d0a3a007bf1d0f0353768af0e089b573ec639ef4249501f7a1039eb450db10cf28f028a0f7531550fcec0ad4b7a0d5f96fa6365d168de66a728c184eeb5ebbe8d191bcf7a00dd5b164fa5d099edcbe7e0162d12641be90c72bb7a8c37e1febc8d1bd5c7b3b805108f90211a09a1d017a8974b524b67f0a921e89e325a8ed0ffe7b8892af8fe4bd2b99c66558a0ddf5c3ffb5c578b4ca041827aef19b4c9ead253d78c67de74c0b253f2f56a77ea0c6b54e42752c28482f9e58ebd22d2d7426f6d5cc338f095ea7671779a9c7f8dca076b618c9095f44fbba89dc5fe73aebf5c45dac20c03c8daccd8f73ceb24cba2aa0f1017b5734304a4ced1661857526efb7855d377242108d31c11643284126ef9ba0f4d111be728321b23cea690a7b9686ea51cbfc823c46f9eb5b6f0b96468feb28a0ee238f35db6c736a95d09fa9008ba8e25db3a43fbb30e7c51d7411ee624e415ba0e0b1ab410b78755484780705e3055846eba49200b103c8a4644cc37550c1d021a03c8cdc01c96ef1e540a6926a3eec37f6b2613238c94cbd42c13cd216c08d9b12a025a093975e7ed5c51bec4532d0c28edf786e1371c461f1481b6bb062ab288608a00ed06e2a0a12022da0413b0df5041454e13f4dfdfa6b83e319bd384c0dc512b3a028e008fbcdba5786df9b8b99f62e9e73371b3495bba3b59a5006c606d5ab0ea7a0692b1bae78364df1315367a88c0c47109517baae362693dd79e5a85fed857d74a0f263961c7a17e6472641655af05daed3b3b70658180b4d0de3d95803c913c407a0f870b1a0ae3b7e6d8f607a338411d65b4b7767eb7fd7ddcf6b9b8d1410277e68a04be83aa290d05e9af78d11ac3143f0b08d7b87521688c753d728ca6b803f6244805108f90211a095fb2f625de7c891c05162826929b968b4e59e64b826afdc9a59fd2541d0e44da0dfc72e5ac52c0ec372d7c3de2a77ea59763c125e47d5205c853b0a9f35f64eafa0df761e6267819e5532ff85de0ef2560aef8f36795ed98229522472c65280cea7a09f7bc872fceb7837b7a0f474e0a6deafbe45874bbab03afbf501e4ac480a9d47a06fb5586dbe8dfc142f0be2a879cc28a864d47166d11c9aa57acf1ba14ef7eef0a00a8b655c514f7b93307f022108ec5a183be1e9096ac9612cd8a17f114bfc3c75a0655d4d9e180ce561d946ce4f1315afda7c1eccf740a2fe95e86091a008deb21aa04c4d1e5d4002204d98071a2665fb129998711eaf18b707d527a9bda172c461c1a0a682c3d910f43d54b4a6ce04cf0a920bf547033a0bdee23c7302c10fdf41c63ca09487089830300a19bd4d687476aa9adb28b9cf5f65cdf61a3518395dd0eff401a03d13224efbb3ff1b18a7c40aaebd674f4a7c691811eb669e6cadf1e043aa0750a0251e21bfe77234fa3bfb9928805af1277f1ee6a926f41093002f9acf1b6d9768a0fe0c5a99d645bd10b0e16cc5be8119c093f0db286e2ae80aeace6228ec23b6eea06ab1924c038d4cacee65538304695f8de7ff1c031376696e0be49b527ea84b3ca0a9c56a940a38b3a66ce5a011305960728cf38199286044e279ff698e9ce0ede6a00c06521e6742b3b7a8aa281a104698f27b0cd8d5390407daa3dea17f090fe569805108f90211a0cf37e8b4ed3bb3639c29e8fc5aeeb5b1206ce04901b9d51da34630ab40f34315a06be004fb4675f716a473c56177b79495b82c591813f8e7117f6b7a48202fdf5ba0d10ed0457ed1f3412db8d7537965ceb6fd564f07665d92cd69f57c60bc397025a058ec4a802528243b2a2119f123c19f035bfafc12ec96a2c0f6b4560ad44ae8d3a013b26d7707e7d0325317ace8de38989c690d04f2108c53be0942fae5cb0138e3a0d560187232aa66cc14705e9a1516c0d0184321df87ef5d47a63793f6b474ba6da089f077ee6eef8bc74ef6abe1684e47a6aada71a642ef9fb196d1b324a1de3c43a084a2bd45a56c85f7ba779b29c6380528d3d41333f153a24f53ff74d5af545235a016fe9254442db909b6a26b20a7c53901258f951c45044e6f9c938c8f589c0a9ba09e60c9e117435ece82c77963133c45ccf747c62496a46096e97d8628b8b13f26a04e3cffb04935d9915ffe51c323617de30dfca9403107ec194e1b85d2b458d7d0a0424ab8ab54a83774bd1eebcedc673cc01003717d17d8020fe85ae0393cc0e192a096da2524c757030a1079aa5d72a7de7be2537bdb41724c3999ef974e601f28cea041dbfd72ec2b4483056c260163bd7992f0cad4aa9ea1431472489c8e72bbe0aaa0e1944e4f8d1e8dffd9c118e209f0da886472ed8f82c4528aa8326ebab2098580a0d30eb7982d94297340a0aa5d612d16faae89df31ab20c2ca9da0378b1c54681a804d03f8d180a008e0eefa0183e091c2d605fce96e72446df6727e3a9573a12d51ca1463e66646a0c97bb301153ef741b60ceade236f492ac9dfd8c2a258caa165d21f987bbddc83a0ccfc8d240c5fb876969cd673617a860c35cffd969e0f6f8bdbc723307a0f841880808080a05daf87c236d3cec54be9abd4152e41f24a3099fec3c963c403469b77399c6d638080a0747e7e7315c251e1e44bcc6b8175e998320352061d7e6221746c3643b40c50508080a063c7bb9c5c53f351713f35177ae7bd54b57d0c62381c7484c1283a8dec6625e980804d01f851808080808080808080a06ec39144a27d9b64efe6db9b9283ceaa0381fd97d4c72f988e08357ef8ed8d9180808080a0bac8d471d92f1032eebdee3ac2a3bddd5804a5d324f1e4b8089540a9705d59ed8080a501f8679e2058ffd1710ecb31f89ba278f724badf9ad59584e4f90244ec528a3308feb846f8440180a0e0a4a5d6327d44a504037776854a3c423f51f21d6261387c4f835eb54299ee04a05f6dcb4dbb25da4ccadbb6f4660038481bdee8d3d6ac92910c7a6afe4b128cd0045058a41b89f4871725e5d898d98ef4bf917601c5eb145108f90211a0bd912e9bb0d615c781c25848951288013fc57ea9f1f0c9c7c26c463c3486a041a0de4f88c2a54f752a9a0753b92d0688f628f3d9bbefc846775787194f69d611e3a08872d061c1cc82e833cdec0343d7459d3d0e783465eb26092984f927fa294a95a06322f53441a8fa9f8de9a7d0f947a78e976060bec2982e37dc83b3b472360d7aa04427c604d9bb04df996a76be768e92e473876790d44ace9276b9889f4f44e411a087fbb0ce680b9454d94e10d38a1ad888de629b837afca4f3606e559dac8f4196a0c1cc52248ff71edccc25edd78e6d45c5d456858812090419d310c9f5da1d1b75a0013eefc9b3abd91a7108312a4139ef7dd76800884a3cbd1ccddf5c480e056934a034a167eb036651a9e0b3ff8478fbf284f6d03487aee0dd92b1ef25926a144779a0c78c14222e216fe49e633194808b14adb90d1495b7f9a85ee9fd9f5244426270a05c7ce9359fb7008546d2198f35599d99c9a8f15856a829310d00a252378bb8fca080c34b805b7f080edfd0f4626dfe375177a2dee0d877c9289dee77c27926515ea061f9a47e3ee5e4267d3d06059b1ead3e0cb6b09648dac712bf1081b2ba96e4efa0ab9264ffab8ad5a39bd49d0145741faee9c48456d886456a3dee823832dbd8b5a07306361d1ec2f53320108262300ad840247c50856ffe4f15288ad938ae5d7311a0e3a754b96c767dbabf0bab5fcdfa89bcd5090069453e9c93cdaeca8f0364175b805108f90211a07709767459e851bfb2afee62a891596801a19a5e312f38804769a6ec1b08503ea016ee2a870298b3820f09eabba17d398bdcb2854dab24913bfe3c42db8aa3076ea01d6e60144cb2af7d5b736d01a67092d000292ea1b579477ecdd7e3e7cea4c8f9a0998e0bb03ddec391b980fd44f4c1d53edce04beb416028c5bebe182740084e88a07c932c5fef311a348194d5c92626476d618abda6cbb85c8ebccd7379d28715d7a00675f4d77b0dbbd293ea6ebe30ac4ecd25783c0fe0b2b5b6ca104a45f7dafc4da041facc5bcb26f8c9782abbc4a9d758807877d2bcb334490f9b30328f6cd6f5cca0e49fdfc75c8c17899310f1dcd5fd39006a1e4b5c7b7348e113498d0c5f8d33cba0d94a1af5fd0fc0612af04d1b34e65cffc55c26b48ccf8304201b36aed8610c13a0e99921dcdad0ee6a59ac3c18e3f8f230d94960e0d9f1f8ee42e66a2800d8ea85a096d74d756c0614605400f2cfed4288b5c749aa83fc8c621df84620ea0805f58ba01a7a062edd3555372c176c3ee44ece0cff099f49c3d31ba623dda195c3ab9a3da07c7363c3181257dda6726da1df43e60fd3466f90780b2788513a4a259a01b69aa0cbd2fd49e10525d9f705ee670e5e4a03a9cd83806ed3673a1ff026cba942b15ca0f18f0a5587d18fc1bccb67f7574f8246b0d49eaaabd6d2d9f108d4802d13452da0b48138276dbe009c9221084821521f01986c2bbb7da9862349ba672c77d9f2d5805107f901d1a0c70c0047a62253b52fc39226a7eaa55356f1f0b75b1e2a0138b6bc61b84355c9a0a9652fd2e605f2f6705de369f9c6abf1b5b0891fb1be73f8bca492003005cc9ca0198b8955576bdbfcb957f6721302a5f4c3748fe8eb9910620a53bba25c70056aa03870f2c723b2c099169030a6edafd911b48ae9ec76e37a6c836b67f891e805faa05b7c3a7edac8be95cd8bf5092c620b9672ccd4e0642c148ece9dd62a7d4d45b7a095f5c32e09269c1476f0098120eeafb998c280092583f915a7338006713a8136a08bd6298bfc98f6f25c8adc4a28005af529478ddd70a48111e9c807032c002393a04704ab8c161e123e6b8c2a2fdc0aba207f37f8269154587ee5c1902e95a8ddd3a0eb96c063c0048ab4ffa32bd3fd0cfd70ebc96222b3ff35c345ce30a0666ea8c280a014e30d258afcc23ea4e16493fd04aa95e87325480e583cda6713dbc3b42766baa0631597a49f516827dd2abda01b46dd1da17ee14ffb5c0e148eb36ba66e915f42a0323a1937eb7d238e2a7f5bd2537d250622e68344d5cc60987c147773dddeb6d680a0956b6cdffa6b1496ae1dfb2284161c98d57503cb91cfc83b6e5aaa79790cec68a0b23d3c71647522b78f5bf35ea01e3fbe2809d6a86305140d970e9734720aa13d804d01f85180a000b4bcbd5d7ff682d53a0e6b503eb602caa980433067877fac4ab5146b88abad80808080a0222ba5547832038028bad582b04df45de3149a42c99514f67cfd89ea9f97a9e78080808080808080808000", + stateMachine: "EVM-10200", + }, + requests: [ + { + body: "0x68656c6c6f2066726f6d2045564d2d3937", + dest: "EVM-10200", + from: "0xFE9f23F0F2fE83b8B9576d3FC94e9a7458DdDD35", + nonce: 2247n, + source: "EVM-97", + timeoutTimestamp: 1740610545n, + to: "0xfe9f23f0f2fe83b8b9576d3fc94e9a7458dddd35", + }, + ], + }) + + const evmChain = new EvmChain({ + rpcUrl: process.env.GNOSIS_CHIADO!, + chainId: 10200, + host: "0x58A41B89F4871725E5D898d98eF4BF917601c5eB", + }) + + const receipt = await evmChain.queryRequestReceipt( + "0x659f5bc8bb0073d4f1a25c1d420770d6aa08177bdf8d6bd6bd8476184d77de7d", + ) + + expect(receipt).toBeUndefined() + + // should not throw + hyperbridgeInstance.api?.tx.ismp.handleUnsigned(hexToBytes(tx).slice(2)) + }) + + it("should successfully stream and query the post request status", async () => { + const { bscTestnetClient, gnosisChiadoHandler, bscPing, gnosisChiadoClient, gnosisChiadoHost } = + await setUp() + console.log("\n\nSending Post Request\n\n") + + const hash = await bscPing.write.ping([ + { + dest: await gnosisChiadoHost.read.host(), + count: BigInt(1), + fee: BigInt(0), + module: process.env.PING_MODULE_ADDRESS! as HexString, + timeout: BigInt(60 * 60), + }, + ]) + + const receipt = await bscTestnetClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log(`Transaction reciept: ${bscTestnet.blockExplorers.default.url}/tx/${hash}`) + console.log("Block: ", receipt.blockNumber) + + // parse EvmHost PostRequestEvent emitted in the transcation logs + const event = parseEventLogs({ abi: EVM_HOST.ABI, logs: receipt.logs })[0] + + if (event.eventName !== "PostRequestEvent") { + throw new Error("Unexpected Event type") + } + + const request = event.args + console.log("PostRequestEvent", { request }) + const commitment = postRequestCommitment(request).commitment + + for await (const status of indexer.postRequestStatusStream(commitment)) { + console.log(JSON.stringify(status, null, 4)) + switch (status.status) { + case RequestStatus.SOURCE_FINALIZED: { + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${status.metadata.transactionHash}`, + ) + break + } + case RequestStatus.HYPERBRIDGE_DELIVERED: { + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${status.metadata.transactionHash}`, + ) + break + } + case RequestStatus.HYPERBRIDGE_FINALIZED: { + console.log( + `Status ${status.status}, Transaction: https://gnosis-chiado.blockscout.com/tx/${status.metadata.transactionHash}`, + ) + const { args, functionName } = decodeFunctionData({ + abi: HANDLER.ABI, + data: status.metadata.calldata, + }) + + expect(functionName).toBe("handlePostRequests") + + try { + const hash = await gnosisChiadoHandler.write.handlePostRequests(args as any) + await gnosisChiadoClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log(`Transaction submitted: https://gnosis-chiado.blockscout.com/tx/${hash}`) + } catch (e) { + console.error("Error self-relaying: ", e) + } + + break + } + case RequestStatus.DESTINATION: { + console.log( + `Status ${status.status}, Transaction: https://gnosis-chiado.blockscout.com/tx/${status.metadata.transactionHash}`, + ) + break + } + } + } + + const req = await indexer.queryRequestWithStatus(commitment) + console.log(JSON.stringify(req, bigIntReplacer, 4)) + expect(req?.statuses.length).toBe(5) + }, 1_000_000) + }) + + describe.sequential("Get Request", () => { + it("should successfully stream and query the get request status to yield the finality events", async () => { + const { bscTestnetClient, bscPing, ethSepoliaHost, bscIsmpHost, bscHandler } = await setUp() + console.log("\n\nSending Get Request\n\n") + + const latestHeight = await hyperbridgeInstance.latestStateMachineHeight({ + stateId: { Evm: 11155111 }, + consensusStateId: toHex("ETH0"), + }) + + const hash = await bscPing.write.dispatch([ + { + source: await bscIsmpHost.read.host(), + dest: await ethSepoliaHost.read.host(), + nonce: await bscIsmpHost.read.nonce(), + from: process.env.PING_MODULE_ADDRESS! as `0x${string}`, + timeoutTimestamp: BigInt(Math.floor(Date.now() / 1000) + 60 * 60), + keys: ["0xFE9f23F0F2fE83b8B9576d3FC94e9a7458DdDD35"], + height: latestHeight, + context: "0x", + }, + ]) + + const receipt = await bscTestnetClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log(`Transaction reciept: ${bscTestnet.blockExplorers.default.url}/tx/${hash}`) + console.log("Block: ", receipt.blockNumber) + + // parse EvmHost GetRequestEvent emitted in the transcation logs + const event = parseEventLogs({ abi: EVM_HOST.ABI, logs: receipt.logs })[0] + + if (event.eventName !== "GetRequestEvent") { + throw new Error("Unexpected Event type") + } + + const request = event.args + console.log("GetRequestEvent", { request }) + const commitment = getRequestCommitment({ ...request, keys: [...request.keys] }) + console.log("Get Request Commitment: ", commitment) + + for await (const status of indexer.getRequestStatusStream(commitment)) { + switch (status.status) { + case RequestStatus.SOURCE_FINALIZED: { + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${status.metadata.transactionHash}`, + ) + break + } + case RequestStatus.HYPERBRIDGE_DELIVERED: { + console.log( + `Status ${status.status}, Transaction: https://gargantua.statescan.io/#/extrinsics/${status.metadata.transactionHash}`, + ) + break + } + case RequestStatus.HYPERBRIDGE_FINALIZED: { + console.log( + `Status ${status.status}, Transaction: https://testnet.bscscan.com/tx/${status.metadata.transactionHash}`, + ) + const { args, functionName } = decodeFunctionData({ + abi: HANDLER.ABI, + data: status.metadata.calldata, + }) + + expect(functionName).toBe("handleGetResponses") + + try { + const hash = await bscHandler.write.handleGetResponses(args as any) + await bscTestnetClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log(`Transaction submitted: https://testnet.bscscan.com/tx/${hash}`) + } catch (e) { + console.error("Error self-relaying: ", e) + } + + break + } + case RequestStatus.DESTINATION: { + console.log( + `Status ${status.status}, Transaction: https://testnet.bscscan.com/tx/${status.metadata.transactionHash}`, + ) + break + } + } + } + + const req = await indexer.queryGetRequest(commitment) + expect(req?.statuses.length).toBe(3) + + const reqWithStatus = await indexer.queryGetRequestWithStatus(commitment) + console.log("Full status from queryGetRequestWithStatus:", JSON.stringify(reqWithStatus, bigIntReplacer, 4)) + + expect(reqWithStatus).toBeDefined() + + const sourceFinalizedStatus = reqWithStatus?.statuses.find( + (status) => status.status === RequestStatus.SOURCE_FINALIZED, + ) + expect(sourceFinalizedStatus).toBeDefined() + + const hyperbridgeFinalizedStatus = reqWithStatus?.statuses.find( + (status) => status.status === RequestStatus.HYPERBRIDGE_FINALIZED, + ) + + expect(hyperbridgeFinalizedStatus).toBeDefined() + expect(hyperbridgeFinalizedStatus?.metadata.calldata).toBeDefined() + }, 1_800_000) + + it.skip("should successfully query the get request with its finality statuses", async () => { + const { bscPing, ethSepoliaHost, bscIsmpHost, bscTestnetClient } = await setUp() + console.log("\n\nSending Get Request for queryGetRequestWithStatus test\n\n") + + const latestHeight = await hyperbridgeInstance.latestStateMachineHeight({ + stateId: { Evm: 11155111 }, + consensusStateId: toHex("ETH0"), + }) + + const hash = await bscPing.write.dispatch([ + { + source: await bscIsmpHost.read.host(), + dest: await ethSepoliaHost.read.host(), + nonce: await bscIsmpHost.read.nonce(), + from: process.env.PING_MODULE_ADDRESS! as `0x${string}`, + timeoutTimestamp: BigInt(Math.floor(Date.now() / 1000) + 60 * 60), + keys: ["0xFE9f23F0F2fE83b8B9576d3FC94e9a7458DdDD35"], + height: latestHeight, + context: "0x", + }, + ]) + + const receipt = await bscTestnetClient.waitForTransactionReceipt({ + hash, + confirmations: 1, + }) + + console.log(`Transaction receipt: ${bscTestnet.blockExplorers.default.url}/tx/${hash}`) + + const event = parseEventLogs({ abi: EVM_HOST.ABI, logs: receipt.logs })[0] + if (event.eventName !== "GetRequestEvent") { + throw new Error("Unexpected Event type") + } + + const request = event.args + const commitment = getRequestCommitment({ ...request, keys: [...request.keys] }) + console.log("Get Request Commitment: ", commitment) + + console.log("Waiting 200 seconds for indexer to process finality events...") + await new Promise((resolve) => setTimeout(resolve, 200000)) + + const req = await indexer.queryGetRequestWithStatus(commitment) + console.log("Full status from queryGetRequestWithStatus:", JSON.stringify(req, bigIntReplacer, 4)) + + expect(req).toBeDefined() + + const sourceFinalizedStatus = req?.statuses.find( + (status) => status.status === RequestStatus.SOURCE_FINALIZED, + ) + expect(sourceFinalizedStatus).toBeDefined() + + const hyperbridgeFinalizedStatus = req?.statuses.find( + (status) => status.status === RequestStatus.HYPERBRIDGE_FINALIZED, + ) + + expect(hyperbridgeFinalizedStatus).toBeDefined() + expect(hyperbridgeFinalizedStatus?.metadata.calldata).toBeDefined() + }, 1_800_000) + }) +}) + +async function setUp() { + const account = privateKeyToAccount(process.env.PRIVATE_KEY as any) + + const bscWalletClient = createWalletClient({ + chain: bscTestnet, + account, + transport: http(process.env.BSC_CHAPEL), + }) + + const gnosisChiadoWallet = createWalletClient({ + chain: gnosisChiado, + account, + transport: http(process.env.GNOSIS_CHIADO), + }) + + const bscTestnetClient = createPublicClient({ + chain: bscTestnet, + transport: http(process.env.BSC_CHAPEL), + }) + + const gnosisChiadoClient = createPublicClient({ + chain: gnosisChiado, + transport: http(process.env.GNOSIS_CHIADO), + }) + + const ethSepoliaClient = createPublicClient({ + chain: sepolia, + transport: http(process.env.SEPOLIA), + }) + + const bscPing = getContract({ + address: process.env.PING_MODULE_ADDRESS! as HexString, + abi: PING_MODULE.ABI, + client: { public: bscTestnetClient, wallet: bscWalletClient }, + }) + + const bscIsmpHostAddress = await bscPing.read.host() + + const bscIsmpHost = getContract({ + address: bscIsmpHostAddress, + abi: EVM_HOST.ABI, + client: bscTestnetClient, + }) + + const bscHostParams = await bscIsmpHost.read.hostParams() + + const bscHandler = getContract({ + address: bscHostParams.handler, + abi: HANDLER.ABI, + client: { public: bscTestnetClient, wallet: bscWalletClient }, + }) + + const bscFeeToken = getContract({ + address: bscHostParams.feeToken, + abi: ERC6160.ABI, + client: { public: bscTestnetClient, wallet: bscWalletClient }, + }) + + const gnosisChiadoPing = getContract({ + address: process.env.PING_MODULE_ADDRESS! as HexString, + abi: PING_MODULE.ABI, + client: { public: gnosisChiadoClient, wallet: gnosisChiadoWallet }, + }) + + const ethSepoliaPing = getContract({ + address: process.env.PING_MODULE_ADDRESS! as HexString, + abi: PING_MODULE.ABI, + client: ethSepoliaClient, + }) + + const ethSepoliaHostAddress = await ethSepoliaPing.read.host() + + const gnosisChiadoHostAddress = await gnosisChiadoPing.read.host() + + const gnosisChiadoHost = getContract({ + address: gnosisChiadoHostAddress, + abi: EVM_HOST.ABI, + client: gnosisChiadoClient, + }) + + const ethSepoliaHost = getContract({ + address: ethSepoliaHostAddress, + abi: EVM_HOST.ABI, + client: ethSepoliaClient, + }) + + const gnosisChiadoHostParams = await gnosisChiadoHost.read.hostParams() + + const gnosisChiadoHandler = getContract({ + address: gnosisChiadoHostParams.handler, + abi: HANDLER.ABI, + client: { public: gnosisChiadoClient, wallet: gnosisChiadoWallet }, + }) + + const tokenFaucet = getContract({ + address: "0x17d8cc0859fbA942A7af243c3EBB69AbBfe0a320", + abi: parseAbi(["function drip(address token) public"]), + client: { public: bscTestnetClient, wallet: bscWalletClient }, + }) + + const hyperbridge = new SubstrateChain({ + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + hasher: "Keccak", + stateMachineId: "KUSAMA-4009", + consensusStateId: "PAS0", + }) + + return { + ethSepoliaClient, + ethSepoliaHost, + bscTestnetClient, + bscFeeToken, + account, + tokenFaucet, + gnosisChiadoHandler, + bscHandler, + bscPing, + gnosisChiadoPing, + gnosisChiadoClient, + gnosisChiadoHost, + bscIsmpHost, + hyperbridge, + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/tokenPrices.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/tokenPrices.test.ts new file mode 100644 index 00000000..9722abab --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/sequential/tokenPrices.test.ts @@ -0,0 +1,96 @@ +import "log-timestamp" +import { describe, it, expect, beforeAll } from "vitest" +import { createQueryClient, _queryTokenPriceInternal } from "@/query-client" +import type { IndexerQueryClient } from "@/types" + +describe.sequential("Token Price and Registry Integration Tests", () => { + let queryClient: IndexerQueryClient + + beforeAll(async () => { + queryClient = createQueryClient({ url: process.env.INDEXER_URL! }) + }, 10_000) + + it.sequential( + "should query and validate token price indexing", + async () => { + try { + const symbol = "DOT" + const tokenPrice = await _queryTokenPriceInternal({ symbol, queryClient }) + + expect(tokenPrice).toBeDefined() + expect(tokenPrice!.symbol).toBe(symbol) + expect(tokenPrice!.currency).toBe("USD") + expect(tokenPrice!.lastUpdatedAt).toBeDefined() + expect(parseFloat(tokenPrice!.price)).toBeGreaterThan(0) + } catch (error) { + console.error(error) + expect(error).toBeUndefined() + } + }, + 20_000, + ) + + it.sequential( + "should validate token price updates and freshness", + async () => { + const tokenPricesQuery = ` + query RecentTokenPrices { + tokenPrices( + first: 5, + orderBy: LAST_UPDATED_AT_DESC + ) { + nodes { + symbol + price + lastUpdatedAt + } + } + } + ` + + const result = (await queryClient.request(tokenPricesQuery)) as { + tokenPrices: { nodes: [{ symbol: string; price: string; lastUpdatedAt: bigint }] } + } + expect(result.tokenPrices.nodes).toBeInstanceOf(Array) + expect(result.tokenPrices.nodes.length).toBeGreaterThan(0) + + const now = Date.now() + for (const tokenPrice of result.tokenPrices.nodes) { + expect(tokenPrice.symbol).toBeDefined() + expect(parseFloat(tokenPrice.price)).toBeGreaterThan(0) + + const lastUpdated = Number(tokenPrice.lastUpdatedAt) + const hoursSinceUpdate = (now - lastUpdated) / (1000 * 60 * 60) + + expect(lastUpdated).toBeGreaterThan(0) + expect(hoursSinceUpdate).toBeLessThanOrEqual(1) + } + }, + 15_000, + ) + + it.sequential( + "should validate indexer connectivity and basic functionality", + async () => { + const tokens = ` + query TokenRegistries { + tokenRegistries(first: 1) { + totalCount + } + } + ` + + try { + const result = (await queryClient.request(tokens)) as { tokenRegistries: { totalCount: number } } + + expect(result.tokenRegistries).toBeDefined() + expect(typeof result.tokenRegistries.totalCount).toBe("number") + expect(result.tokenRegistries.totalCount).toBeGreaterThan(0) + } catch (error) { + console.error(error) + expect(error).toBeUndefined() + } + }, + 10_000, + ) +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/setup.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/setup.ts new file mode 100644 index 00000000..7f1b889d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/setup.ts @@ -0,0 +1,7 @@ +process.env.NODE_ENV = "test" + +import * as dotenv from "dotenv" +import * as path from "node:path" + +const root = process.cwd() +dotenv.config({ path: path.resolve(root, "../../.env.local") }) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/stateCalls.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/stateCalls.test.ts new file mode 100644 index 00000000..c9cab2e6 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/stateCalls.test.ts @@ -0,0 +1,131 @@ +import "log-timestamp" + +import type { HexString, IEvmConfig, ISubstrateConfig } from "@/types" +import { http, createPublicClient, getContract, toHex } from "viem" + +import { bscTestnet } from "viem/chains" +import PING_MODULE from "@/abis/pingModule" + +import { getChain } from "@/chain" + +describe.sequential("State Queries", () => { + let bscConfig: IEvmConfig + let hyperbridgeConfig: ISubstrateConfig + + beforeAll(async () => { + const { bscIsmpHostAddress } = await bscSetup() + bscConfig = { + consensusStateId: "BSC0", + rpcUrl: process.env.BSC_CHAPEL!, + stateMachineId: "EVM-97", + host: bscIsmpHostAddress, + } + + hyperbridgeConfig = { + consensusStateId: "PAS0", + stateMachineId: "KUSAMA-4009", + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + hasher: "Keccak", + } + }) + + it("should read latest state machine height on EVM", async () => { + try { + const chain = await getChain(bscConfig) + const stateMachineId = { stateId: { Kusama: 4009 }, consensusStateId: toHex("PASO") } + const latestHeight = await chain.latestStateMachineHeight(stateMachineId) + expect(latestHeight).toBeGreaterThan(0) + + console.log(latestHeight) + } catch (err) { + console.error(err) + expect(err).toBeUndefined() + } + }, 300_000) + + it("should read latest state machine height on Substrate", async () => { + try { + const chain = await getChain(hyperbridgeConfig) + const stateMachineId = { stateId: { Evm: 97 }, consensusStateId: toHex("BSC0") } + const latestHeight = await chain.latestStateMachineHeight(stateMachineId) + expect(latestHeight).toBeGreaterThan(0) + console.log(latestHeight) + } catch (err) { + console.error(err) + expect(err).toBeUndefined() + } + }, 300_000) + + it("should read challenge period on Substrate", async () => { + try { + const chain = await getChain(hyperbridgeConfig) + const stateMachineId = { stateId: { Evm: 97 }, consensusStateId: toHex("BSC0") } + const challengePeriod = await chain.challengePeriod(stateMachineId) + expect(challengePeriod).toBe(BigInt(0)) + } catch (err) { + console.error(err) + expect(err).toBeUndefined() + } + }, 300_000) + + it("should read challenge period on EVM", async () => { + try { + const chain = await getChain(bscConfig) + const stateMachineId = { stateId: { Kusama: 4009 }, consensusStateId: toHex("PASO") } + const challengePeriod = await chain.challengePeriod(stateMachineId) + expect(challengePeriod).toBe(BigInt(0)) + } catch (err) { + console.error(err) + expect(err).toBeUndefined() + } + }, 300_000) + + it("should read state machine update time on EVM", async () => { + try { + const chain = await getChain(bscConfig) + const stateMachineId = { stateId: { Kusama: 4009 }, consensusStateId: toHex("PASO") } + const latestHeight = await chain.latestStateMachineHeight(stateMachineId) + const stateMachineheight = { id: stateMachineId, height: latestHeight } + const updateTime = await chain.stateMachineUpdateTime(stateMachineheight) + expect(updateTime).toBeGreaterThan(0) + } catch (err) { + console.error(err) + expect(err).toBeUndefined() + } + }, 300_000) + + it("should read state machine update time on substrate", async () => { + try { + const chain = await getChain(hyperbridgeConfig) + const stateMachineId = { stateId: { Evm: 97 }, consensusStateId: toHex("BSC0") } + const latestHeight = await chain.latestStateMachineHeight(stateMachineId) + const stateMachineheight = { id: stateMachineId, height: latestHeight } + const updateTime = await chain.stateMachineUpdateTime(stateMachineheight) + expect(updateTime).toBeGreaterThan(0) + + console.log(updateTime) + } catch (err) { + console.error(err) + expect(err).toBeUndefined() + } + }, 300_000) +}) + +async function bscSetup() { + const bscTestnetClient = createPublicClient({ + chain: bscTestnet, + transport: http(process.env.BSC_CHAPEL), + }) + + const bscPing = getContract({ + address: process.env.PING_MODULE_ADDRESS! as HexString, + abi: PING_MODULE.ABI, + client: { public: bscTestnetClient }, + }) + + const bscIsmpHostAddress = await bscPing.read.host() + + return { + bscIsmpHostAddress, + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/tokenGateway.test.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/tokenGateway.test.ts new file mode 100644 index 00000000..41e9a876 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/tests/tokenGateway.test.ts @@ -0,0 +1,414 @@ +import "log-timestamp" +import { ApiPromise, WsProvider } from "@polkadot/api" +import { Keyring } from "@polkadot/keyring" +import { + createPublicClient, + createWalletClient, + getContract, + hexToBytes, + http, + maxUint256, + parseAbi, + parseEventLogs, + PublicClient, + stringToHex, + WalletClient, +} from "viem" +import { teleport } from "@/utils/tokenGateway" +import type { HexString } from "@/types" +import type { Signer, SignerResult } from "@polkadot/api/types" +import type { SignerPayloadRaw } from "@polkadot/types/types" +import { hexToU8a, u8aToHex } from "@polkadot/util" +import type { KeyringPair } from "@polkadot/keyring/types" +import { encodeISMPMessage, getChain } from "@/chain" +import { __test, ADDRESS_ZERO, bytes20ToBytes32 } from "@/utils" +import { createQueryClient } from "@/query-client" +import { IndexerClient } from "@/client" +import { privateKeyToAccount, privateKeyToAddress } from "viem/accounts" +import { bscTestnet, gnosisChiado } from "viem/chains" +import tokenGateway from "@/abis/tokenGateway" +import { keccakAsU8a } from "@polkadot/util-crypto" +import erc6160 from "@/abis/erc6160" +import { getPostRequestEventFromTx } from "@/utils/txEvents" + +// private key for testnet transactions +const secret_key = process.env.SECRET_PHRASE || "" + +/** + * Jest test for the teleport function + The goal of this test is to ensure the teleport extrinsic is correctly encoded + The tx can be decoded by the rpc node + */ +describe("teleport function", () => { + it.skip("should teleport assets correctly", async () => { + // Set up the connection to a local node + const wsProvider = new WsProvider(process.env.BIFROST_PASEO) + const api = await ApiPromise.create({ provider: wsProvider }) + + console.log("Api connected") + // Set up BOB account from keyring + const keyring = new Keyring({ type: "sr25519" }) + const bob = keyring.addFromUri(secret_key) + // Implement the Signer interface + const signer: Signer = createKeyringPairSigner(bob) + + // Prepare test parameters + const params = { + symbol: "BNC", + destination: "EVM-84532", + recipient: "0x742d35Cc6634C0532925a3b844Bc454e4438f44e" as HexString, + amount: BigInt(200000000000), + timeout: BigInt(3600), + tokenGatewayAddress: hexToBytes("0xFcDa26cA021d5535C3059547390E6cCd8De7acA6"), + relayerFee: BigInt(0), + redeem: false, + } + + try { + // Call the teleport function + console.log("Teleport started") + let dispatched = null + let finalized = null + const stream = await teleport({ apiPromise: api, who: bob.address, params, options: { signer } }) + + for await (const event of stream) { + console.log(event.kind) + if (event.kind === "Dispatched") { + dispatched = event + } + if (event.kind === "Finalized") { + finalized = event + } + } + + expect(dispatched).toMatchObject( + expect.objectContaining({ + kind: "Dispatched", + transaction_hash: expect.stringContaining("0x"), + block_number: expect.any(BigInt), + commitment: expect.stringContaining("0x"), + }), + ) + + expect(finalized).toMatchObject( + expect.objectContaining({ + kind: "Finalized", + transaction_hash: expect.stringContaining("0x"), + block_number: expect.any(BigInt), + commitment: expect.stringContaining("0x"), + }), + ) + } catch (error) { + console.log(error) + // The extrinsic should be decoded correctly but should fail at transaction fee payment since we are using the BOB account + expect(error).toBeUndefined() + } + }, 300_000) + + it("should query the order status", async () => { + const { bscTokenGateway, bscPublicClient, bscWalletClient } = await setUp() + const bscIsmpHostAddress = "0x8Aa0Dea6D675d785A882967Bf38183f6117C09b7" as HexString + const gnosisChiadoIsmpHostAddress = "0x58a41b89f4871725e5d898d98ef4bf917601c5eb" as HexString + const query_client = createQueryClient({ + url: process.env.INDEXER_URL!, + }) + + // Create chain instances + const sourceChain = await getChain({ + consensusStateId: "BSC0", + rpcUrl: process.env.BSC_CHAPEL!, + stateMachineId: "EVM-97", + host: bscIsmpHostAddress, + }) + + const destChain = await getChain({ + consensusStateId: "GNO0", + rpcUrl: process.env.GNOSIS_CHIADO!, + stateMachineId: "EVM-10200", + host: gnosisChiadoIsmpHostAddress, + }) + + const hyperbridgeChain = await getChain({ + consensusStateId: "PAS0", + stateMachineId: "KUSAMA-4009", + wsUrl: process.env.HYPERBRIDGE_GARGANTUA!, + hasher: "Keccak" as const, + }) + + const indexer = new IndexerClient({ + source: sourceChain, + dest: destChain, + hyperbridge: hyperbridgeChain, + queryClient: query_client, + pollInterval: 1_000, + }) + + const amount = BigInt(200000000000) + + const params = { + amount: amount, + relayerFee: BigInt(0), + assetId: u8aToHex(keccakAsU8a("USD.h")), + redeem: false, + to: bytes20ToBytes32(privateKeyToAddress(process.env.PRIVATE_KEY as any) as HexString), + dest: stringToHex("EVM-10200"), + timeout: 65337297n, + nativeCost: BigInt(0), + data: "0x" as HexString, + } + + const { erc20, erc6160 } = await getAssetDetails(params.assetId, bscPublicClient) + + const tokenToApprove = erc20 != ADDRESS_ZERO ? erc20 : erc6160 + + // Reject test if assetId is unknown + + if (tokenToApprove === ADDRESS_ZERO) { + throw new Error("Unknown asset Id") + } + + // Apporve tokens if needed + await approveTokens(bscWalletClient, bscPublicClient, erc6160, bscTokenGateway.address) + await dripTokensIfNeeded(bscWalletClient, bscPublicClient, amount) + + const tx = await bscTokenGateway.write.teleport([params], { + account: bscWalletClient.account!, + chain: bscTestnet, + }) + + const receipt = await bscPublicClient.waitForTransactionReceipt({ + hash: tx, + confirmations: 1, + }) + + console.log("Teleported to Gnosis Chiado:", receipt.transactionHash) + + const postRequest = await getPostRequestEventFromTx(bscPublicClient, tx) + + console.log("postRequest event", postRequest) + + // Get the commitment from the AssetTeleported event + const teleportEvent = parseEventLogs({ + abi: tokenGateway.ABI, + logs: receipt.logs, + strict: false, + })[0] as { eventName: "AssetTeleported"; args: any } + + if (teleportEvent.eventName !== "AssetTeleported") { + throw new Error("Unexpected Event type") + } + + const commitment = teleportEvent.args.commitment + console.log("Teleport Commitment:", commitment) + + // Stream the teleport status + for await (const status of indexer.tokenGatewayAssetTeleportedStatusStream(commitment)) { + console.log(JSON.stringify(status, (_, value) => (typeof value === "bigint" ? value.toString() : value), 4)) + switch (status.status) { + case "TELEPORTED": { + console.log( + `Status ${status.status}, Transaction: https://testnet.bscscan.com/tx/${status.metadata.transactionHash}`, + ) + break + } + case "RECEIVED": { + console.log( + `Status ${status.status}, Transaction: https://gnosis-chiado.blockscout.com/tx/${status.metadata.transactionHash}`, + ) + break + } + case "REFUNDED": { + console.log( + `Status ${status.status}, Transaction: https://testnet.bscscan.com/tx/${status.metadata.transactionHash}`, + ) + break + } + } + } + }, 300_000_000) +}) + +function createKeyringPairSigner(pair: KeyringPair): Signer { + return { + /** + * Signs a raw payload + */ + async signRaw({ data }: SignerPayloadRaw): Promise { + // Sign the data + const signature = u8aToHex(pair.sign(hexToU8a(data), { withType: true })) + + return { + id: 1, + signature, + } + }, + } +} + +describe("encode ISMP Message", () => { + const JsonBigInt = { + stringify: (value: unknown) => { + function bigIntReplacer(key: string, value: unknown) { + if (typeof value === "bigint") { + return `${value.toString()}n` + } + + return value + } + + return JSON.stringify(value, bigIntReplacer) + }, + + parse: (text: string) => { + function bigIntReviver(key: string, value: unknown) { + if (typeof value === "string" && /^\d+n$/.test(value)) { + return BigInt(value.slice(0, -1)) + } + return value + } + + return JSON.parse(text, bigIntReviver) + }, + } + + it("should encode `PostRequest`", () => { + const payload = `{"kind":"PostRequest","proof":{"stateMachine":"POLKADOT-3367","consensusStateId":"DOT0","proof":"0x000020150180a00080ca3a85525576886bec6c8d14af36a431f65cd69b186534ac4663fa0e27814cc3807c23c7a89f2bbd4f645294d8b38cd95e4a0d3f3d0d3b1fea5201f4af039a24be31018d02657175657374300080a920a50b2e9ba78e1dd0672a66d2f570ab33e118d0bd1f96d2147896292a5569807dc17b63e746171eff175360d83f867cf3a0b970e1f2c1ea44458204386168fd790895036f6d6d69746d656e7473ffff809218209ff94f779d571f37ac604f169a6882596e117c82e1ddde30a9468d838980f5e98bf19d3da8debf66441bb7765fb7ecb30acfa407afd713066d810ba54b2a80d955284bd0aa6fd3a5fb345362d970c6aefa4059ae58e943ba2d0592beaaf2a680306a9f48c656fadc0f5b1d7389d363f437c877bbb5f378ea1c78971950540bc580112aa1a00afd2d8fb0fbbafa51eb2b224e7e0c5c5883f6282a017afffee5075f804d1a02f10c23773279ed2f8e8343113c2070f7ae543c44a793fd585c040cb6e48051509abed107806b1442ee57a46b88775574d3e618a0a88e60489cfa731a4185808cd548c4fdd2a56c64ede561ff904286d2c55fbd00a3282d0b1e9272ad32b0dc805a475ea80a255761e0bc86a5f2dcdbcc489bdab805f028f6c6737094cec2a8a28052d89e68c5f281764966bf0e5c7933254f8447878cb9d9a783065f1000b5b98880469b1151ce050506cde87707e3ea0201bf646f3db6b587df3ab613f663be9a3080f54f9705d886edea6980898d31b9793ad0526baaf0187bcaa9bf9bf7015d4bf38086c4d2041c66d77db5ef174567343ad51e1458ccaaf7bf49d5d1a33522d7b86e80e0d7418f7da18a52401ce28e3d6955eb0da2a257fe2efdbc7c5d7fcddcb1d4f080e606d29855e081f7a32280db940a61f738025889da4a89040dfc270e30bbf26280217ca4f37e1b38b6e0d40f661f8d3754060a4580605e9027221415051762101e4d0880ffff80f784b6cf74b54ffc87cf3435415bb5368ac1c2c7cad21aa416d9ed9c8801ef94805e1501d7a070fb808add0bb93bc3e7df658631164e64cea044572bb39ce0568580f2d9de6fd21fcaf07fc676fb6cb05964fabb221b1365038ca34fc4cbaaf47051807ba5e861d3acae1495773cb408588cea830341d3db9f4719cfe175bbc904bfa880f571713eedbb22d8c61b06f974fea2fe03b587d346cebb249181d57e637409e180db5cf05a2bbd19eec2b26e515f04de442f97aa9a59c4792feb15d84c311e8ebb80d9adb2288642139f815640885701207eb9f91a77580f793b1e385f9814d8d630804edf752f1ff409cbafbbe40b46c3a21a3758e304439eff3c5f55cf6a0e912db080ec03d93b653c1479708b08eabe329c35986f5f4c2a78b45542f50be3d246afaf80c40e9c9da3c628cf4d57a7c89cad3126ce90d3e7c2759b047e0d5832eac46c7080dacedd80db8b7949b1cc8d58d3a62db2b69f2cafe92e72d8732647537f33688b8093d5b873c6d79abaeeb8267f057f0e93a8bbbda00ea0bdc24a1f9fa3e4d403838028509038542f7deb35cc961f071875280af9a0e485cbce77b8c763074aa6b4e58038ed71251cc4e26631ad2f6e504380cdca45be1db98e1c7eb43123e1eed615e980e96c04521701fbf5aec0069c482e705fb64d305889c4bcdd392b72e84ff3b4fe8024dc2f6f85ecff62cc0a40b8689a899d1f00f1e449e9171d89adef8b7cbb5d40b90580737e801e17cce5a9dd5178697c49d63b0e92578929dd5f99c296f4297901af00009e10809cda22e50076c30855370e72246c6137e761b4ddcd4f35b45ae8c4aea5e99f68809a1245a8f9e826ff521e7936c926445ce1b8dae51d45db5932ddaa19db17551e802ddf046292ae5ced08e848aa06204ae9a59a4b1ccf6f64810b74a169b8a095c18029e516dd9c41341073ae89072f0ec7d605a3c542983532c823a52e29a580167f808e47453bf2762aa02cf8837ab6580818408bc9447136d13cd91b37d29ec795cf807d59458a0199a22a2644a2b6f1e4d9c39654b32441db4a686e170b9e8b4618d0802ea1e2eccab065cf03b83de59a71a1f1647a38f4e72cb0ae9f58a46b5886a5f88064c5264fa7561678d05e3420bd50e928d4d5afaa5756fbecd96986bd2ce16e4f80c802bad572870bee7acb5fc358c58667a37cfe686a7cc3a750e8e317735f54a980f35ead630446103d8b800d49c625d3a0767c6671b9d0dcfb2191a22287d0b20d9901808c0080e5f168fcc2393a88f033fb5d856367912d336085ebd3ee8746041099586cbb6c801967e4d33076a7a26f4dd046fcd9aa24876269adcb4979a1420988aac3d8f3ef802ff41d763a2d5667944151c6312b3c1a332efcb70066df372e24b240e4df7aa301013f1dfcb5d3bc4413d7e22c617ab322ba07ecd0c1ee81332f769319759e19fede364499657d121012cca16379e58e1693794d3d26f04e9c3f4e737c6bc79b67cc05015c12000000000000b22400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","height":"5065606n"},"requests":[{"commitment":"0xcc93fcb5d3bc4413d7e22c617ab322ba07ecd0c1ee81332f769319759e19fede","timeoutTimestamp":"1746109367","source":"EVM-1","dest":"SUBSTRATE-cere","to":"0xa09b1c60e8650245f92518c8a17314878c4043ed","from":"0xFd413e3AFe560182C4471F4d143A96d3e259B6dE","nonce":"162","body":"0x000000000000000000000000000000000000000000000000000000000b2d05e000ac05b69379f7ac8d594d29d1cc11e6ed5bec3b481c0882bbb1c4fdaa08ba77c60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c4ce6549c5f26de05898ab6e99005f0dbcd0d83a7aec163072f2e144b16f8a27a7ef164080577f3d4f1c8914de44768dd227ff34","statuses":[{"status":"SOURCE","metadata":{"blockHash":"0xde6cfc83c0745bfa30aa4e6cb0d798e8aea8eaf40d77fba8a1cc909875cc2cf6","blockNumber":22389271,"transactionHash":"0x691d41aa65f692285e4caab8ad79afa9299b17b44aea58d0442ceb8357c48b77","timestamp":"1746105767"}},{"status":"HYPERBRIDGE_DELIVERED","metadata":{"blockHash":"0xf353c01572d36f56b0c6a9b1e4b1f83c73bc482e553e1cf547c7c463ebd0390c","blockNumber":5065599,"transactionHash":"0xa74595b6c684437b0af33eaf4e4fcd6e60c3950af9b762ba86cdbce471645d81","timestamp":"1746106788000"}},{"status":"DESTINATION","metadata":{"blockHash":"0x1f37d55ecedf679ad221fb1d80db7c7119cc63c8d4f4617516476601988680e7","blockNumber":20453321,"transactionHash":"0xfa32d1d156443f2b016c62ce830fb9275ac8d111d23c3698183e639553f7be79","timestamp":"1746106908000"}}]}],"signer":"0x0000000000000000000000000000000000000000000000000000000000000000"}` + + const message = JsonBigInt.parse(payload) + const output = encodeISMPMessage(message) + + expect(u8aToHex(output)).toMatchInlineSnapshot( + `"0x04020400010000000363657265a20000000000000050fd413e3afe560182c4471f4d143a96d3e259b6de50a09b1c60e8650245f92518c8a17314878c4043edb7831368000000008502000000000000000000000000000000000000000000000000000000000b2d05e000ac05b69379f7ac8d594d29d1cc11e6ed5bec3b481c0882bbb1c4fdaa08ba77c60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c4ce6549c5f26de05898ab6e99005f0dbcd0d83a7aec163072f2e144b16f8a27a7ef164080577f3d4f1c8914de44768dd227ff3401270d0000444f5430864b4d0000000000a91c000020150180a00080ca3a85525576886bec6c8d14af36a431f65cd69b186534ac4663fa0e27814cc3807c23c7a89f2bbd4f645294d8b38cd95e4a0d3f3d0d3b1fea5201f4af039a24be31018d02657175657374300080a920a50b2e9ba78e1dd0672a66d2f570ab33e118d0bd1f96d2147896292a5569807dc17b63e746171eff175360d83f867cf3a0b970e1f2c1ea44458204386168fd790895036f6d6d69746d656e7473ffff809218209ff94f779d571f37ac604f169a6882596e117c82e1ddde30a9468d838980f5e98bf19d3da8debf66441bb7765fb7ecb30acfa407afd713066d810ba54b2a80d955284bd0aa6fd3a5fb345362d970c6aefa4059ae58e943ba2d0592beaaf2a680306a9f48c656fadc0f5b1d7389d363f437c877bbb5f378ea1c78971950540bc580112aa1a00afd2d8fb0fbbafa51eb2b224e7e0c5c5883f6282a017afffee5075f804d1a02f10c23773279ed2f8e8343113c2070f7ae543c44a793fd585c040cb6e48051509abed107806b1442ee57a46b88775574d3e618a0a88e60489cfa731a4185808cd548c4fdd2a56c64ede561ff904286d2c55fbd00a3282d0b1e9272ad32b0dc805a475ea80a255761e0bc86a5f2dcdbcc489bdab805f028f6c6737094cec2a8a28052d89e68c5f281764966bf0e5c7933254f8447878cb9d9a783065f1000b5b98880469b1151ce050506cde87707e3ea0201bf646f3db6b587df3ab613f663be9a3080f54f9705d886edea6980898d31b9793ad0526baaf0187bcaa9bf9bf7015d4bf38086c4d2041c66d77db5ef174567343ad51e1458ccaaf7bf49d5d1a33522d7b86e80e0d7418f7da18a52401ce28e3d6955eb0da2a257fe2efdbc7c5d7fcddcb1d4f080e606d29855e081f7a32280db940a61f738025889da4a89040dfc270e30bbf26280217ca4f37e1b38b6e0d40f661f8d3754060a4580605e9027221415051762101e4d0880ffff80f784b6cf74b54ffc87cf3435415bb5368ac1c2c7cad21aa416d9ed9c8801ef94805e1501d7a070fb808add0bb93bc3e7df658631164e64cea044572bb39ce0568580f2d9de6fd21fcaf07fc676fb6cb05964fabb221b1365038ca34fc4cbaaf47051807ba5e861d3acae1495773cb408588cea830341d3db9f4719cfe175bbc904bfa880f571713eedbb22d8c61b06f974fea2fe03b587d346cebb249181d57e637409e180db5cf05a2bbd19eec2b26e515f04de442f97aa9a59c4792feb15d84c311e8ebb80d9adb2288642139f815640885701207eb9f91a77580f793b1e385f9814d8d630804edf752f1ff409cbafbbe40b46c3a21a3758e304439eff3c5f55cf6a0e912db080ec03d93b653c1479708b08eabe329c35986f5f4c2a78b45542f50be3d246afaf80c40e9c9da3c628cf4d57a7c89cad3126ce90d3e7c2759b047e0d5832eac46c7080dacedd80db8b7949b1cc8d58d3a62db2b69f2cafe92e72d8732647537f33688b8093d5b873c6d79abaeeb8267f057f0e93a8bbbda00ea0bdc24a1f9fa3e4d403838028509038542f7deb35cc961f071875280af9a0e485cbce77b8c763074aa6b4e58038ed71251cc4e26631ad2f6e504380cdca45be1db98e1c7eb43123e1eed615e980e96c04521701fbf5aec0069c482e705fb64d305889c4bcdd392b72e84ff3b4fe8024dc2f6f85ecff62cc0a40b8689a899d1f00f1e449e9171d89adef8b7cbb5d40b90580737e801e17cce5a9dd5178697c49d63b0e92578929dd5f99c296f4297901af00009e10809cda22e50076c30855370e72246c6137e761b4ddcd4f35b45ae8c4aea5e99f68809a1245a8f9e826ff521e7936c926445ce1b8dae51d45db5932ddaa19db17551e802ddf046292ae5ced08e848aa06204ae9a59a4b1ccf6f64810b74a169b8a095c18029e516dd9c41341073ae89072f0ec7d605a3c542983532c823a52e29a580167f808e47453bf2762aa02cf8837ab6580818408bc9447136d13cd91b37d29ec795cf807d59458a0199a22a2644a2b6f1e4d9c39654b32441db4a686e170b9e8b4618d0802ea1e2eccab065cf03b83de59a71a1f1647a38f4e72cb0ae9f58a46b5886a5f88064c5264fa7561678d05e3420bd50e928d4d5afaa5756fbecd96986bd2ce16e4f80c802bad572870bee7acb5fc358c58667a37cfe686a7cc3a750e8e317735f54a980f35ead630446103d8b800d49c625d3a0767c6671b9d0dcfb2191a22287d0b20d9901808c0080e5f168fcc2393a88f033fb5d856367912d336085ebd3ee8746041099586cbb6c801967e4d33076a7a26f4dd046fcd9aa24876269adcb4979a1420988aac3d8f3ef802ff41d763a2d5667944151c6312b3c1a332efcb70066df372e24b240e4df7aa301013f1dfcb5d3bc4413d7e22c617ab322ba07ecd0c1ee81332f769319759e19fede364499657d121012cca16379e58e1693794d3d26f04e9c3f4e737c6bc79b67cc05015c12000000000000b22400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000"`, + ) + }) +}) + +it("should ensure wasm function loads", async () => { + await expect(__test()).resolves.toMatchInlineSnapshot( + `"{"root":"0x85835c4d5287fe023073eb733f4e4103935d61b4397f0f9d0fe627d434757fa5","proof":["0x894376e04f932deadc9ab212ac514f37b41e670be2f8002babde1faf20935461","0xf3ace1896f86f91627cc1c09eeaba2cd76d82a75be6f09b94c861524fa5e5289","0x0ffa0900c838d17341df2d00fa4832755de619e646137844700668ad544c8aae","0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470","0x9c6b2c1b0d0b25a008e6c882cc7b415f309965c72ad2b944ac0931048ca31cd5","0xfadbd3c7f79fa2bdc4f24857709cd4a4e870623dc9e9abcdfd6e448033e35212"],"mmr_size":236,"leaf_positions":[232],"keccak_hash_calldata":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"}"`, + ) +}) + +async function setUp() { + const account = privateKeyToAccount(process.env.PRIVATE_KEY as any) + + const bscWalletClient = createWalletClient({ + chain: bscTestnet, + account, + transport: http(process.env.BSC_CHAPEL), + }) + + const gnosisChiadoWalletClient = createWalletClient({ + chain: gnosisChiado, + account, + transport: http(process.env.GNOSIS_CHIADO), + }) + + const bscPublicClient = createPublicClient({ + chain: bscTestnet, + transport: http(process.env.BSC_CHAPEL), + }) + + const gnosisChiadoPublicClient = createPublicClient({ + chain: gnosisChiado, + transport: http(process.env.GNOSIS_CHIADO), + }) + + const bscTokenGateway = getContract({ + address: process.env.TOKEN_GATEWAY_ADDRESS! as HexString, + abi: tokenGateway.ABI, + client: { public: bscPublicClient, wallet: bscWalletClient }, + }) + + const gnosisChiadoTokenGateway = getContract({ + address: process.env.TOKEN_GATEWAY_ADDRESS! as HexString, + abi: tokenGateway.ABI, + client: { public: gnosisChiadoPublicClient, wallet: gnosisChiadoWalletClient }, + }) + + return { + bscTokenGateway, + gnosisChiadoTokenGateway, + bscPublicClient, + gnosisChiadoPublicClient, + bscWalletClient, + gnosisChiadoWalletClient, + } +} + +async function getAssetDetails(assetId: string, publicClient: PublicClient) { + const erc20 = await publicClient.readContract({ + abi: tokenGateway.ABI, + address: process.env.TOKEN_GATEWAY_ADDRESS! as HexString, + functionName: "erc20", + args: [assetId as HexString], + }) + + const erc6160 = await publicClient.readContract({ + abi: tokenGateway.ABI, + address: process.env.TOKEN_GATEWAY_ADDRESS! as HexString, + functionName: "erc6160", + args: [assetId as HexString], + }) + + return { + erc20, + erc6160, + } +} + +async function approveTokens( + walletClient: WalletClient, + publicClient: PublicClient, + tokenAddress: HexString, + spender: HexString, +) { + const approval = await publicClient.readContract({ + abi: erc6160.ABI, + address: tokenAddress, + functionName: "allowance", + args: [walletClient.account?.address as HexString, spender], + account: walletClient.account, + }) + + if (approval == 0n) { + console.log("Approving tokens for test") + const tx = await walletClient.writeContract({ + abi: erc6160.ABI, + address: tokenAddress, + functionName: "approve", + args: [spender, maxUint256], + chain: walletClient.chain, + account: walletClient.account!, + }) + + const receipt = await publicClient.waitForTransactionReceipt({ hash: tx }) + console.log("Approved tokens for test:", receipt) + } +} + +async function dripTokensIfNeeded(walletClient: WalletClient, publicClient: PublicClient, amountCheck: bigint) { + const USDH = "0xA801da100bF16D07F668F4A49E1f71fc54D05177" as HexString + const balance = await publicClient.readContract({ + abi: erc6160.ABI, + address: USDH, + functionName: "balanceOf", + args: [walletClient.account?.address as HexString], + account: walletClient.account, + }) + + if (balance < amountCheck) { + console.log("Dripping tokens for test") + const tx = await walletClient.writeContract({ + abi: parseAbi(["function drip(address token) public"]), + address: "0x1794aB22388303ce9Cb798bE966eeEBeFe59C3a3", + functionName: "drip", + args: [USDH], + chain: walletClient.chain, + account: walletClient.account!, + }) + + const receipt = await publicClient.waitForTransactionReceipt({ hash: tx }) + console.log("Dripped tokens for test:", receipt) + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/types/index.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/types/index.ts new file mode 100644 index 00000000..23e2ae77 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/types/index.ts @@ -0,0 +1,1198 @@ +import type { ConsolaInstance } from "consola" +import type { GraphQLClient } from "graphql-request" +import type { ContractFunctionArgs, Hex, Log } from "viem" +import type HandlerV1 from "@/abis/handler" +import type { IChain } from "@/chain" + +export type EstimateGasCallData = ContractFunctionArgs< + typeof HandlerV1.ABI, + "nonpayable" | "payable", + "handlePostRequests" +> + +export type HexString = `0x${string}` + +export interface IConfig { + // confuration object for the source chain + source: IEvmConfig | ISubstrateConfig + // confuration object for the destination chain + dest: IEvmConfig | ISubstrateConfig + // confuration object for hyperbridge + hyperbridge: IHyperbridgeConfig + // Flag to enable tracing console logs + tracing?: boolean +} + +export interface IEvmConfig { + // rpc url of the chain + rpcUrl: string + // state machine identifier as a string + stateMachineId: string + // contract address of the `IsmpHost` on this chain + host: HexString + // consensus state identifier of this chain on hyperbridge + consensusStateId: string +} + +export interface ISubstrateConfig { + // rpc url of the chain + wsUrl: string + // consensus state identifier of this chain on hyperbridge + consensusStateId: string + // consensus state identifier of this chain on hyperbridge + hasher: "Keccak" | "Blake2" + // state machine identifier as a string + stateMachineId: string +} + +export interface IHyperbridgeConfig { + // websocket rpc endpoint for hyperbridge + wsUrl: string + // state machine identifier as a string + stateMachineId: string + // consensus state identifier of hyperbridge on the destination chain + consensusStateId: string +} + +export interface IPostRequest { + // The source state machine of this request. + source: string + // The destination state machine of this request. + dest: string + // Module Id of the sending module + from: HexString + // Module ID of the receiving module + to: HexString + // The nonce of this request on the source chain + nonce: bigint + // Encoded request body. + body: HexString + // Timestamp which this request expires in seconds. + timeoutTimestamp: bigint +} + +export interface IGetRequest { + // The source state machine of this request. + source: string + // The destination state machine of this request. + dest: string + // Module Id of the sending module + from: HexString + // The nonce of this request on the source chain + nonce: bigint + // Height at which to read the state machine. + height: bigint + /// Raw Storage keys that would be used to fetch the values from the counterparty + /// For deriving storage keys for ink contract fields follow the guide in the link below + /// `` + /// The algorithms for calculating raw storage keys for different substrate pallet storage + /// types are described in the following links + /// `` + /// `` + /// `` + /// `` + /// For fetching keys from EVM contracts each key should be 52 bytes + /// This should be a concatenation of contract address and slot hash + keys: HexString[] + // Timestamp which this request expires in seconds. + timeoutTimestamp: bigint + context: HexString +} + +export interface GetResponseStorageValues { + key: HexString + value: HexString +} + +export interface IPostResponse { + // The request that triggered this response. + post: IPostRequest + // The response message. + response: string + // Timestamp at which this response expires in seconds. + timeoutTimestamp: bigint +} + +export type IMessage = { Requests: HexString[] } | { Responses: HexString[] } + +export type IndexerQueryClient = GraphQLClient + +export interface ClientConfig { + pollInterval: number + queryClient: IndexerQueryClient + tracing?: boolean + source: IChain + dest: IChain + hyperbridge: IChain +} + +export interface RetryConfig { + maxRetries: number + /** + * @description The initial backoff time in milliseconds before the first retry attempt. + */ + backoffMs: number + logMessage?: string + logger?: ConsolaInstance +} + +export interface IsmpRequest { + source: string + dest: string + from: string + to: string + nonce: bigint + body: string + timeoutTimestamp: bigint + storage_key?: string +} + +export const RequestStatus = Object.freeze({ + SOURCE: "SOURCE", + SOURCE_FINALIZED: "SOURCE_FINALIZED", + HYPERBRIDGE_DELIVERED: "HYPERBRIDGE_DELIVERED", + HYPERBRIDGE_FINALIZED: "HYPERBRIDGE_FINALIZED", + DESTINATION: "DESTINATION", + TIMED_OUT: "TIMED_OUT", + HYPERBRIDGE_TIMED_OUT: "HYPERBRIDGE_TIMED_OUT", +}) +export type RequestStatus = typeof RequestStatus +export type RequestStatusKey = keyof typeof RequestStatus + +export const TimeoutStatus = Object.freeze({ + PENDING_TIMEOUT: "PENDING_TIMEOUT", + DESTINATION_FINALIZED_TIMEOUT: "DESTINATION_FINALIZED_TIMEOUT", + HYPERBRIDGE_TIMED_OUT: "HYPERBRIDGE_TIMED_OUT", + HYPERBRIDGE_FINALIZED_TIMEOUT: "HYPERBRIDGE_FINALIZED_TIMEOUT", + TIMED_OUT: "TIMED_OUT", +}) + +export type TimeoutStatus = typeof TimeoutStatus +export type TimeoutStatusKey = keyof typeof TimeoutStatus + +export type AllStatusKey = RequestStatusKey | TimeoutStatusKey + +export enum HyperClientStatus { + PENDING = "PENDING", + SOURCE_FINALIZED = "SOURCE_FINALIZED", + HYPERBRIDGE_FINALIZED = "HYPERBRIDGE_FINALIZED", + HYPERBRIDGE_VERIFIED = "HYPERBRIDGE_VERIFIED", + DESTINATION = "DESTINATION", + TIMED_OUT = "TIMED_OUT", + HYPERBRIDGE_TIMED_OUT = "HYPERBRIDGE_TIMED_OUT", + ERROR = "ERROR", +} + +export enum OrderStatus { + PLACED = "PLACED", + FILLED = "FILLED", + REDEEMED = "REDEEMED", + REFUNDED = "REFUNDED", +} + +export enum TeleportStatus { + TELEPORTED = "TELEPORTED", + RECEIVED = "RECEIVED", + REFUNDED = "REFUNDED", +} + +export interface TokenGatewayAssetTeleportedResponse { + tokenGatewayAssetTeleporteds: { + nodes: Array<{ + id: string + from: string + to: string + sourceChain: string + destChain: string + commitment: string + amount: string + usdValue: string + assetId: string + redeem: boolean + status: TeleportStatus + createdAt: string + blockNumber: string + blockTimestamp: string + transactionHash: string + statusMetadata: { + nodes: Array<{ + status: TeleportStatus + chain: string + timestamp: string + blockNumber: string + blockHash: string + transactionHash: string + }> + } + }> + } +} + +export interface TokenGatewayAssetTeleportedWithStatus { + id: string + from: string + to: string + sourceChain: string + destChain: string + commitment: string + amount: bigint + usdValue: string + assetId: string + redeem: boolean + status: TeleportStatus + createdAt: Date + blockNumber: bigint + blockTimestamp: bigint + transactionHash: string + statuses: Array<{ + status: TeleportStatus + metadata: { + blockHash: string + blockNumber: number + transactionHash: string + timestamp: bigint + } + }> +} + +export interface BlockMetadata { + blockHash: string + blockNumber: number + transactionHash: string + calldata?: string + timestamp?: number +} + +export interface PostRequestStatus { + status: RequestStatusKey + metadata: Partial +} + +export interface PostRequestTimeoutStatus { + status: TimeoutStatusKey + metadata?: Partial +} + +export interface StateMachineUpdate { + height: number + chain: string + blockHash: string + blockNumber: number + transactionHash: string + transactionIndex: number + stateMachineId: string + timestamp: number +} + +export interface RequestResponse { + requests: { + nodes: Array<{ + source: string + dest: string + to: HexString + from: HexString + nonce: bigint + body: HexString + timeoutTimestamp: bigint + statusMetadata: { + nodes: Array<{ + blockHash: string + blockNumber: string + timestamp: string + chain: string + status: string + transactionHash: string + }> + } + }> + } +} + +export interface GetRequestResponse { + getRequests: { + nodes: Array<{ + source: string + dest: string + to: HexString + from: HexString + nonce: bigint + height: bigint + keys: HexString[] + context: HexString + timeoutTimestamp: bigint + statusMetadata: { + nodes: Array<{ + blockHash: string + blockNumber: string + timestamp: string + chain: string + status: string + transactionHash: string + }> + } + }> + } +} + +export type RequestStatusWithMetadata = + | { + status: RequestStatus["SOURCE"] + metadata: { + blockHash: string + blockNumber: number + transactionHash: string + timestamp?: number + } + } + | { + status: RequestStatus["SOURCE_FINALIZED"] + metadata: { + blockHash: string + blockNumber: number + transactionHash: string + timestamp?: number + } + } + | { + status: RequestStatus["HYPERBRIDGE_DELIVERED"] + metadata: { + blockHash: string + blockNumber: number + transactionHash: string + timestamp?: number + } + } + | { + status: RequestStatus["HYPERBRIDGE_FINALIZED"] + metadata: { + calldata: Hex + blockHash: string + blockNumber: number + transactionHash: string + timestamp?: number + } + } + | { + status: RequestStatus["DESTINATION"] + metadata: { + blockHash: string + blockNumber: number + transactionHash: string + timestamp?: number + } + } + | { + status: TimeoutStatus["PENDING_TIMEOUT"] + metadata: { + blockHash: string + blockNumber: number + transactionHash: string + } + } + | { + status: TimeoutStatus["DESTINATION_FINALIZED_TIMEOUT"] + metadata: { + blockHash: string + blockNumber: number + transactionHash: string + timestamp?: number + } + } + | { + status: TimeoutStatus["HYPERBRIDGE_TIMED_OUT"] + metadata: { + blockHash: string + blockNumber: number + transactionHash: string + timestamp?: number + } + } + | { + status: TimeoutStatus["HYPERBRIDGE_FINALIZED_TIMEOUT"] + metadata: { + calldata: Hex + blockHash: string + blockNumber: number + transactionHash: string + timestamp?: number + } + } + | { + status: TimeoutStatus["TIMED_OUT"] + metadata: { + blockHash: string + blockNumber: number + transactionHash: string + timestamp?: number + } + } + +interface GenericRequestWithStatuses { + source: string + dest: string + from: HexString + nonce: bigint + timeoutTimestamp: bigint + statuses: Array +} + +export interface PostRequestWithStatus extends GenericRequestWithStatuses { + to: HexString + body: HexString +} + +export interface GetRequestWithStatus extends GenericRequestWithStatuses { + height: bigint + keys: HexString[] + context: HexString + commitment: HexString +} + +export interface GetResponseByRequestIdResponse { + getResponses: { + nodes: Array<{ + id: string + commitment: string + responseMessage: string[] + }> + } +} + +export interface ResponseCommitmentWithValues { + commitment: string + values: string[] +} + +export interface RequestCommitment { + requests: { + nodes: Array<{ + id: string + commitment: string + }> + } +} + +export interface StateMachineResponse { + stateMachineUpdateEvents: { + nodes: { + height: number + chain: string + blockHash: string + blockNumber: number + transactionHash: string + transactionIndex: number + stateMachineId: string + createdAt: string + }[] + } +} + +export interface AssetTeleported { + id: string + from: string + to: string + amount: bigint + dest: string + commitment: HexString + createdAt: Date + blockNumber: number +} + +export interface AssetTeleportedResponse { + assetTeleported: AssetTeleported +} + +export interface StateMachineIdParams { + stateId: { Evm?: number; Substrate?: HexString; Polkadot?: number; Kusama?: number } + consensusStateId: HexString +} + +/** + * Configuration for a blockchain chain + */ +export interface ChainConfig { + /** + * The unique identifier for the chain + */ + chainId: number + + /** + * The RPC URL to connect to the chain + */ + rpcUrl: string + + /** + * The address of the IntentGateway contract on this chain + */ + intentGatewayAddress: string +} + +/** + * Represents token information for an order + */ +export interface TokenInfo { + /** + * The address of the ERC20 token + * address(0) is used as a sentinel for the native token + */ + token: HexString + + /** + * The amount of the token + */ + amount: bigint +} + +/** + * Represents payment information for an order + */ +export interface PaymentInfo extends TokenInfo { + /** + * The address to receive the output tokens + */ + beneficiary: HexString +} + +/** + * Represents an order in the IntentGateway + */ +export interface Order { + /** + * The unique identifier for the order + */ + id?: string + + /** + * The address of the user who is initiating the transfer + */ + user: HexString + + /** + * The state machine identifier of the origin chain + */ + sourceChain: string + + /** + * The state machine identifier of the destination chain + */ + destChain: string + + /** + * The block number by which the order must be filled on the destination chain + */ + deadline: bigint + + /** + * The nonce of the order + */ + nonce: bigint + + /** + * Represents the dispatch fees associated with the IntentGateway + */ + fees: bigint + + /** + * The tokens that the filler will provide + */ + outputs: PaymentInfo[] + + /** + * The tokens that are escrowed for the filler + */ + inputs: TokenInfo[] + + /** + * A bytes array to store the calls if any + */ + callData: HexString + + // Additional Data + /** + * The transaction hash of the order + */ + transactionHash?: HexString +} + +export interface DecodedOrderPlacedLog extends Log { + eventName: string + args: { + user: HexString + sourceChain: Hex + destChain: Hex + deadline: bigint + nonce: bigint + fees: bigint + outputs: Array<{ + token: HexString + amount: bigint + beneficiary: HexString + }> + inputs: Array<{ + token: HexString + amount: bigint + }> + callData: HexString + } + transactionHash: HexString +} + +export interface DecodedPostRequestEvent extends Log { + eventName: string + args: { + source: string + dest: string + from: HexString + to: HexString + nonce: bigint + timeoutTimestamp: bigint + body: HexString + fee: bigint + } + transactionHash: HexString +} + +export interface DecodedPostResponseEvent extends Log { + eventName: string + args: { + source: string + dest: string + from: HexString + to: HexString + nonce: bigint + timeoutTimestamp: bigint + body: HexString + response: HexString + responseTimeoutTimestamp: bigint + fee: bigint + } + transactionHash: HexString +} + +/** + * Options for filling an order + */ +export interface FillOptions { + /** + * The fee paid to the relayer for processing transactions + */ + relayerFee: bigint +} + +/** + * Options for canceling an order + */ +export interface CancelOptions { + /** + * The fee paid to the relayer for processing transactions + */ + relayerFee: string + + /** + * Stores the height value + */ + height: string +} + +/** + * Represents a new deployment of IntentGateway + */ +export interface NewDeployment { + /** + * Identifier for the state machine + */ + stateMachineId: HexString + + /** + * The gateway identifier + */ + gateway: HexString +} + +/** + * Represents the body of a request + */ +export interface RequestBody { + /** + * Represents the commitment of an order + */ + commitment: HexString + + /** + * Stores the identifier for the beneficiary + */ + beneficiary: HexString + + /** + * An array of token identifiers + */ + tokens: TokenInfo[] +} + +/** + * Represents the parameters for the IntentGateway module + */ +export interface IntentGatewayParams { + /** + * The address of the host contract + */ + host: string + + /** + * Address of the dispatcher contract responsible for handling intents + */ + dispatcher: string +} + +/** + * Enum representing the different kinds of incoming requests + */ +export enum RequestKind { + /** + * Identifies a request for redeeming an escrow + */ + RedeemEscrow = 0, + + /** + * Identifies a request for recording new contract deployments + */ + NewDeployment = 1, + + /** + * Identifies a request for updating parameters + */ + UpdateParams = 2, +} + +/** + * Configuration for the IntentFiller + */ +export interface FillerConfig { + /** + * Policy for determining confirmation requirements + */ + confirmationPolicy: { + getConfirmationBlocks: (chainId: number, amountUsd: number) => number + } + + /** + * Maximum number of orders to process concurrently + */ + maxConcurrentOrders?: number + + /** + * Minimum profitability threshold to consider filling an order + * Expressed as a percentage (e.g., 0.5 = 0.5%) + */ + minProfitabilityThreshold?: number + + /** + * Gas price strategy for each chain + * Maps chainId to a gas price strategy function + */ + gasPriceStrategy?: Record Promise> + + /** + * Maximum gas price willing to pay for each chain + * Maps chainId to maximum gas price in wei + */ + maxGasPrice?: Record + + /** + * Retry configuration for failed transactions + */ + retryConfig?: { + /** + * Maximum number of retry attempts + */ + maxAttempts: number + + /** + * Initial delay between retries in ms + */ + initialDelayMs: number + } + + /** + * Configuration for the pending queue + */ + pendingQueueConfig?: { + /** + * Delay in milliseconds before rechecking an order for confirmations + * Default: 30000 (30 seconds) + */ + recheckDelayMs?: number + + /** + * Maximum number of times to recheck an order before giving up + * Default: 10 + */ + maxRechecks?: number + } +} + +/** + * Result of an order execution attempt + */ +export interface ExecutionResult { + /** + * Whether the execution was successful + */ + success: boolean + + /** + * The transaction hash if successful + */ + txHash?: string + + /** + * Error message if unsuccessful + */ + error?: string + + /** + * Gas used by the transaction + */ + gasUsed?: string + + /** + * Gas price used for the transaction + */ + gasPrice?: string + + /** + * Total transaction cost in wei + */ + txCost?: string + + /** + * Block number when the transaction was confirmed + */ + confirmedAtBlock?: number + + /** + * Timestamp when the transaction was confirmed + */ + confirmedAt?: Date + + /** + * Actual profitability achieved + */ + actualProfitability?: number + + /** + * Strategy used to fill the order + */ + strategyUsed?: string + + /** + * Any tokens exchanged during the fill process + */ + exchanges?: Array<{ + fromToken: HexString + toToken: HexString + fromAmount: string + toAmount: string + exchangeRate: string + }> + + /** + * The time it took to fill the order + */ + processingTimeMs?: number +} + +/** + * Represents a dispatch post for cross-chain communication + */ +export interface DispatchPost { + /** + * Bytes representation of the destination state machine + */ + dest: HexString + + /** + * The destination module + */ + to: HexString + + /** + * The request body + */ + body: HexString + + /** + * Timeout for this request in seconds + */ + timeout: bigint + + /** + * The amount put up to be paid to the relayer, + * this is charged in `IIsmpHost.feeToken` to `msg.sender` + */ + fee: bigint + + /** + * Who pays for this request? + */ + payer: HexString +} + +export interface DispatchGet { + /** + * Bytes representation of the destination state machine + */ + dest: HexString + + /** + * Height at which to read the state machine + */ + height: bigint + + /** + * Raw storage keys to fetch values from the counterparty + */ + keys: HexString[] + + /** + * Timeout for this request in seconds + */ + timeout: bigint + + /** + * The amount put up to be paid to the relayer + */ + fee: bigint + + /** + * Context for the request + */ + context: HexString +} + +export interface StateMachineHeight { + id: { + stateId: { Evm?: number; Substrate?: HexString; Polkadot?: number; Kusama?: number } + consensusStateId: HexString + } + height: bigint +} + +/** + * The EvmHost protocol parameters + */ +export interface HostParams { + /** + * The default timeout in seconds for messages. If messages are dispatched + * with a timeout value lower than this this value will be used instead + */ + defaultTimeout: bigint + /** + * The default per byte fee + */ + perByteFee: bigint + /** + * The cost for applications to access the hyperbridge state commitment. + * They might do so because the hyperbridge state contains the verified state commitments + * for all chains and they want to directly read the state of these chains state bypassing + * the ISMP protocol entirely. + */ + stateCommitmentFee: bigint + /** + * The fee token contract address. This will typically be DAI. + * but we allow it to be configurable to prevent future regrets. + */ + feeToken: HexString + /** + * The admin account, this only has the rights to freeze, or unfreeze the bridge + */ + admin: HexString + /** + * Ismp message handler contract. This performs all verification logic + * needed to validate cross-chain messages before they are dispatched to local modules + */ + handler: HexString + /** + * The authorized host manager contract, is itself an `IIsmpModule` + * which receives governance requests from the Hyperbridge chain to either + * withdraw revenue from the host or update its protocol parameters + */ + hostManager: HexString + /** + * The local UniswapV2Router02 contract, used for swapping the native token to the feeToken. + */ + uniswapV2: HexString + /** + * The unstaking period of Polkadot's validators. In order to prevent long-range attacks + */ + unStakingPeriod: bigint + /** + * Minimum challenge period for state commitments in seconds + */ + challengePeriod: bigint + /** + * The consensus client contract which handles consensus proof verification + */ + consensusClient: HexString + /** + * State machines whose state commitments are accepted + */ + readonly stateMachines: readonly bigint[] + /** + * The state machine identifier for hyperbridge + */ + hyperbridge: HexString +} + +export interface OrderStatusMetadata { + status: OrderStatus + chain: string + timestamp: bigint + blockNumber: string + transactionHash: string + filler?: string +} + +export interface OrderWithStatus { + id: string + user: string + sourceChain: string + destChain: string + commitment: string + deadline: bigint + nonce: bigint + fees: bigint + inputTokens: string[] + inputAmounts: bigint[] + inputValuesUSD: string[] + inputUSD: string + outputTokens: string[] + outputAmounts: bigint[] + outputBeneficiaries: string[] + calldata: string + status: OrderStatus + createdAt: Date + blockNumber: bigint + blockTimestamp: bigint + transactionHash: string + statuses: Array<{ + status: OrderStatus + metadata: { + blockHash: string + blockNumber: number + transactionHash: string + timestamp: bigint + filler?: string + } + }> +} + +export interface OrderResponse { + orderPlaceds: { + nodes: Array<{ + id: string + user: string + sourceChain: string + destChain: string + commitment: string + deadline: string + nonce: string + fees: string + inputTokens: string[] + inputAmounts: string[] + inputValuesUSD: string[] + inputUSD: string + outputTokens: string[] + outputAmounts: string[] + outputBeneficiaries: string[] + calldata: string + status: OrderStatus + createdAt: string + blockNumber: string + blockTimestamp: string + transactionHash: string + statusMetadata: { + nodes: Array<{ + status: OrderStatus + chain: string + timestamp: string + blockNumber: string + blockHash: string + transactionHash: string + filler?: string + }> + } + }> + } +} + +export interface TokenPrice { + symbol: string + address?: string + currency: string + price: string + lastUpdatedAt: bigint +} + +export interface TokenPricesResponse { + tokenPrices: { + nodes: Array<{ + id: string + symbol: string + address: string + currency: string + price: string + lastUpdatedAt: bigint + }> + } +} + +export interface TokenRegistry { + id: string + name: string + symbol: string + address?: string + updateFrequencySeconds: number + lastUpdatedAt: bigint + createdAt: Date +} + +export interface TokenRegistryResponse { + tokenRegistries: { + nodes: Array<{ + id: string + name: string + symbol: string + address: string + updateFrequencySeconds: number + lastUpdatedAt: bigint + createdAt: string + }> + } +} + +/** + * Represents a complete transaction structure for swap operations + */ +export interface Transaction { + /** + * The address to send the transaction to (typically the Universal Router address) + */ + to: HexString + + /** + * The value to send with the transaction (in wei) + */ + value: bigint + + /** + * The calldata for the transaction + */ + data: HexString +} + +export interface StorageFacade { + get(key: string): Promise + set(key: string, value: T): Promise + delete(key: string): Promise +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils.ts new file mode 100644 index 00000000..b2f2e9ae --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils.ts @@ -0,0 +1,842 @@ +import { + type HexString, + type IGetRequest, + type IPostRequest, + RequestKind, + RequestStatus, + type StateMachineHeight, + TimeoutStatus, +} from "@/types" +import type { EstimateGasCallData, Order, RequestStatusKey, RetryConfig, TimeoutStatusKey } from "@/types" +import { LogLevels, createConsola } from "consola" +import { + type CallParameters, + type PublicClient, + bytesToHex, + concatHex, + encodeAbiParameters, + encodePacked, + hexToBytes, + keccak256, + toHex, +} from "viem" +import evmHost from "./abis/evmHost" +import handler from "./abis/handler" +import { type IChain, getStateCommitmentFieldSlot } from "./chain" +import { _queryRequestInternal } from "./query-client" +import { generateRootWithProof } from "./utils" +import { ChainConfigService } from "./configs/ChainConfigService" + +export * from "./utils/mmr" +export * from "./utils/substrate" + +export const DEFAULT_POLL_INTERVAL = 5_000 +export const ADDRESS_ZERO = "0x0000000000000000000000000000000000000000" as HexString +export const MOCK_ADDRESS = "0x1234567890123456789012345678901234567890" as HexString +export const DUMMY_PRIVATE_KEY = "0x0000000000000000000000000000000000000000000000000000000000000000" as HexString +export const DEFAULT_GRAFFITI = "0x0000000000000000000000000000000000000000000000000000000000000000" as HexString + +/** + * Returns the maximum of two bigint values + * @param a - First bigint value + * @param b - Second bigint value + * @returns The larger of the two values + */ +export function maxBigInt(a: bigint, b: bigint): bigint { + return a > b ? a : b +} + +/** + * Sleeps for the specified number of milliseconds. + * @param ms The number of milliseconds to sleep. + */ +export function sleep(ms?: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms || DEFAULT_POLL_INTERVAL)) +} + +/** + * Waits for the challenge period to elapse on a chain. + * This function will sleep until the challenge period has elapsed. + * + * @param chain The chain object implementing IChain interface + * @param stateMachineHeight The state machine height to wait for + * @returns Promise that resolves when the challenge period has elapsed + */ +export async function waitForChallengePeriod(chain: IChain, stateMachineHeight: StateMachineHeight): Promise { + // Get the challenge period for this state machine + const challengePeriod = await chain.challengePeriod(stateMachineHeight.id) + + if (challengePeriod === BigInt(0)) return + + // Get the state machine update time + const updateTime = await chain.stateMachineUpdateTime(stateMachineHeight) + // Check current timestamp + let currentTimestamp = await chain.timestamp() + // Calculate time passed since update + let timeElapsed = currentTimestamp - updateTime + + if (timeElapsed > challengePeriod) return + + // First sleep for the whole challenge period + await sleep(Number(challengePeriod) * 1000) + + // Keep sleeping until challenge period has fully elapsed + while (timeElapsed <= challengePeriod) { + // Sleep for remaining time + const remainingTime = challengePeriod - timeElapsed + await sleep(Number(remainingTime) * 1000) + + // Check timestamp again + currentTimestamp = await chain.timestamp() + timeElapsed = currentTimestamp - updateTime + } +} + +/** + * Checks if the given state machine ID represents an EVM chain. + * @param stateMachineId The state machine ID to check. + */ +export function isEvmChain(stateMachineId: string): boolean { + return stateMachineId.startsWith("EVM") +} + +/** + * Checks if the given state machine ID represents a Substrate chain. + * @param stateMachineId The state machine ID to check. + */ +export function isSubstrateChain(stateMachineId: string): boolean { + return ( + stateMachineId.startsWith("POLKADOT") || + stateMachineId.startsWith("KUSAMA") || + stateMachineId.startsWith("SUBSTRATE") + ) +} + +/** + * Converts a state machine ID string to a stateId object. + * Handles formats like: + * - "EVM-97" → { Evm: 97 } + * - "SUBSTRATE-cere" → { Substrate: "0x63657265" } (hex encoded UTF-8 bytes) + * - "POLKADOT-3367" → { Polkadot: 3367 } + * - "KUSAMA-123" → { Kusama: 123 } + * + * @param stateMachineId The state machine ID string + * @returns A stateId object conforming to the StateMachineIdParams interface + */ +export function parseStateMachineId(stateMachineId: string): { + stateId: { Evm?: number; Substrate?: HexString; Polkadot?: number; Kusama?: number } +} { + const [type, value] = stateMachineId.split("-") + + if (!type || !value) { + throw new Error( + `Invalid state machine ID format: ${stateMachineId}. Expected format like "EVM-97" or "SUBSTRATE-cere"`, + ) + } + + const stateId: { Evm?: number; Substrate?: HexString; Polkadot?: number; Kusama?: number } = {} + + switch (type.toUpperCase()) { + case "EVM": { + const evmChainId = Number.parseInt(value, 10) + if (Number.isNaN(evmChainId)) { + throw new Error(`Invalid EVM chain ID: ${value}. Expected a number.`) + } + stateId.Evm = evmChainId + break + } + + case "SUBSTRATE": { + // Convert the string to hex-encoded UTF-8 bytes + const bytes = Buffer.from(value, "utf8") + stateId.Substrate = `0x${bytes.toString("hex")}` as HexString + break + } + + case "POLKADOT": { + const polkadotChainId = Number.parseInt(value, 10) + if (Number.isNaN(polkadotChainId)) { + throw new Error(`Invalid Polkadot chain ID: ${value}. Expected a number.`) + } + stateId.Polkadot = polkadotChainId + break + } + + case "KUSAMA": { + const kusamaChainId = Number.parseInt(value, 10) + if (Number.isNaN(kusamaChainId)) { + throw new Error(`Invalid Kusama chain ID: ${value}. Expected a number.`) + } + stateId.Kusama = kusamaChainId + break + } + + default: + throw new Error(`Unsupported chain type: ${type}. Expected one of: EVM, SUBSTRATE, POLKADOT, KUSAMA.`) + } + + return { stateId } +} + +/** + * Checks if the given string is a valid UTF-8 string. + * @param str The string to check. + */ +export function isValidUTF8(str: string): boolean { + return Buffer.from(str).toString("utf8") === str +} + +/** + * Calculates the commitment hash for a post request. + * @param post The post request to calculate the commitment hash for. + * @returns The commitment hash and the encode packed data. + */ +export function postRequestCommitment(post: IPostRequest): { commitment: HexString; encodePacked: HexString } { + const data = encodePacked( + ["bytes", "bytes", "uint64", "uint64", "bytes", "bytes", "bytes"], + [toHex(post.source), toHex(post.dest), post.nonce, post.timeoutTimestamp, post.from, post.to, post.body], + ) + + return { + commitment: keccak256(data), + encodePacked: data, + } +} + +export function orderCommitment(order: Order): HexString { + const encodedOrder = encodeAbiParameters( + [ + { + name: "order", + type: "tuple", + components: [ + { name: "user", type: "bytes32" }, + { name: "sourceChain", type: "bytes" }, + { name: "destChain", type: "bytes" }, + { name: "deadline", type: "uint256" }, + { name: "nonce", type: "uint256" }, + { name: "fees", type: "uint256" }, + { + name: "outputs", + type: "tuple[]", + components: [ + { name: "token", type: "bytes32" }, + { name: "amount", type: "uint256" }, + { name: "beneficiary", type: "bytes32" }, + ], + }, + { + name: "inputs", + type: "tuple[]", + components: [ + { name: "token", type: "bytes32" }, + { name: "amount", type: "uint256" }, + ], + }, + { name: "callData", type: "bytes" }, + ], + }, + ], + [ + { + user: order.user, + sourceChain: order.sourceChain.startsWith("0x") + ? (order.sourceChain as `0x${string}`) + : toHex(order.sourceChain), + destChain: order.destChain.startsWith("0x") + ? (order.destChain as `0x${string}`) + : toHex(order.destChain), + deadline: order.deadline, + nonce: order.nonce, + fees: order.fees, + outputs: order.outputs, + inputs: order.inputs, + callData: order.callData, + }, + ], + ) + + return keccak256(encodedOrder) +} + +/** + * Converts a bytes32 token address to bytes20 format + * This removes the extra padded zeros from the address + */ +export function bytes32ToBytes20(bytes32Address: string): HexString { + if (bytes32Address === ADDRESS_ZERO) { + return ADDRESS_ZERO + } + + const bytes = hexToBytes(bytes32Address as HexString) + const addressBytes = bytes.slice(12) + return bytesToHex(addressBytes) as HexString +} + +export function bytes20ToBytes32(bytes20Address: string): HexString { + return `0x${bytes20Address.slice(2).padStart(64, "0")}` as HexString +} + +export function hexToString(hex: string): string { + const hexWithoutPrefix = hex.startsWith("0x") ? hex.slice(2) : hex + + const bytes = new Uint8Array(hexWithoutPrefix.length / 2) + for (let i = 0; i < hexWithoutPrefix.length; i += 2) { + bytes[i / 2] = Number.parseInt(hexWithoutPrefix.slice(i, i + 2), 16) + } + + return new TextDecoder().decode(bytes) +} + +export const DEFAULT_LOGGER = createConsola({ + level: LogLevels.silent, +}) + +/** + * Retries a promise-returning operation with exponential backoff. + * This function will attempt to execute the operation up to maxRetries times, + * with an exponential backoff delay between attempts. + * + * @param operation The async operation to retry + * @param retryConfig Configuration object containing retry parameters + * @returns Promise that resolves with the operation result or rejects with the last error + */ +export async function retryPromise(operation: () => Promise, retryConfig: RetryConfig): Promise { + const { logger = DEFAULT_LOGGER, logMessage = "Retry operation failed" } = retryConfig + + let lastError: unknown + for (let i = 0; i < retryConfig.maxRetries; i++) { + try { + return await operation() + } catch (error) { + logger.trace(`Retrying(${i}) > ${logMessage}`) + lastError = error + await new Promise((resolve) => setTimeout(resolve, retryConfig.backoffMs * 2 ** i)) + } + } + + throw lastError +} + +/** + * Calculates the commitment hash for a get request. + * @param get The get request to calculate the commitment hash for. + * @returns The commitment hash. + */ +export function getRequestCommitment(get: IGetRequest): HexString { + const keysEncoding = "0x".concat(get.keys.map((key) => key.slice(2)).join("")) + return keccak256( + encodePacked( + ["bytes", "bytes", "uint64", "uint64", "uint64", "bytes", "bytes", "bytes"], + [ + toHex(get.source), + toHex(get.dest), + get.nonce, + get.height, + get.timeoutTimestamp, + get.from, + keysEncoding as HexString, + get.context, + ], + ), + ) +} + +/** + ** Calculates the weight of a request status. + * Used to determine the progression of a request through its lifecycle. + * Higher weights represent more advanced states in the processing pipeline. + * @returns A record mapping each RequestStatus to its corresponding weight value. + */ +export const REQUEST_STATUS_WEIGHTS: Record = { + [RequestStatus.SOURCE]: 0, + [RequestStatus.SOURCE_FINALIZED]: 1, + [RequestStatus.HYPERBRIDGE_DELIVERED]: 2, + [RequestStatus.HYPERBRIDGE_FINALIZED]: 3, + [RequestStatus.DESTINATION]: 4, + [RequestStatus.HYPERBRIDGE_TIMED_OUT]: 5, + [RequestStatus.TIMED_OUT]: 6, +} + +/** + * Calculates the weight of a timeout status. + * Used to determine the progression of a timeout through its lifecycle. + * Higher weights represent more advanced states in the timeout processing. + * @returns A record mapping each TimeoutStatus to its corresponding weight value. + */ +export const TIMEOUT_STATUS_WEIGHTS: Record = { + [TimeoutStatus.PENDING_TIMEOUT]: 1, + [TimeoutStatus.DESTINATION_FINALIZED_TIMEOUT]: 2, + [TimeoutStatus.HYPERBRIDGE_TIMED_OUT]: 3, + [TimeoutStatus.HYPERBRIDGE_FINALIZED_TIMEOUT]: 4, + [TimeoutStatus.TIMED_OUT]: 5, +} + +/** + * Combines both request and timeout status weights into a single mapping. + * This provides a comprehensive view of all possible states a request can be in, + * with higher weights representing more advanced states in either the normal + * processing pipeline or the timeout handling process. + * + * The weights follow this progression: + * 0-4: Normal request processing (SOURCE to DESTINATION) + * 5-9: Timeout handling progression (PENDING_TIMEOUT to TIMED_OUT) + * + * @returns A record mapping each RequestStatus and TimeoutStatus to its corresponding weight value. + */ +export const COMBINED_STATUS_WEIGHTS: Record = { + [RequestStatus.SOURCE]: 0, + [RequestStatus.SOURCE_FINALIZED]: 1, + [RequestStatus.HYPERBRIDGE_DELIVERED]: 2, + [RequestStatus.HYPERBRIDGE_FINALIZED]: 3, + [RequestStatus.DESTINATION]: 4, + [TimeoutStatus.PENDING_TIMEOUT]: 5, + [TimeoutStatus.DESTINATION_FINALIZED_TIMEOUT]: 6, + [TimeoutStatus.HYPERBRIDGE_TIMED_OUT]: 7, + [TimeoutStatus.HYPERBRIDGE_FINALIZED_TIMEOUT]: 8, + [TimeoutStatus.TIMED_OUT]: 9, +} + +/** + * Estimates the gas required for a post request transaction on the source chain. + * This function constructs a post request, generates mock proofs, and estimates + * the gas cost for executing the transaction on the source chain. + */ +export async function estimateGasForPost(params: { + postRequest: IPostRequest + sourceClient: PublicClient + hostLatestStateMachineHeight: bigint + hostAddress: HexString +}): Promise<{ gas_fee: bigint; call_data: EstimateGasCallData }> { + const hostParams = await params.sourceClient.readContract({ + address: params.hostAddress, + abi: evmHost.ABI, + functionName: "hostParams", + }) + + const { root, proof, index, kIndex, treeSize } = await generateRootWithProof(params.postRequest, 2n ** 10n) + const latestStateMachineHeight = params.hostLatestStateMachineHeight + const overlayRootSlot = getStateCommitmentFieldSlot( + BigInt(4009n), // Hyperbridge chain id + latestStateMachineHeight, // Hyperbridge chain height + 1, // For overlayRoot + ) + const postParams = { + height: { + stateMachineId: BigInt(4009n), + height: latestStateMachineHeight, + }, + multiproof: proof, + leafCount: treeSize, + } + + const call_data: EstimateGasCallData = [ + params.hostAddress, + { + proof: postParams, + requests: [ + { + request: { + ...params.postRequest, + source: toHex(params.postRequest.source), + dest: toHex(params.postRequest.dest), + }, + index, + kIndex, + }, + ], + }, + ] + + const gas_fee = await params.sourceClient.estimateContractGas({ + address: hostParams.handler, + abi: handler.ABI, + functionName: "handlePostRequests", + args: call_data, + stateOverride: [ + { + address: params.hostAddress, + stateDiff: [ + { + slot: overlayRootSlot, + value: root, + }, + ], + }, + ], + }) + + return { gas_fee, call_data } +} + +/** + * Constructs the request body for a redeem escrow operation. + * This function encodes the order commitment, beneficiary address, and token inputs + * to match the format expected by the IntentGateway contract. + */ +export function constructRedeemEscrowRequestBody(order: Order, beneficiary: HexString): HexString { + const commitment = order.id as HexString + const inputs = order.inputs + + // RequestKind.RedeemEscrow is 0 as defined in the contract + const requestKind = encodePacked(["uint8"], [RequestKind.RedeemEscrow]) + + const requestBody = { + commitment: commitment as HexString, + beneficiary: bytes20ToBytes32(beneficiary), + tokens: inputs, + } + + const encodedRequestBody = encodeAbiParameters( + [ + { + name: "requestBody", + type: "tuple", + components: [ + { name: "commitment", type: "bytes32" }, + { name: "beneficiary", type: "bytes32" }, + { + name: "tokens", + type: "tuple[]", + components: [ + { name: "token", type: "bytes32" }, + { name: "amount", type: "uint256" }, + ], + }, + ], + }, + ], + [requestBody], + ) + + return concatHex([requestKind, encodedRequestBody]) as HexString +} + +export const normalizeTimestamp = (timestamp: bigint): bigint => { + if (timestamp.toString().length <= 11) { + return timestamp * 1000n + } + return timestamp +} + +/// Convert ensure a date string is in iso format before getting it's timestamp +export const dateStringtoTimestamp = (date: string): number => { + if (!date.endsWith("Z")) { + date = `${date}Z` + } + return new Date(date).getTime() +} + +/** + * Maps testnet identifiers to mainnet identifiers for price lookup + * @param identifier - The original token identifier (symbol or contract address) + * @returns The mapped mainnet identifier + */ +export function mapToValidCoingeckoId(identifier: string): string { + identifier = identifier.toLowerCase() + + switch (identifier) { + case "bnb": + return "wbnb" + case "eth": + return "weth" + case "tbnb": + return "wbnb" + case "0xc043f483373072f7f27420d6e7d7ad269c018e18".toLowerCase(): + return "dai" + case "0xae13d989dac2f0debff460ac112a837c89baa7cd".toLowerCase(): + return "wbnb" + case "0x1938165569A5463327fb206bE06d8D9253aa06b7".toLowerCase(): + return "dai" + case "0xC625ec7D30A4b1AAEfb1304610CdAcD0d606aC92".toLowerCase(): + return "dai" + case "0x50B1d3c7c073c9caa1Ef207365A2c9C976bD70b9".toLowerCase(): + return "dai" + case "0xa801da100bf16d07f668f4a49e1f71fc54d05177".toLowerCase(): + return "dai" + case "pol": + return "polygon-ecosystem-token" + default: + return identifier + } +} + +export async function fetchPrice(identifier: string, chainId = 1, apiKey?: string): Promise { + const mappedIdentifier = mapToValidCoingeckoId(identifier) + + const network = new ChainConfigService().getCoingeckoId(`EVM-${chainId}`) || "ethereum" + + apiKey = apiKey || (typeof process !== "undefined" ? (process as any)?.env?.COINGECKO : undefined) + const baseUrl = apiKey ? "https://pro-api.coingecko.com/api/v3" : "https://api.coingecko.com/api/v3" + + const url = mappedIdentifier.startsWith("0x") + ? `${baseUrl}/simple/token_price/${network}?contract_addresses=${mappedIdentifier}&vs_currencies=usd` + : `${baseUrl}/simple/price?ids=${mappedIdentifier}&vs_currencies=usd` + + const headers = apiKey ? { "x-cg-pro-api-key": apiKey as string } : undefined + + const response = await fetch(url, { headers }) + + if (!response.ok) { + throw new Error(`CoinGecko API error: ${response.status} ${response.statusText}`) + } + + const data = await response.json() + const key = mappedIdentifier.toLowerCase() + + if (!data[key]?.usd) { + throw new Error(`Price not found for token: ${mappedIdentifier} on ${network}`) + } + + return data[key].usd +} + +/** + * Fetches the current network gas price from an Etherscan-family explorer API. + * Returns the ProposeGasPrice (in gwei) converted to wei as bigint. + */ +export async function getGasPriceFromEtherscan(chainId: string, apiKey?: string): Promise { + let parsedChainId = Number(chainId.split("-")[1]) + const url = apiKey + ? `https://api.etherscan.io/v2/api?chainid=${parsedChainId}&module=gastracker&action=gasoracle&apikey=${apiKey}` + : `https://api.etherscan.io/v2/api?chainid=${parsedChainId}&module=gastracker&action=gasoracle` + const response = await fetch(url) + const data = await response.json() + return gweiToWei(data.result.ProposeGasPrice) +} + +/** + * Converts a decimal gwei string to wei bigint without floating point errors. + */ +function gweiToWei(gwei: string): bigint { + if (!gwei || typeof gwei !== "string") { + throw new Error(`Invalid gwei value: ${gwei}`) + } + const [intPart, fracPartRaw] = gwei.split(".") + const fracPart = (fracPartRaw || "").slice(0, 9) // up to 9 decimal places for gwei->wei + const fracPadded = fracPart.padEnd(9, "0") + const whole = BigInt(intPart || "0") * 1_000_000_000n + const fractional = BigInt(fracPadded || "0") + return whole + fractional +} + +/** + * ERC20 method signatures used for storage slot detection + */ +export enum ERC20Method { + /** ERC20 balanceOf(address) method signature */ + BALANCE_OF = "0x70a08231", + /** ERC20 allowance(address,address) method signature */ + ALLOWANCE = "0xdd62ed3e", +} + +export enum UniversalRouterCommands { + WRAP_ETH = 0x0b, + UNWRAP_WETH = 0x0c, + V2_SWAP_EXACT_IN = 0x08, + V2_SWAP_EXACT_OUT = 0x09, + V3_SWAP_EXACT_IN = 0x00, + V3_SWAP_EXACT_OUT = 0x01, + V4_SWAP = 0x10, + V4_SWAP_EXACT_IN_SINGLE = 0x06, + V4_SWAP_EXACT_OUT_SINGLE = 0x08, + SETTLE_ALL = 0x0c, + TAKE_ALL = 0x0f, +} + +/** + * Retrieves the storage slot for a contract call using debug_traceCall + * + * This function uses the Ethereum debug API to trace contract execution and identify + * the storage slot accessed during the call. It's commonly used for ERC20 token state + * mappings like balanceOf and allowance, but can work with any contract call that + * performs SLOAD operations. + * + * @param client - The viem PublicClient instance connected to an RPC node with debug API enabled + * @param tokenAddress - The address of the contract to trace + * @param data - The full encoded function call data (method signature + encoded parameters) + * @returns The storage slot as a hex string + * @throws Error if the storage slot cannot be found or if debug API is not available + * + * @example + * ```ts + * import { ERC20Method, bytes20ToBytes32 } from '@hyperbridge/sdk' + * + * // Get balance storage slot for ERC20 + * const balanceData = ERC20Method.BALANCE_OF + bytes20ToBytes32(userAddress).slice(2) + * const balanceSlot = await getStorageSlot( + * client, + * tokenAddress, + * balanceData as HexString + * ) + * + * // Get allowance storage slot for ERC20 + * const allowanceData = ERC20Method.ALLOWANCE + + * bytes20ToBytes32(ownerAddress).slice(2) + + * bytes20ToBytes32(spenderAddress).slice(2) + * const allowanceSlot = await getStorageSlot( + * client, + * tokenAddress, + * allowanceData as HexString + * ) + * ``` + */ +export async function getStorageSlot( + client: PublicClient, + contractAddress: HexString, + data: HexString, +): Promise { + // Default tracer (struct logger) + async function tryDefaultTracer(): Promise { + const traceCallClient = client.extend((client) => ({ + async traceCall(args: CallParameters) { + return client.request({ + // @ts-ignore + method: "debug_traceCall", + // @ts-ignore + params: [args, "latest", {}], + }) + }, + })) + + const response = await traceCallClient.traceCall({ + to: contractAddress, + data: data, + }) + + const methodSignature = data.slice(0, 10) as HexString + // @ts-ignore + const logs = response.structLogs + + if (!logs || logs.length === 0) { + throw new Error("No struct logs found") + } + + for (let i = logs.length - 1; i >= 0; i--) { + const log = logs[i] + if (log.op === "SLOAD" && log.stack?.length >= 3) { + const sigHash = log.stack[0] + const slotHex = log.stack[log.stack.length - 1] + // Extract method signature from data (first 4 bytes) + if (sigHash === methodSignature && slotHex.length === 66) { + return slotHex + } + } + } + + throw new Error(`Storage slot not found for data: ${methodSignature}`) + } + + // prestateTracer + async function tryPrestateTracer(): Promise { + const traceCallClient = client.extend((client) => ({ + async traceCall(args: CallParameters) { + return client.request({ + // @ts-ignore + method: "debug_traceCall", + // @ts-ignore + params: [ + // @ts-ignore + args, + "latest", + { + // @ts-ignore + tracer: "prestateTracer", + tracerConfig: { + disableCode: true, + }, + }, + ], + }) + }, + })) + + const response = await traceCallClient.traceCall({ + to: contractAddress, + data: data, + }) + + // @ts-ignore + let contractData = response[contractAddress.toLowerCase()] + + if (!contractData) { + // @ts-ignore + const addressKey = Object.keys(response).find( + (addr) => addr.toLowerCase() === contractAddress.toLowerCase(), + ) + if (addressKey) { + // @ts-ignore + contractData = response[addressKey] + } + } + + if (!contractData || !contractData.storage) { + throw new Error(`No storage access found for contract ${contractAddress} with data: ${data}`) + } + + let storageSlots = Object.keys(contractData.storage) + + const PROXY_SLOTS = [ + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc", // EIP-1967 implementation + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103", // EIP-1967 beacon + "0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50", // EIP-1967 admin + ] + + storageSlots = storageSlots.filter((slot) => !PROXY_SLOTS.includes(slot)) + + if (storageSlots.length === 0) { + throw new Error(`No storage slots accessed for contract ${contractAddress} with data: ${data}`) + } + + if (storageSlots.length === 1) { + return storageSlots[0] as HexString + } + + return storageSlots[storageSlots.length - 1] as HexString + } + + return tryDefaultTracer().catch(() => tryPrestateTracer()) +} + +/** + * Adjusts fee amounts between different decimal precisions. + * Handles scaling up or down based on the decimal difference. + * + * @param feeInFeeToken - The fee amount to adjust + * @param fromDecimals - The current decimal precision + * @param toDecimals - The target decimal precision + * @returns The adjusted fee amount with the target decimal precision + */ +export function adjustFeeDecimals(feeInFeeToken: bigint, fromDecimals: number, toDecimals: number): bigint { + if (fromDecimals === toDecimals) return feeInFeeToken + if (fromDecimals < toDecimals) { + const scaleFactor = BigInt(10 ** (toDecimals - fromDecimals)) + return feeInFeeToken * scaleFactor + } else { + const scaleFactor = BigInt(10 ** (fromDecimals - toDecimals)) + return (feeInFeeToken + scaleFactor - 1n) / scaleFactor + } +} + +/** + * Chains that should prefer the Etherscan API for gas price lookup + */ +export const USE_ETHERSCAN_CHAINS = new Set(["EVM-137", "EVM-56", "EVM-1"]) + +/** + * Testnet chains + */ +export const TESTNET_CHAINS = new Set(["EVM-10200", "EVM-97"]) + +/** + * Replace Websocket with HTTP is a function that replaces a websocket URL with an HTTP URL. + * @param url The URL to replace + */ +export function replaceWebsocketWithHttp(url: string): string { + if (url.startsWith("ws://")) { + return url.replace("ws://", "http://") + } else if (url.startsWith("wss://")) { + return url.replace("wss://", "https://") + } + return url +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/.gitignore b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/.gitignore new file mode 100644 index 00000000..cbdb9611 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/.gitignore @@ -0,0 +1 @@ +!dist diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/Cargo.lock b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/Cargo.lock new file mode 100644 index 00000000..d7133dfd --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/Cargo.lock @@ -0,0 +1,229 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "ckb-merkle-mountain-range" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ccb671c5921be8a84686e6212ca184cb1d7c51cadcdbfcbd1cc3f042f5dfb8" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ckb-mmr-wasm" +version = "0.1.0" +dependencies = [ + "ckb-merkle-mountain-range", + "hex", + "js-sys", + "serde", + "serde_json", + "tiny-keccak", + "wasm-bindgen", +] + +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[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 = "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 = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[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 = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[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 = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[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", +] + +[[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 = "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 = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[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", + "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", + "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", +] diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/Cargo.toml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/Cargo.toml new file mode 100644 index 00000000..c02f1bb9 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "ckb-mmr-wasm" +version = "0.1.0" +edition = "2021" + +[lib] +name = "ckb_mmr_wasm" +crate-type = ["cdylib", "rlib"] + +[[bin]] +name = "ckb-mmr-wasm" +path = "src/main.rs" + +[dependencies] +ckb-merkle-mountain-range = "0.5.0" +hex = "0.4.3" +wasm-bindgen = "0.2.99" +js-sys = "0.3" +tiny-keccak = { version = "2.0.2", features = ["keccak"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/README.md b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/README.md new file mode 100644 index 00000000..63635d83 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/README.md @@ -0,0 +1,3 @@ +# ckb-mmr + +#### `sh build.sh` diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/build.sh b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/build.sh new file mode 100755 index 00000000..2a464e79 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/build.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash +rm -rf dist + +pwd + +echo ">> Generate Distribution" +wasm-pack build -t web -d dist/web --release --mode="normal" --no-default-features --out-name=web $1 +wasm-pack build -t nodejs -d dist/node --release --mode="normal" --no-default-features --out-name=node $1 +# wasm-pack build -t bundler -d dist/bundler --release --mode="normal" --no-default-features --out-name=bundler $1 + +echo ">> Remove unnecessary files from dist folder" +rm ./dist/**/.gitignore ./dist/**/README.md ./dist/**/package.json + +echo ">> Replace CJS with ESM" +rm ./dist/node/node.js +cp ./overwrites/node-esm.js ./dist/node/node.js diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/node/node.d.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/node/node.d.ts new file mode 100644 index 00000000..23ed563a --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/node/node.d.ts @@ -0,0 +1,8 @@ +/* tslint:disable */ +/* eslint-disable */ +export function generate_root_with_proof(calldata_bytes: Uint8Array, tree_size: bigint): string; +export function verify_proof(root_hex: string, proof_hex: string[], mmr_size: bigint, leaf_position: bigint, calldata_bytes: Uint8Array): boolean; +export class KeccakMerge { + private constructor(); + free(): void; +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/node/node.js b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/node/node.js new file mode 100644 index 00000000..791af575 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/node/node.js @@ -0,0 +1,255 @@ +import { readFileSync } from "node:fs" +import { join } from "node:path" +import { TextDecoder, TextEncoder } from "node:util" + +let wasm + +// new URL('.', import.meta.url).pathname doesn't work fine with Nextjs +// so I switched to this method of resolving the directory +const full_path = import.meta.url.split("/").slice(1) +const __dirname = `${full_path.slice(0, full_path.length - 1).join("/")}/` + +let cachedTextDecoder = new TextDecoder("utf-8", { ignoreBOM: true, fatal: true }) + +cachedTextDecoder.decode() + +let cachedUint8ArrayMemory0 = null + +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer) + } + return cachedUint8ArrayMemory0 +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0 + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)) +} + +let WASM_VECTOR_LEN = 0 + +let cachedTextEncoder = new TextEncoder("utf-8") + +const encodeString = + typeof cachedTextEncoder.encodeInto === "function" + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view) + } + : function (arg, view) { + const buf = cachedTextEncoder.encode(arg) + view.set(buf) + return { + read: arg.length, + written: buf.length, + } + } + +function passStringToWasm0(arg, malloc, realloc) { + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg) + const ptr = malloc(buf.length, 1) >>> 0 + getUint8ArrayMemory0() + .subarray(ptr, ptr + buf.length) + .set(buf) + WASM_VECTOR_LEN = buf.length + return ptr + } + + let len = arg.length + let ptr = malloc(len, 1) >>> 0 + + const mem = getUint8ArrayMemory0() + + let offset = 0 + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset) + if (code > 0x7f) break + mem[ptr + offset] = code + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset) + } + ptr = realloc(ptr, len, (len = offset + arg.length * 3), 1) >>> 0 + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len) + const ret = encodeString(arg, view) + + offset += ret.written + ptr = realloc(ptr, len, offset, 1) >>> 0 + } + + WASM_VECTOR_LEN = offset + return ptr +} + +function isLikeNone(x) { + return x === undefined || x === null +} + +let cachedDataViewMemory0 = null + +function getDataViewMemory0() { + if ( + cachedDataViewMemory0 === null || + cachedDataViewMemory0.buffer.detached === true || + (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer) + ) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer) + } + return cachedDataViewMemory0 +} + +function passArray8ToWasm0(arg, malloc) { + const ptr = malloc(arg.length * 1, 1) >>> 0 + getUint8ArrayMemory0().set(arg, ptr / 1) + WASM_VECTOR_LEN = arg.length + return ptr +} + +function takeFromExternrefTable0(idx) { + const value = wasm.__wbindgen_export_0.get(idx) + wasm.__externref_table_dealloc(idx) + return value +} + +/** + * @param {Uint8Array} calldata_bytes + * @param {bigint} tree_size + * @returns {string} + */ +export function generate_root_with_proof(calldata_bytes, tree_size) { + let deferred3_0 + let deferred3_1 + try { + const ptr0 = passArray8ToWasm0(calldata_bytes, wasm.__wbindgen_malloc) + const len0 = WASM_VECTOR_LEN + const ret = wasm.generate_root_with_proof(ptr0, len0, tree_size) + var ptr2 = ret[0] + var len2 = ret[1] + if (ret[3]) { + ptr2 = 0 + len2 = 0 + throw takeFromExternrefTable0(ret[2]) + } + deferred3_0 = ptr2 + deferred3_1 = len2 + return getStringFromWasm0(ptr2, len2) + } finally { + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1) + } +} + +function addToExternrefTable0(obj) { + const idx = wasm.__externref_table_alloc() + wasm.__wbindgen_export_0.set(idx, obj) + return idx +} + +function passArrayJsValueToWasm0(array, malloc) { + const ptr = malloc(array.length * 4, 4) >>> 0 + for (let i = 0; i < array.length; i++) { + const add = addToExternrefTable0(array[i]) + getDataViewMemory0().setUint32(ptr + 4 * i, add, true) + } + WASM_VECTOR_LEN = array.length + return ptr +} + +/** + * @param {string} root_hex + * @param {string[]} proof_hex + * @param {bigint} mmr_size + * @param {bigint} leaf_position + * @param {Uint8Array} calldata_bytes + * @returns {boolean} + */ +export function verify_proof(root_hex, proof_hex, mmr_size, leaf_position, calldata_bytes) { + const ptr0 = passStringToWasm0(root_hex, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc) + const len0 = WASM_VECTOR_LEN + const ptr1 = passArrayJsValueToWasm0(proof_hex, wasm.__wbindgen_malloc) + const len1 = WASM_VECTOR_LEN + const ptr2 = passArray8ToWasm0(calldata_bytes, wasm.__wbindgen_malloc) + const len2 = WASM_VECTOR_LEN + const ret = wasm.verify_proof(ptr0, len0, ptr1, len1, mmr_size, leaf_position, ptr2, len2) + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]) + } + return ret[0] !== 0 +} + +const KeccakMergeFinalization = + typeof FinalizationRegistry === "undefined" + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry((ptr) => wasm.__wbg_keccakmerge_free(ptr >>> 0, 1)) + +export class KeccakMerge { + __destroy_into_raw() { + const ptr = this.__wbg_ptr + this.__wbg_ptr = 0 + KeccakMergeFinalization.unregister(this) + return ptr + } + + free() { + const ptr = this.__destroy_into_raw() + wasm.__wbg_keccakmerge_free(ptr, 0) + } +} + +export function __wbindgen_error_new(arg0, arg1) { + const ret = new Error(getStringFromWasm0(arg0, arg1)) + return ret +} + +export function __wbindgen_init_externref_table() { + const table = wasm.__wbindgen_export_0 + const offset = table.grow(4) + table.set(0, undefined) + table.set(offset + 0, undefined) + table.set(offset + 1, null) + table.set(offset + 2, true) + table.set(offset + 3, false) +} + +export function __wbindgen_string_get(arg0, arg1) { + const obj = arg1 + const ret = typeof obj === "string" ? obj : undefined + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc) + var len1 = WASM_VECTOR_LEN + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true) + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true) +} + +export function __wbindgen_throw(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)) +} + +// Load and initialize the WebAssembly module +const wasmPath = join(__dirname, "./node_bg.wasm") +const wasmBytes = readFileSync(wasmPath) + +const bindings = { + generate_root_with_proof, + verify_proof, + KeccakMerge, + __wbindgen_error_new, + __wbindgen_init_externref_table, + __wbindgen_string_get, + __wbindgen_throw, +} + +const wasmModule = new WebAssembly.Module(wasmBytes) +const wasmInstance = new WebAssembly.Instance(wasmModule, { + __wbindgen_placeholder__: bindings, +}) +wasm = wasmInstance.exports +export const __wasm = wasm + +wasm.__wbindgen_start() + +export default function init() { + console.log("CKB MMR WASM initialized") +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/node/node_bg.wasm b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/node/node_bg.wasm new file mode 100644 index 0000000000000000000000000000000000000000..e542020442ef92a3d5a639ee429aaea1e015fb17 GIT binary patch literal 77679 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 void; +export const generate_root_with_proof: (a: number, b: number, c: bigint) => [number, number, number, number]; +export const verify_proof: (a: number, b: number, c: number, d: number, e: bigint, f: bigint, g: number, h: number) => [number, number, number]; +export const __wbindgen_export_0: WebAssembly.Table; +export const __wbindgen_malloc: (a: number, b: number) => number; +export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; +export const __externref_table_dealloc: (a: number) => void; +export const __wbindgen_free: (a: number, b: number, c: number) => void; +export const __externref_table_alloc: () => number; +export const __wbindgen_start: () => void; diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/web/web.d.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/web/web.d.ts new file mode 100644 index 00000000..9d7a9549 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/web/web.d.ts @@ -0,0 +1,45 @@ +/* tslint:disable */ +/* eslint-disable */ +export function generate_root_with_proof(calldata_bytes: Uint8Array, tree_size: bigint): string; +export function verify_proof(root_hex: string, proof_hex: string[], mmr_size: bigint, leaf_position: bigint, calldata_bytes: Uint8Array): boolean; +export class KeccakMerge { + private constructor(); + free(): void; +} + +export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; + +export interface InitOutput { + readonly memory: WebAssembly.Memory; + readonly __wbg_keccakmerge_free: (a: number, b: number) => void; + readonly generate_root_with_proof: (a: number, b: number, c: bigint) => [number, number, number, number]; + readonly verify_proof: (a: number, b: number, c: number, d: number, e: bigint, f: bigint, g: number, h: number) => [number, number, number]; + readonly __wbindgen_export_0: WebAssembly.Table; + readonly __wbindgen_malloc: (a: number, b: number) => number; + readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; + readonly __externref_table_dealloc: (a: number) => void; + readonly __wbindgen_free: (a: number, b: number, c: number) => void; + readonly __externref_table_alloc: () => number; + readonly __wbindgen_start: () => void; +} + +export type SyncInitInput = BufferSource | WebAssembly.Module; +/** +* Instantiates the given `module`, which can either be bytes or +* a precompiled `WebAssembly.Module`. +* +* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated. +* +* @returns {InitOutput} +*/ +export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput; + +/** +* If `module_or_path` is {RequestInfo} or {URL}, makes a request and +* for everything else, calls `WebAssembly.instantiate` directly. +* +* @param {{ module_or_path: InitInput | Promise }} module_or_path - Passing `InitInput` directly is deprecated. +* +* @returns {Promise} +*/ +export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise } | InitInput | Promise): Promise; diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/web/web.js b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/web/web.js new file mode 100644 index 00000000..37c52bb7 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/web/web.js @@ -0,0 +1,316 @@ +let wasm; + +const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); + +if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; + +let cachedUint8ArrayMemory0 = null; + +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + +let WASM_VECTOR_LEN = 0; + +const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } ); + +const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view); +} + : function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; +}); + +function passStringToWasm0(arg, malloc, realloc) { + + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8ArrayMemory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + + offset += ret.written; + ptr = realloc(ptr, len, offset, 1) >>> 0; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +function isLikeNone(x) { + return x === undefined || x === null; +} + +let cachedDataViewMemory0 = null; + +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); + } + return cachedDataViewMemory0; +} + +function passArray8ToWasm0(arg, malloc) { + const ptr = malloc(arg.length * 1, 1) >>> 0; + getUint8ArrayMemory0().set(arg, ptr / 1); + WASM_VECTOR_LEN = arg.length; + return ptr; +} + +function takeFromExternrefTable0(idx) { + const value = wasm.__wbindgen_export_0.get(idx); + wasm.__externref_table_dealloc(idx); + return value; +} +/** + * @param {Uint8Array} calldata_bytes + * @param {bigint} tree_size + * @returns {string} + */ +export function generate_root_with_proof(calldata_bytes, tree_size) { + let deferred3_0; + let deferred3_1; + try { + const ptr0 = passArray8ToWasm0(calldata_bytes, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.generate_root_with_proof(ptr0, len0, tree_size); + var ptr2 = ret[0]; + var len2 = ret[1]; + if (ret[3]) { + ptr2 = 0; len2 = 0; + throw takeFromExternrefTable0(ret[2]); + } + deferred3_0 = ptr2; + deferred3_1 = len2; + return getStringFromWasm0(ptr2, len2); + } finally { + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1); + } +} + +function addToExternrefTable0(obj) { + const idx = wasm.__externref_table_alloc(); + wasm.__wbindgen_export_0.set(idx, obj); + return idx; +} + +function passArrayJsValueToWasm0(array, malloc) { + const ptr = malloc(array.length * 4, 4) >>> 0; + for (let i = 0; i < array.length; i++) { + const add = addToExternrefTable0(array[i]); + getDataViewMemory0().setUint32(ptr + 4 * i, add, true); + } + WASM_VECTOR_LEN = array.length; + return ptr; +} +/** + * @param {string} root_hex + * @param {string[]} proof_hex + * @param {bigint} mmr_size + * @param {bigint} leaf_position + * @param {Uint8Array} calldata_bytes + * @returns {boolean} + */ +export function verify_proof(root_hex, proof_hex, mmr_size, leaf_position, calldata_bytes) { + const ptr0 = passStringToWasm0(root_hex, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passArrayJsValueToWasm0(proof_hex, wasm.__wbindgen_malloc); + const len1 = WASM_VECTOR_LEN; + const ptr2 = passArray8ToWasm0(calldata_bytes, wasm.__wbindgen_malloc); + const len2 = WASM_VECTOR_LEN; + const ret = wasm.verify_proof(ptr0, len0, ptr1, len1, mmr_size, leaf_position, ptr2, len2); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); + } + return ret[0] !== 0; +} + +const KeccakMergeFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_keccakmerge_free(ptr >>> 0, 1)); + +export class KeccakMerge { + + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + KeccakMergeFinalization.unregister(this); + return ptr; + } + + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_keccakmerge_free(ptr, 0); + } +} + +async function __wbg_load(module, imports) { + if (typeof Response === 'function' && module instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === 'function') { + try { + return await WebAssembly.instantiateStreaming(module, imports); + + } catch (e) { + if (module.headers.get('Content-Type') != 'application/wasm') { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + + } else { + throw e; + } + } + } + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + + } else { + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + + } else { + return instance; + } + } +} + +function __wbg_get_imports() { + const imports = {}; + imports.wbg = {}; + imports.wbg.__wbindgen_error_new = function(arg0, arg1) { + const ret = new Error(getStringFromWasm0(arg0, arg1)); + return ret; + }; + imports.wbg.__wbindgen_init_externref_table = function() { + const table = wasm.__wbindgen_export_0; + const offset = table.grow(4); + table.set(0, undefined); + table.set(offset + 0, undefined); + table.set(offset + 1, null); + table.set(offset + 2, true); + table.set(offset + 3, false); + ; + }; + imports.wbg.__wbindgen_string_get = function(arg0, arg1) { + const obj = arg1; + const ret = typeof(obj) === 'string' ? obj : undefined; + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; + + return imports; +} + +function __wbg_init_memory(imports, memory) { + +} + +function __wbg_finalize_init(instance, module) { + wasm = instance.exports; + __wbg_init.__wbindgen_wasm_module = module; + cachedDataViewMemory0 = null; + cachedUint8ArrayMemory0 = null; + + + wasm.__wbindgen_start(); + return wasm; +} + +function initSync(module) { + if (wasm !== undefined) return wasm; + + + if (typeof module !== 'undefined') { + if (Object.getPrototypeOf(module) === Object.prototype) { + ({module} = module) + } else { + console.warn('using deprecated parameters for `initSync()`; pass a single object instead') + } + } + + const imports = __wbg_get_imports(); + + __wbg_init_memory(imports); + + if (!(module instanceof WebAssembly.Module)) { + module = new WebAssembly.Module(module); + } + + const instance = new WebAssembly.Instance(module, imports); + + return __wbg_finalize_init(instance, module); +} + +async function __wbg_init(module_or_path) { + if (wasm !== undefined) return wasm; + + + if (typeof module_or_path !== 'undefined') { + if (Object.getPrototypeOf(module_or_path) === Object.prototype) { + ({module_or_path} = module_or_path) + } else { + console.warn('using deprecated parameters for the initialization function; pass a single object instead') + } + } + + if (typeof module_or_path === 'undefined') { + module_or_path = new URL('web_bg.wasm', import.meta.url); + } + const imports = __wbg_get_imports(); + + if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) { + module_or_path = fetch(module_or_path); + } + + __wbg_init_memory(imports); + + const { instance, module } = await __wbg_load(await module_or_path, imports); + + return __wbg_finalize_init(instance, module); +} + +export { initSync }; +export default __wbg_init; diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/web/web_bg.wasm b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/dist/web/web_bg.wasm new file mode 100644 index 0000000000000000000000000000000000000000..acb3d0c743129a936e8aa28e3a783d86d5f9557c GIT binary patch literal 77594 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 void; +export const generate_root_with_proof: (a: number, b: number, c: bigint) => [number, number, number, number]; +export const verify_proof: (a: number, b: number, c: number, d: number, e: bigint, f: bigint, g: number, h: number) => [number, number, number]; +export const __wbindgen_export_0: WebAssembly.Table; +export const __wbindgen_malloc: (a: number, b: number) => number; +export const __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; +export const __externref_table_dealloc: (a: number) => void; +export const __wbindgen_free: (a: number, b: number, c: number) => void; +export const __externref_table_alloc: () => number; +export const __wbindgen_start: () => void; diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/overwrites/node-esm.js b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/overwrites/node-esm.js new file mode 100644 index 00000000..791af575 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/overwrites/node-esm.js @@ -0,0 +1,255 @@ +import { readFileSync } from "node:fs" +import { join } from "node:path" +import { TextDecoder, TextEncoder } from "node:util" + +let wasm + +// new URL('.', import.meta.url).pathname doesn't work fine with Nextjs +// so I switched to this method of resolving the directory +const full_path = import.meta.url.split("/").slice(1) +const __dirname = `${full_path.slice(0, full_path.length - 1).join("/")}/` + +let cachedTextDecoder = new TextDecoder("utf-8", { ignoreBOM: true, fatal: true }) + +cachedTextDecoder.decode() + +let cachedUint8ArrayMemory0 = null + +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer) + } + return cachedUint8ArrayMemory0 +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0 + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)) +} + +let WASM_VECTOR_LEN = 0 + +let cachedTextEncoder = new TextEncoder("utf-8") + +const encodeString = + typeof cachedTextEncoder.encodeInto === "function" + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view) + } + : function (arg, view) { + const buf = cachedTextEncoder.encode(arg) + view.set(buf) + return { + read: arg.length, + written: buf.length, + } + } + +function passStringToWasm0(arg, malloc, realloc) { + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg) + const ptr = malloc(buf.length, 1) >>> 0 + getUint8ArrayMemory0() + .subarray(ptr, ptr + buf.length) + .set(buf) + WASM_VECTOR_LEN = buf.length + return ptr + } + + let len = arg.length + let ptr = malloc(len, 1) >>> 0 + + const mem = getUint8ArrayMemory0() + + let offset = 0 + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset) + if (code > 0x7f) break + mem[ptr + offset] = code + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset) + } + ptr = realloc(ptr, len, (len = offset + arg.length * 3), 1) >>> 0 + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len) + const ret = encodeString(arg, view) + + offset += ret.written + ptr = realloc(ptr, len, offset, 1) >>> 0 + } + + WASM_VECTOR_LEN = offset + return ptr +} + +function isLikeNone(x) { + return x === undefined || x === null +} + +let cachedDataViewMemory0 = null + +function getDataViewMemory0() { + if ( + cachedDataViewMemory0 === null || + cachedDataViewMemory0.buffer.detached === true || + (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer) + ) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer) + } + return cachedDataViewMemory0 +} + +function passArray8ToWasm0(arg, malloc) { + const ptr = malloc(arg.length * 1, 1) >>> 0 + getUint8ArrayMemory0().set(arg, ptr / 1) + WASM_VECTOR_LEN = arg.length + return ptr +} + +function takeFromExternrefTable0(idx) { + const value = wasm.__wbindgen_export_0.get(idx) + wasm.__externref_table_dealloc(idx) + return value +} + +/** + * @param {Uint8Array} calldata_bytes + * @param {bigint} tree_size + * @returns {string} + */ +export function generate_root_with_proof(calldata_bytes, tree_size) { + let deferred3_0 + let deferred3_1 + try { + const ptr0 = passArray8ToWasm0(calldata_bytes, wasm.__wbindgen_malloc) + const len0 = WASM_VECTOR_LEN + const ret = wasm.generate_root_with_proof(ptr0, len0, tree_size) + var ptr2 = ret[0] + var len2 = ret[1] + if (ret[3]) { + ptr2 = 0 + len2 = 0 + throw takeFromExternrefTable0(ret[2]) + } + deferred3_0 = ptr2 + deferred3_1 = len2 + return getStringFromWasm0(ptr2, len2) + } finally { + wasm.__wbindgen_free(deferred3_0, deferred3_1, 1) + } +} + +function addToExternrefTable0(obj) { + const idx = wasm.__externref_table_alloc() + wasm.__wbindgen_export_0.set(idx, obj) + return idx +} + +function passArrayJsValueToWasm0(array, malloc) { + const ptr = malloc(array.length * 4, 4) >>> 0 + for (let i = 0; i < array.length; i++) { + const add = addToExternrefTable0(array[i]) + getDataViewMemory0().setUint32(ptr + 4 * i, add, true) + } + WASM_VECTOR_LEN = array.length + return ptr +} + +/** + * @param {string} root_hex + * @param {string[]} proof_hex + * @param {bigint} mmr_size + * @param {bigint} leaf_position + * @param {Uint8Array} calldata_bytes + * @returns {boolean} + */ +export function verify_proof(root_hex, proof_hex, mmr_size, leaf_position, calldata_bytes) { + const ptr0 = passStringToWasm0(root_hex, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc) + const len0 = WASM_VECTOR_LEN + const ptr1 = passArrayJsValueToWasm0(proof_hex, wasm.__wbindgen_malloc) + const len1 = WASM_VECTOR_LEN + const ptr2 = passArray8ToWasm0(calldata_bytes, wasm.__wbindgen_malloc) + const len2 = WASM_VECTOR_LEN + const ret = wasm.verify_proof(ptr0, len0, ptr1, len1, mmr_size, leaf_position, ptr2, len2) + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]) + } + return ret[0] !== 0 +} + +const KeccakMergeFinalization = + typeof FinalizationRegistry === "undefined" + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry((ptr) => wasm.__wbg_keccakmerge_free(ptr >>> 0, 1)) + +export class KeccakMerge { + __destroy_into_raw() { + const ptr = this.__wbg_ptr + this.__wbg_ptr = 0 + KeccakMergeFinalization.unregister(this) + return ptr + } + + free() { + const ptr = this.__destroy_into_raw() + wasm.__wbg_keccakmerge_free(ptr, 0) + } +} + +export function __wbindgen_error_new(arg0, arg1) { + const ret = new Error(getStringFromWasm0(arg0, arg1)) + return ret +} + +export function __wbindgen_init_externref_table() { + const table = wasm.__wbindgen_export_0 + const offset = table.grow(4) + table.set(0, undefined) + table.set(offset + 0, undefined) + table.set(offset + 1, null) + table.set(offset + 2, true) + table.set(offset + 3, false) +} + +export function __wbindgen_string_get(arg0, arg1) { + const obj = arg1 + const ret = typeof obj === "string" ? obj : undefined + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc) + var len1 = WASM_VECTOR_LEN + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true) + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true) +} + +export function __wbindgen_throw(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)) +} + +// Load and initialize the WebAssembly module +const wasmPath = join(__dirname, "./node_bg.wasm") +const wasmBytes = readFileSync(wasmPath) + +const bindings = { + generate_root_with_proof, + verify_proof, + KeccakMerge, + __wbindgen_error_new, + __wbindgen_init_externref_table, + __wbindgen_string_get, + __wbindgen_throw, +} + +const wasmModule = new WebAssembly.Module(wasmBytes) +const wasmInstance = new WebAssembly.Instance(wasmModule, { + __wbindgen_placeholder__: bindings, +}) +wasm = wasmInstance.exports +export const __wasm = wasm + +wasm.__wbindgen_start() + +export default function init() { + console.log("CKB MMR WASM initialized") +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/src/lib.rs b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/src/lib.rs new file mode 100644 index 00000000..f5dca961 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/src/lib.rs @@ -0,0 +1,184 @@ +use std::collections::HashMap; + +use ckb_merkle_mountain_range::{util::MemStore, Merge, Result as CkbResult, MMR}; +use hex; +use serde::{Deserialize, Serialize}; +use tiny_keccak::{Hasher, Keccak}; +use wasm_bindgen::prelude::*; +use wasm_bindgen::JsError; + +#[derive(Serialize, Deserialize, Debug)] +pub struct MMRResult { + pub root: String, + pub proof: Vec, + pub mmr_size: u64, + pub leaf_positions: Vec, + pub keccak_hash_calldata: String, +} + +#[wasm_bindgen] +#[derive(Debug)] +struct KeccakMerge; +impl Merge for KeccakMerge { + type Item = Vec; + fn merge(lhs: &Self::Item, rhs: &Self::Item) -> CkbResult { + let mut input = Vec::new(); + input.extend_from_slice(lhs); + input.extend_from_slice(rhs); + + let mut keccak = Keccak::v256(); + let mut result = [0u8; 32]; + keccak.update(&input); + keccak.finalize(&mut result); + + Ok(result.to_vec()) + } +} + +fn bytes_to_hex(bytes: &[u8]) -> String { + format!("0x{}", hex::encode(bytes)) +} + +fn bytes_to_hex_proof(bytes: &[Vec]) -> Vec { + bytes.iter().map(|item| bytes_to_hex(item)).collect() +} + +fn hash_leaf(data: &[u8]) -> Vec { + let mut keccak = Keccak::v256(); + let mut result = [0u8; 32]; + keccak.update(data); + keccak.finalize(&mut result); + result.to_vec() +} + +#[wasm_bindgen] +pub fn generate_root_with_proof(calldata_bytes: &[u8], tree_size: u64) -> Result { + let store = MemStore::>::default(); + let mut mmr = MMR::, KeccakMerge, &MemStore>>::new(0, &store); + let mut leaf_positions = Vec::new(); + + for i in 0..tree_size { + let mut tx = calldata_bytes.to_vec(); + + if i != tree_size - 1 { + for j in 0..tx.len() { + tx[j] ^= i as u8; + } + } + + let hashed_leaf = hash_leaf(&tx); + let pos = mmr.push(hashed_leaf)?; + + if i == tree_size - 1 { + leaf_positions.push(pos); + } + } + + let root = mmr.get_root()?; + let root_hex = bytes_to_hex(&root); + + let proof = mmr.gen_proof(leaf_positions.clone())?; + + let proof_hex = bytes_to_hex_proof(proof.proof_items()); + let mmr_size = mmr.mmr_size(); + + Ok(serde_json::to_string(&MMRResult { + root: root_hex, + proof: proof_hex, + mmr_size, + leaf_positions, + keccak_hash_calldata: bytes_to_hex(&hash_leaf(calldata_bytes)), + })?) +} + +#[wasm_bindgen] +pub fn verify_proof( + root_hex: &str, + proof_hex: Vec, + mmr_size: u64, + leaf_position: u64, + calldata_bytes: &[u8], +) -> Result { + let root = hex::decode(root_hex.trim_start_matches("0x")) + .map_err(|e| JsError::new(&format!("Failed to decode root: {}", e)))?; + + let proof_items: Vec> = proof_hex + .iter() + .map(|item| { + hex::decode(item.trim_start_matches("0x")) + .map_err(|e| JsError::new(&format!("Failed to decode proof item: {}", e))) + }) + .collect::>, JsError>>()?; + + let proof = ckb_merkle_mountain_range::MerkleProof::, KeccakMerge>::new( + mmr_size, + proof_items.clone(), + ); + + let hashed_leaf = hash_leaf(calldata_bytes); + + // For debugging + #[cfg(test)] + { + println!("Verifying leaf at position: {}", leaf_position); + println!("Leaf hash: {:?}", hashed_leaf); + println!("Root: {:?}", root); + println!("Proof items: {:?}", proof_items); + } + + let result = proof.verify(root.clone(), vec![(leaf_position, hashed_leaf.clone())]); + + // For debugging + #[cfg(test)] + { + println!("Verification result: {:?}", result); + } + + // Extract the boolean result from the Result + let is_valid = result.unwrap_or(false); + + Ok(is_valid) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_proof_verification() { + let calldata_bytes: Vec = (0..32).map(|i| i as u8).collect(); + let tree_size = 10u64; + + println!("Original calldata: {:?}", calldata_bytes); + let root_with_proof = generate_root_with_proof(&calldata_bytes, tree_size).unwrap(); + let result: MMRResult = serde_json::from_str(&root_with_proof).unwrap(); + + let last_leaf_position = result.leaf_positions[result.leaf_positions.len() - 1]; + let proof_result = verify_proof( + &result.root, + result.proof.clone(), + result.mmr_size, + last_leaf_position, + &calldata_bytes, + ) + .unwrap(); + + assert!(proof_result); + + let mut modified_calldata = calldata_bytes.clone(); + modified_calldata[0] ^= 1; // Flip one bit + println!("Modified calldata: {:?}", modified_calldata); + + let modified_proof_result = verify_proof( + &result.root, + result.proof, + result.mmr_size, + last_leaf_position, + &modified_calldata, + ) + .unwrap(); + + println!("Modified Proof Result: {}", modified_proof_result); + assert!(!modified_proof_result); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/src/main.rs b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/src/main.rs new file mode 100644 index 00000000..22e522e0 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/ckb-mmr-wasm/src/main.rs @@ -0,0 +1,26 @@ +use ckb_mmr_wasm::{generate_root_with_proof, verify_proof, MMRResult}; + +fn main() -> Result<(), Box> { + let calldata_bytes: Vec = (0..128).map(|i| i as u8).collect(); + let tree_size = 100u64; + let root_with_proof = generate_root_with_proof(&calldata_bytes, tree_size).unwrap(); + let result: MMRResult = serde_json::from_str(&root_with_proof)?; + + println!("Root: {}", result.root); + println!("Proof: {:?}", result.proof); + println!("MMR Size: {}", result.mmr_size); + println!("Leaf Positions: {:?}", result.leaf_positions); + + let proof_result = verify_proof( + &result.root, + result.proof, + result.mmr_size, + result.leaf_positions[0], + &calldata_bytes, + ) + .unwrap(); + + println!("Proof Result: {}", proof_result); + + Ok(()) +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/exceptions.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/exceptions.ts new file mode 100644 index 00000000..e8daf5ca --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/exceptions.ts @@ -0,0 +1,25 @@ +export class AbortSignalInternal extends Error { + constructor(message: string) { + super() + + this.name = "Hyperbridge/SDK/AbortSignalInternal" + this.message = message + } + + static isError(error: unknown): error is AbortSignalInternal { + return error instanceof AbortSignalInternal + } +} + +export class ExpectedError extends Error { + constructor(message: string) { + super() + + this.name = "Hyperbridge/SDK/ExpectedError" + this.message = message + } + + static isError(error: unknown): error is ExpectedError { + return error instanceof ExpectedError + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/mmr.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/mmr.ts new file mode 100644 index 00000000..d679ae16 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/mmr.ts @@ -0,0 +1,249 @@ +import { hexToBytes } from "viem" +import { env, hasWindow, isNode } from "std-env" +import { postRequestCommitment } from "@/utils" +import type { HexString, IPostRequest } from "@/types" + +/** + * Gets peak position for a given height + */ +function getPeakPosByHeight(height: number): bigint { + return (1n << BigInt(height + 1)) - 2n +} + +/** + * Gets the height and position of the leftmost peak + */ +function leftPeakHeightPos(mmrSize: bigint): [number, bigint] { + let height = 1 + let prevPos = 0n + let pos = getPeakPosByHeight(height) + + while (pos < mmrSize) { + height += 1 + prevPos = pos + pos = getPeakPosByHeight(height) + } + + return [height - 1, prevPos] +} + +/** + * Gets the right peak at a given height and position + */ +function getRightPeak(initialHeight: number, initialPos: bigint, mmrSize: bigint): [number, bigint] | null { + let height = initialHeight + let pos = initialPos + + // move to right sibling pos + pos += siblingOffset(height) + + // loop until we find a pos in mmr + while (pos > mmrSize - 1n) { + if (height === 0) { + return null + } + // move to left child + pos -= parentOffset(height - 1) + height -= 1 + } + + return [height, pos] +} + +/** + * Gets all peaks in the MMR + */ +function getPeaks(mmrSize: bigint): bigint[] { + const positions: bigint[] = [] + let [height, pos] = leftPeakHeightPos(mmrSize) + + positions.push(pos) + + while (height > 0) { + const peak = getRightPeak(height, pos, mmrSize) + if (!peak) break + ;[height, pos] = peak + positions.push(pos) + } + + return positions +} + +/** + * Checks if a number consists of all ones in its binary representation + */ +function allOnes(num: bigint): boolean { + if (num === 0n) return false + return num + .toString(2) + .split("") + .every((bit) => bit === "1") +} + +/** + * Calculates the position after jumping left in the tree + */ +function jumpLeft(pos: bigint): bigint { + const bitLength = pos.toString(2).length + const mostSignificantBits = 1n << BigInt(bitLength - 1) + return pos - (mostSignificantBits - 1n) +} + +/** + * Calculates the height of a position in the tree + */ +function posHeightInTree(initialPos: bigint): number { + let pos = initialPos + 1n + + while (!allOnes(pos)) { + pos = jumpLeft(pos) + } + + return pos.toString(2).length - 1 +} + +/** + * Calculates the parent offset for a given height + */ +function parentOffset(height: number): bigint { + return 2n << BigInt(height) +} + +/** + * Calculates the sibling offset for a given height + */ +function siblingOffset(height: number): bigint { + return (2n << BigInt(height)) - 1n +} + +/** + * Takes elements from a vector while they satisfy a predicate + */ +function takeWhileVec(v: T[], p: (item: T) => boolean): T[] { + const index = v.findIndex((item) => !p(item)) + if (index === -1) { + const result = [...v] + v.length = 0 + return result + } + return v.splice(0, index) +} + +/** + * Converts a node's MMR position to its k-index + * @param leaves - Array of leaf positions + * @param mmrSize - Size of the MMR + * @returns Array of tuples containing position and k-index + */ +export function mmrPositionToKIndex(initialLeaves: bigint[], mmrSize: bigint): Array<[bigint, bigint]> { + const leaves = [...initialLeaves] + const peaks = getPeaks(mmrSize) + const leavesWithKIndices: Array<[bigint, bigint]> = [] + + for (const peak of peaks) { + const peakLeaves = takeWhileVec(leaves, (pos) => pos <= peak) + + if (peakLeaves.length > 0) { + for (const pos of peakLeaves) { + const height = posHeightInTree(peak) + let index = 0n + let parentPos = peak + + for (let h = height; h >= 1; h--) { + const leftChild = parentPos - parentOffset(h - 1) + const rightChild = leftChild + siblingOffset(h - 1) + index *= 2n + + if (leftChild >= pos) { + parentPos = leftChild + } else { + parentPos = rightChild + index += 1n + } + } + + leavesWithKIndices.push([pos, index]) + } + } + } + + return leavesWithKIndices +} + +/** + * Calculate the total size of MMR (number of nodes) from the number of leaves. + * @param numberOfLeaves - The number of leaves in the MMR + * @returns The total size of the MMR (total number of nodes) + */ +export function calculateMMRSize(numberOfLeaves: bigint): bigint { + const numberOfPeaks = numberOfLeaves.toString(2).split("1").length - 1 + return 2n * numberOfLeaves - BigInt(numberOfPeaks) +} + +/** + * Generates a Merkle Mountain Range (MMR) root hash and proof for a post request. + * + * This function takes a post request and tree size, encodes it according to the PostRequest format, + * and generates both the MMR root hash and a proof. The function builds an MMR with `treeSize` leaves, + * where most leaves are variations of the encoded request (XORed with their index), except for the + * last leaf, which is the unmodified request. The proof is generated for this unmodified leaf. + * + * @param postRequest - The post request to generate the MMR root and proof for + * @param treeSize - Controls how many leaves will be added to the MMR (exactly `treeSize` leaves) + * @returns An object containing: + * - root: The MMR root hash as a hex string + * - proof: An array of hex strings representing the MMR proof for the unmodified request + * - index: The index of the unmodified request in the MMR + * - kIndex: The k-index of the unmodified request in the MMR + * - treeSize: The number of leaves in the MMR + * - mmrSize: The size of the MMR in nodes + */ +export async function generateRootWithProof( + postRequest: IPostRequest, + treeSize: bigint, +): Promise<{ root: HexString; proof: HexString[]; index: bigint; kIndex: bigint; treeSize: bigint; mmrSize: bigint }> { + const { generate_root_with_proof } = await load_ckb_mmr() + const { commitment: hash, encodePacked } = postRequestCommitment(postRequest) + + const result = JSON.parse(generate_root_with_proof(hexToBytes(encodePacked), treeSize)) + const { root, proof, mmr_size, leaf_positions, keccak_hash_calldata } = result + + if (keccak_hash_calldata !== hash) { + console.log("keccak_hash", keccak_hash_calldata) + console.log("hash", hash) + throw new Error("Abi keccak hash mismatch") + } + + const [[, kIndex]] = mmrPositionToKIndex(leaf_positions, BigInt(mmr_size)) + + return { + root: root as HexString, + proof: proof as HexString[], + index: treeSize - 1n, + kIndex, + treeSize, + mmrSize: mmr_size, + } +} + +async function load_ckb_mmr() { + if (hasWindow) { + const wasm = await import("@/ckb-utils/web") + await wasm.default() + + return wasm + } + + if (isNode) { + const wasm = await import("@/ckb-utils/node") + return wasm + } + + throw new Error(`SDK not setup for ${env}`) +} + +export async function __test() { + const { generate_root_with_proof } = await load_ckb_mmr() + + return generate_root_with_proof(new Uint8Array(), 120n) +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/substrate.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/substrate.ts new file mode 100644 index 00000000..28bef768 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/substrate.ts @@ -0,0 +1,435 @@ +import { Struct, Vector, u8, u64, Tuple, Enum, _void, u32, Option } from "scale-ts" + +export type IStateMachine = + | { + tag: "Evm" + value: number + } + | { + tag: "Polkadot" + value: number + } + | { + tag: "Kusama" + value: number + } + | { + tag: "Substrate" + value: number[] + } + | { + tag: "Tendermint" + value: number[] + } + +export const H256 = Vector(u8, 32) + +export const EvmStateProof = Struct({ + /** + * Proof of the contract state. + */ + contractProof: Vector(Vector(u8)), + /** + * Proof of the storage state. + */ + storageProof: Vector(Tuple(Vector(u8), Vector(Vector(u8)))), +}) + +export const SubstrateHashing = Enum({ + /* For chains that use keccak as their hashing algo */ + Keccak: _void, + /* For chains that use blake2b as their hashing algo */ + Blake2: _void, +}) + +export const SubstrateStateMachineProof = Struct({ + /** + * The hasher used to hash the state machine state. + */ + hasher: SubstrateHashing, + /** + * Proof of the state machine state. + */ + storageProof: Vector(Vector(u8)), +}) + +export const SubstrateStateProof = Enum({ + /* + * Uses overlay root for verification + */ + OverlayProof: SubstrateStateMachineProof, + /* + * Uses state root for verification + */ + StateProof: SubstrateStateMachineProof, +}) + +export const BasicProof = Vector(Vector(u8)) + +export const LeafIndexAndPos = Struct({ + /* + * Leaf index + */ + leafIndex: u64, + /* + * Leaf position in the MMR + */ + pos: u64, +}) + +export const MmrProof = Struct({ + /* + * Proof of the leaf index and position. + */ + leafIndexAndPos: Vector(LeafIndexAndPos), + /* + * Proof of the leaf data. + */ + leafCount: u64, + /* + * Proof elements (hashes of siblings of inner nodes on the path to the leaf). + */ + items: Vector(H256), +}) + +export const ConsensusStateId = Vector(u8, 4) + +export const ConsensusMessage = Struct({ + /* + * Consensus message data. + */ + consensusProof: Vector(u8), + /* + * Consensus state Id + */ + consensusStateId: ConsensusStateId, + /* + * Public key of the sender + */ + signer: Vector(u8), +}) + +export const FraudProofMessage = Struct({ + /* + * The first valid consensus proof + */ + proof1: Vector(u8), + /* + * The second valid consensus proof + */ + proof2: Vector(u8), + /* + * Consensus state Id + */ + consensusStateId: ConsensusStateId, +}) + +export const StateMachine = Enum({ + /* + * Evm state machines + */ + Evm: u32, + /* + * Polkadot parachains + */ + Polkadot: u32, + /* + * Kusama parachains + */ + Kusama: u32, + /* + * Substrate-based standalone chain + */ + Substrate: ConsensusStateId, + /* + * Tendermint chains + */ + Tendermint: ConsensusStateId, +}) + +export const StateMachineId = Struct({ + /* + * The state machine id + */ + id: StateMachine, + /* + * The consensus state id + */ + consensusStateId: ConsensusStateId, +}) + +export const StateMachineHeight = Struct({ + /* + * The state machine id + */ + id: StateMachineId, + /* + * The height of the state machine + */ + height: u64, +}) + +export const Proof = Struct({ + /* + * The height of the state machine + */ + height: StateMachineHeight, + /* + * The proof + */ + proof: Vector(u8), +}) + +export const PostRequest = Struct({ + /* + * The source state machine of this request. + */ + source: StateMachine, + /* + * The destination state machine of this request. + */ + dest: StateMachine, + /* + * The nonce of this request on the source chain + */ + nonce: u64, + /* + * Module identifier of the sending module + */ + from: Vector(u8), + /* + * Module identifier of the receiving module + */ + to: Vector(u8), + /* + * Timestamp which this request expires in seconds. + */ + timeoutTimestamp: u64, + /* + * Encoded request body + */ + body: Vector(u8), +}) + +export const PostResponse = Struct({ + /* + * The request that triggered this response. + */ + post: PostRequest, + /* + * The response message. + */ + response: Vector(u8), + /* + * Timestamp at which this response expires in seconds. + */ + timeoutTimestamp: u64, +}) + +export const GetRequest = Struct({ + /* + * The source state machine of this request. + */ + source: StateMachine, + /* + * The destination state machine of this request. + */ + dest: StateMachine, + /* + * The nonce of this request on the source chain + */ + nonce: u64, + /* + * Module identifier of the sending module + */ + from: Vector(u8), + /* + * Raw Storage keys that would be used to fetch the values from the counterparty + * For deriving storage keys for ink contract fields follow the guide in the link below + * `` + * Substrate Keys + */ + keys: Vector(Vector(u8)), + /* + * The height of the state machine + */ + height: u64, + /* + * Some application-specific metadata relating to this request + */ + context: Vector(u8), + /* + * Host timestamp at which this request expires in seconds + */ + timeoutTimestamp: u64, +}) + +export const StorageValue = Struct({ + /* + * The request storage keys + */ + key: Vector(u8), + /* + * The verified value + */ + value: Option(Vector(u8)), +}) + +export const GetResponse = Struct({ + /* + * The Get request that triggered this response. + */ + get: GetRequest, + /* + * Values derived from the state proof + */ + values: Vector(StorageValue), +}) + +export const Request = Enum({ + /* + * A post request allows a module on a state machine to send arbitrary bytes to another module + * living in another state machine. + */ + Post: PostRequest, + /* + * A get request allows a module on a state machine to read the storage of another module + * living in another state machine. + */ + Get: GetRequest, +}) + +export const Response = Enum({ + /* + * The response to a POST request + */ + Post: PostResponse, + /* + * The response to a GET request + */ + Get: GetResponse, +}) + +export const RequestMessage = Struct({ + /* + * Requests from source chain + */ + requests: Vector(PostRequest), + /* + * Membership batch proof for these requests + */ + proof: Proof, + /* + * Signer information. Ideally should be their account identifier + */ + signer: Vector(u8), +}) + +export const RequestResponse = Enum({ + /* + * A set of requests + */ + Request: Vector(Request), + /* + * A set of responses + */ + Response: Vector(Response), +}) + +export const ResponseMessage = Struct({ + /* + * A set of either POST requests or responses to be handled + */ + datagram: Vector(RequestResponse), + /* + * Membership batch proof for these requests/responses + */ + proof: Proof, + /* + * Signer information. Ideally should be their account identifier + */ + signer: Vector(u8), +}) + +export const TimeoutMessage = Enum({ + /* + * A non memership proof for POST requests + */ + Post: Struct({ + /* + * Timed out requests + */ + requests: Vector(Request), + /* + * Membership batch proof for these requests + */ + proof: Proof, + }), + /* + * A non memership proof for POST responses + */ + PostResponse: Struct({ + /* + * Timed out responses + */ + responses: Vector(Response), + /* + * Membership batch proof for these responses + */ + proof: Proof, + }), + /* + * There are no proofs for Get timeouts + */ + Get: Struct({ + /* + * Timed out requests + */ + requests: Vector(Request), + }), +}) + +export const GetRequestsWithProof = Struct({ + /* + * Requests to be fetched + */ + requests: Vector(GetRequest), + + /* + * Membership batch proof for these requests + */ + source: Proof, + + /* + * Storage proof for these responses + */ + response: Proof, + + /* + * Signer information. Ideally should be their account identifier + */ + signer: Vector(u8), +}) + +export const Message = Enum({ + /* + * A consensus update message + */ + ConsensusMessage: ConsensusMessage, + /* + * A fraud proof message + */ + FraudProofMessage: FraudProofMessage, + /* + * A request message + */ + RequestMessage: RequestMessage, + /* + * A response message + */ + ResponseMessage: ResponseMessage, + /* + * A request timeout message + */ + TimeoutMessage: TimeoutMessage, +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/swap.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/swap.ts new file mode 100644 index 00000000..6ee6e38b --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/swap.ts @@ -0,0 +1,1756 @@ +import { + PublicClient, + maxUint256, + encodeAbiParameters, + parseAbiParameters, + parseAbiItem, + encodePacked, + encodeFunctionData, + erc20Abi, +} from "viem" +import { ADDRESS_ZERO, ChainConfigService, HexString, Transaction } from ".." +import UniswapRouterV2 from "@/abis/uniswapRouterV2" +import UniswapV3Quoter from "@/abis/uniswapV3Quoter" +import { UNISWAP_V4_QUOTER_ABI } from "@/abis/uniswapV4Quoter" +import universalRouter from "@/abis/universalRouter" +import { UniversalRouterCommands } from "@/utils" +import { PERMIT2_ABI } from "@/abis/permit2" +import { popularTokens } from "@/configs/chain" + +const COMMON_FEE_TIERS = [100, 500, 2500, 3000, 10000] + +export class Swap { + private chainConfigService: ChainConfigService + constructor() { + this.chainConfigService = new ChainConfigService() + } + /** + * Gets V2 quote for exact output swap. + */ + async getV2QuoteWithAmountOut( + client: PublicClient, + tokenIn: HexString, + tokenOut: HexString, + amountOut: bigint, + evmChainID: string, + ): Promise { + const v2Router = this.chainConfigService.getUniswapRouterV2Address(evmChainID) + + const wethAsset = this.chainConfigService.getWrappedNativeAssetWithDecimals(evmChainID).asset + const tokenInForQuote = tokenIn === ADDRESS_ZERO ? wethAsset : tokenIn + const tokenOutForQuote = tokenOut === ADDRESS_ZERO ? wethAsset : tokenOut + + try { + const v2AmountIn = await client.simulateContract({ + address: v2Router, + abi: UniswapRouterV2.ABI, + // @ts-ignore + functionName: "getAmountsIn", + // @ts-ignore + args: [amountOut, [tokenInForQuote, tokenOutForQuote]], + }) + + return v2AmountIn.result[0] + } catch { + console.warn("V2 quote failed:") + return maxUint256 + } + } + + /** + * Gets V2 quote for exact input swap. + */ + async getV2QuoteWithAmountIn( + client: PublicClient, + tokenIn: HexString, + tokenOut: HexString, + amountIn: bigint, + evmChainID: string, + ): Promise { + const v2Router = this.chainConfigService.getUniswapRouterV2Address(evmChainID) + + const wethAsset = this.chainConfigService.getWrappedNativeAssetWithDecimals(evmChainID).asset + const tokenInForQuote = tokenIn === ADDRESS_ZERO ? wethAsset : tokenIn + const tokenOutForQuote = tokenOut === ADDRESS_ZERO ? wethAsset : tokenOut + + try { + const v2AmountOut = await client.simulateContract({ + address: v2Router, + abi: UniswapRouterV2.ABI, + // @ts-ignore + functionName: "getAmountsOut", + // @ts-ignore + args: [amountIn, [tokenInForQuote, tokenOutForQuote]], + }) + + return v2AmountOut.result[1] + } catch { + console.warn("V2 quote failed:") + return BigInt(0) + } + } + + /** + * Gets V3 quote for exact output swap. + */ + async getV3QuoteWithAmountOut( + client: PublicClient, + tokenIn: HexString, + tokenOut: HexString, + amountOut: bigint, + evmChainID: string, + ): Promise<{ amountIn: bigint; fee: number }> { + let bestAmountIn = maxUint256 + let bestFee = 0 + + const v3Quoter = this.chainConfigService.getUniswapV3QuoterAddress(evmChainID) + + const wethAsset = this.chainConfigService.getWrappedNativeAssetWithDecimals(evmChainID).asset + const tokenInForQuote = tokenIn === ADDRESS_ZERO ? wethAsset : tokenIn + const tokenOutForQuote = tokenOut === ADDRESS_ZERO ? wethAsset : tokenOut + + for (const fee of COMMON_FEE_TIERS) { + try { + const quoteResult = ( + await client.simulateContract({ + address: v3Quoter, + abi: UniswapV3Quoter.ABI, + functionName: "quoteExactOutputSingle", + args: [ + { + tokenIn: tokenInForQuote, + tokenOut: tokenOutForQuote, + fee: fee, + amount: amountOut, + sqrtPriceLimitX96: BigInt(0), + }, + ], + }) + ).result as [bigint, bigint, number, bigint] + + const amountIn = quoteResult[0] + + if (amountIn < bestAmountIn) { + bestAmountIn = amountIn + bestFee = fee + } + } catch { + console.warn(`V3 quote failed for fee ${fee}, continuing to next fee tier`) + } + } + + return { amountIn: bestAmountIn, fee: bestFee } + } + + /** + * Gets V3 quote for exact input swap. + */ + async getV3QuoteWithAmountIn( + client: PublicClient, + tokenIn: HexString, + tokenOut: HexString, + amountIn: bigint, + evmChainID: string, + ): Promise<{ amountOut: bigint; fee: number }> { + let bestAmountOut = BigInt(0) + let bestFee = 0 + + const v3Quoter = this.chainConfigService.getUniswapV3QuoterAddress(evmChainID) + + const wethAsset = this.chainConfigService.getWrappedNativeAssetWithDecimals(evmChainID).asset + const tokenInForQuote = tokenIn === ADDRESS_ZERO ? wethAsset : tokenIn + const tokenOutForQuote = tokenOut === ADDRESS_ZERO ? wethAsset : tokenOut + + for (const fee of COMMON_FEE_TIERS) { + try { + const quoteResult = ( + await client.simulateContract({ + address: v3Quoter, + abi: UniswapV3Quoter.ABI, + functionName: "quoteExactInputSingle", + args: [ + { + tokenIn: tokenInForQuote, + tokenOut: tokenOutForQuote, + fee: fee, + amountIn: amountIn, + sqrtPriceLimitX96: BigInt(0), + }, + ], + }) + ).result as [bigint, bigint, number, bigint] + + const amountOut = quoteResult[0] + + if (amountOut > bestAmountOut) { + bestAmountOut = amountOut + bestFee = fee + } + } catch { + console.warn(`V3 quote failed for fee ${fee}, continuing to next fee tier`) + } + } + + return { amountOut: bestAmountOut, fee: bestFee } + } + + /** + * Gets V4 quote for exact output swap. + */ + async getV4QuoteWithAmountOut( + client: PublicClient, + tokenIn: HexString, + tokenOut: HexString, + amountOut: bigint, + evmChainID: string, + ): Promise<{ amountIn: bigint; fee: number }> { + let bestAmountIn = maxUint256 + let bestFee = 0 + + const v4Quoter = this.chainConfigService.getUniswapV4QuoterAddress(evmChainID) + + for (const fee of COMMON_FEE_TIERS) { + try { + const currency0 = tokenIn.toLowerCase() < tokenOut.toLowerCase() ? tokenIn : tokenOut + const currency1 = tokenIn.toLowerCase() < tokenOut.toLowerCase() ? tokenOut : tokenIn + + const zeroForOne = tokenIn.toLowerCase() === currency0.toLowerCase() + + const poolKey = { + currency0: currency0, + currency1: currency1, + fee: fee, + tickSpacing: this.getTickSpacing(fee), + hooks: ADDRESS_ZERO, + } + + const quoteResult = ( + await client.simulateContract({ + address: v4Quoter, + abi: UNISWAP_V4_QUOTER_ABI, + functionName: "quoteExactOutputSingle", + args: [ + { + poolKey: poolKey, + zeroForOne: zeroForOne, + exactAmount: amountOut, + hookData: "0x", + }, + ], + }) + ).result as [bigint, bigint] + + const amountIn = quoteResult[0] + + if (amountIn < bestAmountIn) { + bestAmountIn = amountIn + bestFee = fee + } + } catch { + console.warn(`V4 quote failed for fee ${fee}, continuing to next fee tier`) + } + } + + return { amountIn: bestAmountIn, fee: bestFee } + } + + /** + * Gets V4 quote for exact input swap. + */ + async getV4QuoteWithAmountIn( + client: PublicClient, + tokenIn: HexString, + tokenOut: HexString, + amountIn: bigint, + evmChainID: string, + ): Promise<{ amountOut: bigint; fee: number }> { + let bestAmountOut = BigInt(0) + let bestFee = 0 + + const v4Quoter = this.chainConfigService.getUniswapV4QuoterAddress(evmChainID) + + for (const fee of COMMON_FEE_TIERS) { + try { + const currency0 = tokenIn.toLowerCase() < tokenOut.toLowerCase() ? tokenIn : tokenOut + const currency1 = tokenIn.toLowerCase() < tokenOut.toLowerCase() ? tokenOut : tokenIn + + const zeroForOne = tokenIn.toLowerCase() === currency0.toLowerCase() + + const poolKey = { + currency0: currency0, + currency1: currency1, + fee: fee, + tickSpacing: this.getTickSpacing(fee), + hooks: ADDRESS_ZERO, + } + + const quoteResult = ( + await client.simulateContract({ + address: v4Quoter, + abi: UNISWAP_V4_QUOTER_ABI, + functionName: "quoteExactInputSingle", + args: [ + { + poolKey: poolKey, + zeroForOne: zeroForOne, + exactAmount: amountIn, + hookData: "0x", + }, + ], + }) + ).result as [bigint, bigint] + + const amountOut = quoteResult[0] + + if (amountOut > bestAmountOut) { + bestAmountOut = amountOut + bestFee = fee + } + } catch { + console.warn(`V4 quote failed for fee ${fee}, continuing to next fee tier`) + } + } + + return { amountOut: bestAmountOut, fee: bestFee } + } + + /** + * Creates transaction structure for V2 exact input swap, including ERC20 transfer if needed. + * Supports both single-hop and multi-hop swaps. + */ + createV2SwapCalldataExactIn( + path: HexString[], + amountIn: bigint, + amountOutMinimum: bigint, + recipient: HexString, + evmChainID: string, + ): Transaction[] { + if (path.length < 2) { + throw new Error("Path must contain at least 2 tokens") + } + + if (path[0].toLowerCase() === path[path.length - 1].toLowerCase()) { + throw new Error("Source and target tokens cannot be the same") + } + + const isPermit2 = false + const wethAsset = this.chainConfigService.getWrappedNativeAssetWithDecimals(evmChainID).asset + const universalRouterAddress = this.chainConfigService.getUniversalRouterAddress(evmChainID) + + const swapPath = path.map((token) => (token === ADDRESS_ZERO ? wethAsset : token)) + + const sourceTokenAddress = path[0] + const targetTokenAddress = path[path.length - 1] + + const commands: number[] = [] + const inputs: HexString[] = [] + + if (sourceTokenAddress === ADDRESS_ZERO) { + commands.push(UniversalRouterCommands.WRAP_ETH) + inputs.push( + encodeAbiParameters(parseAbiParameters("address recipient, uint256 amountMin"), [ + universalRouterAddress, + amountIn, + ]), + ) + } + + commands.push(UniversalRouterCommands.V2_SWAP_EXACT_IN) + inputs.push( + encodeAbiParameters( + parseAbiParameters( + "address recipient, uint256 amountIn, uint256 amountOutMinimum, address[] path, bool isPermit2", + ), + [ + targetTokenAddress === ADDRESS_ZERO ? universalRouterAddress : recipient, + amountIn, + amountOutMinimum, + swapPath, + isPermit2, + ], + ), + ) + + if (targetTokenAddress === ADDRESS_ZERO) { + commands.push(UniversalRouterCommands.UNWRAP_WETH) + inputs.push( + encodeAbiParameters(parseAbiParameters("address recipient, uint256 amountMin"), [ + recipient, + amountOutMinimum, + ]), + ) + } + + const commandsEncoded = this.encodeCommands(commands) + const executeData = encodeFunctionData({ + abi: universalRouter.ABI, + functionName: "execute", + args: [commandsEncoded, inputs], + }) + + const transactions: Transaction[] = [] + + if (sourceTokenAddress !== ADDRESS_ZERO) { + const transferData = encodeFunctionData({ + abi: erc20Abi, + functionName: "transfer", + args: [universalRouterAddress, amountIn], + }) + + transactions.push({ + to: sourceTokenAddress, + value: 0n, + data: transferData, + }) + } + + transactions.push({ + to: universalRouterAddress, + value: sourceTokenAddress === ADDRESS_ZERO ? amountIn : 0n, + data: executeData, + }) + + return transactions + } + + /** + * Creates transaction structure for V2 exact output swap, including ERC20 transfer if needed. + * Supports both single-hop and multi-hop swaps. + */ + createV2SwapCalldataExactOut( + path: HexString[], + amountOut: bigint, + amountInMax: bigint, + recipient: HexString, + evmChainID: string, + ): Transaction[] { + if (path.length < 2) { + throw new Error("Path must contain at least 2 tokens") + } + + if (path[0].toLowerCase() === path[path.length - 1].toLowerCase()) { + throw new Error("Source and target tokens cannot be the same") + } + + const isPermit2 = false + const wethAsset = this.chainConfigService.getWrappedNativeAssetWithDecimals(evmChainID).asset + const universalRouterAddress = this.chainConfigService.getUniversalRouterAddress(evmChainID) + + // Convert ADDRESS_ZERO to WETH in path + const swapPath = path.map((token) => (token === ADDRESS_ZERO ? wethAsset : token)) + + const sourceTokenAddress = path[0] + const targetTokenAddress = path[path.length - 1] + + const commands: number[] = [] + const inputs: HexString[] = [] + const transactions: Transaction[] = [] + + if (sourceTokenAddress === ADDRESS_ZERO) { + commands.push(UniversalRouterCommands.WRAP_ETH) + inputs.push( + encodeAbiParameters(parseAbiParameters("address recipient, uint256 amountMin"), [ + universalRouterAddress, + amountInMax, + ]), + ) + } + + commands.push(UniversalRouterCommands.V2_SWAP_EXACT_OUT) + inputs.push( + encodeAbiParameters( + parseAbiParameters( + "address recipient, uint256 amountOut, uint256 amountInMax, address[] path, bool isPermit2", + ), + [ + targetTokenAddress === ADDRESS_ZERO ? universalRouterAddress : recipient, + amountOut, + amountInMax, + swapPath, + isPermit2, + ], + ), + ) + + if (targetTokenAddress === ADDRESS_ZERO) { + commands.push(UniversalRouterCommands.UNWRAP_WETH) + inputs.push( + encodeAbiParameters(parseAbiParameters("address recipient, uint256 amountMin"), [recipient, amountOut]), + ) + } + + const commandsEncoded = this.encodeCommands(commands) + const executeData = encodeFunctionData({ + abi: universalRouter.ABI, + functionName: "execute", + args: [commandsEncoded, inputs], + }) + + if (sourceTokenAddress !== ADDRESS_ZERO) { + const transferData = encodeFunctionData({ + abi: erc20Abi, + functionName: "transfer", + args: [universalRouterAddress, amountInMax], + }) + + transactions.push({ + to: sourceTokenAddress, + value: 0n, + data: transferData, + }) + } + + transactions.push({ + to: universalRouterAddress, + value: sourceTokenAddress === ADDRESS_ZERO ? amountInMax : 0n, + data: executeData, + }) + + return transactions + } + + /** + * Creates transaction structure for V3 exact input swap, including ERC20 transfer if needed. + * Supports both single-hop and multi-hop swaps. + */ + createV3SwapCalldataExactIn( + path: HexString[], + amountIn: bigint, + amountOutMinimum: bigint, + fees: number[], + recipient: HexString, + evmChainID: string, + ): Transaction[] { + if (path.length < 2) { + throw new Error("Path must contain at least 2 tokens") + } + + if (path[0].toLowerCase() === path[path.length - 1].toLowerCase()) { + throw new Error("Source and target tokens cannot be the same") + } + + if (fees.length !== path.length - 1) { + throw new Error("Fees array length must be one less than path length") + } + + const isPermit2 = false + const wethAsset = this.chainConfigService.getWrappedNativeAssetWithDecimals(evmChainID).asset + const universalRouterAddress = this.chainConfigService.getUniversalRouterAddress(evmChainID) + + // Build path elements with alternating tokens and fees + const pathElements: Array = [] + for (let i = 0; i < path.length; i++) { + const token = path[i] === ADDRESS_ZERO ? wethAsset : path[i] + pathElements.push(token) + + if (i < path.length - 1) { + pathElements.push(fees[i]) + } + } + + const types: string[] = [] + for (let i = 0; i < pathElements.length; i++) { + types.push(i % 2 === 0 ? "address" : "uint24") + } + + const pathV3 = encodePacked(types, pathElements) + + const sourceTokenAddress = path[0] + const targetTokenAddress = path[path.length - 1] + + const commands: number[] = [] + const inputs: HexString[] = [] + + if (sourceTokenAddress === ADDRESS_ZERO) { + commands.push(UniversalRouterCommands.WRAP_ETH) + inputs.push( + encodeAbiParameters(parseAbiParameters("address recipient, uint256 amountMin"), [ + universalRouterAddress, + amountIn, + ]), + ) + } + + commands.push(UniversalRouterCommands.V3_SWAP_EXACT_IN) + inputs.push( + encodeAbiParameters( + parseAbiParameters( + "address recipient, uint256 amountIn, uint256 amountOutMinimum, bytes path, bool isPermit2", + ), + [ + targetTokenAddress === ADDRESS_ZERO ? universalRouterAddress : recipient, + amountIn, + amountOutMinimum, + pathV3, + isPermit2, + ], + ), + ) + + if (targetTokenAddress === ADDRESS_ZERO) { + commands.push(UniversalRouterCommands.UNWRAP_WETH) + inputs.push( + encodeAbiParameters(parseAbiParameters("address recipient, uint256 amountMin"), [ + recipient, + amountOutMinimum, + ]), + ) + } + + const commandsEncoded = this.encodeCommands(commands) + const executeData = encodeFunctionData({ + abi: universalRouter.ABI, + functionName: "execute", + args: [commandsEncoded, inputs], + }) + + const transactions: Transaction[] = [] + + if (sourceTokenAddress !== ADDRESS_ZERO) { + const transferData = encodeFunctionData({ + abi: erc20Abi, + functionName: "transfer", + args: [universalRouterAddress, amountIn], + }) + + transactions.push({ + to: sourceTokenAddress, + value: 0n, + data: transferData, + }) + } + + transactions.push({ + to: universalRouterAddress, + value: sourceTokenAddress === ADDRESS_ZERO ? amountIn : 0n, + data: executeData, + }) + + return transactions + } + + /** + * Creates transaction structure for V3 exact output swap, including ERC20 transfer if needed. + * Supports both single-hop and multi-hop swaps. + */ + createV3SwapCalldataExactOut( + path: HexString[], + amountOut: bigint, + amountInMax: bigint, + fees: number[], + recipient: HexString, + evmChainID: string, + ): Transaction[] { + if (path.length < 2) { + throw new Error("Path must contain at least 2 tokens") + } + + if (path[0].toLowerCase() === path[path.length - 1].toLowerCase()) { + throw new Error("Source and target tokens cannot be the same") + } + + if (fees.length !== path.length - 1) { + throw new Error("Fees array length must be one less than path length") + } + + const isPermit2 = false + const wethAsset = this.chainConfigService.getWrappedNativeAssetWithDecimals(evmChainID).asset + const universalRouterAddress = this.chainConfigService.getUniversalRouterAddress(evmChainID) + + // Build path elements with alternating tokens and fees (reversed for exact output) + const pathElements: Array = [] + for (let i = path.length - 1; i >= 0; i--) { + const token = path[i] === ADDRESS_ZERO ? wethAsset : path[i] + pathElements.push(token) + + if (i > 0) { + pathElements.push(fees[i - 1]) + } + } + + const types: string[] = [] + for (let i = 0; i < pathElements.length; i++) { + types.push(i % 2 === 0 ? "address" : "uint24") + } + + const pathV3 = encodePacked(types, pathElements) + + const sourceTokenAddress = path[0] + const targetTokenAddress = path[path.length - 1] + + const commands: number[] = [] + const inputs: HexString[] = [] + + if (sourceTokenAddress === ADDRESS_ZERO) { + commands.push(UniversalRouterCommands.WRAP_ETH) + inputs.push( + encodeAbiParameters(parseAbiParameters("address recipient, uint256 amountMin"), [ + universalRouterAddress, + amountInMax, + ]), + ) + } + + commands.push(UniversalRouterCommands.V3_SWAP_EXACT_OUT) + inputs.push( + encodeAbiParameters( + parseAbiParameters( + "address recipient, uint256 amountOut, uint256 amountInMax, bytes path, bool isPermit2", + ), + [ + targetTokenAddress === ADDRESS_ZERO ? universalRouterAddress : recipient, + amountOut, + amountInMax, + pathV3, + isPermit2, + ], + ), + ) + + if (targetTokenAddress === ADDRESS_ZERO) { + commands.push(UniversalRouterCommands.UNWRAP_WETH) + inputs.push( + encodeAbiParameters(parseAbiParameters("address recipient, uint256 amountMin"), [recipient, amountOut]), + ) + } + + const commandsEncoded = this.encodeCommands(commands) + const executeData = encodeFunctionData({ + abi: universalRouter.ABI, + functionName: "execute", + args: [commandsEncoded, inputs], + }) + + const transactions: Transaction[] = [] + + if (sourceTokenAddress !== ADDRESS_ZERO) { + const transferData = encodeFunctionData({ + abi: erc20Abi, + functionName: "transfer", + args: [universalRouterAddress, amountInMax], + }) + + transactions.push({ + to: sourceTokenAddress, + value: 0n, + data: transferData, + }) + } + + transactions.push({ + to: universalRouterAddress, + value: sourceTokenAddress === ADDRESS_ZERO ? amountInMax : 0n, + data: executeData, + }) + + return transactions + } + + /** + * Creates transaction structure for V4 exact input swap, including Permit2 approvals for ERC20 tokens. + */ + createV4SwapCalldataExactIn( + sourceTokenAddress: HexString, + targetTokenAddress: HexString, + amountIn: bigint, + amountOutMinimum: bigint, + fee: number, + evmChainID: string, + ): Transaction[] { + if (sourceTokenAddress.toLowerCase() === targetTokenAddress.toLowerCase()) { + throw new Error("Source and target tokens cannot be the same") + } + const currency0 = + sourceTokenAddress.toLowerCase() < targetTokenAddress.toLowerCase() + ? sourceTokenAddress + : targetTokenAddress + const currency1 = + sourceTokenAddress.toLowerCase() < targetTokenAddress.toLowerCase() + ? targetTokenAddress + : sourceTokenAddress + + const zeroForOne = sourceTokenAddress.toLowerCase() === currency0.toLowerCase() + + const poolKey = { + currency0: currency0, + currency1: currency1, + fee: fee, + tickSpacing: this.getTickSpacing(fee), + hooks: ADDRESS_ZERO, + } + + const actions = encodePacked( + ["uint8", "uint8", "uint8"], + [ + UniversalRouterCommands.V4_SWAP_EXACT_IN_SINGLE, + UniversalRouterCommands.SETTLE_ALL, + UniversalRouterCommands.TAKE_ALL, + ], + ) + + const swapParams = encodeAbiParameters( + parseAbiParameters( + "((address currency0, address currency1, uint24 fee, int24 tickSpacing, address hooks) poolKey, bool zeroForOne, uint128 amountIn, uint128 amountOutMinimum, bytes hookData)", + ), + [ + { + poolKey, + zeroForOne, + amountIn, + amountOutMinimum, + hookData: "0x", + }, + ], + ) + + const settleParams = encodeAbiParameters(parseAbiParameters("address currency, uint128 amount"), [ + sourceTokenAddress, + amountIn, + ]) + + const takeParams = encodeAbiParameters(parseAbiParameters("address currency, uint128 amount"), [ + targetTokenAddress, + amountOutMinimum, + ]) + + const params = [swapParams, settleParams, takeParams] + + const commands = encodePacked(["uint8"], [UniversalRouterCommands.V4_SWAP]) + const inputs = [encodeAbiParameters(parseAbiParameters("bytes actions, bytes[] params"), [actions, params])] + + const executeData = encodeFunctionData({ + abi: universalRouter.ABI, + functionName: "execute", + args: [commands, inputs], + }) + + const transactions: Transaction[] = [] + + if (sourceTokenAddress !== ADDRESS_ZERO) { + const approveToPermit2Data = encodeFunctionData({ + abi: erc20Abi, + functionName: "approve", + args: [this.chainConfigService.getPermit2Address(evmChainID), amountIn], + }) + + transactions.push({ + to: sourceTokenAddress, + value: 0n, + data: approveToPermit2Data, + }) + + const permit2ApprovalData = encodeFunctionData({ + abi: PERMIT2_ABI, + functionName: "approve", + args: [ + sourceTokenAddress, + this.chainConfigService.getUniversalRouterAddress(evmChainID), + amountIn, + 281474976710655, // Max expiration + ], + }) + + transactions.push({ + to: this.chainConfigService.getPermit2Address(evmChainID), + value: 0n, + data: permit2ApprovalData, + }) + } + + transactions.push({ + to: this.chainConfigService.getUniversalRouterAddress(evmChainID), + value: sourceTokenAddress === ADDRESS_ZERO ? amountIn : 0n, + data: executeData, + }) + + return transactions + } + + /** + * Creates transaction structure for V4 exact output swap, including Permit2 approvals for ERC20 tokens. + */ + createV4SwapCalldataExactOut( + sourceTokenAddress: HexString, + targetTokenAddress: HexString, + amountOut: bigint, + amountInMax: bigint, + fee: number, + evmChainID: string, + ): Transaction[] { + if (sourceTokenAddress.toLowerCase() === targetTokenAddress.toLowerCase()) { + throw new Error("Source and target tokens cannot be the same") + } + const currency0 = + sourceTokenAddress.toLowerCase() < targetTokenAddress.toLowerCase() + ? sourceTokenAddress + : targetTokenAddress + const currency1 = + sourceTokenAddress.toLowerCase() < targetTokenAddress.toLowerCase() + ? targetTokenAddress + : sourceTokenAddress + + const zeroForOne = sourceTokenAddress.toLowerCase() === currency0.toLowerCase() + + const poolKey = { + currency0: currency0, + currency1: currency1, + fee: fee, + tickSpacing: this.getTickSpacing(fee), + hooks: ADDRESS_ZERO, + } + + const actions = encodePacked( + ["uint8", "uint8", "uint8"], + [ + UniversalRouterCommands.V4_SWAP_EXACT_OUT_SINGLE, + UniversalRouterCommands.SETTLE_ALL, + UniversalRouterCommands.TAKE_ALL, + ], + ) + + const swapParams = encodeAbiParameters( + parseAbiParameters( + "((address currency0, address currency1, uint24 fee, int24 tickSpacing, address hooks) poolKey, bool zeroForOne, uint128 amountOut, uint128 amountInMaximum, bytes hookData)", + ), + [ + { + poolKey, + zeroForOne, + amountOut, + amountInMaximum: amountInMax, + hookData: "0x", + }, + ], + ) + + const settleParams = encodeAbiParameters(parseAbiParameters("address currency, uint128 amount"), [ + sourceTokenAddress, + amountInMax, + ]) + + const takeParams = encodeAbiParameters(parseAbiParameters("address currency, uint128 amount"), [ + targetTokenAddress, + amountOut, + ]) + + const params = [swapParams, settleParams, takeParams] + + const commands = encodePacked(["uint8"], [UniversalRouterCommands.V4_SWAP]) + const inputs = [encodeAbiParameters(parseAbiParameters("bytes actions, bytes[] params"), [actions, params])] + + const executeData = encodeFunctionData({ + abi: universalRouter.ABI, + functionName: "execute", + args: [commands, inputs], + }) + + const transactions: Transaction[] = [] + + if (sourceTokenAddress !== ADDRESS_ZERO) { + const approveToPermit2Data = encodeFunctionData({ + abi: erc20Abi, + functionName: "approve", + args: [this.chainConfigService.getPermit2Address(evmChainID), amountInMax], + }) + + transactions.push({ + to: sourceTokenAddress, + value: 0n, + data: approveToPermit2Data, + }) + + const permit2ApprovalData = encodeFunctionData({ + abi: PERMIT2_ABI, + functionName: "approve", + args: [ + sourceTokenAddress, + this.chainConfigService.getUniversalRouterAddress(evmChainID), + amountInMax, + 281474976710655, // Max expiration + ], + }) + + transactions.push({ + to: this.chainConfigService.getPermit2Address(evmChainID), + value: 0n, + data: permit2ApprovalData, + }) + } + + transactions.push({ + to: this.chainConfigService.getUniversalRouterAddress(evmChainID), + value: sourceTokenAddress === ADDRESS_ZERO ? amountInMax : 0n, + data: executeData, + }) + + return transactions + } + + /** + * Finds the best Uniswap protocol (V2, V3, or V4) for swapping tokens given a desired output amount. + * Compares liquidity and pricing across different protocols and fee tiers. + * + * @param getQuoteIn - Whether to use "source" or "dest" chain for the swap + * @param tokenIn - The address of the input token + * @param tokenOut - The address of the output token + * @param amountOut - The desired output amount + * @returns Object containing the best protocol, required input amount, fee tier (for V3/V4), and transaction structure + */ + async findBestProtocolWithAmountOut( + client: PublicClient, + tokenIn: HexString, + tokenOut: HexString, + amountOut: bigint, + evmChainID: string, + options?: { + selectedProtocol?: "v2" | "v3" | "v4" + generateCalldata?: boolean + recipient?: HexString + }, + ): Promise<{ + protocol: "v2" | "v3" | "v4" | null + amountIn: bigint + fee?: number + transactions?: Transaction[] + }> { + if (options?.generateCalldata && !options?.recipient) { + throw new Error("Recipient address is required when generating calldata") + } + + if (options?.selectedProtocol) { + if (options.selectedProtocol === "v2") { + const amountInV2 = await this.getV2QuoteWithAmountOut(client, tokenIn, tokenOut, amountOut, evmChainID) + if (amountInV2 === maxUint256) { + return { protocol: null, amountIn: maxUint256 } + } + let transactions: Transaction[] | undefined + if (options?.generateCalldata) { + transactions = this.createV2SwapCalldataExactOut( + [tokenIn, tokenOut], + amountOut, + amountInV2, + options.recipient!, + evmChainID, + ) + } + return { protocol: "v2", amountIn: amountInV2, transactions } + } + + if (options.selectedProtocol === "v3") { + const { amountIn: amountInV3, fee: bestV3Fee } = await this.getV3QuoteWithAmountOut( + client, + tokenIn, + tokenOut, + amountOut, + evmChainID, + ) + if (amountInV3 === maxUint256) { + return { protocol: null, amountIn: maxUint256 } + } + let transactions: Transaction[] | undefined + if (options?.generateCalldata) { + transactions = this.createV3SwapCalldataExactOut( + [tokenIn, tokenOut], + amountOut, + amountInV3, + [bestV3Fee], + options.recipient!, + evmChainID, + ) + } + return { protocol: "v3", amountIn: amountInV3, fee: bestV3Fee, transactions } + } + + if (options.selectedProtocol === "v4") { + const { amountIn: amountInV4, fee: bestV4Fee } = await this.getV4QuoteWithAmountOut( + client, + tokenIn, + tokenOut, + amountOut, + evmChainID, + ) + if (amountInV4 === maxUint256) { + return { protocol: null, amountIn: maxUint256 } + } + let transactions: Transaction[] | undefined + if (options?.generateCalldata) { + transactions = this.createV4SwapCalldataExactOut( + tokenIn, + tokenOut, + amountOut, + amountInV4, + bestV4Fee, + evmChainID, + ) + } + return { protocol: "v4", amountIn: amountInV4, fee: bestV4Fee, transactions } + } + } + + // If no protocol is selected, query all protocols to find the best one + const amountInV2 = await this.getV2QuoteWithAmountOut(client, tokenIn, tokenOut, amountOut, evmChainID) + + const { amountIn: amountInV3, fee: bestV3Fee } = await this.getV3QuoteWithAmountOut( + client, + tokenIn, + tokenOut, + amountOut, + evmChainID, + ) + + const { amountIn: amountInV4, fee: bestV4Fee } = await this.getV4QuoteWithAmountOut( + client, + tokenIn, + tokenOut, + amountOut, + evmChainID, + ) + + if (amountInV2 === maxUint256 && amountInV3 === maxUint256 && amountInV4 === maxUint256) { + return { + protocol: null, + amountIn: maxUint256, + } + } + + // Prefer V4 when V4 is close to the best of V2/V3 (within thresholdBps) + if (amountInV4 !== maxUint256) { + const thresholdBps = 100n // 1% + if (amountInV3 !== maxUint256 && this.isWithinThreshold(amountInV4, amountInV3, thresholdBps)) { + let transactions: Transaction[] | undefined + if (options?.generateCalldata) { + transactions = this.createV4SwapCalldataExactOut( + tokenIn, + tokenOut, + amountOut, + amountInV4, + bestV4Fee, + evmChainID, + ) + } + return { protocol: "v4", amountIn: amountInV4, fee: bestV4Fee, transactions } + } + if (amountInV2 !== maxUint256 && this.isWithinThreshold(amountInV4, amountInV2, thresholdBps)) { + let transactions: Transaction[] | undefined + if (options?.generateCalldata) { + transactions = this.createV4SwapCalldataExactOut( + tokenIn, + tokenOut, + amountOut, + amountInV4, + bestV4Fee, + evmChainID, + ) + } + return { protocol: "v4", amountIn: amountInV4, fee: bestV4Fee, transactions } + } + } + + const minAmount = [ + { protocol: "v2" as const, amountIn: amountInV2 }, + { protocol: "v3" as const, amountIn: amountInV3, fee: bestV3Fee }, + { protocol: "v4" as const, amountIn: amountInV4, fee: bestV4Fee }, + ].reduce((best, current) => (current.amountIn < best.amountIn ? current : best)) + + let transactions: Transaction[] | undefined + if (options?.generateCalldata) { + if (minAmount.protocol === "v2") { + transactions = this.createV2SwapCalldataExactOut( + [tokenIn, tokenOut], + amountOut, + amountInV2, + options.recipient!, + evmChainID, + ) + } else if (minAmount.protocol === "v3") { + transactions = this.createV3SwapCalldataExactOut( + [tokenIn, tokenOut], + amountOut, + amountInV3, + [bestV3Fee], + options.recipient!, + evmChainID, + ) + } else { + transactions = this.createV4SwapCalldataExactOut( + tokenIn, + tokenOut, + amountOut, + amountInV4, + bestV4Fee, + evmChainID, + ) + } + } + + if (minAmount.protocol === "v2") { + return { + protocol: "v2", + amountIn: amountInV2, + transactions, + } + } else if (minAmount.protocol === "v3") { + return { + protocol: "v3", + amountIn: amountInV3, + fee: bestV3Fee, + transactions, + } + } else { + return { + protocol: "v4", + amountIn: amountInV4, + fee: bestV4Fee, + transactions, + } + } + } + + /** + * Finds the best Uniswap protocol (V2, V3, or V4) for swapping tokens given an input amount. + * Compares liquidity and pricing across different protocols and fee tiers. + * + * @param getQuoteIn - Whether to use "source" or "dest" chain for the swap + * @param tokenIn - The address of the input token + * @param tokenOut - The address of the output token + * @param amountIn - The input amount to swap + * @param evmChainID - The EVM chain ID in format "EVM-{id}" + * @param selectedProtocol - Optional specific protocol to use ("v2", "v3", or "v4") + * @returns Object containing the best protocol, expected output amount, fee tier (for V3/V4), and transaction structure + */ + async findBestProtocolWithAmountIn( + client: PublicClient, + tokenIn: HexString, + tokenOut: HexString, + amountIn: bigint, + evmChainID: string, + options?: { + selectedProtocol?: "v2" | "v3" | "v4" + generateCalldata?: boolean + recipient?: HexString + }, + ): Promise<{ + protocol: "v2" | "v3" | "v4" | null + amountOut: bigint + fee?: number + transactions?: Transaction[] + }> { + if (options?.generateCalldata && !options?.recipient) { + throw new Error("Recipient address is required when generating calldata") + } + + if (options?.selectedProtocol) { + if (options.selectedProtocol === "v2") { + const amountOutV2 = await this.getV2QuoteWithAmountIn(client, tokenIn, tokenOut, amountIn, evmChainID) + if (amountOutV2 === BigInt(0)) { + return { protocol: null, amountOut: BigInt(0) } + } + let transactions: Transaction[] | undefined + if (options?.generateCalldata) { + transactions = this.createV2SwapCalldataExactIn( + [tokenIn, tokenOut], + amountIn, + amountOutV2, + options.recipient!, + evmChainID, + ) + } + return { protocol: "v2", amountOut: amountOutV2, transactions } + } + + if (options.selectedProtocol === "v3") { + const { amountOut: amountOutV3, fee: bestV3Fee } = await this.getV3QuoteWithAmountIn( + client, + tokenIn, + tokenOut, + amountIn, + evmChainID, + ) + if (amountOutV3 === BigInt(0)) { + return { protocol: null, amountOut: BigInt(0) } + } + let transactions: Transaction[] | undefined + if (options?.generateCalldata) { + transactions = this.createV3SwapCalldataExactIn( + [tokenIn, tokenOut], + amountIn, + amountOutV3, + [bestV3Fee], + options.recipient!, + evmChainID, + ) + } + return { protocol: "v3", amountOut: amountOutV3, fee: bestV3Fee, transactions } + } + + if (options.selectedProtocol === "v4") { + const { amountOut: amountOutV4, fee: bestV4Fee } = await this.getV4QuoteWithAmountIn( + client, + tokenIn, + tokenOut, + amountIn, + evmChainID, + ) + if (amountOutV4 === BigInt(0)) { + return { protocol: null, amountOut: BigInt(0) } + } + let transactions: Transaction[] | undefined + if (options?.generateCalldata) { + transactions = this.createV4SwapCalldataExactIn( + tokenIn, + tokenOut, + amountIn, + amountOutV4, + bestV4Fee, + evmChainID, + ) + } + return { protocol: "v4", amountOut: amountOutV4, fee: bestV4Fee, transactions } + } + } + + // If no protocol is selected, query all protocols to find the best one + const amountOutV2 = await this.getV2QuoteWithAmountIn(client, tokenIn, tokenOut, amountIn, evmChainID) + + const { amountOut: amountOutV3, fee: bestV3Fee } = await this.getV3QuoteWithAmountIn( + client, + tokenIn, + tokenOut, + amountIn, + evmChainID, + ) + + const { amountOut: amountOutV4, fee: bestV4Fee } = await this.getV4QuoteWithAmountIn( + client, + tokenIn, + tokenOut, + amountIn, + evmChainID, + ) + + // If no liquidity found in any protocol + if (amountOutV2 === BigInt(0) && amountOutV3 === BigInt(0) && amountOutV4 === BigInt(0)) { + return { + protocol: null, + amountOut: BigInt(0), + } + } + + // Prefer V4 when V4 is close to the best of V2/V3 (within thresholdBps) + if (amountOutV4 !== BigInt(0)) { + const thresholdBps = 100n // 1% + if (amountOutV3 !== BigInt(0) && this.isWithinThreshold(amountOutV4, amountOutV3, thresholdBps)) { + let transactions: Transaction[] | undefined + if (options?.generateCalldata) { + transactions = this.createV4SwapCalldataExactIn( + tokenIn, + tokenOut, + amountIn, + amountOutV4, + bestV4Fee, + evmChainID, + ) + } + return { protocol: "v4", amountOut: amountOutV4, fee: bestV4Fee, transactions } + } + if (amountOutV2 !== BigInt(0) && this.isWithinThreshold(amountOutV4, amountOutV2, thresholdBps)) { + let transactions: Transaction[] | undefined + if (options?.generateCalldata) { + transactions = this.createV4SwapCalldataExactIn( + tokenIn, + tokenOut, + amountIn, + amountOutV4, + bestV4Fee, + evmChainID, + ) + } + return { protocol: "v4", amountOut: amountOutV4, fee: bestV4Fee, transactions } + } + } + + const maxAmount = [ + { protocol: "v2" as const, amountOut: amountOutV2 }, + { protocol: "v3" as const, amountOut: amountOutV3, fee: bestV3Fee }, + { protocol: "v4" as const, amountOut: amountOutV4, fee: bestV4Fee }, + ].reduce((best, current) => (current.amountOut > best.amountOut ? current : best)) + + let transactions: Transaction[] | undefined + if (options?.generateCalldata) { + if (maxAmount.protocol === "v2") { + transactions = this.createV2SwapCalldataExactIn( + [tokenIn, tokenOut], + amountIn, + amountOutV2, + options.recipient!, + evmChainID, + ) + } else if (maxAmount.protocol === "v3") { + transactions = this.createV3SwapCalldataExactIn( + [tokenIn, tokenOut], + amountIn, + amountOutV3, + [bestV3Fee], + options.recipient!, + evmChainID, + ) + } else { + transactions = this.createV4SwapCalldataExactIn( + tokenIn, + tokenOut, + amountIn, + amountOutV4, + bestV4Fee, + evmChainID, + ) + } + } + + if (maxAmount.protocol === "v2") { + return { + protocol: "v2", + amountOut: amountOutV2, + transactions, + } + } else if (maxAmount.protocol === "v3") { + return { + protocol: "v3", + amountOut: amountOutV3, + fee: bestV3Fee, + transactions, + } + } else { + return { + protocol: "v4", + amountOut: amountOutV4, + fee: bestV4Fee, + transactions, + } + } + } + + /** + * Finds the best pair for multi-hop swaps based on popular tokens and liquidity. + * Prefers pairs with tokenIn as intermediate token, then returns the pair with highest liquidity. + */ + async findPair( + client: PublicClient, + tokenIn: HexString, + tokenOut: HexString, + evmChainID: string, + protocol?: "v2" | "v3", + ): Promise<{ pairAddress: HexString; intermediateToken: HexString }> { + const chainPopularTokens = popularTokens[evmChainID as keyof typeof popularTokens] + + if (chainPopularTokens.length === 0) { + throw new Error(`No suitable intermediate tokens found for chain ${evmChainID}`) + } + + const pairCandidates: Array<{ + pairAddress: HexString + token0: HexString + token1: HexString + liquidity: bigint + hasTokenIn: boolean + fee?: number + }> = [] + + for (const intermediateToken of chainPopularTokens) { + try { + const pair = await this.getPairAddress( + client, + intermediateToken as HexString, + tokenOut, + evmChainID, + protocol, + ) + + if (pair.poolAddress && pair.poolAddress !== ADDRESS_ZERO) { + let liquidity = 0n + + if (protocol === "v2") { + const reserves = await client.readContract({ + address: pair.poolAddress, + abi: [parseAbiItem("function getReserves() view returns (uint112, uint112, uint32)")], + functionName: "getReserves", + }) + + liquidity = BigInt(reserves[0]) + BigInt(reserves[1]) + } else if (protocol === "v3") { + liquidity = await client.readContract({ + address: pair.poolAddress, + abi: [parseAbiItem("function liquidity() view returns (uint128)")], + functionName: "liquidity", + }) + } + + const hasTokenIn = intermediateToken.toLowerCase() === tokenIn.toLowerCase() + + pairCandidates.push({ + pairAddress: pair.poolAddress, + token0: intermediateToken as HexString, + token1: tokenOut, + liquidity, + hasTokenIn, + fee: pair.fee, + }) + } + } catch { + continue + } + } + + if (pairCandidates.length === 0) { + throw new Error(`No valid pairs found for chain ${evmChainID}`) + } + + pairCandidates.sort((a, b) => { + if (a.hasTokenIn && !b.hasTokenIn) return -1 + if (!a.hasTokenIn && b.hasTokenIn) return 1 + return b.liquidity > a.liquidity ? 1 : -1 + }) + + return { + pairAddress: pairCandidates[0].pairAddress, + intermediateToken: pairCandidates[0].token0, + } + } + + /** + * Gets pair address for V2 or V3 based on protocol parameter + * For V3, returns both pool address and fee + */ + private async getPairAddress( + client: PublicClient, + tokenA: HexString, + tokenB: HexString, + evmChainID: string, + protocolParam?: "v2" | "v3", + ): Promise<{ poolAddress: HexString; fee?: number }> { + const factoryAddress = this.chainConfigService.getUniswapV2FactoryAddress(evmChainID) + if (protocolParam === "v2") { + const poolAddress = await client.readContract({ + address: factoryAddress, + abi: [parseAbiItem("function getPair(address tokenA, address tokenB) view returns (address pair)")], + functionName: "getPair", + args: [tokenA, tokenB], + }) + return { poolAddress } + } + if (protocolParam === "v3") { + return await this.getBestV3Pool(client, tokenA, tokenB, evmChainID) + } + throw new Error(`Invalid protocol parameter: ${protocolParam}`) + } + + /** + * Gets the best V3 pool based on liquidity across different fee tiers + */ + private async getBestV3Pool( + client: PublicClient, + token0: HexString, + token1: HexString, + evmChainID: string, + ): Promise<{ poolAddress: HexString; fee: number }> { + const factoryAddress = this.chainConfigService.getUniswapV3FactoryAddress(evmChainID) + + let mostLiquidPool = ADDRESS_ZERO + let bestFee = 0 + let deepestLiquidity = 0n + + for (const fee of COMMON_FEE_TIERS) { + try { + const poolAddress = (await client.readContract({ + address: factoryAddress, + abi: [ + parseAbiItem( + "function getPool(address tokenA, address tokenB, uint24 fee) view returns (address pool)", + ), + ], + functionName: "getPool", + args: [token0, token1, fee], + })) as HexString + + if (poolAddress !== ADDRESS_ZERO) { + const liquidity = await client.readContract({ + address: poolAddress, + abi: [parseAbiItem("function liquidity() view returns (uint128)")], + functionName: "liquidity", + }) + + if (liquidity > deepestLiquidity) { + deepestLiquidity = liquidity + mostLiquidPool = poolAddress + bestFee = fee + } + } + } catch { + console.warn(`Failed to get V3 pool for fee ${fee}:`) + continue + } + } + + if (mostLiquidPool === ADDRESS_ZERO) { + throw new Error(`No V3 pools found for tokens ${token0} and ${token1}`) + } + + return { poolAddress: mostLiquidPool, fee: bestFee } + } + + async createMultiHopSwapThroughPair( + client: PublicClient, + tokenIn: HexString, + tokenOut: HexString, + amountIn: bigint, + evmChainID: string, + recipient: HexString, + protocol: "v2" | "v3" = "v2", + slippagePercentage: bigint, + dexPairAddress?: HexString, + ): Promise<{ finalAmountOut: bigint; calldata: Transaction[] }> { + const wethAsset = this.chainConfigService.getWrappedNativeAssetWithDecimals(evmChainID).asset + + // Convert ADDRESS_ZERO to WETH for pair lookup (DEX pairs use WETH, not ADDRESS_ZERO) + const tokenInForPairLookup = tokenIn === ADDRESS_ZERO ? wethAsset : tokenIn + const tokenOutForPairLookup = tokenOut === ADDRESS_ZERO ? wethAsset : tokenOut + + let intermediateToken: HexString + + if (dexPairAddress) { + const [token0Result, token1Result] = await Promise.all([ + client.readContract({ + address: dexPairAddress, + abi: [parseAbiItem("function token0() view returns (address)")], + functionName: "token0", + }), + client.readContract({ + address: dexPairAddress, + abi: [parseAbiItem("function token1() view returns (address)")], + functionName: "token1", + }), + ]) + // Handle native token: if tokenOut is ADDRESS_ZERO, check if either token0 or token1 is WETH + const normalizedTokenOut = tokenOut === ADDRESS_ZERO ? wethAsset : tokenOut + intermediateToken = + normalizedTokenOut.toLowerCase() === token0Result.toLowerCase() ? token1Result : token0Result + } else { + const { intermediateToken: foundIntermediateToken } = await this.findPair( + client, + tokenInForPairLookup, + tokenOutForPairLookup, + evmChainID, + protocol, + ) + intermediateToken = foundIntermediateToken + } + + const swapPath = this.buildSwapPath(tokenIn, tokenOut, intermediateToken, wethAsset) + + const { finalAmountOut, fees } = await this.getQuoteForPath(client, swapPath, amountIn, evmChainID, protocol) + + const amountOutMinimum = (finalAmountOut * (10000n - slippagePercentage)) / 10000n + + const calldata = + protocol === "v2" + ? this.createV2SwapCalldataExactIn(swapPath, amountIn, amountOutMinimum, recipient, evmChainID) + : this.createV3SwapCalldataExactIn(swapPath, amountIn, amountOutMinimum, fees, recipient, evmChainID) + + return { + finalAmountOut: amountOutMinimum, + calldata, + } + } + + private buildSwapPath( + tokenIn: HexString, + tokenOut: HexString, + intermediateToken: HexString, + wethAsset: HexString, + ): HexString[] { + const normalize = (token: HexString) => token.toLowerCase() + + if (normalize(intermediateToken) === normalize(tokenIn)) { + return [tokenIn, tokenOut] + } + + if (normalize(intermediateToken) === normalize(wethAsset)) { + return [tokenIn, wethAsset, tokenOut] + } + + return [tokenIn, wethAsset, intermediateToken, tokenOut] + } + + private async getQuoteForPath( + client: PublicClient, + path: HexString[], + initialAmount: bigint, + evmChainID: string, + protocol: "v2" | "v3", + ): Promise<{ finalAmountOut: bigint; fees: number[] }> { + let currentAmount = initialAmount + const fees: number[] = [] + + for (let i = 0; i < path.length - 1; i++) { + const tokenIn = path[i] + const tokenOut = path[i + 1] + + if (protocol === "v2") { + currentAmount = await this.getV2QuoteWithAmountIn(client, tokenIn, tokenOut, currentAmount, evmChainID) + } else { + const quote = await this.getV3QuoteWithAmountIn(client, tokenIn, tokenOut, currentAmount, evmChainID) + currentAmount = quote.amountOut + fees.push(quote.fee) + } + } + + return { finalAmountOut: currentAmount, fees } + } + + /** + * Returns true if candidate <= reference * (1 + thresholdBps/10000) + * @param candidate - The candidate amount to compare + * @param reference - The reference amount + * @param thresholdBps - The threshold in basis points + * @returns True if candidate is within threshold of reference + */ + private isWithinThreshold(candidate: bigint, reference: bigint, thresholdBps: bigint): boolean { + const basisPoints = 10000n + return candidate * basisPoints <= reference * (basisPoints + thresholdBps) + } + + /** + * Encodes multiple command bytes into packed format + * @private + */ + private encodeCommands(commands: number[]): HexString { + if (commands.length === 0) { + throw new Error("Commands array cannot be empty") + } + + // Build the type array and ensure proper typing + const types = Array(commands.length).fill("uint8") + + // Use type assertion for viem's strict typing + return encodePacked(types as any, commands as any) + } + + /** + * Returns the tick spacing for a given fee tier in Uniswap V4 + * @param fee - The fee tier in basis points + * @returns The tick spacing value + */ + private getTickSpacing(fee: number): number { + switch (fee) { + case 100: // 0.01% + return 1 + case 500: // 0.05% + return 10 + case 3000: // 0.30% + return 60 + case 10000: // 1.00% + return 200 + default: + return 60 // Default to medium + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/tokenGateway.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/tokenGateway.ts new file mode 100644 index 00000000..e03db660 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/tokenGateway.ts @@ -0,0 +1,261 @@ +import { hexToBytes, pad, bytesToHex } from "viem" +import type { ApiPromise } from "@polkadot/api" +import { Struct, Vector, u8, u64, _void, Option, u128, bool } from "scale-ts" +import { H256, StateMachine } from "@/utils/substrate" +import type { HexString } from "@/types" +import { convertStateMachineIdToEnum } from "@/chain" +import { keccakAsU8a, xxhashAsU8a } from "@polkadot/util-crypto" +import type { Option as PolakdotOption } from "@polkadot/types" +import type { EventRecord, StorageData } from "@polkadot/types/interfaces" +import type { SignerOptions } from "@polkadot/api/types" +import type { HyperbridgeTxEvents } from "./xcmGateway" + +export type Params = { + /** Asset symbol for the teleport operation */ + symbol: string + /** + * Destination state machine identifier (e.g., "EVM-1", "SUBSTRATE-cere") + * that specifies the target blockchain or network + */ + destination: string + /** + * Recipient address in hexadecimal format where the assets will be sent + * on the destination chain + */ + recipient: HexString + /** + * Amount of tokens to teleport, represented as a bigint to handle + * large numeric values precisely + */ + amount: bigint + /** + * Request timeout in block numbers or timestamp, after which the + * teleport operation will be considered failed + */ + timeout: bigint + /** + * Address of the token gateway contract on the destination chain + * that will process the teleported assets + */ + tokenGatewayAddress: Uint8Array + /** + * Fee paid to relayers who process the cross-chain transaction, + * represented as a bigint + */ + relayerFee: bigint + /** + * Optional call data to be executed on the destination chain + * as part of the teleport operation + */ + callData?: Uint8Array + /** + * Flag indicating whether to automatically redeem the tokens + * for erc20 + */ + redeem: boolean +} + +const TeleportParams = Struct({ + /// StateMachine + destination: StateMachine, + /// Receipient + recepient: H256, + /// Amount + amount: u128, + /// Request timeout + timeout: u64, + /// Token gateway address + tokenGatewayAddress: Vector(u8), + /// Relayer fee + relayerFee: u128, + /// Call data + callData: Option(Vector(u8)), + /// Redeem + redeem: bool, +}) + +async function fetchLocalAssetId(params: { api: ApiPromise; assetId: Uint8Array }) { + const { api, assetId } = params + + // twox_128 + const palletPrefix = xxhashAsU8a("TokenGateway", 128) + // twox_128 + const storagePrefix = xxhashAsU8a("LocalAssets", 128) + + const full_key = new Uint8Array([...palletPrefix, ...storagePrefix, ...assetId]) + + const hexKey = bytesToHex(full_key) + + // read account balance + + const storage_value: PolakdotOption = (await api.rpc.state.getStorage( + hexKey, + )) as PolakdotOption + + if (storage_value.isSome) { + const assetId = storage_value.value.toU8a() + + return assetId + } + + return null +} + +/** + * Teleports assets from Substrate to other chains via the token gateway + * + * Note: There is no guarantee that both Dispatched and Finalized events will be yielded. + * Consumers should listen for either one of these events instead of expecting both. + * + * + * @param apiPromise - Polkadot API instance + * @param who - SS58Address + * @param params - Teleport parameters + * @param params.symbol - Asset symbol + * @param params.destination - Target state machine ID + * @param params.recipient - Recipient address + * @param params.amount - Amount to teleport + * @param params.timeout - Operation timeout + * @param params.tokenGatewayAddress - Gateway contract address + * @param params.relayerFee - Fee for the relayer + * @param params.redeem - Whether to redeem on arrival + * @param params.callData - Optional additional call data + * @param options - Signer options + * @yields {HyperbridgeTxEvents} Stream of events indicating transaction status + * @throws Error when asset ID is unknown or transaction fails + */ +export async function teleport(teleport_param: { + who: string + params: Params + apiPromise: ApiPromise + options: Partial +}): Promise> { + const { who, options, params, apiPromise } = teleport_param + + const substrateComplianceAddr = (address: HexString, stateMachine: string) => { + if (stateMachine.startsWith("EVM-")) return pad(address, { size: 32, dir: "left" }) + + return address + } + + const assetId = keccakAsU8a(params.symbol) + + // Fetch scale encoded local asset id + + const scaleEncodedAssetId = await fetchLocalAssetId({ api: apiPromise, assetId }) + + if (scaleEncodedAssetId === null) { + throw new Error("Unknown asset id provided") + } + + const destination = convertStateMachineIdToEnum(params.destination) + + const recipient = hexToBytes(substrateComplianceAddr(params.recipient, params.destination)) + + const teleportParams = { + destination: destination, + recepient: Array.from(recipient), + amount: params.amount, + timeout: BigInt(params.timeout), + tokenGatewayAddress: Array.from(params.tokenGatewayAddress), + relayerFee: BigInt(params.relayerFee), + redeem: params.redeem, + callData: params.callData ? Array.from(params.callData) : undefined, + } + + const encoded = TeleportParams.enc(teleportParams) + const fullCallData = new Uint8Array([...scaleEncodedAssetId, ...encoded]) + + const tx = apiPromise.tx.tokenGateway.teleport(fullCallData) + let unsub = () => {} + let closed = false + + const stream = new ReadableStream( + { + async start(controller) { + unsub = await tx.signAndSend(who, options, async (result) => { + try { + const { isInBlock, isError, dispatchError, txHash, isFinalized, status } = result + // @ts-expect-error Type Mismatch + const events = result.events as ISubmittableResult["events"] + + if (isError) { + console.error("Transaction failed: ", dispatchError) + controller.enqueue({ kind: "Error", error: dispatchError }) + unsub?.() + controller.close() + closed = true + return + } + + if (status.type === "Ready") { + controller.enqueue({ + kind: "Ready", + transaction_hash: txHash.toHex(), + }) + } + + if (isInBlock || isFinalized) { + const commitment_hash = readIsmpCommitmentHash(events) + const blockHash = isInBlock ? status.asInBlock.toHex() : status.asFinalized.toHex() + + if (!commitment_hash) { + controller.enqueue({ + kind: "Error", + error: new Error("Commitment Hash missing"), + }) + return controller.close() + } + + const header = await apiPromise.rpc.chain.getHeader(blockHash) + + controller.enqueue({ + kind: isInBlock ? "Dispatched" : "Finalized", + transaction_hash: txHash.toHex(), + block_number: header.number.toBigInt(), + commitment: commitment_hash, + }) + + if (isFinalized) { + unsub?.() + controller.close() + closed = true + return + } + } + } catch (err) { + // For some unknown reason the call back is called again after unsubscribing, this check prevents it from trying to push an event to the closed stream + if (closed) { + return + } + controller.enqueue({ + kind: "Error", + error: String(err), + }) + } + }) + }, + cancel: () => unsub?.(), + }, + { + highWaterMark: 3, + size: () => 1, + }, + ) + + return stream +} + +function readIsmpCommitmentHash(events: EventRecord[]): HexString | undefined { + for (const record of events) { + const { event } = record + + if (event.section === "ismp" && event.method === "Request") { + const commitment = event.data[3].toHex() + + if (!commitment) return + + return commitment + } + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/txEvents.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/txEvents.ts new file mode 100644 index 00000000..664109f7 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/txEvents.ts @@ -0,0 +1,52 @@ +import IntentGatewayABI from "@/abis/IntentGateway" +import EVM_HOST from "@/abis/evmHost" +import type { DecodedOrderPlacedLog, DecodedPostRequestEvent, DecodedPostResponseEvent, HexString } from "@/types" +import { parseEventLogs, type Hex } from "viem" + +/** + * Extracts the IntentGateway OrderPlaced event from a transaction hash. + * @param client - A viem PublicClient-compatible instance + * @param txHash - Transaction hash + * @returns Decoded OrderPlaced event or undefined if not found + */ +export async function getOrderPlacedFromTx( + client: { getTransactionReceipt: (args: { hash: Hex }) => Promise<{ logs: any[] }> }, + txHash: HexString, +): Promise { + const receipt = await client.getTransactionReceipt({ hash: txHash as Hex }) + const events = parseEventLogs({ + abi: IntentGatewayABI.ABI, + logs: receipt.logs, + }) as unknown as DecodedOrderPlacedLog[] + return events.find((e) => e.eventName === "OrderPlaced") +} + +/** + * Extracts the EvmHost PostRequestEvent from a transaction hash. + * @param client - A viem PublicClient-compatible instance + * @param txHash - Transaction hash + * @returns Decoded PostRequestEvent or undefined if not found + */ +export async function getPostRequestEventFromTx( + client: { getTransactionReceipt: (args: { hash: Hex }) => Promise<{ logs: any[] }> }, + txHash: HexString, +): Promise { + const receipt = await client.getTransactionReceipt({ hash: txHash as Hex }) + const events = parseEventLogs({ abi: EVM_HOST.ABI, logs: receipt.logs }) as unknown as DecodedPostRequestEvent[] + return events.find((e) => e.eventName === "PostRequestEvent") +} + +/** + * Extracts the EvmHost PostResponseEvent from a transaction hash. + * @param client - A viem PublicClient-compatible instance + * @param txHash - Transaction hash + * @returns Decoded PostResponseEvent or undefined if not found + */ +export async function getPostResponseEventFromTx( + client: { getTransactionReceipt: (args: { hash: Hex }) => Promise<{ logs: any[] }> }, + txHash: HexString, +): Promise { + const receipt = await client.getTransactionReceipt({ hash: txHash as Hex }) + const events = parseEventLogs({ abi: EVM_HOST.ABI, logs: receipt.logs }) as unknown as DecodedPostResponseEvent[] + return events.find((e) => e.eventName === "PostResponseEvent") +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/xcmGateway.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/xcmGateway.ts new file mode 100644 index 00000000..d5361d2f --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/src/utils/xcmGateway.ts @@ -0,0 +1,282 @@ +import type { HexString } from "@/types" +import { StateMachine } from "@/utils" +import type { ApiPromise } from "@polkadot/api" +import type { SignerOptions } from "@polkadot/api/types" +import { hexToU8a, u8aToHex } from "@polkadot/util" +import { decodeAddress, keccakAsHex } from "@polkadot/util-crypto" +import { Bytes, Struct, u64 } from "scale-ts" +import { parseUnits } from "viem" + +const MultiAccount = Struct({ + substrate_account: Bytes(32), + evm_account: Bytes(20), + dest_state_machine: StateMachine, + timeout: u64, + account_nonce: u64, +}) + +export type HyperbridgeTxEvents = + | { + kind: "Ready" + transaction_hash: HexString + message_id?: HexString + } + | { + kind: "Dispatched" + transaction_hash: HexString + block_number: bigint + message_id?: HexString + commitment: HexString + } + | { + kind: "Finalized" + transaction_hash: HexString + message_id?: HexString + block_number?: bigint + commitment?: HexString + } + | { + kind: "Error" + error: unknown + } + +const DECIMALS = 10 +/** + * Parameters for teleporting DOT from AssetHub to EVM-based destination + */ +export type XcmGatewayParams = { + /** + * Destination state machine ID (chain ID) where assets will be teleported to + * This value identifies the specific EVM chain in the destination network + */ + destination: number + + /** + * The recipient address on the destination chain (in hex format) + * This is the EVM address that will receive the teleported assets + */ + recipient: HexString + + /** + * Amount of DOT to teleport + * This will be converted to the appropriate format internally + */ + amount: number + + /** + * Request timeout value in blocks or timestamp + * Specifies how long the teleport request remains valid before expiring + */ + timeout: bigint + + /** + * The parachain ID of the Hyperbridge + */ + paraId: number +} + +/** + * Teleports DOT tokens from AssetHub to Hyperbridge parachain + * using XCM V3 with transferAssetsUsingTypeAndThen. + * + * This function uses transferAssetsUsingTypeAndThen to construct XCM V3 transfers with a custom + * beneficiary structure that embeds Hyperbridge-specific parameters (sender account, recipient EVM address, + * timeout, and nonce) within an X4 junction. The beneficiary is wrapped in a DepositAsset XCM V3 instruction + * that deposits all transferred assets. The assets are transferred using LocalReserve transfer type. + * + * It handles the complete lifecycle of a teleport operation: + * 1. Encoding Hyperbridge parameters into the beneficiary X4 junction + * 2. Wrapping the beneficiary in a DepositAsset XCM V3 instruction using sourceApi.createType + * 3. Constructing the XCM V3 transfer transaction using polkadotXcm.transferAssetsUsingTypeAndThen + * 4. Transaction signing and broadcasting + * 5. Yielding events about transaction status through a ReadableStream + * + * Note: There is no guarantee that both Dispatched and Finalized events will be yielded. + * Consumers should listen for either one of these events instead of expecting both. + * + * @param sourceApi - Polkadot API instance connected to AssetHub + * @param who - Sender's SS58Address address + * @param options - Transaction signing options + * @param params - Teleport parameters including destination, recipient, amount, timeout, and paraId + * @yields {HyperbridgeTxEvents} Stream of events indicating transaction status + */ +export async function teleportDot(param_: { + sourceApi: ApiPromise + who: string + xcmGatewayParams: XcmGatewayParams + options: Partial +}): Promise> { + const { sourceApi, who, options, xcmGatewayParams: params } = param_ + const { nonce: accountNonce } = (await sourceApi.query.system.account(who)) as any + + const encoded_message = MultiAccount.enc({ + substrate_account: decodeAddress(who), + evm_account: hexToU8a(params.recipient), + dest_state_machine: { tag: "Evm", value: params.destination }, + timeout: params.timeout, + account_nonce: accountNonce, + }) + + const message_id = keccakAsHex(encoded_message) + + // Set up the custom beneficiary with embedded Hyperbridge parameters + const beneficiary = { + V4: { + parents: 0, + interior: { + X4: [ + { + AccountId32: { + id: u8aToHex(decodeAddress(who)), + network: null, + }, + }, + { + AccountKey20: { + network: { + Ethereum: { + chainId: params.destination, + }, + }, + key: params.recipient, + }, + }, + { + GeneralIndex: params.timeout, + }, + { + GeneralIndex: accountNonce, + }, + ], + }, + }, + } + + // AssetHub -> Hyperbridge parachain destination and assets + const destination = { + V4: { + parents: 1, + interior: { + X1: [{ Parachain: params.paraId }], + }, + }, + } + + const assets = { + V4: [ + { + id: { + parents: 1, + interior: "Here", + }, + fun: { + Fungible: parseUnits(params.amount.toString(), DECIMALS), + }, + }, + ], + } + + const weightLimit = "Unlimited" + + // Fee asset ID must be wrapped with V4 version header as VersionedAssetId + const feeAssetId = { + V4: assets.V4[0].id, + } + + // Wrap beneficiary in DepositAsset XCM instruction as required by transferAssetsUsingTypeAndThen + // This instruction deposits all transferred assets to the custom beneficiary + const customXcmOnDest = { + V4: [ + { + DepositAsset: { + assets: { + Wild: { + AllCounted: 1, + }, + }, + beneficiary: beneficiary.V4, + }, + }, + ], + } + + // Use transferAssetsUsingTypeAndThen for AssetHub -> Hyperbridge transfer + // This method allows us to specify custom beneficiary with embedded Hyperbridge parameters + // TransferType: LocalReserve means assets are held in reserve on the source chain (AssetHub) + const tx = sourceApi.tx.polkadotXcm.transferAssetsUsingTypeAndThen( + destination, + assets, + { LocalReserve: null }, // Assets transfer type + feeAssetId, // Fee asset ID wrapped as VersionedAssetId + { LocalReserve: null }, // Remote fee transfer type + customXcmOnDest, // XCM instruction with DepositAsset containing custom beneficiary + weightLimit, + ) + + let closed = false + // Create the stream to report events + let unsubscribe: () => void + const stream = new ReadableStream( + { + async start(controller) { + unsubscribe = await tx.signAndSend(who, options, async (result: any) => { + try { + const { status, dispatchError, txHash } = result + + if (dispatchError) { + controller.enqueue({ + kind: "Error", + error: `Error watching extrinsic: ${dispatchError.toString()}`, + }) + unsubscribe?.() + controller.close() + closed = true + return + } + + if (status.isReady) { + // Send tx hash as soon as it is available + controller.enqueue({ + kind: "Ready", + transaction_hash: txHash.toHex(), + message_id, + }) + } else if (status.isInBlock || status.isFinalized) { + // Send event with the status kind (either Dispatched or Finalized) + controller.enqueue({ + kind: "Finalized", + transaction_hash: txHash.toHex(), + message_id, + }) + + // We can end the stream because indexer only indexes finalized events from hyperbridge + closed = true + unsubscribe?.() + controller.close() + return + } + } catch (err) { + // For some unknown reason the call back is called again after unsubscribing, this check prevents it from trying to push an event to the closed stream + if (closed) { + return + } + controller.enqueue({ + kind: "Error", + error: String(err), + }) + } + }) + }, + cancel() { + // This is called if the reader cancels, + unsubscribe?.() + }, + }, + { + highWaterMark: 3, + size: () => 1, + }, + ) + + return stream +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/tsconfig.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/tsconfig.json new file mode 100644 index 00000000..9322c112 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/tsconfig.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig.json", + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "outDir": "./dist", + "sourceMap": true, + "strictNullChecks": true, + "rootDir": "./src", + "baseUrl": ".", + "paths": { + "@/*": ["src/*"], + "@/ckb-utils/*": ["./src/utils/ckb-mmr-wasm/dist/node/*", "./src/utils/ckb-mmr-wasm/dist/web/*"] + }, + "allowSyntheticDefaultImports": true, + "types": ["node", "vitest/globals"] + }, + "include": ["src/**/*", "tests/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/tsup-browser.config.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/tsup-browser.config.ts new file mode 100644 index 00000000..fc3a8cd0 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/tsup-browser.config.ts @@ -0,0 +1,47 @@ +import { copyFileSync, existsSync, mkdirSync } from "node:fs" +import { dirname } from "node:path" +import { defineConfig } from "tsup" + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist/browser", + format: ["esm"], + dts: true, + sourcemap: true, + platform: "browser", + clean: true, + splitting: false, + treeshake: true, + esbuildOptions: (esbuildOpt) => { + esbuildOpt.alias = { + "@/ckb-utils/web": "./src/utils/ckb-mmr-wasm/dist/web/web", + "@/ckb-utils/node": "./src/utils/ckb-mmr-wasm/dist/web/web", + "@/storage/load-driver": "./src/storage/drivers/browser", + } + }, + async onSuccess() { + // Copy WebAssembly files to dist directory + const fullPath = (path: string) => new URL(path, import.meta.url).pathname + + let files = [{ from: "src/utils/ckb-mmr-wasm/dist/web/web_bg.wasm", to: "dist/browser/web_bg.wasm" }] + + files = files.map((e) => ({ + from: fullPath(e.from), + to: fullPath(e.to), + })) + + // Ensure the destination directory exists + for (const entry of files) { + const dest_dir = dirname(entry.to) + + if (!existsSync(dest_dir)) { + mkdirSync(dest_dir, { recursive: true }) + } + + // Copy the file + copyFileSync(entry.from, entry.to) + } + + console.log("📦 Copied WebAssembly files to dist directory") + }, +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/tsup-node.config.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/tsup-node.config.ts new file mode 100644 index 00000000..e221bd87 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/tsup-node.config.ts @@ -0,0 +1,47 @@ +import { copyFileSync, existsSync, mkdirSync } from "node:fs" +import { dirname } from "node:path" +import { defineConfig } from "tsup" + +export default defineConfig({ + entry: ["src/index.ts"], + outDir: "dist/node", + format: ["esm"], + dts: true, + sourcemap: true, + platform: "node", + clean: true, + splitting: false, + treeshake: true, + esbuildOptions: (esbuildOpt) => { + esbuildOpt.alias = { + "@/ckb-utils/web": "./src/utils/ckb-mmr-wasm/dist/node/node", + "@/ckb-utils/node": "./src/utils/ckb-mmr-wasm/dist/node/node", + "@/storage/load-driver": "./src/storage/drivers/node", + } + }, + async onSuccess() { + // Copy WebAssembly files to dist directory + const fullPath = (path: string) => new URL(path, import.meta.url).pathname + + let files = [{ from: "src/utils/ckb-mmr-wasm/dist/node/node_bg.wasm", to: "dist/node/node_bg.wasm" }] + + files = files.map((e) => ({ + from: fullPath(e.from), + to: fullPath(e.to), + })) + + // Ensure the destination directory exists + for (const entry of files) { + const dest_dir = dirname(entry.to) + + if (!existsSync(dest_dir)) { + mkdirSync(dest_dir, { recursive: true }) + } + + // Copy the file + copyFileSync(entry.from, entry.to) + } + + console.log("📦 Copied WebAssembly files to dist directory") + }, +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/vitest.config.ts b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/vitest.config.ts new file mode 100644 index 00000000..e5567571 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/packages/sdk/vitest.config.ts @@ -0,0 +1,18 @@ +import { defineConfig } from "vitest/config" +import tsconfigPaths from "vite-tsconfig-paths" + +export default defineConfig({ + plugins: [tsconfigPaths()], + test: { + globals: true, + // mode defines what ".env.{mode}" file to choose if exists + setupFiles: ["./src/tests/setup.ts"], + reporters: ["verbose"], + environment: "node", + coverage: { + provider: "v8", + reporter: ["text", "json", "html"], + exclude: ["node_modules/**", "test/**"], + }, + }, +}) diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/pnpm-lock.yaml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/pnpm-lock.yaml new file mode 100644 index 00000000..002de938 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/pnpm-lock.yaml @@ -0,0 +1,4095 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@12.20.55)(ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3)) + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@12.20.55)(typescript@5.7.3) + devDependencies: + '@changesets/cli': + specifier: ^2.28.1 + version: 2.28.1 + '@typescript-eslint/eslint-plugin': + specifier: ^8.25.0 + version: 8.25.0(@typescript-eslint/parser@8.25.0(eslint@9.21.0)(typescript@5.7.3))(eslint@9.21.0)(typescript@5.7.3) + '@typescript-eslint/parser': + specifier: ^8.25.0 + version: 8.25.0(eslint@9.21.0)(typescript@5.7.3) + eslint: + specifier: ^9.21.0 + version: 9.21.0 + eslint-config-prettier: + specifier: ^10.0.2 + version: 10.0.2(eslint@9.21.0) + husky: + specifier: 9.1.7 + version: 9.1.7 + lint-staged: + specifier: 15.4.3 + version: 15.4.3 + prettier: + specifier: 3.5.2 + version: 3.5.2 + typescript: + specifier: 5.7.3 + version: 5.7.3 + +packages: + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.27.2': + resolution: {integrity: sha512-TUtMJYRPyUb/9aU8f3K0mjmjf6M9N5Woshn2CS6nqJSeJtTtQcpLUXjGt9vbF8ZGff0El99sWkLgzwW3VXnxZQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.27.1': + resolution: {integrity: sha512-IaaGWsQqfsQWVLqMn9OB92MNN7zukfVA4s7KKAI0KfrrDsZ0yhi5uV4baBuLuN7n3vsZpwP8asPPcVwApxvjBQ==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.27.1': + resolution: {integrity: sha512-UnJfnIpc/+JO0/+KRVQNGU+y5taA5vCbwN8+azkX6beii/ZF+enZJSOKo11ZSzGJjlNfJHfQtmQT8H+9TXPG2w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.27.2': + resolution: {integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.27.1': + resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.27.1': + resolution: {integrity: sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.27.1': + resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.27.1': + resolution: {integrity: sha512-FCvFTm0sWV8Fxhpp2McP5/W53GPllQ9QeQ7SiqGWjMf/LVG07lFa5+pgK05IRhVwtvafT22KF+ZSnM9I545CvQ==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.27.2': + resolution: {integrity: sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.27.1': + resolution: {integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.27.1': + resolution: {integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.27.1': + resolution: {integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.26.9': + resolution: {integrity: sha512-aA63XwOkcl4xxQa3HjPMqOP6LiK0ZDv3mUPYEFXkpHbaFjtGggE1A61FjFzJnB+p7/oy2gA8E+rcBNl/zC1tMg==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.27.2': + resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.27.1': + resolution: {integrity: sha512-ZCYtZciz1IWJB4U61UPu4KEaqyfj+r5T1Q5mqPo+IBpcG9kHv30Z0aD8LXPgC1trYa6rK0orRyAhqUgk4MjmEg==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.27.1': + resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} + engines: {node: '>=6.9.0'} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@changesets/apply-release-plan@7.0.10': + resolution: {integrity: sha512-wNyeIJ3yDsVspYvHnEz1xQDq18D9ifed3lI+wxRQRK4pArUcuHgCTrHv0QRnnwjhVCQACxZ+CBih3wgOct6UXw==} + + '@changesets/assemble-release-plan@6.0.6': + resolution: {integrity: sha512-Frkj8hWJ1FRZiY3kzVCKzS0N5mMwWKwmv9vpam7vt8rZjLL1JMthdh6pSDVSPumHPshTTkKZ0VtNbE0cJHZZUg==} + + '@changesets/changelog-git@0.2.1': + resolution: {integrity: sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==} + + '@changesets/cli@2.28.1': + resolution: {integrity: sha512-PiIyGRmSc6JddQJe/W1hRPjiN4VrMvb2VfQ6Uydy2punBioQrsxppyG5WafinKcW1mT0jOe/wU4k9Zy5ff21AA==} + hasBin: true + + '@changesets/config@3.1.1': + resolution: {integrity: sha512-bd+3Ap2TKXxljCggI0mKPfzCQKeV/TU4yO2h2C6vAihIo8tzseAn2e7klSuiyYYXvgu53zMN1OeYMIQkaQoWnA==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.3': + resolution: {integrity: sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==} + + '@changesets/get-release-plan@4.0.8': + resolution: {integrity: sha512-MM4mq2+DQU1ZT7nqxnpveDMTkMBLnwNX44cX7NSxlXmr7f8hO6/S2MXNiXG54uf/0nYnefv0cfy4Czf/ZL/EKQ==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.2': + resolution: {integrity: sha512-r1/Kju9Y8OxRRdvna+nxpQIsMsRQn9dhhAZt94FLDeu0Hij2hnOozW8iqnHBgvu+KdnJppCveQwK4odwfw/aWQ==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.1': + resolution: {integrity: sha512-iwksMs5Bf/wUItfcg+OXrEpravm5rEd9Bf4oyIPL4kVTmJQ7PNDSd6MDYkpSJR1pn7tz/k8Zf2DhTCqX08Ou+Q==} + + '@changesets/pre@2.0.2': + resolution: {integrity: sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==} + + '@changesets/read@0.6.3': + resolution: {integrity: sha512-9H4p/OuJ3jXEUTjaVGdQEhBdqoT2cO5Ts95JTFsQyawmKzpL8FnIeJSyhTDPW1MBRDnwZlHFEM9SpPwJDY5wIg==} + + '@changesets/should-skip-package@0.1.2': + resolution: {integrity: sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@6.1.0': + resolution: {integrity: sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==} + + '@changesets/write@0.4.0': + resolution: {integrity: sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@eslint-community/eslint-utils@4.4.1': + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.19.2': + resolution: {integrity: sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.12.0': + resolution: {integrity: sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.0': + resolution: {integrity: sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.21.0': + resolution: {integrity: sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.6': + resolution: {integrity: sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.7': + resolution: {integrity: sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.2': + resolution: {integrity: sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==} + engines: {node: '>=18.18'} + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.8': + resolution: {integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.7': + resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@17.0.33': + resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} + + '@typescript-eslint/eslint-plugin@8.25.0': + resolution: {integrity: sha512-VM7bpzAe7JO/BFf40pIT1lJqS/z1F8OaSsUB3rpFJucQA4cOSuH2RVVVkFULN+En0Djgr29/jb4EQnedUo95KA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/parser@8.25.0': + resolution: {integrity: sha512-4gbs64bnbSzu4FpgMiQ1A+D+urxkoJk/kqlDJ2W//5SygaEiAP2B4GoS7TEdxgwol2el03gckFV9lJ4QOMiiHg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/scope-manager@8.25.0': + resolution: {integrity: sha512-6PPeiKIGbgStEyt4NNXa2ru5pMzQ8OYKO1hX1z53HMomrmiSB+R5FmChgQAP1ro8jMtNawz+TRQo/cSXrauTpg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.25.0': + resolution: {integrity: sha512-d77dHgHWnxmXOPJuDWO4FDWADmGQkN5+tt6SFRZz/RtCWl4pHgFl3+WdYCn16+3teG09DY6XtEpf3gGD0a186g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/types@8.25.0': + resolution: {integrity: sha512-+vUe0Zb4tkNgznQwicsvLUJgZIRs6ITeWSCclX1q85pR1iOiaj+4uZJIUp//Z27QWu5Cseiw3O3AR8hVpax7Aw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.25.0': + resolution: {integrity: sha512-ZPaiAKEZ6Blt/TPAx5Ot0EIB/yGtLI2EsGoY6F7XKklfMxYQyvtL+gT/UCqkMzO0BVFHLDlzvFqQzurYahxv9Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/utils@8.25.0': + resolution: {integrity: sha512-syqRbrEv0J1wywiLsK60XzHnQe/kRViI3zwFALrNEgnntn1l24Ra2KvOAWwWbWZ1lBZxZljPDGOq967dsl6fkA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <5.8.0' + + '@typescript-eslint/visitor-keys@8.25.0': + resolution: {integrity: sha512-kCYXKAum9CecGVHGij7muybDfTS2sD3t0L4bJsEZLkyrXUImiCTq1M3LG2SRtOhiHFwMR9wAFplpT6XHYjTkwQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-escapes@7.0.0: + resolution: {integrity: sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==} + engines: {node: '>=18'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + babel-preset-current-node-syntax@1.1.0: + resolution: {integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==} + peerDependencies: + '@babel/core': ^7.0.0 + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.24.5: + resolution: {integrity: sha512-FDToo4Wo82hIdgc1CQ+NQD0hEhmpPjrZ3hiUgwgOG6IuTdlpr8jdjyG24P6cNP1yJpTLzS5OcGgSw0xmDU1/Tw==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-lite@1.0.30001718: + resolution: {integrity: sha512-AflseV1ahcSunK53NfEs9gFWgOEmzr0f+kaMFA4xiLZlr9Hzt7HxcSpIFcnNCUkz6R6dWKa54rUz3HUmI3nVcw==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.4.1: + resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + + cli-truncate@4.0.0: + resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} + engines: {node: '>=18'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + commander@13.1.0: + resolution: {integrity: sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==} + engines: {node: '>=18'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + debug@4.4.0: + resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + dedent@1.6.0: + resolution: {integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + electron-to-chromium@1.5.152: + resolution: {integrity: sha512-xBOfg/EBaIlVsHipHl2VdTPJRSvErNUaqW8ejTq5OlOlIYx1wOllCHsAvAIrr55jD1IYEfdR86miUEt8H5IeJg==} + + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + + emoji-regex@10.4.0: + resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@10.0.2: + resolution: {integrity: sha512-1105/17ZIMjmCOJOPNfVdbXafLCLj3hPmkmB7dLgt7XsQ/zkxSuDerE/xgO3RxoHysR1N1whmquY0lSn2O0VLg==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-scope@8.2.0: + resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.21.0: + resolution: {integrity: sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.3: + resolution: {integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.3.0: + resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} + engines: {node: '>=18'} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + human-id@4.1.1: + resolution: {integrity: sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg==} + hasBin: true + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + + husky@9.1.7: + resolution: {integrity: sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==} + engines: {node: '>=18'} + hasBin: true + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {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. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-fullwidth-code-point@4.0.0: + resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} + engines: {node: '>=12'} + + is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + lint-staged@15.4.3: + resolution: {integrity: sha512-FoH1vOeouNh1pw+90S+cnuoFwRfUD9ijY2GKy5h7HS3OR7JVir2N2xrsa0+Twc1B7cW72L+88geG5cW4wIhn7g==} + engines: {node: '>=18.12.0'} + hasBin: true + + listr2@8.2.5: + resolution: {integrity: sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==} + engines: {node: '>=18.0.0'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + log-update@6.1.0: + resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} + engines: {node: '>=18'} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-releases@2.0.19: + resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-manager-detector@0.2.9: + resolution: {integrity: sha512-+vYvA/Y31l8Zk8dwxHhL3JfTuHPm6tlxM2A3GeQyl7ovYnSp1+mzAxClxaOr0qO1TtPxbQxetI7v5XqKLJZk7Q==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + prettier@3.5.2: + resolution: {integrity: sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==} + engines: {node: '>=14'} + hasBin: true + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} + engines: {node: '>=10'} + + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rfdc@1.4.1: + resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@5.0.0: + resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} + engines: {node: '>=12'} + + slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + spawndamnit@3.0.1: + resolution: {integrity: sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-api-utils@2.0.1: + resolution: {integrity: sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + engines: {node: '>=14.17'} + hasBin: true + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + update-browserslist-db@1.1.3: + resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yaml@2.7.0: + resolution: {integrity: sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==} + engines: {node: '>= 14'} + hasBin: true + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.27.2': {} + + '@babel/core@7.27.1': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/helper-compilation-targets': 7.27.2 + '@babel/helper-module-transforms': 7.27.1(@babel/core@7.27.1) + '@babel/helpers': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/template': 7.27.2 + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + convert-source-map: 2.0.0 + debug: 4.4.0 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.27.1': + dependencies: + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + '@jridgewell/gen-mapping': 0.3.8 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.27.2': + dependencies: + '@babel/compat-data': 7.27.2 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.24.5 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-module-imports@7.27.1': + dependencies: + '@babel/traverse': 7.27.1 + '@babel/types': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-module-imports': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + '@babel/traverse': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.27.1': {} + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.27.1': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.27.1': + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + + '@babel/parser@7.27.2': + dependencies: + '@babel/types': 7.27.1 + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.1)': + dependencies: + '@babel/core': 7.27.1 + '@babel/helper-plugin-utils': 7.27.1 + + '@babel/runtime@7.26.9': + dependencies: + regenerator-runtime: 0.14.1 + + '@babel/template@7.27.2': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + + '@babel/traverse@7.27.1': + dependencies: + '@babel/code-frame': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/parser': 7.27.2 + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.27.1': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.27.1 + + '@bcoe/v8-coverage@0.2.3': {} + + '@changesets/apply-release-plan@7.0.10': + dependencies: + '@changesets/config': 3.1.1 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.2 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.7.1 + + '@changesets/assemble-release-plan@6.0.6': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.7.1 + + '@changesets/changelog-git@0.2.1': + dependencies: + '@changesets/types': 6.1.0 + + '@changesets/cli@2.28.1': + dependencies: + '@changesets/apply-release-plan': 7.0.10 + '@changesets/assemble-release-plan': 6.0.6 + '@changesets/changelog-git': 0.2.1 + '@changesets/config': 3.1.1 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/get-release-plan': 4.0.8 + '@changesets/git': 3.0.2 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.3 + '@changesets/should-skip-package': 0.1.2 + '@changesets/types': 6.1.0 + '@changesets/write': 0.4.0 + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + ci-info: 3.9.0 + enquirer: 2.4.1 + external-editor: 3.1.0 + fs-extra: 7.0.1 + mri: 1.2.0 + p-limit: 2.3.0 + package-manager-detector: 0.2.9 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.7.1 + spawndamnit: 3.0.1 + term-size: 2.2.1 + + '@changesets/config@3.1.1': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.3 + '@changesets/logger': 0.1.1 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.3': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.7.1 + + '@changesets/get-release-plan@4.0.8': + dependencies: + '@changesets/assemble-release-plan': 6.0.6 + '@changesets/config': 3.1.1 + '@changesets/pre': 2.0.2 + '@changesets/read': 0.6.3 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.2': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 3.0.1 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.1 + + '@changesets/parse@0.4.1': + dependencies: + '@changesets/types': 6.1.0 + js-yaml: 3.14.1 + + '@changesets/pre@2.0.2': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.3': + dependencies: + '@changesets/git': 3.0.2 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.1 + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + '@changesets/should-skip-package@0.1.2': + dependencies: + '@changesets/types': 6.1.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@6.1.0': {} + + '@changesets/write@0.4.0': + dependencies: + '@changesets/types': 6.1.0 + fs-extra: 7.0.1 + human-id: 4.1.1 + prettier: 2.8.8 + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@eslint-community/eslint-utils@4.4.1(eslint@9.21.0)': + dependencies: + eslint: 9.21.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.19.2': + dependencies: + '@eslint/object-schema': 2.1.6 + debug: 4.4.0 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.12.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.0': + dependencies: + ajv: 6.12.6 + debug: 4.4.0 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.21.0': {} + + '@eslint/object-schema@2.1.6': {} + + '@eslint/plugin-kit@0.2.7': + dependencies: + '@eslint/core': 0.12.0 + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.2': {} + + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@12.20.55)(ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + jest-mock: 29.7.0 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 12.20.55 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + '@types/node': 12.20.55 + chalk: 4.1.2 + collect-v8-coverage: 1.0.2 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 + + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.27.1 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.25 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 12.20.55 + '@types/yargs': 17.0.33 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.8': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.26.9 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.26.9 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@sinclair/typebox@0.27.8': {} + + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.7 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.27.1 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.27.2 + '@babel/types': 7.27.1 + + '@types/babel__traverse@7.20.7': + dependencies: + '@babel/types': 7.27.1 + + '@types/estree@1.0.6': {} + + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 12.20.55 + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/json-schema@7.0.15': {} + + '@types/node@12.20.55': {} + + '@types/stack-utils@2.0.3': {} + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@17.0.33': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@typescript-eslint/eslint-plugin@8.25.0(@typescript-eslint/parser@8.25.0(eslint@9.21.0)(typescript@5.7.3))(eslint@9.21.0)(typescript@5.7.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.25.0(eslint@9.21.0)(typescript@5.7.3) + '@typescript-eslint/scope-manager': 8.25.0 + '@typescript-eslint/type-utils': 8.25.0(eslint@9.21.0)(typescript@5.7.3) + '@typescript-eslint/utils': 8.25.0(eslint@9.21.0)(typescript@5.7.3) + '@typescript-eslint/visitor-keys': 8.25.0 + eslint: 9.21.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 2.0.1(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.25.0(eslint@9.21.0)(typescript@5.7.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.25.0 + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/typescript-estree': 8.25.0(typescript@5.7.3) + '@typescript-eslint/visitor-keys': 8.25.0 + debug: 4.4.0 + eslint: 9.21.0 + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.25.0': + dependencies: + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/visitor-keys': 8.25.0 + + '@typescript-eslint/type-utils@8.25.0(eslint@9.21.0)(typescript@5.7.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.25.0(typescript@5.7.3) + '@typescript-eslint/utils': 8.25.0(eslint@9.21.0)(typescript@5.7.3) + debug: 4.4.0 + eslint: 9.21.0 + ts-api-utils: 2.0.1(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.25.0': {} + + '@typescript-eslint/typescript-estree@8.25.0(typescript@5.7.3)': + dependencies: + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/visitor-keys': 8.25.0 + debug: 4.4.0 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.1 + ts-api-utils: 2.0.1(typescript@5.7.3) + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.25.0(eslint@9.21.0)(typescript@5.7.3)': + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0) + '@typescript-eslint/scope-manager': 8.25.0 + '@typescript-eslint/types': 8.25.0 + '@typescript-eslint/typescript-estree': 8.25.0(typescript@5.7.3) + eslint: 9.21.0 + typescript: 5.7.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.25.0': + dependencies: + '@typescript-eslint/types': 8.25.0 + eslint-visitor-keys: 4.2.0 + + acorn-jsx@5.3.2(acorn@8.14.0): + dependencies: + acorn: 8.14.0 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.14.0 + + acorn@8.14.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-colors@4.1.3: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-escapes@7.0.0: + dependencies: + environment: 1.1.0 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.1: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@4.1.3: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-union@2.1.0: {} + + babel-jest@29.7.0(@babel/core@7.27.1): + dependencies: + '@babel/core': 7.27.1 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.27.1) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-istanbul@6.1.1: + dependencies: + '@babel/helper-plugin-utils': 7.27.1 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.27.2 + '@babel/types': 7.27.1 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.7 + + babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.1): + dependencies: + '@babel/core': 7.27.1 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.27.1) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.27.1) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.27.1) + '@babel/plugin-syntax-import-attributes': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.27.1) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.27.1) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.27.1) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.27.1) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.27.1) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.27.1) + + babel-preset-jest@29.6.3(@babel/core@7.27.1): + dependencies: + '@babel/core': 7.27.1 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.1) + + balanced-match@1.0.2: {} + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.24.5: + dependencies: + caniuse-lite: 1.0.30001718 + electron-to-chromium: 1.5.152 + node-releases: 2.0.19 + update-browserslist-db: 1.1.3(browserslist@4.24.5) + + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + + buffer-from@1.1.2: {} + + callsites@3.1.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-lite@1.0.30001718: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.4.1: {} + + char-regex@1.0.2: {} + + chardet@0.7.0: {} + + ci-info@3.9.0: {} + + cjs-module-lexer@1.4.3: {} + + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-truncate@4.0.0: + dependencies: + slice-ansi: 5.0.0 + string-width: 7.2.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + co@4.6.0: {} + + collect-v8-coverage@1.0.2: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colorette@2.0.20: {} + + commander@13.1.0: {} + + concat-map@0.0.1: {} + + convert-source-map@2.0.0: {} + + create-jest@29.7.0(@types/node@12.20.55)(ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@12.20.55)(ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + create-require@1.1.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@4.4.0: + dependencies: + ms: 2.1.3 + + dedent@1.6.0: {} + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + detect-indent@6.1.0: {} + + detect-newline@3.1.0: {} + + diff-sequences@29.6.3: {} + + diff@4.0.2: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + electron-to-chromium@1.5.152: {} + + emittery@0.13.1: {} + + emoji-regex@10.4.0: {} + + emoji-regex@8.0.0: {} + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + environment@1.1.0: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + escalade@3.2.0: {} + + escape-string-regexp@2.0.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@10.0.2(eslint@9.21.0): + dependencies: + eslint: 9.21.0 + + eslint-scope@8.2.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.0: {} + + eslint@9.21.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.19.2 + '@eslint/core': 0.12.0 + '@eslint/eslintrc': 3.3.0 + '@eslint/js': 9.21.0 + '@eslint/plugin-kit': 0.2.7 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.2 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.0 + escape-string-regexp: 4.0.0 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.3.0: + dependencies: + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 + + esprima@4.0.1: {} + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + eventemitter3@5.0.1: {} + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + execa@8.0.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + + exit@0.1.2: {} + + expect@29.7.0: + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + + extendable-error@0.1.7: {} + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fb-watchman@2.0.2: + dependencies: + bser: 2.1.1 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.3 + keyv: 4.5.4 + + flatted@3.3.3: {} + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.3.0: {} + + get-package-type@0.1.0: {} + + get-stream@6.0.1: {} + + get-stream@8.0.1: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@11.12.0: {} + + globals@14.0.0: {} + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-flag@4.0.0: {} + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + html-escaper@2.0.2: {} + + human-id@4.1.1: {} + + human-signals@2.1.0: {} + + human-signals@5.0.0: {} + + husky@9.1.7: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-local@3.2.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-arrayish@0.2.1: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-fullwidth-code-point@4.0.0: {} + + is-fullwidth-code-point@5.0.0: + dependencies: + get-east-asian-width: 1.3.0 + + is-generator-fn@2.1.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-stream@2.0.1: {} + + is-stream@3.0.0: {} + + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-windows@1.0.2: {} + + isexe@2.0.0: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@5.2.1: + dependencies: + '@babel/core': 7.27.1 + '@babel/parser': 7.27.2 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.27.1 + '@babel/parser': 7.27.2 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 7.7.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@4.0.1: + dependencies: + debug: 4.4.0 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jest-changed-files@29.7.0: + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + + jest-circus@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.6.0 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-cli@29.7.0(@types/node@12.20.55)(ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@12.20.55)(ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3)) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@12.20.55)(ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest-config@29.7.0(@types/node@12.20.55)(ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3)): + dependencies: + '@babel/core': 7.27.1 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.27.1) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 12.20.55 + ts-node: 10.9.2(@types/node@12.20.55)(typescript@5.7.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-docblock@29.7.0: + dependencies: + detect-newline: 3.1.0 + + jest-each@29.7.0: + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + jest-get-type@29.6.3: {} + + jest-haste-map@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 12.20.55 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-leak-detector@29.7.0: + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-matcher-utils@29.7.0: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-message-util@29.7.0: + dependencies: + '@babel/code-frame': 7.27.1 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + jest-util: 29.7.0 + + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 + + jest-regex-util@29.6.3: {} + + jest-resolve-dependencies@29.7.0: + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + jest-resolve@29.7.0: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.10 + resolve.exports: 2.0.3 + slash: 3.0.0 + + jest-runner@29.7.0: + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + + jest-runtime@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + chalk: 4.1.2 + cjs-module-lexer: 1.4.3 + collect-v8-coverage: 1.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + + jest-snapshot@29.7.0: + dependencies: + '@babel/core': 7.27.1 + '@babel/generator': 7.27.1 + '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.1) + '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.27.1) + '@babel/types': 7.27.1 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.1) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.7.1 + transitivePeerDependencies: + - supports-color + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + + jest-validate@29.7.0: + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + + jest-watcher@29.7.0: + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 12.20.55 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + + jest-worker@29.7.0: + dependencies: + '@types/node': 12.20.55 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest@29.7.0(@types/node@12.20.55)(ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3)) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@12.20.55)(ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + js-tokens@4.0.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@3.0.3: {} + + leven@3.1.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + lint-staged@15.4.3: + dependencies: + chalk: 5.4.1 + commander: 13.1.0 + debug: 4.4.0 + execa: 8.0.1 + lilconfig: 3.1.3 + listr2: 8.2.5 + micromatch: 4.0.8 + pidtree: 0.6.0 + string-argv: 0.3.2 + yaml: 2.7.0 + transitivePeerDependencies: + - supports-color + + listr2@8.2.5: + dependencies: + cli-truncate: 4.0.0 + colorette: 2.0.20 + eventemitter3: 5.0.1 + log-update: 6.1.0 + rfdc: 1.4.1 + wrap-ansi: 9.0.0 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash.startcase@4.4.0: {} + + log-update@6.1.0: + dependencies: + ansi-escapes: 7.0.0 + cli-cursor: 5.0.0 + slice-ansi: 7.1.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + make-dir@4.0.0: + dependencies: + semver: 7.7.1 + + make-error@1.3.6: {} + + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mimic-fn@2.1.0: {} + + mimic-fn@4.0.0: {} + + mimic-function@5.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + mri@1.2.0: {} + + ms@2.1.3: {} + + natural-compare@1.4.0: {} + + node-int64@0.4.0: {} + + node-releases@2.0.19: {} + + normalize-path@3.0.0: {} + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + os-tmpdir@1.0.2: {} + + outdent@0.5.0: {} + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-map@2.1.0: {} + + p-try@2.2.0: {} + + package-manager-detector@0.2.9: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.27.1 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-key@4.0.0: {} + + path-parse@1.0.7: {} + + path-type@4.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + pidtree@0.6.0: {} + + pify@4.0.1: {} + + pirates@4.0.7: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + prelude-ls@1.2.1: {} + + prettier@2.8.8: {} + + prettier@3.5.2: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + punycode@2.3.1: {} + + pure-rand@6.1.0: {} + + queue-microtask@1.2.3: {} + + react-is@18.3.1: {} + + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + + regenerator-runtime@0.14.1: {} + + require-directory@2.1.1: {} + + resolve-cwd@3.0.0: + dependencies: + resolve-from: 5.0.0 + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve.exports@2.0.3: {} + + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + + reusify@1.1.0: {} + + rfdc@1.4.1: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safer-buffer@2.1.2: {} + + semver@6.3.1: {} + + semver@7.7.1: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + slice-ansi@5.0.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 4.0.0 + + slice-ansi@7.1.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + + source-map-support@0.5.13: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + spawndamnit@3.0.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + sprintf-js@1.0.3: {} + + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + + string-argv@0.3.2: {} + + string-length@4.0.2: + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@7.2.0: + dependencies: + emoji-regex: 10.4.0 + get-east-asian-width: 1.3.0 + strip-ansi: 7.1.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-bom@3.0.0: {} + + strip-bom@4.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-final-newline@3.0.0: {} + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + term-size@2.2.1: {} + + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + tmpl@1.0.5: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-api-utils@2.0.1(typescript@5.7.3): + dependencies: + typescript: 5.7.3 + + ts-node@10.9.2(@types/node@12.20.55)(typescript@5.7.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 12.20.55 + acorn: 8.14.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.7.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-detect@4.0.8: {} + + type-fest@0.21.3: {} + + typescript@5.7.3: {} + + universalify@0.1.2: {} + + update-browserslist-db@1.1.3(browserslist@4.24.5): + dependencies: + browserslist: 4.24.5 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + v8-compile-cache-lib@3.0.1: {} + + v8-to-istanbul@9.3.0: + dependencies: + '@jridgewell/trace-mapping': 0.3.25 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@9.0.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 7.2.0 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yaml@2.7.0: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/pnpm-workspace.yaml b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/pnpm-workspace.yaml new file mode 100644 index 00000000..18ec407e --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - 'packages/*' diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/tsconfig.base.json b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/tsconfig.base.json new file mode 100644 index 00000000..69e00e6d --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/lib/hyperbridge-sdk/tsconfig.base.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://json.schemastore.org/tsconfig.json", + "compilerOptions": { + "target": "ES2020", + "esModuleInterop": true, + "declaration": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/script/Counter.s.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/script/Counter.s.sol new file mode 100644 index 00000000..f01d69c3 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/script/Counter.s.sol @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Script} from "forge-std/Script.sol"; +import {Counter} from "../src/Counter.sol"; + +contract CounterScript is Script { + Counter public counter; + + function setUp() public {} + + function run() public { + vm.startBroadcast(); + + counter = new Counter(); + + vm.stopBroadcast(); + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/src/BridgeableToken.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/src/BridgeableToken.sol new file mode 100644 index 00000000..34c4c5b3 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/src/BridgeableToken.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import { + HyperFungibleToken +} from "@hyperbridge/core/contracts/apps/HyperFungibleToken.sol"; + +contract BridgeableToken is HyperFungibleToken { + address private immutable _gateway; + + constructor( + string memory name, + string memory symbol, + address gatewayAddress + ) HyperFungibleToken(name, symbol) { + _gateway = gatewayAddress; + } + + function gateway() public view override returns (address) { + return _gateway; + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/src/Counter.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/src/Counter.sol new file mode 100644 index 00000000..aded7997 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/src/Counter.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +contract Counter { + uint256 public number; + + function setNumber(uint256 newNumber) public { + number = newNumber; + } + + function increment() public { + number++; + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/src/TokenBridge.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/src/TokenBridge.sol new file mode 100644 index 00000000..72dfb545 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/src/TokenBridge.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.17; + +import {ITokenGateway} from "@hyperbridge/core/contracts/apps/TokenGateway.sol"; +import { + StateMachine +} from "@hyperbridge/core/contracts/libraries/StateMachine.sol"; + +contract TokenBridge { + ITokenGateway public immutable tokenGateway; + + constructor(address _tokenGateway) { + tokenGateway = ITokenGateway(_tokenGateway); + } + + /// @notice Bridge tokens to another chain + /// @param token The token address to bridge + /// @param amount The amount to bridge + /// @param recipient The recipient address on the destination chain + /// @param destChain The destination chain identifier + function bridgeTokens( + address token, + uint256 amount, + address recipient, + bytes memory destChain + ) external payable { + // Approve the gateway to spend tokens + IERC20(token).transferFrom(msg.sender, address(this), amount); + IERC20(token).approve(address(tokenGateway), amount); + + // Initiate the cross-chain transfer + // Implementation depends on TokenGateway interface + } +} diff --git a/1-xcm-hyperbridge/hyperbridge-token-bridge/test/Counter.t.sol b/1-xcm-hyperbridge/hyperbridge-token-bridge/test/Counter.t.sol new file mode 100644 index 00000000..48319108 --- /dev/null +++ b/1-xcm-hyperbridge/hyperbridge-token-bridge/test/Counter.t.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import {Test} from "forge-std/Test.sol"; +import {Counter} from "../src/Counter.sol"; + +contract CounterTest is Test { + Counter public counter; + + function setUp() public { + counter = new Counter(); + counter.setNumber(0); + } + + function test_Increment() public { + counter.increment(); + assertEq(counter.number(), 1); + } + + function testFuzz_SetNumber(uint256 x) public { + counter.setNumber(x); + assertEq(counter.number(), x); + } +} From f130d9edeebb8663219972231a7ce4ee26b5cd20 Mon Sep 17 00:00:00 2001 From: Harry Riddle Date: Thu, 1 Jan 2026 15:44:57 +0700 Subject: [PATCH 02/25] feat: modified the TokenBridge contract and added frontend by dotui --- .gitmodules | 3 + 1-xcm-hyperbridge/README.md | 6 +- 1-xcm-hyperbridge/frontend/.eslintrc.json | 3 + 1-xcm-hyperbridge/frontend/.gitignore | 36 + 1-xcm-hyperbridge/frontend/CONTRIBUTING.md | 86 + 1-xcm-hyperbridge/frontend/LICENSE | 21 + 1-xcm-hyperbridge/frontend/README.md | 75 + .../frontend/app/balance/loading.tsx | 17 + .../frontend/app/balance/page.tsx | 15 + 1-xcm-hyperbridge/frontend/app/favicon.ico | Bin 0 -> 25931 bytes .../frontend/app/fonts/GeistMonoVF.woff | Bin 0 -> 67864 bytes .../frontend/app/fonts/GeistVF.woff | Bin 0 -> 66268 bytes 1-xcm-hyperbridge/frontend/app/globals.css | 81 + 1-xcm-hyperbridge/frontend/app/layout.tsx | 36 + .../app/mint-redeem-lst-bifrost/loading.tsx | 17 + .../app/mint-redeem-lst-bifrost/page.tsx | 15 + 1-xcm-hyperbridge/frontend/app/page.tsx | 87 + 1-xcm-hyperbridge/frontend/app/providers.tsx | 108 + .../frontend/app/send-transaction/loading.tsx | 17 + .../frontend/app/send-transaction/page.tsx | 15 + .../frontend/app/wallet/loading.tsx | 17 + .../frontend/app/wallet/page.tsx | 18 + .../frontend/app/write-contract/loading.tsx | 17 + .../frontend/app/write-contract/page.tsx | 15 + 1-xcm-hyperbridge/frontend/components.json | 21 + .../frontend/components/copy-button.tsx | 27 + .../components/mint-redeem-lst-bifrost.tsx | 649 ++ .../frontend/components/navbar.tsx | 32 + .../frontend/components/portfolio-card.tsx | 17 + .../frontend/components/send-transaction.tsx | 346 + .../frontend/components/sigpasskit.tsx | 381 + .../components/string-copy-button.tsx | 42 + .../frontend/components/ui/button.tsx | 56 + .../frontend/components/ui/dialog.tsx | 122 + .../frontend/components/ui/drawer.tsx | 118 + .../frontend/components/ui/form.tsx | 178 + .../frontend/components/ui/input.tsx | 22 + .../frontend/components/ui/label.tsx | 26 + .../frontend/components/ui/select.tsx | 160 + .../frontend/components/ui/separator.tsx | 31 + .../frontend/components/ui/skeleton.tsx | 15 + .../frontend/components/ui/tabs.tsx | 55 + .../frontend/components/ui/toast.tsx | 129 + .../frontend/components/ui/toaster.tsx | 35 + .../frontend/components/write-contract.tsx | 428 + 1-xcm-hyperbridge/frontend/docs/contracts.md | 23 + .../docs/send-transaction-component.md | 111 + .../frontend/docs/sigpass-lib.md | 109 + 1-xcm-hyperbridge/frontend/docs/sigpasskit.md | 96 + .../frontend/docs/write-contract-component.md | 128 + .../frontend/hooks/use-media-query.tsx | 19 + 1-xcm-hyperbridge/frontend/hooks/use-toast.ts | 194 + 1-xcm-hyperbridge/frontend/lib/abi.ts | 2419 ++++ 1-xcm-hyperbridge/frontend/lib/sigpass.ts | 170 + 1-xcm-hyperbridge/frontend/lib/utils.ts | 10 + 1-xcm-hyperbridge/frontend/next.config.mjs | 10 + 1-xcm-hyperbridge/frontend/package-lock.json | 9770 +++++++++++++++++ 1-xcm-hyperbridge/frontend/package.json | 47 + 1-xcm-hyperbridge/frontend/postcss.config.mjs | 8 + .../public/frontend-kit-challenge.webp | Bin 0 -> 8768 bytes 1-xcm-hyperbridge/frontend/public/og-logo.png | Bin 0 -> 17012 bytes .../frontend/public/rainbowkit-1.svg | 1 + .../frontend/public/rainbowkit-2.svg | 1 + .../frontend/public/reown-projectId.png | Bin 0 -> 110502 bytes 1-xcm-hyperbridge/frontend/tailwind.config.ts | 63 + 1-xcm-hyperbridge/frontend/tsconfig.json | 26 + .../hyperbridge-token-bridge/foundry.lock | 6 + .../hyperbridge-token-bridge/foundry.toml | 2 +- .../lib/openzeppelin-contracts | 1 + .../script/BridgeToken.s.sol | 0 .../script/Counter.s.sol | 19 - .../script/Deployment.s.sol | 0 .../hyperbridge-token-bridge/src/Counter.sol | 14 - .../src/TokenBridge.sol | 28 +- 74 files changed, 16828 insertions(+), 42 deletions(-) create mode 100644 .gitmodules create mode 100644 1-xcm-hyperbridge/frontend/.eslintrc.json create mode 100644 1-xcm-hyperbridge/frontend/.gitignore create mode 100644 1-xcm-hyperbridge/frontend/CONTRIBUTING.md create mode 100644 1-xcm-hyperbridge/frontend/LICENSE create mode 100644 1-xcm-hyperbridge/frontend/README.md create mode 100644 1-xcm-hyperbridge/frontend/app/balance/loading.tsx create mode 100644 1-xcm-hyperbridge/frontend/app/balance/page.tsx create mode 100644 1-xcm-hyperbridge/frontend/app/favicon.ico create mode 100644 1-xcm-hyperbridge/frontend/app/fonts/GeistMonoVF.woff create mode 100644 1-xcm-hyperbridge/frontend/app/fonts/GeistVF.woff create mode 100644 1-xcm-hyperbridge/frontend/app/globals.css create mode 100644 1-xcm-hyperbridge/frontend/app/layout.tsx create mode 100644 1-xcm-hyperbridge/frontend/app/mint-redeem-lst-bifrost/loading.tsx create mode 100644 1-xcm-hyperbridge/frontend/app/mint-redeem-lst-bifrost/page.tsx create mode 100644 1-xcm-hyperbridge/frontend/app/page.tsx create mode 100644 1-xcm-hyperbridge/frontend/app/providers.tsx create mode 100644 1-xcm-hyperbridge/frontend/app/send-transaction/loading.tsx create mode 100644 1-xcm-hyperbridge/frontend/app/send-transaction/page.tsx create mode 100644 1-xcm-hyperbridge/frontend/app/wallet/loading.tsx create mode 100644 1-xcm-hyperbridge/frontend/app/wallet/page.tsx create mode 100644 1-xcm-hyperbridge/frontend/app/write-contract/loading.tsx create mode 100644 1-xcm-hyperbridge/frontend/app/write-contract/page.tsx create mode 100644 1-xcm-hyperbridge/frontend/components.json create mode 100644 1-xcm-hyperbridge/frontend/components/copy-button.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/mint-redeem-lst-bifrost.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/navbar.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/portfolio-card.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/send-transaction.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/sigpasskit.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/string-copy-button.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/ui/button.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/ui/dialog.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/ui/drawer.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/ui/form.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/ui/input.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/ui/label.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/ui/select.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/ui/separator.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/ui/skeleton.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/ui/tabs.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/ui/toast.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/ui/toaster.tsx create mode 100644 1-xcm-hyperbridge/frontend/components/write-contract.tsx create mode 100644 1-xcm-hyperbridge/frontend/docs/contracts.md create mode 100644 1-xcm-hyperbridge/frontend/docs/send-transaction-component.md create mode 100644 1-xcm-hyperbridge/frontend/docs/sigpass-lib.md create mode 100644 1-xcm-hyperbridge/frontend/docs/sigpasskit.md create mode 100644 1-xcm-hyperbridge/frontend/docs/write-contract-component.md create mode 100644 1-xcm-hyperbridge/frontend/hooks/use-media-query.tsx create mode 100644 1-xcm-hyperbridge/frontend/hooks/use-toast.ts create mode 100644 1-xcm-hyperbridge/frontend/lib/abi.ts create mode 100644 1-xcm-hyperbridge/frontend/lib/sigpass.ts create mode 100644 1-xcm-hyperbridge/frontend/lib/utils.ts create mode 100644 1-xcm-hyperbridge/frontend/next.config.mjs create mode 100644 1-xcm-hyperbridge/frontend/package-lock.json create mode 100644 1-xcm-hyperbridge/frontend/package.json create mode 100644 1-xcm-hyperbridge/frontend/postcss.config.mjs create mode 100644 1-xcm-hyperbridge/frontend/public/frontend-kit-challenge.webp create mode 100644 1-xcm-hyperbridge/frontend/public/og-logo.png create mode 100644 1-xcm-hyperbridge/frontend/public/rainbowkit-1.svg create mode 100644 1-xcm-hyperbridge/frontend/public/rainbowkit-2.svg create mode 100644 1-xcm-hyperbridge/frontend/public/reown-projectId.png create mode 100644 1-xcm-hyperbridge/frontend/tailwind.config.ts create mode 100644 1-xcm-hyperbridge/frontend/tsconfig.json create mode 160000 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/openzeppelin-contracts create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/script/BridgeToken.s.sol delete mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/script/Counter.s.sol create mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/script/Deployment.s.sol delete mode 100644 1-xcm-hyperbridge/hyperbridge-token-bridge/src/Counter.sol diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..84f03935 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "1-xcm-hyperbridge/hyperbridge-token-bridge/lib/openzeppelin-contracts"] + path = 1-xcm-hyperbridge/hyperbridge-token-bridge/lib/openzeppelin-contracts + url = https://github.com/OpenZeppelin/openzeppelin-contracts diff --git a/1-xcm-hyperbridge/README.md b/1-xcm-hyperbridge/README.md index 56842898..b7b4cab7 100644 --- a/1-xcm-hyperbridge/README.md +++ b/1-xcm-hyperbridge/README.md @@ -140,9 +140,9 @@ Create a basic UI to interact with your bridge: Your submission should include: 1. **Smart Contracts** - - [ ] `TokenBridge.sol` - Bridge logic contract - - [ ] Deployment scripts - - [ ] Bridge token script + - [x] `TokenBridge.sol` - Bridge logic contract + - [x] Deployment scripts + - [x] Bridge token script 2. **Documentation** - [ ] README explaining your implementation diff --git a/1-xcm-hyperbridge/frontend/.eslintrc.json b/1-xcm-hyperbridge/frontend/.eslintrc.json new file mode 100644 index 00000000..37224185 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": ["next/core-web-vitals", "next/typescript"] +} diff --git a/1-xcm-hyperbridge/frontend/.gitignore b/1-xcm-hyperbridge/frontend/.gitignore new file mode 100644 index 00000000..fd3dbb57 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/1-xcm-hyperbridge/frontend/CONTRIBUTING.md b/1-xcm-hyperbridge/frontend/CONTRIBUTING.md new file mode 100644 index 00000000..1367914d --- /dev/null +++ b/1-xcm-hyperbridge/frontend/CONTRIBUTING.md @@ -0,0 +1,86 @@ +# Welcome to DotUI Contributing Guide + +Thank you for investing your time in contributing to DotUI! + +This guide aims to provide an overview of the contribution workflow to help us make the contribution process effective for everyone involved. + +## About the Project + +DotUI is a minimal and forkable repo providing builders with a starter kit to build decentralized applications on Polkadot. + +Read the [README](README.md) to get an overview of the project. + +### Vision + +The goal of DotUI is to provide the primary building blocks for a decentralized application. + +The repo can be forked to include integrations and more features, but we want to keep the master branch simple and minimal. + +### Project Status + +The project is under active development. + +You can view the open Issues, follow the development process and contribute to the project. + +## Getting started + +You can contribute to this repo in many ways: + +- Solve open issues +- Report bugs or feature requests +- Improve the documentation + +Contributions are made via Issues and Pull Requests (PRs). A few general guidelines for contributions: + +- Search for existing Issues and PRs before creating your own. +- Contributions should only fix/add the functionality in the issue OR address style issues, not both. +- If you're running into an error, please give context. Explain what you're trying to do and how to reproduce the error. +- Please use the same formatting in the code repository. You can configure your IDE to do it by using the prettier / linting config files included in each package. +- If applicable, please edit the README.md file to reflect the changes. + +### Issues + +Issues should be used to report problems, request a new feature, or discuss potential changes before a PR is created. + +#### Solve an issue + +Scan through our [existing issues](https://github.com/buildstationorg/dotui/issues) to find one that interests you. + +If a contributor is working on the issue, they will be assigned to the individual. If you find an issue to work on, you are welcome to assign it to yourself and open a PR with a fix for it. + +#### Create a new issue + +If a related issue doesn't exist, you can open a new issue. + +Some tips to follow when you are creating an issue: + +- Provide as much context as possible. Over-communicate to give the most details to the reader. +- Include the steps to reproduce the issue or the reason for adding the feature. +- Screenshots, videos etc., are highly appreciated. + +### Pull Requests + +#### Pull Request Process + +We follow the ["fork-and-pull" Git workflow](https://github.com/susam/gitpr) + +1. Fork the repo +2. Clone the project +3. Create a new branch with a descriptive name +4. Commit your changes to the new branch +5. Push changes to your fork +6. Open a PR in our repository and tag one of the maintainers to review your PR + +Here are some tips for a high-quality pull request: + +- Create a title for the PR that accurately defines the work done. +- Structure the description neatly to make it easy to consume by the readers. For example, you can include bullet points and screenshots instead of having one large paragraph. +- Add the link to the issue if applicable. +- Have a good commit message that summarises the work done. + +Once you submit your PR: + +- We may ask questions, request additional information or ask for changes to be made before a PR can be merged. Please note that these are to make the PR clear for everyone involved and aims to create a frictionless interaction process. +- As you update your PR and apply changes, mark each conversation resolved. + +Once the PR is approved, we'll "squash-and-merge" to keep the git commit history clean. \ No newline at end of file diff --git a/1-xcm-hyperbridge/frontend/LICENSE b/1-xcm-hyperbridge/frontend/LICENSE new file mode 100644 index 00000000..783de167 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 buildstation and OpenGuild + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/1-xcm-hyperbridge/frontend/README.md b/1-xcm-hyperbridge/frontend/README.md new file mode 100644 index 00000000..14f673a6 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/README.md @@ -0,0 +1,75 @@ +![DOT UI Kit](/public/frontend-kit-challenge.webp) + +# DOT UI Kit + +An open-source, up-to-date, opinionated UI scaffolding kit for the Polkadot ecosystem (starting with Asset Hub). The technical stack is: +- [Next.js](https://nextjs.org/) +- [Tailwind CSS](https://tailwindcss.com/) +- [Lucide icons](https://lucide.dev/) +- [ShadCN UI](https://ui.shadcn.com/) +- [RainbowKit](https://www.rainbowkit.com/) +- [Wagmi](https://wagmi.sh/) +- [Viem](https://viem.sh/) +- [Jotai](https://jotai.org/) +- [Tanstack React Query](https://tanstack.com/query) +- [Vaul](https://vaul.fun/) +- [Zod](https://zod.dev/) +- [React Hook Form](https://react-hook-form.com/) + +## Features + +- [x] Multi-chain support +- [x] In-dapp-wallet support +- [x] WalletConnect support +- [x] Collection of web3 components to quickly build your frontend or use as a reference +- [x] React hooks for various onchain interactions with Wagmi + +## Requirements + +Before you begin, you need to install the following tools: + +- [Node (current LTS version)](https://nodejs.org/en/download/) +- [npm (latest version or > v10)](https://www.npmjs.com/get-npm) +- [Git](https://git-scm.com/downloads) + + +## Getting started + +``` +git clone https://github.com/buildstationorg/dotui.git +cd dotui +npm install +``` + +## Running the project + +``` +npm run dev +``` +Default port is 3002. You can change the port in the `package.json` file. + +```json +"scripts": { + "dev": "next dev -p 3002", // Change the port here to -p + "build": "next build", + "start": "next start", + "lint": "next lint" +}, +``` + +## Building the project + +``` +npm run build +``` + +## Documentation + +Please see [`docs`](docs) for more information and guidelines for contributing to DotUI. + +## Contributing to DotUI + +We welcome contributions to DotUI! + +Please see [`CONTRIBUTING.md`](CONTRIBUTING.md) for more information and guidelines for contributing to DotUI. + diff --git a/1-xcm-hyperbridge/frontend/app/balance/loading.tsx b/1-xcm-hyperbridge/frontend/app/balance/loading.tsx new file mode 100644 index 00000000..64936374 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/balance/loading.tsx @@ -0,0 +1,17 @@ +import { Skeleton } from "@/components/ui/skeleton" + +export default function Loading() { + // You can add any UI inside Loading, including a Skeleton. + return ( +
+ +
+ + + + +
+ +
+ ) +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/frontend/app/balance/page.tsx b/1-xcm-hyperbridge/frontend/app/balance/page.tsx new file mode 100644 index 00000000..735f5458 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/balance/page.tsx @@ -0,0 +1,15 @@ +"use client"; + +import SigpassKit from "@/components/sigpasskit"; +import Navbar from "@/components/navbar"; + + +export default function BalancePage() { + return ( +
+ + +

Balance

+
+ ); +} diff --git a/1-xcm-hyperbridge/frontend/app/favicon.ico b/1-xcm-hyperbridge/frontend/app/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..718d6fea4835ec2d246af9800eddb7ffb276240c GIT binary patch literal 25931 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 LrJugUA?W`A8`#=m literal 0 HcmV?d00001 diff --git a/1-xcm-hyperbridge/frontend/app/fonts/GeistMonoVF.woff b/1-xcm-hyperbridge/frontend/app/fonts/GeistMonoVF.woff new file mode 100644 index 0000000000000000000000000000000000000000..f2ae185cbfd16946a534d819e9eb03924abbcc49 GIT binary patch literal 67864 zcmZsCV{|6X^LDby#!fc2?QCp28{4*X$D569+qP}vj&0lKKhN*HAKy9W>N!=Xdb(?> zQB^(TCNCxi0tx~G0t$@@g8bk8lJvX$|6bxEqGBK*H_sp-KYBnwz$0Q}BT2;-%I=)X2ub{=04r2*}TK5D+LXt~5{t z)Bof^+#0@Rw7=mKi|m$bX6?Bh~_rVfN!~Z5D+lYZ~eMdYd=)1 z?To(VG`{%|MBi{mhZ2~!F#vq`Pec9x)g^>91o^TxurUDvvGDqSS9st3-kw(m@3Xga z`qtIzyIr_nARq+I@sH7;0MG(2NPTSa#jh!1f4cEF5Xll)bpZ(>cyI|Q1wleT1wA5Y zq9^hv^x;~(?2G$>(CTL2)#Ou-rP=XDW$spn8<%0TH%F=^X^(F62Vd@bY`Wi$j$33w zf!U^8o_B|x>{pW$eFZG}b7#|uFueKt$`e9j!wHNBGQX67&nfgl(Ae`3qE-E+yBSfA zEnJSA6p%}|+P9ZIYR{w}nfaKIlV@b3YYzcH!?WNXRvg|J( z((lq^WAE%Q7;oE?zDk~Nvg1Dr_0)KH8m&HF%^&8bI!=#YAGqIx$Yf2lH9S*;=c=b6 zUHi?R*$?Q;>HU4-#?hGJ&dj2jq>d3;_NN_TeipMG!(E+ou)RL-kMQv(W$b9+k# z*%bh8;4)9Je-Giu+XwdbyoaSGei^KG*(1D)5+h{Kfg<`v)nU>dj}RiD_+VvZgb7>9 z-Qb^cdc0k1VSIW!onbm2*_uY*_+r1qe${8^DzXxMnX@F#u>I3_n0j_0ih#p?wd+gPI5niQVbIIsk zkxy%JZZqLeb?p_DXdh1*9Z(O`Nm%TZ(zL`RA!dd+$VNO>qwecEt;dy5w%UK1@1exK zD~__{?4}pb@sGL5CjI=xAR7Jym_*l%fS~I(m>6873y~E7k;IfdA_0)|1$o9?h92Js zt4eu6$WMaSodkz#g|LB%Iw?^B?6x^A=arKjpBhhH6ZCbk2{;io5x)B3eh9R{KEOQX z9|&Q1T3-YGeF+9$doOBzU`TntM~LF~ON3aEZ|p9Y7+wF9qBi`6(hl}&)@-uZ`4zJl z>R`Cps(&x90dBZ~SLeCp?oa*PgM%P!bZaG*OS96bkBT*gF)q0a zxEd&4ZXnQHBuCrYm@m@ffPQTObP*2j+P z_?=gLxmGc32nceW5l5oy=+SB$=N%F^{g}lKR9(TljKIPHw)zVyZ?3ODUL^k;0CuW% z!;ErXcl6|m8OB+{5iYNEq}!Y@o<%r_^{5a($V)INcxkIcMA}Gd8LUShZK5U!u)=PR z6ZALS*{0F1Oxl?y$xE;JA+eyc6mW}LqFTZ3ZvVl#h*UFfj`$%JE0l8D!JRBYUlH!L zJ!uZs@&)nqNg9x8t`fZ?k4Ihgdv(Ogzr)|%{JQ|-g@#=7rCIq(Oo={zr!i7F_F!6; zqpKdMO={?6)e1SETQW+U?L?WPzQx9x#RrVu%xa5u$bDgLQrF-K4Iwd}9a=yS3(f1J z=&B1p=UwPU_#kfxrJ(YnDYZkc%{pp&sn{<~MdR_9^8y%u``RUJaJtY*yi=~R9ryu@ z9kzsKGwMLhZ1egl=e5m~k^Ft9pSfxI5B!$g1WaeqpO`4?C-3aj(gSm%1+@BdqpyAV z@X|;G-&|(jA;zG>T=$%}2gC%)gu@pTPQ)SpSw*2DuSrX((%PM=kQ&E@b=Ygy)l&#k zn6Q419734+(;{THjU2Uy9No0H4_jV1#6O)c>u@tbG6oWD;-8yHLnM^;;b@dWvle!?{40o`dO)$$EZ zM^@JN7b3@-+?UUO*P#gtLsy$!7gZcziDwAj59PsCAJm>m6r+l^X1z|%wu-jJhnQ&_ znPJwq9_*qBLoo*W`sPdYk10kPgf$aH@4qU~%&pFl2rZ0AHR*E-AvBR{F9QCehDa@z z95xXU{QZg|=zb2Pq36>@3je4inO+>S(`ht?)Z#zrHM(i>qE+>iU#!8v4QnWDruR08 zihT~ec3TRJh#llhgk(NqF04=VE8}61FWwvTi_}KWRnkIGbxQ)CAyBfBoVsTvRsR!v zeeHuptQ&5sDmg3vV_f9UtqYjdrR(_D^waATK``ZJjfZD5Kduvl1+l2-u6Qf=6Ombx z7Sq ztJ92oU^LD6n$?=8G?#FGx#fF$d!2WBTf$UGVa}#`S@X&5dFIq%K!1Ikjs!+ybc~8&;<*f2$gyb>j{=&y@=kHsC%Xl#WTojY!)xQxm z+xUe-8Of9gTp&DDOh{Yy9#6leUk5m&-h{G7M@bsLtAJZq1|X(5;ulY z-D2nY-`lAFFZza${swOYsV>&wyw;MiiXw9Ze4so}{Flt`IeJQ5b1l1!d)yG4v?WEO zO3yg9oy--%g}hya8*T);IAWhS&T>>KL9Je(WS#9P#!$_f6!1`7cfKj*+i>@*tP8Mjj|un5Z`YGD>MiCU!adPX zx#5sU8_)@)5fHgRLdp7k;l9Mr_8H3SOvpCBbBRGBQ`Wih*Xpj<)C6}E4SH?GeM1wt)HAM~N<~ejyt^Wpq0tmp z6X&e+wbKjOt@{1ng^s>(semrGFCQLXu|@O1tvtmYwuZ`$BSe{a-011Sk2a~(>MVE0 zpIQ7LpuG+o?lOHuw%e_kJ6yAoXCpu*QQeY%8SNh6?$89*3`>%=;EOJb+gtz&Kp|yv zfPV+nw`uTKbxE3vpT)v3C@L}V3(f*@_3N$Flc(8e<6F?hmPF|Dt%$W})5dMX(nql2 zOMy&yEWPokJ^l?odvVv&l(un4B`x0UHu6T8LraPoL*NltIUElZ5m!YVjcyZe{0Gtx zK{scl85IYuMO$EBG$tHHu0zc0wi&8rW3`d{VJC$oYNJ?m2MBStoGQ!4xQLHS_tBeI z4=tL^Lv>Bj^g79fzfCc?aTHu%Uvn6&+a@&*N~Rba)gbaLl?WBo%1^Pjx=t&|S^9nh zu(^m2A5XEp+ZN2L2#w^7IpLW%BW#F@6{50p0liwKYe!&NWu2F@oIV-5r<}*;+3|bP ze>zfTOAXqW760vNex|NG!Xz~@Wcd5UhOk&n5clNgylEGuS)lF7K$c{a+Hl#rx-2Ic zD(HhN(=Sa(v|zonLt6q9;>ZBVh6n__yB8Pn7WCY*KX8V+u(@n9e zOTe7&?}Fvh8wHRCgku@eEVodSv4NBH%wJEO4wEp#-}%%$wR$2D5JR|@$vRkRb7}iIhxv; zshP$6ckt<2KCd5K9#gwy%I*Ey>Fe20M_29Y=)g1AcBH#@^pXEtP30j`IbaZgR2{t^ z`r?E$A9Zdf@wct0$aRwJ=i9-^yxU77e+%zOG9j-MXBP)nekEiIFHfS>Ba|3w;D?|dL35fhFX>Fi zQcepJaiZvXu&=IsDUMoZIo?5N1`h|7?WDfbJmXcY~w_lg&|t|BlK!`YFCDcu*n(Sa{%c z4$vg-+drB`)#x8&q6x0pG5p+BKvfIu#O32<*&LF;z8q?zL`41|Yicx^Yq4jz6>WcO z4=~f8fF;F-A=fL28*f$mLyZ)0X>6z$biG4VuDpiV4z zY~_evrt9XZfAzEyT`LtOtA^qKGM{Tq8NMHGIOL>T;4vaiE@lH-C<@aOeh_^m?<&&h zdXSPA^^n-i>Uj{Z%Lb+6v5B_zD^V_GWE1OBNlHndI9YW5kD^Kk@cZ&Ia z6oRdBan^1xma-m6+`d|wRJR`V~A;L2zw&Yu_yoTtgzTrhi-xxFYK659imn;^%TR%3!4mYTU`we=`K-=!r$)M^U|fng0gd4 zY&D|@id)hQ6lZ6$q#}%snpqqb>@aUApp7;*W>0UoVkg(l}MYC6COXI29 zGc~J-gZ4vC{yy!bjlkXM?rF2de*R#dL=(PI9-L-quUxck&u`DmTQjI#p*2mPjNqc? z$X9XK{UtI;@pJUK?cwIxV;%;lTG0!%y5 zJpWhb11vK@d2I=!;)F5vM`ML)^6b)LCj<7zlFm7!F$_T_`hyDZ>MEBe@A%a+9RG#y z_*KevIxJ(rEBNzd_KBWC<+$;IWH5}W4eTN}TM#4*`n;PelIth54aC}8|KHL1Kd9hY zdg6C1@KJ_+m6OHmY-}EB_QYaDnd8)^Y#fTGC1QB3E&Rq&s{PIUL5DzjJG<4E+;x=! zz3?hDSALlK#YF2II?cmMlq^D)riLWp(`LjFJNTY&BkIxb04C*yZ)Vjb*8{OJ&U(p# z3cxi}BFmgL+V%Ew9*g|D_V>-jj>E&_kXF}@LX&k)UuVIb+!>`~SGXZrZd9yBFoeR5 zNrxA*){}5*BIRJ3GSAb5CW!RX5}9`W*v3|J4v;znteT1Jn6BmRxF0|>v+o2A%ix3E z_}aH+5hk}2B`>5kW}hg%W`rkIVN-e8*j3!A(mQ&IFKdo(2cn%(!rGGG-la2y4dz)d z;cU;$Z5l<(tUS+pPC9~e+Sl_5OnGT=${=;{P%TayUQ^o1bm#Qel@0Ea2wDFsgpR8p z%{42-o*aWIGVFESm@;QGB)am8yb0`j>EazkuEVoKMd!r}nWzO!rg#7+BuCQ?4|TZ^ z`|;e56wJl>(SLl!DEUo1dvlUaqZZ{;%CQg!oaJ?FFxAmVK6uv$_;SHB!^)t!xv-f_$Bs$C)MjJg|HA#qe9b`BSwl8 z2McXH6Uvn|ClJyKV8|OT-V{LIG1v~h>gQprzhfK(DrmFQ4M!VgO!ZS8o6D1p%RSmV z+Xf5C09vC7w0t%eXb8L=U(~wlP)tZ3TaN#j4{NWJFL7# zMeiEPfaIS?IHAdP9aH+sm5udxfk^i!o76N(KewVyMk&0@OpX6rwAKG}3?0IvE?(cPM;r3Az!_xLiYFY&)}Sl<19#fU0x zj-uZ}`Ey9BnVxqbj#D{R24|$jM(dNl2KH#FvbDSz*@x<{sy48Gz=(yRiYW`ofYMu+ zzdPsn^PhpxWX2v}!sahrD*o$$3k;XDHq|HQU^rDKHq%xw$IafF=^BmtY8T@#Z%YDW zAdx@ahu2vaLq%D&-me?D(}&)mEb|5m{{oc6#p!vRnXxnizHWv)adXiBb>q0*jdBJ~Zv<2B}4vZ{P z>E)ayXwPyT&!MqX{ao=#mpGCX5|61&)PEQKmppcZigqM*Xe+;DOlb?AQ8hZ8S0~w3)(nNAK)Iuc7rg zfIT}yB^fVpt`B3Pkl;fBY6u~2&%W5O{d;oadPW=tcE^D^C>VI_JPYukh@TfhQoWZeCJ5B$7I19W@q_TM0($TkNK3wl)QIl3|@|1RCuW$X^KSG)YgdJf$ zD&q2EfNK5$`W1XPc!pW_jn16RK(}y~T4kUY!;u`93tAJiu%lz7ol{&ur{Q zrA4yCFcU|gV0|>p_`D&ByZc`)DL+`Qqx8bmSv%J+qdQd*Y<;Klb{>?OW@XKPzqewj ztIkvI-K;Hlf@9cCVRdISFG4&ME?xbBnin*J=9sxZ+*CAN{PGnwwyeqzbU^u}JEz&U zujyQvjy%LMauULwp0$59k|Lxd4Icntq<^uQ3!iJ0*EJT#GqBhF5^zk{hkBT< zKNwtg4Y`s4lJ-1VzUy%1!)~>kypou8iu}HY$;B}2qhX>w`(0ya>5ndBmNHvwz@<@d z)_T3Arr!pCuZ?)(&jZ=LnXHsU&B)ifpJd12LpQF3x4*zCIMUlbov*YMkDIX`ZQ}#B zDEm7;2>6H|!x9eQMZTTQ#83yK07tV{aiGreb{XKo=?{!()DRH+$I-(B{q;fyyO2n) z-rGbBGoMjZLapRim!$3W&f}tbELYcO^N@9^$@oA{Fw|v>Jo^sP%|m`>OsVrmyd1`r z*_-ScUuU|lzR~%OHT$uyWNQuw)pj`yF@eLl^+;zNjqf~|6huSAAIGYnALff2fZP5> zz7ARH{>mIa^RkT@w4ZV!CXF(cDn9w9CcPN-d;=6xcKKM>?vd2tUshA!XM9hA9JplyPAlKHA3W}2f4;=EdS9$VRk zJd#7BDuS+qpm{NTo#0B*Oj{$Z2l2)5j>joob07T0UCp(y#jl_ioRJq7;CrcFZ;7+D ziT+n)gme?&`MZ8Q3URYd1 zUXO6*c;TeIhsi*l(c2?lau-s#yIh8Vm$bBPLkB24pwd6-v8=f_57U7s_X=;?ZMPX$=V+KD?D%h69Plxj z6s25MR;B`_3y$P%?|Wl%v9)a+)Xt1ovYG0-8ZEx;{wk%oGLr8D(F1mGIiIYKO7qIT zkyAXybQE{@&#($=@kZpE5&n7R;k?&LuC|WbUG$$?mLATHDk-iOwVbXY!1z4~OSn zL9Iql5xuH}kpF|{#T-2i$=3HA7g2YTKZSXE!U$;^53~)*>eS`jehs0aZ z?~}w>o$4HP*axMt=ZuDj#B+$8z;s<~`^+`;?9euOJhNPximpeOXZLVk`?)op?#1LI zsEJ(3NA-`GoL{a>z!{Z>a*D$!ZnSUCRhF+h1{YrQx-{HFin8WzZefO{l z8cNaM;e7wxPv4B1qdM6*FoUE$-f@ij7)Qn+%qi1X#m$C)|q*>heV z_F1E1;>jFo_X_SxU4z7K=dzD=a^~oL!C9SEV-!KD$#mnz60qM-#pJFWBjB{A91?@LxNGc9%0{4?@cU#Y7z;WB&(t+Ux8ij z{ywC~@RW4y=k@~>Rr8pTmb$u=7qLo2Vpes~6>g_ENtTY7^pVeIg!wVc`DUmbY|`3M z-R+tCPAunS>R|zng`6f_20?)pLm}bSq%ja@pW1*wXr=T!IW0oYP6_8+GG^?eKvEc| z0FC0qr5|LsL5JWpacSeAuHLx1qO#F6G*`!D4x6a;L#0WM=HD&Vnsp=Ye)1&&^=NgK z$R=p#49`^kf{*a{V%70)-|osKU4qK8u*Ee`n^}AVgiVqOGq`)`$~)h-UbZ_TpWn5) z4AU%KuIEO^Hr5rLcT?KcOFj<^6-E5p*F`RXe_*jNQ-<*{pcs{>ypy$kvv5&h_=hdL<+0wfo7i8Zr zN2QPM2zwaYFfOrCFU7(G*GymiiuOMUH#o1w-P5{_<`RmBx9=5gvCW1?z*U9M+@ATPF1Psy-Tq}n0&H9|(XuzmZW30{I#a|z_}fb*J@}$Os9qoBgJ+y# zL#8>}`N|}X{(N$J8f*=>O{m7)%z$pbzMS2$yb0xce}L`230Nn-UPkBNZy?Asat0>M==4pw7^P*~|GtzfgB9oEz zSk=B0wEed=|Ip)4I}(ZDBYlprm6N!l&1a{)JCR@4>nZ9els~Gu+`<5ezJ3A;{B3`Ck6-7#p ziFkA{?4$2BcHuw~sGfB+sGG>sgP(eW)M^H@39}u3uf^6HSPdw&q^1jxpusc>E1p9-Su?Z)!3+F+@GwHP~|a`e`o(nklU0c z$M)W3BB{3Wn$(JgntlTNAP(iL>=b;wqp`!xMfLpa7@%+oG3L2vFv0Yd{WYP^a(Nq8 z;2jw%*$3xNJbL7%aTo}j30ZXHpm9k0sVi_dl8xNyUxDA006-~CjL%1|Og^BvD;u`5 z8eUsPX>1Jry+fY`?0PYEo<6g2_UycjSnM=1^3)pT)`AiKgWBpcxjSg3%AirFd5eP* zjvhK=PEj=}3VEoUv38N5?p1FxcdB>$Mz7(sJzqFUM>lEr#N`oGvZQdU_A z`K|dEXc~4j2p{1d#j?jW&BI$yC00u2CH5F#XOFeDJdb_wrIAZDw(D<$uoFNSLNQjK zmiC)`+pCCs75<1NJK7S?oxlh4Tt%Ivo^LVH@gw3D4)|DOKg<>hv+aNnO=o?qd) zBGw!;7ZuIzay6nnEQm`!NKyMPw{nUUXT~md>GPvp*Ji(};@O*%38?IVxSFTwda8h& z9P2K-lj+LZ<%5qMIw`qxMMTPc z%1Ih+=0rkm9R@ptoN^AtL$sNVqokbv6{Nq1?bg%!*-vI88&j7m`-g2-c|Su|XmJBx z42Uub_~d!tp@Fbl(y`29x`NFGQrL6X@8ZCx;)-D4k4cR9IoeQM*@nMU9Mcy3(NVPh zf_5O8k#(#Tw=kX}S;sXT-GpXIvnQowOrmasb{$NgKNzM^`;cBQ=W!Z=VMcOmH1-K5 z^bm4kEA0rOiCv@0Apn-2k&-3;*9MhJ?#( z5?H^2k%5!&3qybCk7+d3658c9fRy__w>T(QRzEr z6APC_Hl-})SqZ!%4*dsbIVE1#BJPv13iV6|Xed34s`O*jDYmyxsWFar_w}g$gsP-F@R z<>#H5`3B+f=oWr9JZTL7Z{APZfW5v-+aMO7e%ivNM-W#S?|Fvcyr?2@iI$Su+QJ(8 zq)JjtA!jdwfSsSQtWg8*n1W0cSx?;@IDH_LVuf6GBSq35qz-=rbdpafaqtpmaJkD6 z)FU4N`0$>ky=urSXvZ>Z5+CCcp%Qe6L{{t03OeZ+ zRCbk>BIWW0M0}3H@E=v2SKJ_R*ZIq!pRh-^0N+(eDiOZF+6xCZvte(X-r1bgx@pkv zyuQ{9&YI}0FuXVNd!Ap~T&FwUkgPRr@D4#DMnvJm1tLU6;X~EEviiyPcadF~p;X(( zPfbc8;^*!TCu>?d3D>G!=ToM}c5s~~nAt0=*7w(iu|XXp80WJwG}1joDxbSx$aAHK z_4SS%_W_33*4oH7igJ$!EPp1HV0E_tW<^(9NXO>(=o@os$07H+%tEmGFeU>MmLY06 zM#|ETy5I{ZDk;tjza2(WL4xUo)ATh)MsAvybn+I26<_Ht)DH2oGS;c^iFp z4=e6_4}OiZpR&2uo*f!1=h32V;?$GJj0|3JHsw|;xTovqX6j}6C`D5HN!C5e+*J7P zKF^L%n<_W(?l+=cLx(%qs`;Bp2y!0pTKzjaegZo4s`ypoU3=-CzI7%Qc0MjP+hvIs zvb;zY9!)RL06PHqC)}A{LHB%6N+xzQphj`@&{1BeOL{q2x78AOd_f7I+j_IvX+|Vn z;q+Ntq*~#0;rD1E65XF4;rnv1(&|XIxp1t$ep72{*Id~ItSweukLcT7ZA-LpPVd|} zI|J&@lEL%J**H(TRG(7%nGS6)l#a|*#lfUcUj($QIM!Fu1yHlZf|t(B?*%dvjr||y zmQG$R(Djjf#x&R_;KPYt+psuo(YjfvRY^YCepUr0KHi`K5E}HpQ}UVqa+|mpE`Q|< zdhU+Q^%%w9`tGj9BKCBPd)P{E&^~Nr7WBf7rUWVMq8{5g_b0ORy#>P_8@k~pp8sm` zAK8t57^DN6D~ln!mx3!7?RnjSQCppf;A@p`!|uysB)zWt0wEJ~NP^3@9h=eFIzj}u zLin3oX0!Gg7N*gAUQ-kEVRUF2Fm*1dw5V-Uda}wp?rS*;JB*a%d<;*zOP(|x(?XuX zT@q#!3@qgxWi@Lnx@t<=W4YNd1RE{H-DO3K!}#f@QS$BNWln5GJmy1GJa}{u+9e|K zO1UT>v>KSj}% z1ang#sQMe>iK-&XnHp09x5iB-ZOc{map*+J5@myMGiwFnRd*g&rOsi|J!C!Hu((A; zk{)gS&m|={yS~CZCVsNh)&>Us*frV$UMqb^bB81yA;$E^JwPt9k4NS5IK(?4EDb^A?E^z_xMj%`kfHxeCO9B#{Q6c ztL=4VCp>ts_-;MHzD@d;1d8)z^Lxwb+b;Za^}>>?(vDJ)dJ=Iw`O6{ zuC-%5D~vgwyL>QxiSK1c-}xkG{zTaJqlTx)N2nHZ+MvhzFKM(L`;XO2D1AhuiWvQ`?uM(s(Phi{U1pa_;IqwzwsmyrO{H3KvRCl7LMSLGWoUjP z$oo{WpJ<}lz@>{WL$!+Q<{hhlP|KdeGe`AZPv;w?o=@B?_3SHT1GjI4PEScrQyH8r zPDPoV{+#wyfE@$V?tuKORJ!R*uK4H84tF{_%-is=TMLf8!&|N1cAt|vc$_3U9X+bX z21!M&@Pr@ry9YoEg2S&IWRFo~(+%E2_Xr~IJZC(CXIR#Lx_2+XtScM&FJ>bgXf0FA zPfTyb_3(SA*w5%HLA_6fMi3xkGmXe{AahG1?v7F4Ylte+sgNx8yGLE6p?5b;zPAG&fcXYZRYmHY~O|d)^ay%!^0=f^?4r>4fNSZd(zC^9ro6d;5Lq& zqu+6;__+p}fb*>b26D^6eI>l%CJ;+T`zM>Jr#}sMG7K%OC?p?w)hi5GGJ05ziOq|! z=x=f4L>vZjEx~HXe#at~R17>w2uJ$!_`)8{^Tc-jR#Hi?jt-prwCrGgGn#3hl24dm zldosg>kw^8#goKcCK=*+s7-U4()3lMoxjW=HnQ_wb_FGqw*!nN`=Q7pBfaSk?msx9 z4w(l2)N4*{gEFy=qg~fFvk7l)fU6LpQTCK@WSvf&0LmzTGANW1@7+QJ3`M+dc2Y8y zt^o_&Lq1iu@x#K_YX3BI(R#bD!1=5b(kTB~ViL`hpz<*}?a~GD5=9I1B{L1C4+Y!A zA*Ore{`=ZUFVl<2uCxSy(0t{=6&oGBQqKe^J}Y>^UK%$EpwlXMh~1Xy6&;h}VGTdcm4+@ESi z$Xo1_84wSsl~^tnvi^v)!MfQFLhjh3Ay~l%t5k;|Spz?SolNM9aJ`XJ+rE?UGs%Ydbo$nb(!mkD|0>$yf2HhWp#)nthTOk*s)IOEU_qIB_MT}8Gv7w z)1iert?Vlq6I<_FNO628gDnvW)ha~1@FnX@JdNItDGO=wkA{|iNP-4H!meaW;A3nZ z*tb~SNjVUMvsZWpGORQw2MXO#j{Y%0y?P5g{}7J&J*BzZp3L|uwdx2Ppq%3F1EY>m zSL{U_Z_W>0&M^inR~kA<-my?xX;qSE7eM-kG>l%7BZ5mn^}%`$CBimAz{c$w(a%;?K4-_vd|h6H=}23A>@E z$ziyCWpieAcE+IVDsiV5^Dr}g5^v|%)Zh~w;uiM{jvo@DzuB7vpcATzIOvzJMkSIt zf26$!EdeSgg|6AiJ*vvTq+1hol{BA7%CN4P83r2@Gmb4!U~TS%DJqALJ@oDxrw{KV zzl@mD$SYoAB;sNOy?`=l4vMHD0iO4wDUDY4$EN2L3ng@)bsU^EZv5b$e3}Ewmj0W$ zGwaO3)M%7dm31}_8(ODTfo&ke!rs{EF#%p+z)O;GFw6Md@=BFP<78(Gb92!|#_5rx zIUId2V7&}LdjT8rMnpf(pkPWuO)k0vo5X+!E55DR^6&6q%s$++q;!;_q-vC3F_M4b z=gR_=C%tuW@`w`aK_{OFYZ`E$WhRj}ezCN(+F`Cp%uP7I-D0kY+|3B={b0ULsgi_5 z^_7K3#>9=Tpy%USwd7)uDGU`1jt;-9T9Z{7(GHK-BjMzSDdaEJrJ|(e19O7=axuiqvckscp64zgVR@{C^ck&^ER#d^@CMPOP)^kX( zvBciKadokDb*w>}3Yf$hgPs?wM^iGo{D8!nZOmF2Geaz!Z#H=kbC?2R(AY92O@8hC zZ9aXT7k0mUsL4-RG!BAO_;t3iI`KBfbxhjQ7 zE;Ou=mhw^wP%bG5sCx1Od@mvWIIS9S82b`Uff+*eb1*tC3mbqwfsNDC!?`lWaoCHb zEK)M5$ysY9F~81=s$x)3YKNzS$}(n_LQY@mSHh2G@bP?taR4NfT+$7Ykzuh+ogQl4 z^q$$^2ZB&A;qB(Ki2`9a2%e%j&<3O{K<;2o>N&ClpX;R=mq;M2xa%OMq^EhT`Er{N zWso(m2D#g%AIvd5;EJt}y#Ue{Y1YEqk*mK`GzGvuApSw#%V1SO?o>+OpM3~a*G|(k zT1ek`jRH@W8PboCmKYhoNq&VNN*NI8s81-U1K1&KfAe2MYhbbY~k zNxeYxvAEWJ#@xYUxwn)%p2xJdw~Zd3)l^xq?ERE+_hq@5VtqNoo+hA`2E4xl4VA9j z<58n##BL}in6!*gpoQ+4W|_icS=XlN=T6gG`&D;0PE!9}oizRS9!o&0e?Q#uw54#z zi4Tl3c}EV2UkyJ11Ruk}HT5Q6lJO$AV58k?a322~4l@s*CRw9nS z>j%EC#ja3R5pUnuw#p0;V4zy%nR6WJo~H)`uAx;!0w7z5CeY{A2(anBn-I6syH*Qe z+%%=3LRx8zE+io$W`pUMC?~j4&VzK>*an#;@^^E>zeK3=XCK6;u9pp6rY22maPvLl z`z&ftU*4?Xpf%&s?A@LcY|-La|I2`^6(e%NX@~FT%g*;q+2P%?JK1yNOM=_W`azLU zv?5hzA00oO6k_rApf~mM&@J+%w_k<3yoLuQS9sH%GISt?oobE9yfUd;ke<2SPrHRU z)9$v_dU#qc?D&aG@9n(%3;oI@{x+*p0=M!i5?XU)S@t4yv&~}?oBj=#>FAI9K2yY- z)%@LA4Nx#dT-f~umG28ayK;YCt0Y1$5%6`7-2#SB3K=uJFp|GV1QAZRyEU>`Qmsm2 z&fx!s*q7P2Ek_1M)KZOXi|5bnf>I@&BAmD55@EIx$eQKCTM?btfx&8BHK1Y2tgkfg zyS>9(&d_G=g5Lh`^Y{U8iJ%Z8iCsK^^ZU<2R8>x1^Cr`Ow%}{^W(Z(Lj7!85c32TY zSX})fwa<3`c=nJ@deoQEe}^t}7q#v%Qp&EhbNX8QF73Kbicrl!e)MJSuLn*#9YzFu z8IBvPn#-rv%m_c2r5L1&?V**H_OCY3){>UhI{?5o6Luq^eaNy`VzVH=tgX*SB;p;u zXpnS9vfL>FBveRvCG8K(t|m@e#y7$8AMb7TcWJ2zpJ;ff+@j-f!M?Md{C%|N?EL=j zq7)69qnr9+(`pngdgxFb|JX~<$JFaqlwAK|H)JX!&f<+A_1usw1UbJSBjBiwDFS1_ zUkZhZB01EPAeBj6Q&t2-d1GpIg z@vmFNf-Rlrte~+O!ehclveAU*))^3)xrKm2m@J&(F;67BpYFIdOKWuVGqY{Y;MLAm zYKcgz?DQ2szyOTX8-XDED*~~Y{5Pqje)Et)n2h(MK=^TB?SfVW>iBMA8Gs|eflsc% zy5s4YhYtd8h6iG6H}m(qj67mc+Vu^I*V;qr{mlJKjJgS*2v)1uM35IpQL%v|{(kH< zrs}>E6Uz)#b}aH2qXRbloOwx15YCG^)Xa3Igeb4KE4j(JH#%3Mn*yF(Bh~$1wEiQ_ zWpkxeyVL?*Q=yBJ$P5>EPaglkjsEBeI0F12nCY>t(OUy4uOkDL4@POv{b!wJw7laU z4}L1ASUHdyqOUnWBZ?_3n;&Cgh%BWL^SK4*$SmGDhw(DQWT8WQJzlR2{i%4r?bz7# znv`Puo^{6X3QCWnH-1xDO^e6`LW3*!x(#}UQYb^$mg z`TrJUaUt75yl^1#r-{J4e^3cAl=I_Dr=>xwm7Lg7C%(`TwY*BG#QR26>le0+ zSjA8Kpk{_9Y|)SEY2B|2Lv-Cl3gV+L#6O}c!&g65jJ@HknlYmzUS$?;sa(dF{aIy7 z=>r`$X{U0m5?@2P!cXZRoH>HH8_3W`dWy13 zce1IF^&L7{DkW(g+eI$1shczxU?#d?dON16jK6flt~Chm`~GAYEV57P{@Oe;9+#Oq zkxXR@C13kLs=fg@v!H1=+1R!=wr$(CZQFJ>w!N`!jUP6r#mw2MMX{-)F_Sgh&vcW zKE{vkxb2N=1XV@_rK%6?*bjC>#k`8`QL88_Dn?4u*vZML5knoj56%U-t0O0_fTM<# z@yL|l)s7tseqKE@4)zPbaLr5&?X}E4Ot8k>PY-VRIH%*kl_$W7(DFrMJqW(|$e|aj z<}Z}X&QMT1GGoQQxSiMf=_!b*(=4>4l#EcTp$czycI(KP4|gOnGO6L0eDozy$`iq7 z+jF{tG>&vUUYR{Kr%9Lla1L*V;2bn1ARfY9ekHvww86i!>4)o}QIaNG6vxwoJBfN& zTG^klmW8FkoO~!yLKNX`W0QJT@pnWPD={ zkDz;wyAkm}F^IwL#dxW_h}LWVc2CV}$_(NXmvU=bO)ZX+l$cV81cR}n0(X4LGVJf3 z?*69|d6rTpKAe^X@(o*wwl|!et)4$unl%-wC0oil(%97D^_P6jz`wT8$Y8Eex`Ri$ zLXK0kqAI<$(RB^aT&In;aa{9*fb^QA#6{ZM3kUoC4I9VH@~zddNKFi2!)|z0EboNE z{ia6Q1z_Y(3Y3Ly7U?{jIitwcPB?I2KkD#~_R13bhc1oA>E=UoNp-Rm^(^Z$3)D+M zBP+9fE^}*E+e~z!_m$WpyYO%_fki#~;DgZnT)#X|4zIP3;zCXlDq<`sXKAaI$LZQ} zyyr@+j|I!~63a@fS&NEj95t-RdUCfMVvVfzMYuT2H}=XOX8I`FmUKz^F>cjo!0k5Q zF?s$VdCpZVq9&~-PfUFk=~ekfUT!72%3sepTk&V6s?>ZsA#WXBWxBkf%zOn9l{e+T zyM|jKz1s1FBgTbu558xvCcama)nrIOB8fOXl%v)5WK^JSqX?#fTc~k5;-d zh(_Pd@tFK?0~+T@Iz9|(X3b6@M??0LlC407cVDzsbbl6>4~eXM1-5VW>Ztk*qTzZ<=h~(g;x?UD>*TPzg327N_qACmOb5l z^@;AHAh=}YglwU6tAbT6ApgiV*B~yXi)m!wUxg2!t8E~ zmiQ;$RIsLL$|H!HI~>8zo}XYOF3N>af&yprcg!_FIHf<+vv$RD{(%0TM>ZN<9x@MX z2+xwNd+uQ|Y`tn8I*GHUX+xEXotm(v{vvG1!!eN7`0KCReg1}Gii3Coe_4@=a;|NC znt+p)%$|a-rLke|+O;%oij#`fw}RyKW|eu;J9Ht{%7%L9JTpnrS2LjFSNIGp#)`I0 zXh`y^GS%fTg$q!#{) zC3`wacCX0}bd!Jo(AKHbye4qa+h8gyvE}Kr|1G1cA8Jg2Nk+DBUvzl|ZyVEFx*kru zTI-lfYI+HKIaSrrZ6v0hvuMLKrJGX$8nje|F&>?Dary8wZ+8jGzV&@ zE-~nInmW6Ep9@1VT3YQjx0*UO=Ps1~wI5IAFxM6<(mK4WENak8@3mY5GSKD66sm2*H*yma)O0?)7Br`1`KeHi86a#yotkjM!s%JhTraYdP+lfcCj4mpTL=a>KSHmtd)aGkvevTSKC{ud zobS+D7KMna$Q}BYHAA6dU@!Rr7)jPv=4DQ`XJXcb#cPuWh78?MNtQ73`71@!K(xT&k9 zMuP)~u=%IFwfGP$jrR`N|4C|9B;RpmzZ1AJYJfm=ly&Tp;D9d` zy*NdJYGnPL4-YR)-|D`r4~Hs5yT^a#x69-*Ix^236v77`Zro|dn&`rsO>J*}k1mP# z;tG1o*fw^5fy}5-p{{6wZE^jWBv*Kbr~+`8Ah>6*${yA%l`d9v`15!BIw9BVfYaC9 z<~*1=*RymuE#tINYfUvTv2dlN_=Eup{6)VHL4SfV(M7W7&`sLY^C6ReR9Rv7=@7%i zgP(+ZRY1XeZqZhR+7uz|f=*)v?ZxTy&A-mIS}jp#8r>)z4ulp9oV;^==msMFeh9?u zUe`TC8bqEaKErcGH^cO11Nr{wFX`Wvq{3OaWr(X$!p-So4Aa9tO`<#mS}lg5go-}G z7qL_={ySe4y)Q@36h~%XPegs65PFSnrTVATTK8e5b4)yPlCx|=sfx<-P|9pNg3T7% zSK{mNqa%XXT~v+Xv2puxdwC?4`ln9%?ClYeXt~8m2~?qnLW3Pub;*sxU4>FJy48F-(=`E7>< zN~(g}>iSE|%k#1=;(wNx?MCj1CAHyk1B4v@j9CX0i%-9WKLkGfY5bk$gd)Ixi+r4d zb3YO1Sz_u0w`4&;oM++e9mWLCTiLZk`)Ol|#i{KF9(DA-NlJS6UX|Ut`=-Oi8NDV^ zkA3{f*A2gx)11?2#&w*QjYe^mxmT`#oF#FSD3jRV9oK-?R(R@_AoU@#6;UgLd2+2D z-KBSQ9etULXa8!;*1M!7`Q77ieY5#*?P|Mzu=^9$9@F3feϣ%UY8`RWp~V-U_7 zDSM&-@cv_g11tXxtR8hhSsvhbm}^TIbEA^ zez~Ise9A5xP83c_%z83NHI&u7X>Mt9`pnf9TVC8vDso9r$$%-f#fu6f@a*df)uo-Q_5os=ED| zcEe;FMSWSJ&ct}ag!R8s`bGUZ`f~{uR>BX_16UIZu3|HQ{An_9v zHp7)lLClDc62YY@VO}JkS_2kF)MYGEO;oHS%W;YuDSf29meyQ*kC&Q@D5Y()UirbQ zeT^&uH7^72nS2!YD|zY#+SZO~YV!l{p=s^XHa8fe1Wr{Ir~lt? z&T9&mFQ)1Obn6G9RBhN4O5^az)h8(>R7Z`?G=z2B6om`t%6fF1Lre{m0c~K~0 zXZ`%Asz;D)&nPl8w^z!q(xW3qYNIS&^j=w1)?4pd)hsHQJu%L&>=IUNSr-?V@a<#y zTe$XUE|?}yQS@G4Hzyq}NAYok$^v;@M3G?#N~=Lk0A7LKEyo$`IGn`T`3c+&xhE&g zGUdOb(GqsDl}c<$s___$V9iP|P`$KE66Ka)!2y>Q0W!(Z1+^C&IwAD7-&RKDm zn@lTqPUJ4whnly4U#AuBOX0`y@9}=T_iKqGj)SrPBvyHgUX8{~cQ&n$YZMhEYGih$;=(NLFnCA; zJ<{P6EViq3GdR@A0F*j71H;Z7rbk7w@|D5)fHG%I7z!A3i&zoOG}HN^4@2Y@zZPW8k#z-2^|-~Kx5rTa2PJ#IoVGbx9( zms$_6iSdGT;U0f^Fi(^HUqEObfHCxveHQQmm5N68!ya{NsbpQ!J&T!=K7H*BqwI3( z<(8F_S1t|R9X3GYtkqCkY%MCbUS*P0tD$w9$x6L;NSmOB={inXdS_%wItd~9g6P?q zbe5ls)xwWyqa@6o*JRjjFm*JXA3Z_f7BV2Q zr|8x;r2WS3q$)JNtkgct{V{eZW>(nSUAP3`gSGb@Ta068{O(62Mo>By3C4Fb0xq|f zF($svLG@T|?ZAQUbnm64rqnxjz@vnk*h&!BzyCpfWGxn*q%`b!2z>QlqgEDaj{z0qttc?)(Dp;3e z(yy(@YjF6%)!PGZ32TFI_{e0?Tr)><@Nh}%lMmyo%EZs_SFe3u*|%^JhjHJ1XGXjI z``I;gHSp+U(PI(CA?ZoqXG6&?-|KFNIGgKWj|g#lmAvsh#qaePKkb)vfkVD7B!sBr ztwrDIu9PhVp@t9Ota(3qIW!E{Stq+;x1M+(GR!qB3mdmJ6EZTkf_M>gnYyV*G~{HY z916Bf_&5)i%wxFAr?Wy1r!~*FqLp^99NyPZ-4ZHUy`0AUEz%0+bKT6;SlXPy5^Tn9 zit~>w<74c@=Of=s&C`mfeNxu7BhA8zZ8aUPGKDEyrHnjrw?v_#{)nzNg>MHveY_6& zIahSkcjLb>)xyrl4^6X;NEoPI)mVS-Scfz&*j>UtsLUHUf3vOFe{VM$n}31R)1_Fa z4wRr_VWG*Hdy0v*FC?d$Ny$k{ruxs|=UgZ|Sy?quvZB$JfE;70t4l^6I!Tg}>eg_Y zhK81qii(yP9MQjwa+ZXOmOLc=wpjZZ^%-&YDc@d%&LQkEUp2PM-s@%<^j>Wd*zN{m z`uIvD`cpvhgNaqh?8!Rgu94tEplL>Qwr-K^bDvl+D{FmgJ(tCsl2)sp@ zO8+Z6RqvHilF0dRCY(_2%LY>mq<5f&S<@pZhp;K@gL)OlJ+wIoR9s4riQb7G*E(lM zT`eb%v_6o2fW3}!gLQdyB7{*2rErWtZ}2<$YTTn(CQ5@*lC)YA5dw-p!l1x?Fy_?9 z3leg;vQHW-#<5G;K_a7kIS|F5x2qAw4Sjry?}hr}BzXo5(-a}1Nc2lv-Ux=7dw_`8 zr#XGH9?Vo})J2ws+jH0iX=yh&74q$+tx?E~Dm3uC#iso#%yxrgdwQ4sCaS#1Ba6qP@BDTTlWER; z_Nr?)h}&+X`Ml*kd?vj9KHR?7)+4QIjnxNdB$-4<7JHBLV%V%f75QVvg=?DA@P6oP z6|+Cm*j}NeBB0y|MVZI3d#*aVv3lH!Q7ug;bw0VX0C1mpTVDuBU-JlZ&L*CrEx~@g zvWYf!%l@HoTQc76+$Rpybh9IpMMRVsTga6ck4{C19$W_b-Af|r-k^#2-F(MyP}23< zJMWV1g}YafX{Z_Rw!3?-w2Q@oq1XAOMa^scf-SjkdSwG>qy_`I@4l?3=ytXtN6RU2 zRZ?CjbKpA1i}Nb`pyH@hS5vF0`s&TH$8A47t|iq@+0wI3nn-*7ob=)T!M(+ruye(< zEom9SCd#4heQ9Q{%npGh?2m^nPetWYjy9zv4ia)CrBY?wNlG2o zo#y=B+)MHX17`SlMY?qZw;;hMoH1JbxC*NXfq=*3fcaLt)%B_ci+Z)ctA0~lZj7Ga z6vPCw82$QeeH~s2j~}m&FVF^B5Z#nSEA;WOmT~aU%`JChOSD#3x0<`7!@a5b^5klL zE{Z37&-828$DM=l8@bj!a;JCkT=(qSYNG~mYkT=r@32~Pp9^&Xo0jSK~pHT?6)f?A*>9E846baRamXh?Tkxg^BjK7qxaHX5Y=?%)&BTXb5Z*`A0_YR#@MG~i$G&mDiVqBUEQmb~ zT-b4iN)tcawMQpfkx7NKEy1{U4Vn; zOn`N`SltDeICuwP!4I|f=KE&G=pA?A`qlH(c;DggP=Hm>jkJD-jK*C)#5xi`pESX`hO z)^AT71c;{_!-jQ+x%G$xqtk23#8vBfe!c#pI5j)(Ml$E{L-uq#7#P3Dj=X_A4S*3H znBlL^`de1}*(c$r2C$6jPAg-6!zeYxwbp@XvS>GY%obNhzgT{!V7`!tha) z-OVAEZ3n1vj2wN3s5_q~K0zKsWlI+qA)%XFSW#i>btv)AF5|UYK=>9Y<6WAGKhDm9 z>~TM~Vs#Y8lnF4USHyMiR4{8lyM^>Z)dfszO%?SH*J5wT-p#cJ8(>q7#3GzJM3d!F z)-Za@re5UMqQu?&n9LL_mJ&?!G}p(vhkYsK$*YuiBRNhjbc7<@KedR3oRvOw-kVSZ zvNJxHu<3gx+=T^c628Kyo3L^%6*UVHBMCbNS2_Jlr-!(Ngw;HidJPwcpmr&Bl;U59 zAB?_`@FD&}7<>qFe0pDef`=aa3O_%Rh`BLksk z1{srtza=8k86*=_O@dPgt9HG}|0hh)8OxMT0bAv-7S4Fb0 zkDTdD6%FGH%Ue}4h>u*^j8xB_GrG5#lle?4ZT|>P~W#{+!GHsZ*!l_U6YuunTFV9Vtqf-CEsVDxn`5_ zegWYFLHw{L|BwU&fdGMe0K@i!pl&e$0rj!O=1jNPZnS(7m~FJ!;{0j+xwhQ_1~U3a z05a}_tpl|I+UO&6fZzNz(^vM}Pl59UBL=z@EIP=wKXq5@hQb5vVDO@jfd;{P@VE}| z0xY~=(gD8rGvaO%D4&jJXmxC?gP==rw>UIMnZNf={z4-^_zT*Ix}^-jB!2k zsR-f(%PW|#fZ&86H7muGRa1F6?9pIhm8d1o)(~P9%PpAKkYJU7&co?v^T_d|XN>#) z!3%Ovp#4Gk3#VVSKe7Ntf`SREr>Nwd-~$rz5UQg@HcIOd^R48sza~N%YRAc*PdML#BJHU% zJ4#DV4c^j`%%U_6meXa;{077Xkq-yUny?@_RH-3I0cN|8tC7J-Yl^_$Rx=_&M=_pvWW=AIentRL+haM^^M| z!TJ`luzS(QKo?tikn2H_8}V;H#ebuMG_;kI2~LHZbhVRt6=mpZSrx`hmuKFx z3p~}OY^Pl#R_&`Tvz(4^{RvRshVqw-X{)yH9 zEB6-L=j}?Bvia1BBkGmEU6oSnRJ0X5#9WAJ5!^$}`yjW`GO}i*_erGV6U72-gx>Mg zW9BMOQH5LzgXPRFBi|ThsvX!{k@({FMf7vMm_e4Kum+_J(dn)Lx?}A7A200KY_cH& zZ?wkfPkq{|_yzY9Mp{DUScVS29VmOGc7M+9)y?>8m5*ZX!DrXh%3k;_&I`f^Jz;aa zG6fxC5KR*@I8v{~$+WUL|Ow zdm)QEgfm<=jDTes8x>}^Dn@G@!Z^BWn9Ycf*$dbtGkju9OVo@ zN9JtXndsN)ukmMZ%1Mg5TXE=SLrr7d` zicE-1gCh69WSS7B=|11x~CP`}>r@j8`xaL>{FyB{^fQ6J{djI=f^&&_Ni6`plZ3X^D3zfCZpN`I&8SBNX_9q)=j-Lf8 zYj3Tk$k~Cdm-m&_^Hkc^D`A`*;amMNkFK47Q+u?<4Y#Q_%qirCD5S5q7wGWybg1UW z$zq7iLKXIoVfZFiSM=*s=+hIaizoRvD#CpOAc7%+GWDghfOQ{tkn;%--4Rdsk7xQ1 zgN;yU_w@wG?XGduS}l@sWdStsu_z{6;wpta-!bKJ1NAzhaD3S(Z8t)%dEs)kE+ZJX zn8YzdzDArt7?Kv}*9<8pI<*d*u?4C%O?XObZYL18(V7*eHk@GU(b-JnjL1;83=vDO zb;;T{Zg#laRQT$Wg#f8g5vXrExuj*tA6dXNu?im;@qC!!En^%oGk<^`Y5@}S?vGnV zm-(nUVZCeBf=!wptO)3Hfz9gv<&t@Q067A9>=;Xr601f*wx}hVjrJs18=Pv$yWBLbvBXw>nybvCzqLC zIvrQL3rJLYh8-HK9rX@x*;aZ$M_Xqe$PWEobiHM zan!Ew`Cb1ABg@_`z-Ti_x(?)N#Fhiceb94=| zCK|AfQTYM6Amb+3f%HP z^V4u0z!4aj5*Yk9nldObupdW=d4v&@(TVAIU?{B2Hx}l~SJ>@fP_{27JOjnY%M8y! zFSIc9J%$(=7`=%Z6NZr7BHnsLv&+2%b>kD-&{MgM;U5Wu%_=ludGG0P;EwJW zw(-;ih3{K>ko83AOA0DgEede`#!H=+2LCmb%YhpN|7{bPt;+fcyrUuMIsZgGWq{iXfqPthbyUu9!)+ zJU47kLMuMCbn6s|E6}bu>(tIG0N>CJ@Q1Pr-g*MPj?{*DqyMSS{34WyvLz~O|1T(2 zL!vZgEsOg4iI8i%i@K`0YFUfAzVi_26`4t4@Yc>Z|G;(e@^zj z$RazYfEor}cw|BSH0p1sR9{H z5rKppn$OY{68FPYH>jflNo`1d5gH7I{M`SGey=+||IUHXQR9o|yI5~A4_rC(H ziNr(c;DY1}bfi`lQWhNvTivA%hIb~>UV>O*vs~WqJra`4%34)gQ6uu5Nrd}@kHYv9 zYLbh=uF#=k5vVROQ>1en6Dca%))vuV#c!4zxpn!=w5MsUA#AfLGdLllZ>os0SP!nK zGUf>;|Jv{1!@HI8m)2JoqbVhd({sx;Gc2P>wrloU#1#(d{Nas#BgdxI^s9)uBt)ia zj2)`u`D3HwLNo5h=+lDJ($hi5Jsnrb*)+;tiWerf?GSdd)}TI|C^nUe1fMU zzfJl#(}0yS{m1j&l~1x4VgC#H{ygyC0zhBjy>E89|ET$zUp;$Yo_wD9rnt914vO=h z8n1c%Fg^%@8mg8@?$*t??Ha4AQyTA5H{7(vs4cN*@=O~5Pf3@p1hkz~1CXK?M93+i zBqXGkV^Z)=$^k*BWke}|h2YK>LY`dmskcsyQ)qfsTllME$jy-N(`S^_8bYftjv&7F z8Ads#u;?7ay*K~W7YjgFIz&}bM46)5{8eq*q3tkjjBQz9Tcgu9bLK6WQr5IK^k4On zw~f9~hp|WEiNtH`~g%s2WN=~vDAXev}Q)o5k(7`1|7#$y#ymJcr$Sy=QryTHvc8)XBDW+kk z7<8p_$g1GU=lWAVB5ZXR!o^d@Hd8*Vj7zic{OJUL zu*i!8;e3v#P+SpiNyT4P&D~X5{!z)^RZ;y>(YILzB1IicRfSYl*>y?Dc1clpNtwD? zO}kl#_f7G8LH@1RZ&~28Q1DGP z_%SQ&3;}K-54)z9MF>J-+OC5F84oRYI!c0vZBCl;q&j^Wkf}{e+uYhFxOy23Vecw%=fq6_;Z3X&;HZgK zY1LfSvQ(F;Hgl%UT50E6Rl`~r2CLAOW?%M7?g1<_MXExofEv2@z5Tuk=I$PiN@D0s zTfCdy!%fImrCanX!RW^jE3Df(1~OM1xT6oZVBbYRj>#wnO{ zo|+`GnVs#`F*RnXWG6Z8b!I=lCcmBJoZChJkMC7wns_p2^7XI{r#*n@IYX~B!#ogR zOlT6gAq5M*#~BrBdd$~P&FmZsKbSZ$9_t8WL_@A>Qcm7P$w6x)?9-(MdAPLd(0*S zkhr0RX15y8;h<;k5lrB8dc^NR2846F>eFVcY9@g1?Jm-l7o+-I%+nqdHoCs0&}=s> z?DXGMD8-uGUnTkbO@FbvT41f|(#}Dn%xFV@>_!_`*p-PNbJ^_Xbw3qD_K;Re=fS)R z_e4U~4iu!8cSHqGU%!EHfL|Ah)B%6n&xq7MGiakN!FG0??PMfDzD^s^sOFsEtIMRE zV4H;eA_%N{(s|;J;^}xkIn1gRm0tQ`$=y&bOnhe^l(^;DZ7OeOtq@yoX#4$;G^O)LQ=g=q(@lq)b>A*=H@mxy1J=1&$=^A?lTO_)l#39YQ>8=k^ zm~&c`E@4bOQGyNNKrF$Sh~dLLVPP!6y3BDP`#UzA>@I>0Kg*Lx_+7KT=$om;f_*0EcZg?l*n zX>l~XdwUjs2d6Y6=?ALU)`6ast-`jVSY9kFg9XYb+lEo4ZL)Gd#>Qpc0$t~2!Mxsk z`973z41*Q_AUwwj;u1XfJ_T!B`yZ`m@4jH3vN$gU&sE|W&*UA@enDVCMIfO5ttcQw z&|P3YpnxpMnl}zXU;{F-NNCjwaP91JN3!W8P{|Fqi^PV}lvZB|k>XffE+?6=4wOt# zY`Gjx_q{|KPW76tHd6V(PHws@UWJFTyx$&u6~BKZ*yj9=WAYzBXuaq1j1{F~C0{Yg zj8?1Ja-~2y&5qaW@s!yPPg6dU^&Md0iW0NX@4opoq*35$~QV9DpFcPN^){+Vw{?Sin6l2 z;`R3Y`llrVF`z%-BU{$GM$u10*rtbz-d6PzU(k^$lxu`asFti2E0k*mi^!(5nxy{k z_m&Ga!ew+@UJqvr_I>$;gJLn*%yt9ClnZ8nOlJH3LefdKDy>Gl!BX0vo>_0a?kgZ3 zmCNRGz8WZ@Ub#IYOH7DzF(JZf9}_2xQgk|>?uPi2%j11}7M|z#dikgK%k%zfu(N6Jwh{(y%8})eFDrzrt0CJ69iK=NHI;V{+r*cDa#0yxXyC{;s zFG9~p?Vdi!(Ed|s<}7A&NPp|sTKDv6ulf{>4cEK3Nea!4X#6K&^4C>tYAW5>>j|6vzAEsWdBL!Irzul32428BP6n;xBh z-j5>ZCV&jv%pUen`nCs)oih!Iea(RjX-G;F~W5+~{MJX+Mq8nHs{#5OWyQbLN!9dgwk7DS!-P&l$( zq@ZmKP;a=}sQjW?tVMRtAe_q)pRVBZN#jX%IA5@$KkkyBUc^C85(;0Rzm7!q*n_PNR$*tPzlZz;(il~CDJR%oms*gR}8Ky_i&nk8k@OHEOulB zF$!Zc2i>M%cUvJmYW2NHG4xn7^qe!u?FJisln=BiFwjvkz{6mQ`bo#pLW(8AtY+i6 z>Xf^LNaije4=*VZ!HY(oVW$XD7tJHSZc_oLiD!TtuK$+72{{d}JNpg54Y3Sn@I@>| z7?==DXM+s>{rzCWMV)xs@}nmZDsUx#C&Eq88WLS(Lbev4rj~YIW^lbEAK_?L|H4=K z{-HZNu@wPE4dqrnZAchZ;H&C_6wY)&+3v!7#}76D{dNyi^cqbnBIUD8y&jeR;F;bT zeSP*Q`@*{(dOtY#Hq7?^nEy7e1E=MBm^WZODTc!=VYDcbO|Lf?CY#FVhR<$ukT#z! z6sDgl1Q7$I*BPXkEr4*dSyHjZU>0Y&48(wSy1=xu$d#IB0pNqHpt5Y>(=NdA$ZVW2 zIiq#pVdzfbv|LV1hpZBwfQw?ls~@14(W{u`I_83}I2`r|XoCf#;k#p^;V~JF2ZB^b zWDzb_O{!KIjN%RFf8M-cqS<8P%HVO!;1$zkc3b1ITch;?tRAg8skQT{ZH8B7)wUAY z<<7Tyz1$^EXMUKhzK>_4n9*p|8;%B|tRxw-X2AaZp3z_^M3ZmPP;avOfB|#ckB!%H z>d7xlkv=VT66ONLL&d{pDuI+h>aTn+^}hNqE~j)|f62w=t4V#&)YE+M!8NOqLt$R;ed=V(&BdkE+%zUu*e2|WOh&KbEFp<3FTBOjQ zCpX;rFkblx;J@$8M-1M(cA}hQ+oFdr2vvvvjOq^JUy|!C_^jNZ z71pFMm#kwXB&{YK?nzgO96d9 znhQcPoU>(ZsU(eentx@bDCGuT&~ncF&15hH;w#sAbmyXRO-5db`(!MXOwUn++L-sL zxa_%NS~TC4T(y=t}1I*7Xv9 z7HY}b#P->8Q3sw@DLwUXot%8iEJC+bHB)e$ueT{=RBxgsh!Ob1p-)8jX68vxZHk!y zLf041kwvK$7B2k5Ns!v$)wQ!QDg3RnX4M;vnoaR{tG^(mxG9fQfk!E^VlCI8uPRy( zF%A9%*_@DrSPa}Ei0wqDv_9Fh3rUIPxnYRmi&JmWFXZJPg+7+Lz4Pw009IOU<6aLU zA3%EYo{PW?5@n&-P(|^|=TX-iO$jpn9zj-{qvKo*e@zpr7kCTY*8#X!lI8gKzAQuw zn73cW^i7z18lQjuDA0ra;*qr0Wn$73v?y;sMh?S~tTH&U11gX|SPE6!~{hmrgr)BMD-fX)gy|Gn%k>5a_ z*t3=Y^$SP=^}vFLKp=bc{6EoT%sv6HdZr~*B`b7BKmo`@CKr-2MUDwnSk{mSmw7*<{BVX1;{23V3J@E)J+B; zfrGG>;+&tTR(09`qC~bEPfx(Vf&9gQ>iRjzUqEo+zfcg0!7~Kp6kt_;u?jNJLOnnX z_JKzjDr!J22Td86a{$$Zdw;!PX`&L82zx4Gslc&{>dpeO;BO6Ms*f}~!fc`;3?1Cq zd}Is}b4n;G1+$RmNboad%8*Nsfj8vvkX%#bLs@8LCZ(1wSsJhB#uaUxh^Z89M*$YGX3rW5heNEJ#Q4xS9Jru^T zhao>?eJc!&rAn53YC@-}lbQr~2+65Rmw0|i=c(+cqM?ZZmHJsvN6I&ngqE zTDHjgsL{O=>f))Z%f5`~qR%TMza0G_)-6x4g7F~xDbc&E56jeZYV($5XjYYBiJpFB z*0^RbmnEH`l^~ixo`Asj5KFKif7W`_`66zsv@zh;I(T8yIabs9eqrf7+0#U?3%jxa z=ZdnW^HYx06(X2M@Y6u7j%5`y8_o_~KKKtIv?wO43~DKibExZJ>Yjb-F7Sli@1G*d zw&dR9R4*}#|M4)`2!4W*{|Q2Bd#9gHP93H?X0>T=I$tqAN3*~7e{lI>_{a1P?SK%@ zA~u2X_5(5C#{637LvtW4bpm{(y9*H(v@+;m(gV=HqAZ61L};#aC}oilL-Gtz03ak9 z80!J>I=Bnq@IFQdaGhW5eU~?|A3)#vixeox3U-U2t^&TZkSxGcg4(mdF1Wg8_66o` zh;-rBduDAYSCQfS^&Vt;0V})LBv|7jkaH4liGPxbmL!Ph<7CKS#;~90JSBVP50lHF zn=S0LvegRUES%Tl+)6-BA-Mvl6A~po*RC!gEeo4;)~S8t`Nkp-V;X4Xlh`NdQ$(b^ zNVNx$p}46&lff=jkBTzInwONU^j&k_h~k-NQ?>{IeMBv44sJJM5>QKU)lk-ZQG0ZI zb9=TI%{O@xxgn&)3q;Yx(M1_Wu7x>;pM^<8&)oWL8a!)x4%M7tvV&cZRj>7$DdG6P2@M$3P z(#9RnWAOd6ntyJt5FIF6X}MQR_wa9Bd7}jT{14xssGw* z>)y%#3i3ym=ixe&HP2QaRy2PdC4_y>UP|=wmL)Q^&cZU$GoSLVW^otPR;K5XI&$9@ z-#Xsj!x%^EZs+qd8?vY}&eGX3r!%56HZsLCb~H3xWu?U@K_|H;v8=VMEve0OfJuXy zghLCQ;_-v>85TjX3-LiNLzD+g3}K%Jn)i+!$lEZwe$q8mRI?H==MgdjY((RJtIr-< zm^J;@f|t!-n040xr(st^u8bp0$H57s?Q=T_y*>7z_krbu&=0;Ik>6{*6&Il*B36tF zfTZt7k&W;>Qyfw;0Tg|Ezw*AGCo|77xX z-nUzOM|o>`ZhL3FV&;i|j_oY+Qz(!z5Z+`yHrTF#U4XkGct>>)_CT8j5!vsX-_r{>3oi&E3=R+a4onVk4~!0^5rYw{5=~1~ORS8&j7^MvQJ`NU z<00puOky^U5Y?B~8`gu}syOQU)bFC7LD7aH4VV}fIp}$i9%Crhx3tOdQ1K;9NDG{i z#46DzJ&j`>?mL-gq<%W-wrBC^=@Am7o^u zYgKPb1%x1`o4|6^yYu{HnK`XzJ8%2$+;k9Bi#<;-9Cy8U(Pu4e`X5|N_P}EX$1)lq zYX15OC23VJo^2~5uLhH@xqn=z`Gl5u4>bIoY zLzfH=cnChWD9kcg5I)bL=|ZU@c`bn4eq}p!DCrZ5y|e|2YXmOiT#ck7Ii^Xmqu;JJI6baux0aV7kP#z8%m3JV z{6#mQfD{F_WYw;tCf~T$RcZ-K{U9SJ=XG<(bd;N!>6Dt9#z{)Y09&CdL78@N6|QY6 zl~^2(kVJ)%n~@<&ma-}a2NSgGh8YIK_c}lFG#HN1x@4drJCJ6=h)FZRz%!~v8!>Oq z%KAh6$^D>0#makW-V{7MEZX~xo75Z1&=HIXy@AV+Iw-a$P#E+V^IxwOu>WA z&N->3J?mU=3 zPv(kPphJ%>;;7R$(C0I!0vS|>>eGorms0mg0Zgq=zwRT@?E0j$OwohG7ph(FYnQ7j zX~X`qrhS=JdTnc6t!i=ESG(BozUw~leopvqltk)E#>Yk0Hl$q(oIgW72Mt@Jl-b3- zS6O(k(Q)CaRcKMAxJ;jQKJ`D$7sY0(IvS|Clq`6mYLJ|vrib92!^IGkUGCNKe!kQr z7s;R;e7`rMr6k$;$=0%AP7fHwa8j4m_`mx1e$JTyo$Lr|Zt2l)YinsqRmNBjVPy&~ zbpYf=r#^j|xmcID7Vtv~h)AF_)pYf0*ml4~TL1tLMK+vhUoxwpzOA-?)*V(0O&u0R zd3myXO>1}l5TqXQCwwDNitITG)RD06uojT24o!wO0U9#xsNn)b{{S+hfFlLnKhnR3 zhYbFJpsUCQVXlTSK0llO9{^-Po4+bH97qfqgpjKy<(9n9HqI!|I8g0)K&-r6SkQGr zQ1g{Wl>?!`unDP}+TDbiHuA_Z2xRXqq*9_NQ-`_Ao3f$aRW@{Q(Mb#6E;Y`1kpl|o z-s2rDe-L4)2n{nL2xyU^OR01;WTh+Vjg5_Th334G2u&Xx9Gui>T2*PlU8RI<)_8z6 zaWCL*st2VP0e4$;D73d%t~KN)yDP(lLa@<50%yIykfWplJOtaZ6tI$F$CM2BM(b1caS63xzb@lPh(a|h4J0!`W(8c}zVgkLAB~FBR3(=A^ zRQ3bPxX;yOg+Ay#=(Q}n@)LA}t10w@f2sbmyUy+`nR*57Koi)9Gic@^Vs|wmB53UN zB3hhAU9FGzw=lZ*cz@eNf)>&Zb+9l7;i(~jxM*GwR#yuR*TlpGFifMN$UH?E$3PM} zmyBI(!li2^?Sq*xeYCK!AV2{Iv~vETp>bf9UWbew)SF!5BQu}2W8{2IC$C#V2t!54 z2K4Z?(u#J+Xwm}uZ5dT$9Ay$VpoE3sH-x)VlL}B&MnxIlTWI4M7a6(H2@h7%qF->C zvqd$C6PB0Dng();%07IU;ItbzP6R=NpLlw@ZS(>e!{2H2ENPj9(cggU1a4lygBNzL z{}=z>Y<&4;=IE%Q(8oVl`&!crwIBU4hX2;L%)UMzh&*7f|LQs-=cnb|0PILVQ^k)6 z-wb8^3jW476ui4jJ`>IupeWmCQ2T^!l6*z^)cle8hm=pzXXrEd{)fyTosZ{*@q7p& zt8kZ``X^0sjsBB@{y@U2N#vBXO*#Du`k!EQf2R!_LW|-%+q>sf+M+q!db;aV1U?4v zs{r>&j^Nd+S5;L-4(V4`#)EaUmAQBCs5IAFqtCUy1>!9j4ElqvUs*5jcDqH+?Z(vH z<&}Q}VWTm1bF&P?63xQsb;L5VbAF?Q#35p7icL#X zi5R47)j*Vm3`C*)Dy(ibk6fdmUq)Rp0?k~Ez|gXDdeDx}Ho*egJVW+DFoWJ-dc2Q+ z(t>MWQFefp0TrQGAhT(E7p~^sg{xT7F{Hi=UvuxqSG)AO(0U`gC5&-tcWv?i{Fndo zU;fYHTJrGlFuAr2mgw@@iD`cEMWgY>7p8ea)Lt1``8dN{QMn@9=66s(EVUnP&(9M> zC6(&w0X7_Av1yu!6`WEa5RjZgVQp=#APhn@V^Gj3>iYFo)nUL!1JQJxp(tcDWZM*M z8nj;t2~$(DWqH}}&txVh&gpMFiqRx$I&_#Os*1RC6c!~z(~P7976+4LWPx*p&_OwJ z>(;@6FH0d7FvcPZn0ga%wpkk;ttoL!IeVPhUR_<4d7*Ja5G4rb=Q@EfRNy0gN{x(+ zP^TE5W=~I{VuA3HdvkLWbpPPs;K|7eeDQj{pZiM8J`8@qlu9-$%xATg4u^&g6*ru9 z&`7~a6Dzssmf zB@n`)W-vB?q}S`Rv5AiI&-OYJa)Fypa;(zwzY`thn6B@6x0*9Oyp0`$^}i2JAoiqG9`O3)RO`txe<|3SQ$9c z{R0Dk`A36r2o|FpiVE)6E+Omkw_udCG=n86@ z%b0;l7;NFBWZo6a)@Hdnnx98??AMLL5lhhx5R0%-;csZ`!-|a8*FU#tcPQhY;K?cSr|9pazyJAb&t|ac z*{tiRCxw{d?9*Ycwmu2Hl1Wk(eCG~$Hp3pjL1l955^q#^szOFdp;YT#!TJb*u4Q+qFM~S1mKL$xUgB}Wz$gTo5Jh}sxeBw8@O z^9}}H6bt!l*9trL?%mtL*REmcRXZz|t5uoah9dJ$DxUevBnT8$K1v^C3|vmGtgLV` z7%vP)UX-%BYz|Qa9$bk?f7I{X&z30BxueW_c$Ol8X1#2hK8So>>Gk^L zF#}UBsYhxZsYw&}i+i+ZpmAUIq@dD{zH1W&Xe&4z=coBG!suHFp=cJs5`?g}j?1MY z*p$Um*#!omvsOw&OIibh#IYF#-``V^IcHxuLO$5cfPmDEg#{%V9UU9bW`~DIqhW~$ z+l-gO$zS~97n^yiXLxwHhb}_*hM`z3PGXaBEQ4kHq{Nnp?5wgbh*`Jza~TY^Dm#$Z#C0)#C03ve+W95I@Sm861EQmgp2x}5R^LD?yd0CPLI^%WHm>mE#fvAi;-@$XR47hGA5)d)uq)>yotcVs(43ky>A0PZ_Sk4?p}c2E1>@49gK5I4ue& zAvlXc7h5Hoti*yd|E7l6y%Zt*9>9MD@S)RG>h#@fZAIhXvf!bGk3U{0VT;9rOWC8H zy}fXFYkTJ?%bo7+?VVae6W{*!x32~i2Td1?=p74ht?&;ZjQ#{dXv`z%%wWvN)EeL+ z4zhL#ui05sS97^sv1U4fG+pK?1V~OnWQ*qDP~94xM8GJh@?%D2vh!7cdJ*HJc!$Gb!I(8crmsB9Vej}gkPi4(7#}aK zTqo3TA=EEc>b%ca1;XD`tGdh)@xp<4iD-F{FZoJcXF&ywO?b=cWRU=mH4vL1sHcx}H`$C~~ zI$fxizje0SeZVi;GWyYsf8xUa+KWrhynYaBhDvUy9q! zMuQcgI7LC2_Q>{#k87w0Kpv+JTO^`%)VYuj?hfxDDIM)_jlezce!esOuOkc<;M1Ch zeog!aiI_sa7LI49Ef#bJdVKP#ueSXF%KFMi8se3ym#a%Z{pAB1O6~N;g9rDY=M3Mq zYu6-0an)*>40;b-kDlikh?3sl$dpKc3?e>$^OR_AMW*(5PvXE+tP`vO7fwhjkmvQW zZ~$Zp7%qoZ574Ws$QDPh7v{3_GKUGfAF7F0w2Pdl6;aOQ2#!yaBg`_@r8fO7+9VF~=~-d-u21)?NL z+&Fd(%hb@*rwQlgema{yp&|LPxtW!utU|8=PU1MbB2ycalWi;Tca33ZNz2&fGmZf4 zJmUuyA@A+mgM;7w=5KxS$?q8eQE5ek3>8kn0E&u!&%f6F!*WQq7Ku%UJfzZEU)=;^fi>*ghYy?*Hz=(h6^v5Q*YbpKf1ir$f@8dziqd3@80d-gt`AVLg)j=ZnyI^GW2R?btO%E#&0x? z8m(dC{A-2dEjZ4t|`}0*tgm} z{UPx5^tAUO#v)+jb6~3siJpAvU-@6+WR#w*5QpLl4uzn7X)RW|k zH4q#kOeWNd+hm(19oY53{hc^t;Zda;r+qg+`Z~C4$4wU~0^8e#qljtKH?Q9s84fx~ ziZM7mcH`E>^t49&?+kKYfz!C+ngi*f7EK2JB@=QCyn*Ggd#VxVM(%7Y1Q-gQ8fU0aF_okFHI>bWt zHd$zPi6=EWNLlW@_n(Vm^p}Xl3?odD7pxHq#o%UP;3okvVFzC;ot$jGI6OW+&Z{^u zFfb6LRo}ost+>19z`8Dn3{)@35 zgETb24}x==fAFP@?w(Um?BX66>+|^_O`SRfB}-@(;)7~ZX4co9o>Qpv@a4;w@KCTv zk}6GydX{$&H5${?lW$Puc(i4K*u^F$Xs85DV%`svTui}d{76lb;p1r1Tl9L1ZR6W@ zJ)1@Cb6k!SfJ8=Fr~=dv+IXT!PBPWS4?enp4`0|!0u+#J$GQUyuUu|uAT$uLDRZ25 z1ke*xp&ULjA*F!yL2UI>+2&=LmBp8P+iMW8s#KwSFDx|(7Mo0sOawYd7%lJeQ*amC z%Iw17^)7I&BfR_gB7xVt%u9D(wH>wclU!sMMRt=hMMn2N=dz<{RT|t>fL*^Q2#Hr- zN(`P9g#|ORi*INfF_atxZ{!}s+*8mWNr>7+pu!(53qlb&N(vT)PtZTd3`5=lq3GWv z{(o9Ymu{Nd`a|pHaB6FR5O4G;sMhphbr}sNY&*LX=5k+u-&6DIzCtANM<9@8G=Jd< zo%?<+HgDRc;FaJ8J)GGEDrXfEZc3^Ox+i1W_{_C_0*=t(W@gx2_Yd~5<#okQLROQJ zh#>qKK^U;Nd7suU=f`)krMWJWp6UX(T);c#w)q=;Wud}8oJ2EE5u5vOIoA(7?Bs^9 zG1+l^<}!WY&Qwix^544q10-_%hX6jz*}#Sm+J;AZD7ZoA7HI=P7A6ww6*((OX)ra= zk0+q=9TX;Mx-+7=duY=j{~5tUPT2;zA}t*BbCpBL&kff}-n*7rc#_dw!&lWaonpY; z%%qM_>*^{<$!1!v*8%#CbGUeiXgyEMS(+BDjMXY+M*x1G~m|Pm`0hD*5W=KMIjN!PyI-Khg^JH4j zU&0yu{EEHp1g>`()%C8`#m;4?)7n%_xk5RcElb6s1bX^#O=i}fz0%XfX^BD!OOiJm z4rk#B>6XllPE0~8*qd*^FWjDI>c3dSIKog7@`BG?wgJxp1D;iLxvF1P{R&57Ea>uD zypKP)dH-y8cef8p$mMb#hC+u5M}jPIDgf`2EvUaWBT^x)onz&;E+;^B zfwNtoZ;LLn&FCTp(Z!CGrnbw?OPu~znQG}EQ_aqN%yn4tC0d2M5l|7jMkJw?@9VQS z@|zpH1vkohC}-tLrEFUKey@Y2ptVoW0J9%MCZxY!Etk}?6Yc?fC=&tKW0cziHf>(1 zp=nwcHjAd;WjD*2%}wQ69iGsu#bOnKY}IuG(JU0sLem&Gs+Drh)N9}wPy&P_1Wth+ z$rgrTbnwvXvWJ2JDdcuRA?`Z#gz=rM0qy}}g;zI?Zj$(X6rlhM(FGPa&d$yn*a=3s z6BohIEs}JUVd6N2O+&V=Fc59@*VS({F?R3%@*yqkw#6h|Sa z1*8|{bhhTY9>wT3;Z6rUe|{euW2g?@_OgCi2d#503@PkQ%t(j&NSy);^5bclpeUeq-iN!hSrL{M1=Fm+Kq`Jt>;u%== zWN{WRp^hAGyykEbVW@~@Fa?FFPLcl2`=JbTpNv5-AsD68vuAF2mO1Dp&yHbumI)rg zvv1rN=ZaMbf7hX0zrMK0UBAAvv~>3ig(3gDNXwY~JLcicOnURnhlean}r~I>4-@gcb{~8(DA$nXZ zt681z1tHjPtH{xcH~`cWwwdbAh7@qKW}^flw4KBB{t6YPApVgiv7xF4nE(@`jN=Uj6dRFJBZ)_teee zSy314HptJ{YPALppMoeTazya?qJXq3UQ0a(J}3B64*g_*74E5R9UrTZ{WJ}|UX@u3 zM_X8&xctAJiHW%xLW=rJq&zvkWou#F_^6R&EPTFjD}o!CJq znGEbCJ39*>GyIR4nQ_lj+cUez%*@R9@y^cd4u-*T5;I%2n57o<|5pM#@?_xnDk-bg z>MpKVuipE;SJ+y?@( zuX8<3o<5yicKy23+F$4z^&RSJZgzgRrJy-cfvk>6?jJvR@OabQ9G7cljlXh*)ZegI zV<}J{tM&fn>qB9B|HRIq zwpUU;fm6X1aWuNMv9?xgWr#8PUYIJv8;-5rSTeQ0wliit4W2#iZft4NIfM%^#V5Za zOnab2yZm%3odvYr1W?O_k1hjm6ejO#yxL>sBV08T3(J#JpkmV#6K#aEvxSGo z62rBEymz+TTb!P}N^V5>8{`I&?YB)2#gA53$hioAj+`S$droW1PP0Y-Ec!PUNb{=(elBS%tYKF zesuFAmOwMtW*d9Z#_qvmd(PdSmC>Y&OQEbs8qn>5p>>o3rEQgT>c~!qKD#bh)|j1+ zXH9UQJ?jzpt~J3sIeBEM6Njy$-m=xvX65HC2Hiboe)#axG+<)Wm&{-JwZHb)e&rIr zpDh-F7#AUgj1}t<<;HeVgv|8DjW_-Ai3x#%nWRGe$-nz||L%!^@613JPlL-G@d^>; z+%V)vg~GXWZ+_NFmvEE=4oBc@x&O@9zIL|%V=G-|d^~gN6i+2pRVB(N5~og8*D!Y0 zs-Lyeb!;qVhuORZgv@5!d~knplh~d-&X%yol(IG-#+gZI0DCRn$@I zoubgJwKh`UjV9vj)6?m+cVx^+)YH>bLjg&W0z>Hb_5%7^AyYYci7 zw8o%UZnj3dWS84G>K-@rcKg^+?kC*LFbX2SsQSVSFQ`RqRkW~xQXCZDwB&N9PTklm za;<{&80XIqIT;Fd$S6)u7O!TrS92&p4idm%s|$L)mNzVZe>9425L+2{VV{R&6Jyn6 zl27N(OxPe$gFtF6k40rVm&y}e$4;wbfasFk?xB{QRDKzqvKEV#!_6g78|s)#K?Z;O zexhR~MH2UJnoT_6`CP7LAz#rWE-+!cSW;jpWf=yI3d*t)=A$U2M!L&paatFavUm#J zIcy=>rw^?T3#pWt2apPxk)#>uQp&Lyv$J2$w~V-k+-|93+Qp-2C|kW$ynNn$WWnV= zH&e{ljtsl3^|}?wD6$+xVUSI36@}YHAtQob!CVdVto=R%ef~nHAAz%o#xlint=dxT z_HtzgxAZVWat7(3RO4i)J1o0TW0QK?En#zeMKfVV>*?!p*~~)33aYoBS4JT{D3bH% z=fZqpH(QTzqTL&opFBqYEIfXy(fjw0d-C!iAtOa_*u`81*=BOhA@t5WQDG2GHz?#b z-}`U>?Z3UZnZqjzsYJL6QRdyOb#ASdh%$n98#a+L+EH^k8DXa!VoT_XKVYFnx%xu< zN3%}q!<_@)aLWCq0?)s9dviW9E`-Ojj;K~jqQpTl|R+h z4ZXp>fH~q)y#4)|x8Htyy{wEp+ZQ?TL4qs^To`7RKEf=}@87@M?2uy$cjdVh?k2ql zwP9MiR}=>arJ}gz>85bv#Dq9DX4E-wWL(`iI2ao%ErDxWDrpw0Ro9LY7-*diHNu8G~6{QU@DbNRaBpkL=X4lU^n-+*4IDFc(XqqJJ{db z+1glN-%pQvy}n>i@4z5JlzfI&=L_EcfX#8Z6J1@|*-h;xOIwOMbaujH6F$q-v!8dk zJ+8sA@$rclUsv+^bZTRLb#>|8pDB~iWdl0c;Tokoaq05;fW2BRHi+~jq=osVr7MFG z0r|Z4%jV_UOK!{K)r=`D2sXEW0Hf{eUth{b1dR4an=Nj;2Wj=Qb@~NLU-+q^yZl%# zH&%Mb`#s;|d8Z`Y9r`Kl@AwzMZ2kLE*}2#nD$rfA7K|Y_|wYWox#DK`^rxbvbX-y5q5GMZ@Ddtix$}H zI;nHj^Gek36Qk(lv#gshZf#xstRZhw z)s+?U-|00#If4B84fy4^G_jk73Sd!YtIOu``PSDr*S0^p{b2LSmM(C0(2fQtcqTw$ zCq0V33-)EZ0!v%7&Fhj$2D_TP5H{I7-q8Nd$B$OC^B|~U`<>-1v5n!KF&oK3C8=Gg z9!3+`D3_|agY9jf&(4PiFP;xLO}wEv-3TgQ+JddjX0C36to_WO1&!RVx_maNCi~m~ zyxR&pTbb>&1a1fc>lR1D_UR#;phsb&eoz%`gGVy@R|Z=girYnaDssHQ2z@JX)a6Ma zkckPhM%>ubyXhL8tp=V}l-z?vC)@kC-s+%JI1P#~bf$KDO`$vf}7^LX#oSNGO% zv6_DM)wE`5!s1Ofg{yIVE#ka560*R``{G46$wkppZujx-)-gzk)Y7BHN4sV=*BH`qx>%Ufcx)51bISBIsUI91 zEH8)Q1CGV{9yJC8{I04#c;GoT<#(&qS1(noK40~gDBjW}4DeT=RSSbOed(&t=X>d; zdi~O+Fn{S%z5ZEf^Uubx``c0}_m2c_3T!ov{)gJ-3+4Y1Rqh6U1TvrZ5@*XheSJIb zmz4*1gqPj5i;4F%DvDu>BC$_QGf`ym*jL0)GHV7~U*GP2wrXOyzaoNy3v(m8v(?wH zHqszFyW87)_((x24Zt5^2&Mg+6^Oq?JXYkHdfrbOhDLcKf}Vc!RC#xIWXLJxAu&Hp zQ<^@+MV6|;UZ7bdCy+NjyWI!Lt3%di$MJm>Eb36eT&>k@c86GJ7{s*R^rEL)BwmyN zr;(54JU)yulY4b_gu&<*FwDq5)5ve0XM0yR1H|~)zGpcont#2S{PR!Noa)-Kt!^)q z$?W{Yr-Olwjlkg2Kiq*##`S~F#Z`}IbLs*qO}4 zL?V$YNdqlm$-c%~v>$XJ^B1UtDwsf({eaB$yLTo@SXWF7i@aQW9*JZdU!7 z>h)6T%$dgnx0)_#en}&LDop;^yyehW-LP05KCJ0uXYx!>{Th-We?3h8@_c8ve~fL$ z4DqaO_YKFx^w1YRk^l^@7xP0KqDuN>X3~7iKFH>BM=s=v55rD-x^0Bd4y0-ROn`<86t&kmCdD_T>aOE4cMYWQU%_nKk z-d@kKV-cPw^?F#nu}^|nD1u}kLV$rRBfJSL3T`O%+*ZP@gff)bXgTOkPtT6lqnE0p z-3?j1+b&j1x<2d>bxdzvbPNx_c_jB`9{+rh7%4SfYGFx|y5W9SU_^^-$z8`JSWfG2 z`W91(I2bzclF$nFxa!*=@aR^};}~+w45^<3m|_?x{mH?Qxr0=8ASc(e5+iYKIPUpw zB}^6~`~q1ZGXKbSL%RL``|>3-F<&Axt$y*NUwQ|hl^A)~*z4U3 z9QJO@W=J^A_}6-W6z@+Co|GVU(%1?N46t-q3GfW%jsw7}rPan_>3#CS+i$C#L@(86 zj-~51@~ljW)rTvhI%40B|6q7cq=ePvNCP*;C>eH2iB|An%P}S<@Esxp#un5d<9QUT zS<&*39%=6MsZ$d{^lWeEb9%Nk%VL8`xepU^mmNsb-)SpI5nOBuQ+yE%x+JO-(X72-lRvE<&Zcp9bHT z*&nsQ8;NBf-@E9}+;Q6;)afCT|V%$&^BlYOf zxasuiiPL5RA|-}RC?b!RRif}+U9;YW5>5}TDYGv`_MxU#k~y;QBKEMsdcGc%b^vJ9Io@#0|1w$bGj1ln$P z7VtLbbXAfQqa?kw#Jm?yBrDZ;*e+Z80GW(2jBPD~S>zdu3R7ri&I;%+LuW!Q5#|quhYz$C;`^v1#)45q#q5sDCM!SNuIOv7r?bCEHA32?g}H|3lEID~d(Icgdj z84CG4zTR`i>ts&(<&Bk<#*4q~m%ZrbB*m-<95IuD__PP8;(~X&S*i)N+yI+CgwmFj zqBV=G7Tgfq-v!Phn@n4Q8#hc+pm4iD%lf>aPff)ZY`UU&$p@ixx#S1Rm%gNg1>H=N z$*`zDeym#ukNs#eyNA(!NIrJcgf>-r7Y58_0I2)>?V}eEa8DNdF-7MfpLui`A+?Ak zHLWzIu!(Jd_ld(n3XzuO>6rB^U%CFmg)5`zAdvi|Y4j^!`HFRKdFcth;U2B-F$*Tm zWwqAt?lCKP>C0c!Z#4rG-ey`Ix`T{*+;BfI;zu)Grr!xmn-+z>7C=HMO)a5UH`3J9knkm4T z6OiWqQ|D)1xOR<`jA9!6+sc!>_g&=EOazYo6k_5Ln|Ha~AL5Jg_(AkAx(MM5_dzdg zKBp1J=56|mmIqHVswhf|%|4*Bt=DgPl0nLl&E0#@p2a;KY&H}>m!7v5fb@m!N8Z_< zEHB$^%i=`(?QbO}#Ol=cI~t`l{3&|^cLzsnfBMwE`;V4}f}5Mcq2+(H3z^JrfB&xg zhg^@>yxz6Pt{-wY)9U7o2}>hz%%e2PKPOk;YjK?#<2s*VQY;UBkK%{^MVXQo@7XMa zx8o7g{gg~3AWUdVV#s$jy0*Y-V$(BOu2)V%ARJa+qS*N~7c6lTLQ|OVBSAB9yX8tO z0Zz1BWMek|fNkz{h`Sh%5g~k7Xv86nh+wGoU@yM4w6(ppy`9NGO93w|PM5>$CEJ4| z+pxWtRi#(l*hBz`D&>V%SAcT3ZcVnYNy*nQH6dT_25A^m7 z;uFR&g@b)X^1*&P1!ApF-EY9~;vVD_GvtS{#f<=hg zQw#O<5@_+G4I4jyzEl7TO6NpT$RQLfRB$I#hU8_+tZ|1_DoJj33581IAPLk|1)z2+ z$|jjqD%onSVMO}s>F?ga6kFIhsHou3u_z^p#XpG^;?fr!^869kfQa?7HGD2e{d8lGUbUjl)Fh5PKFnG~CO6^R*nrw<*zTsSd@C9 z<#99;3-=VW+$d*3d!jqhh4@$`;zl;zv z?XsHhJ;*jK5{9itK5zJ-BlViN-Hkx6*F@Q&4ba@A*nW-&P9{_>IvL2^7qH>Z+HU!S7)j4i{+9(xgE`+2MgCcMRWc+MJ1}=3 z;AMuDRtZVVUO%(+8nV$8%*pU;{cxS>st?eTW^`=@gNq|v+wZfhv&$!~tq_$b&1d0$ zbMlt#-6ZQ?@$+s zc<^w)Tw`XtRUR@lM?){>wwqo!-I(+J4o6tIa%E>FY9NGZ4Q|0IIMrf$%Ee_sOb&>t zZ#Wto8}s#g0#5jIh2X`la!7}P8hTN`kizyCyQy5*^5B6<;#uJ(nWx7+gGk7f%Y$Gl zMb|chK2pl>FM~WK3xy0UV{(S*f$HB`E$p=%nL&SAZd8qkn-fg|=6}DixX842RYqaM z)?2#`H&(Av7##HALo`V9oQ?SA<^dau4Z@tz zIZ2A?oQV_HK5~fb?WS(flxLY)-1Hb4%LzqA6V`AIVFm;G++aGnUi_i)r^AwZ(DG2QZ`gp>Q6nLIM z{=-Nu+TDJR(b#o{GGsLN2pc04ibx1Qm|3%GZ}OXTprN%jX8&K?AJ94LR$-9E6oimf z>>NmH_u>6iJ7iO-t@l5~h27;V=k=L;*fRf#0~+F?M<2UKo0|fdsyu4 zW6Jk8&qYoC;-2iy8>K=a1sYr>s>f#-)Ziox8LQRl^GcGDN+x5;T+U)iX>ZyjWFcUs z!qbqh)Zvr2S_efEZJ-KbEXHImEotZPMd^PBA>^e_>CsT}WZfKu9Mf;cs_)0_@|j60 zVMZ_^a#U!_~JZ6Q_fV38i#8It= zI<=yd`h6CWVVY|^rF<2lm>LI*b_`5T!~lTY1%D-;K2yVQ1S!ueShLL%1?9)@VERzm zLZwoVNR$|qP=2nfrhkJ_^4FPnwoXk2Ns1m;Brg*&gXT$Y2p?TiEp{Lwh=`3kVGXQE z2BwM%?;{SQu)S&6jaC3}m|c8=3+=z7{-4y_^Vd4VyX%bx z;ZY!-vcd_}D5VmKeTXh{W!_>d*-Mp@4h*>=iYA-2(I|b+M*6g|(wdL25=vfV^Rd%% zQYKS{mz&J~J_>U8FQ^7pXW1GU`S!f&W&kkE~*WNHM z1CEXj;*R`m@BPWPef_oPmjP>ZDnqQjY=N}8T-Feik6HO_+KOO76a^W7ZFZ~n@j?nH zb5PKgPr=zsyTL$<5dV{tb8SQD9d5<;nr%d$q0m{kNt5T2ciNZ2By77A|w)>mu*&6G~N zR2hNixg&DZs>h!ol>9M5h|;MCnnp33&`5-faHV275}?G!EE`CMSvEAUZ6wRCKVBz= zBXvsZk}O6PQI_h2Hc*jR>nY^wRxfU$;|qC^4|6`gUzdak=B!!!)RqZ;QpuYYR$kA8Cdn|!@soLMk^ zdi(Z#V*7?*WI!F>H~xp)u$)a+5E`7#R(^gn^?Xt@m9c<^xwtOOAKR5o3=-1AjsoCF zqsENGRLm}wFb`7&A_pr6+Mls+{2B|SgVs(E}piRag*EUQ*Bl&oX2P#YHq66YLyzLp-^4xro!ji2pI6(VTE}?agyTB z)|-S6bGgS)-}odRWmW|{oo4(QwRrtuD@S-_q}XgQpq1s%!Abl8^8F!#&RyH6py zv!6jcXFnG`{85zU#|R-*6oDc(V=@^%K9T5&t(~1BWMC01C06u-MPN>53LJB!TW8kE z<|^SVtoJh;@d)3jBR6%sNX)pU5{8kcke-eRA`whNDpwa&Ur$fKrYOzAH46zKb~+$9MZ2L2>%@%#oX-kDUAP@$^6 zL_+?Iys_bMu&DhRIS|<0Wl=lE=vkk^hBP<>|HKUk`$yC;DTGD;4*S=ABG@db3%T}6 zozz~@Oj}zHM+G#k!2Gq`yh+~rjzH*lG*ck3v(o^2lhPBGkxJ`LVzbSeS}(FBG^O<- zxp{NW)OwGl@W0^Q(~RabYTSPJ$A28c)HxF2zVwyXu9JvnKT4=m4^un2xjAy(_!GkH zciwt?RR=+_9vMaO$g+oh4!aYH!8oLdNYvCjWtFpA z@I-AbXCLj9BF@{lZ@%|osnQTYK$NR5UY?oxX1CovS0u2z=Rmu(ZktWQVKvsM&o{?m zW2Vu=!@1V)0-=b6%#*;}Ji*;AITnQyg4pJ$$)pj}+_9983h=Vi#aHk{$-Us8p_uq` zG#Uu7sPT!x(B7W`Um1o}VtpNOsnRp@)EV|xe{9?L7uZ{Btu{T4WA}QOmn|0UOSL)f zTl}A_e@Xii|C{Q+ruMhFfB5DX8-KL%N9okmSIK|FzrToo6;d%ghKHY=6a?+#NMUNz zJ3a!MZDU-x-D#Dv_WW~y!R!6P`02B!U-kK3WuL)EkAj-UGq(CQIV&%n|9CO@+hwOHcN;wotCKV-@YuD^*=L}|E(EV^R z6k60ctb}0>M0Ni8`LmV{F}1cB7DUfZy!TD=9BcGY5X9ByiUa&mdujV z8$w}Eq|Qp7O2iIYE>Qg*7Zy2Xa*_y~A%r|((GwI5PSBjJ%DzCb7ilAhoxSJ*o_q3y zY{KhKr3lugoQmyjwp0Id$NN4jdymf^7+^dIJW{L&ePUftLydHJxV?`on^m#VLXn3> z0JDbk^9Fb)-sU8Cdict%&f9uKrQzF=?fUbCLI{-Iu< zMIt#c2yw!3nu!vy4T8zx@n~J`K1TqVKxV&WZH{zsW5L0e6^tx3F>C^r+%q$7ayu>! zb5DQq7x`gxmLa)`4VxDGocdrZU4@lGEsev7PqZbq2f|XoULfXlG%Q5ZW>V0c4X-zs zGnd!P=3LI}Z8%OlG-okcuP2KZk~6t@-et;RcsMKZnAubn-D1^bj>RkKt+YnExDDBS zbJKA)EnNn)A&!qoPxaEW_Ggauq0AD;=Efwfp^~iK@j2Hf0X&bu)RGiZaseQy~jy&0bO4pDlB`{Ikjf;^aHEh?=jVCC+7^+n@)EYwG))QUTjiw z1C#9W+=*4gXc%nOXdJB?m)cfE0k_xJnm>oJMB2ePeG4nrc79GcNXB;)VIi>_PaZ^+ zB+7|`ZYAdfj~?BD@`Ro52Ds^yXA3Tbq+p;o?CK2!C8)}}s?o8yXyuzu#130C%jb1F z^3BapGxxb5MWK2JJEf8Z%HV{nQhHhyd(&nwZCKG5bX2&LZAdHiEr-oh8&_;Wjx3xn2`PbpcTW} zN{i5{6{u!68G4m7nR}VujWa|c;^AepYVQkr>~1$XZj@7NPoCa}y69ev`p=$ArSmmW zbue^!@2SDQzO^ip%hnZGfhcv&KGhe1{HU~t=MN1k@S3+)sx@S{Yv_4xCbefL0Sjkn zWD-;K#HDlz8J+egKK5JDOxJAGT*Pl(na%!ANs(;#aP(65{j$9g1A84GF9W7QOremGFpS{x`@C5o(JIgyM zZJw(Van4j&y|r36>lgjZNvnyJAQ2(fxz4T(k&v+#7ini)q`l2WZf+iKAnY9;?y%3p z%}uH~IAU-nhd#ER2hR@m7LBJ}!v zJ?zsrFksXRX@pF^Sj=bGRiSQZD)(R^&vAlGDa?^M>zVTrC&yz~8;kDug!~Q@XAo9a z!$_nM42#8Jp9$!|q@i;N!&XJH46~~tDT}hYUBO_bl!+BmhtUt;zkNI6EbTnnK4{o% z3lF!;4NDzOq&?4e8NFlqwYH^uy#d(yq8eUo(mj!}fsh~E=W62q3^&hN@#>-Q!a&YTE~*(|kKsP@f| z|LVpXUnm$ho56lP>BA`h)I3Yizr@LXU}m-q(njJ@GRNj}w;z~RSzCW$bM)xjc~kz| z&g%IupRa0v;Thh1V7tSccTQde50Ok~5*7`-qcG&zTd8SsK3_1oTuMQU@UgtbJ9qSk zgT3LlJ6w=_|0+70pEzHZfPOOa%gh%?1#JUm?Vwm-B8V3Ko)^Va?S{+XHn{oA+UtwXqtAEJRd#BM7`B25PZFv3iL zeefN=DXo3<(Hhdiw?OpG6HmI`3(@F;yP3s2eAEF*H5|jYqcq(ex>ow&gN4G?tBUEg z7AEE}Q6UV*(%0DDrgTRO^Ln9B4O8qJj&pFd<_)0n4vk1*BF%T5%6RnbOvhi6qUglQ z#6@}{L5tg)n_Dr?o=Dg=nZh_H%adwE!LHm*coU^fpt#RuDnkSqi`A*BjzjN`6Y>K@ zRp(}zi=a!Fv)PDrAK`(`8s?+X|NNh|E(G4Vy0M{}D-7zD2a+ib*`OerL(tc_V3)}` zk%qmnupnt~m<568Wfn>xk~h{%9GGJmz~rSqun}u(+Bh4GD^2S{r>)U&;8Q8AY=FVo z$Oi)XHC(J^1A#1(QY6tN6RxJ~`G^xpnHnH-=g<3u;x0faKHtZzHn9&N6~qC=#!2}D zyaKxh5Q1)ZkbSzm%gb$goMrSl+os34+&k|8&~)$KgG^ZEMZ>668^m_@{P~ET;~^9| z+}jNXJQf)o{Wp8v?!?*(LcCImv(MFp+r3e+_aQiqu*Gn)D|=yMX^C{m>BIMKf;QVho3mvrwlZ5;**ev0`sT6CB(u{yG4l>>mpli|#uH;8#bmbc-W>?XKG$ripyQ$+}P?_MM zBSZjs92%-2JbrAqg9GTcyYEQsMn=MPWMt0T60tEPEQ?2yJBDq&e}B#jA)7%dnrfr3 z@8IBnLt5wBGo_Q(ulY4$?$`Vp2;aiO*RQ?y>en?l3=m7X{QA1x&SJIEsFun{Y5)Dd zALjo4-zQ%*{+RJ~?(JV{O5fZNJl754a;>fP^hBeiRwEp*wXC2BMLd=c9_9Ae=}*1J zWPM@!+E3w|=B?Ih)k2}2Dzg;xrmS%XQpa{~qa7QCR@>GpzwoV}uVk)V$#i6_ z&xma8tp?TW*IxcYeROegRI@XYH@KbV-~Rrik<`?NV z0%x%f{8{yTt~BDIb7E-3zMen!mXCPU+p&N9cG&#Rzm08-jBK!|c{@X>P^{IQ&XYsQ z`D53^=GT7I;kb}ov|?p`$*RrG4xx%@EW@4>&73Kf1%li zx;&pGJc!pEi?y{y*-!;7)*8yrcT%Ws$UhREPnYXzX<%*9Q}zef04XF{)XnIgbk%N z45cWB5{49wVkl|dqe2!4|L!~QX0z>4QEZM1*&wx7UwifP-c9x#lPW2GUYDb=o5fSQPrQS+8lL0H2L`q@=ha|g(K@w7wx+C$h2T|U zwH|wvXY`O7Mi@+87@za%!1A)K)<_KW#twTmjdI*KRq_L6UhA?*XwSse z)i7OMowv67xkLOqGxA)^HL8_1m(dL@qX$?9ENb3XYoT&Q=QB%&=56Ki_P8D^*!RQgnlMYZ&CPlH7AK6RH^+Qqo9R)3+wx(F zljX3WCSuv#RvT6_{tw)-j&0C{6Z(B3?8Sd%)aq8_Ai2u%8??kQ}e~LsjcaE`7 z`Oex?V(e47lgY39bzzFgz4rR`*GPoC!Jao5^F%s}4#$|MHt!T66p@fulV?s(Cu4UX zZyg-&uid|S_tE-JG@UDE4_6i*FYg|fnT_g$<-=U11ZC##@}v8YcjD>9;nv#I+c(~S z|EBh8i-yNy$xMtL*Pcm1znMrLUqja!Hw3t1_p_TJH^k(mwG4tCA7q}8$kxy?RPldkM!n%AqiUfPM3J96hcgd!4h?acX1 zN?+SfWb*N~#Rrd`Z0sE5D)kb8EE~J=bioi5T1Xtk;qHi-9WJNpc(8Ea;a)Oo#cV29 zRcs?>K`&$u_Rx+s&d^hbduz*2kZUQI*j`&%xPR-`?aT%38f&#KwQ%=!@|o*=&7fR! zp2Pjnh0`PbOm{reRv!EC#nZm_9x0Wv`wRAfE?iq%>ivQ5pMXEm@u2{Oi5>_qO;(## zfTSGFRw|V%rF85NB1gEo+1h-1XJ=w~bmzgs%Erd##^zo!GXhJrH1@)|g3dALgv_qM zWU~1Kez!N!+uz^YHvl!lHLTIh?(X!kAF2`W;3-_68umT+`s}G8zrV>ZFfYq+I?VHY zVdQWNt{!&cWqc{MuS>Wt9&WSiM3K2iIN4K9o8!Tg2lp11cMcMTaP=P0S=o*CK6=Jn?r@gqk=9$!4T_O-9s{r-{Du)YJWxVF2$ zJ$C)&7hZnll@~8xnz?l8+{D=UTug-Jzs7pR`8@ltQU@3K8Regd3Z~!5a%dNS%T$lp{FMnJKTC2IHMV=`CL|#WMVWSUX&8aEY=S;clWlo_Y*~GVnAW1T5kwau~62_DNquqk~a_h zv3M+=f{9B8Xu}dTSJ|q>+$lh^!cY!WSL07Iffm41p>irMX!|0qoY=knushZ zSg$3K$-(`24SO8qjYmU*P=dUu1gtfRktihW&9&qvL>Kfde zZ$krha0ovcP*fTE;mV55CiA3GuN4!~DD+a>8|yH}e!770@b1s-pBkIk-_l+!$99(5 z7^Ds!X{C8xuC}JfXs@FUTk1fVtRY-aH4#;vHTZY5ZL?-Wm&EvQV84wLF4k?HxBq zv|K*9eqAW{1)Vn4?jJopKIn5=MGos#pufkbN*wsSGO@auUbX~uMn*TeY__GPI2y$2 zQ1omvldsJVi*|1i=H8VWRV>b)!O=daNmNv~A5{GO*~zo%Z0amH4J_?$y# z^;+YlcNJZZwFO*q=m9&+ghlUesiYKzjugv<vlkLcG0hB#eZ63kYBa^}o zJI0Z$Zs({CB)i9})xNP;baCKSJGG%bRLV%3R_>nmd+Ih=jas3IKXAcK*yjkHunXBx74o){@oimc!LM znvBLXd!tTMqb!eIF*9Z&Qz?5;phkM<>60f30CoGgMzLf_oJ(@}or1wDp|dlmLiUBl z@BI8P-N}~1G-wO^9_-|&LbMoPe(=DM?L#lVaQSr5-q_P#&Zc40luE3uF$Ka#qNEeE zD=<8|aO?dK>a|8gy7A=kZvOE*Z&mE4&zu{qZ^dA{yp`op0*8RSMVNtFETjf{P^;;c zie9f*i`k#}zF~`O@p{5EQw{qro*r9?72%iR(u}!q2><^dt-v3orz5dzOJuCq;F#^& z>mPlT%LRk4zm6uV5#i5S7t$pv^sTov>ahH2()LpG7xCs_W^|)2!*S=Mcu@iq z;Va6_PJeJ_5P!J}Kv+B5eh;Z-)^Hrxdb*fmPRW-(TEX8^rD(+)eY|*x`N1H?0S239 z#~^N343ooZ)QP0jbNe3lQmOG)g8e3KIw3r$N@ieEOy%U(fp$#? ziJUp_rb*UTIp~6u(MPwI(RcA;L$Rrr4{k&aB{V)UIXTjAQ7|xjr-B$X7@kq&oundj zX5`ehYhEvq6I0i(Uq93D7HVK9O4$ll=xWvAnbmT&n!vcO5GU z@e!wyK_(f)IXZ3_yrKOC&(pm!kwYkANFtTJr%#DN7=@r=vl};UBnyuoi7+wdU#{1Y zQqx^y(>V+>fQlO#2zIF7?E(>+ldT5F64{m2Y|Rdwti6_9TghhYHRk9MPclc3C}}dF*;Zx0eufgBlKp?x-hs6@@e{ z%3EG}`g%{6zLR>h2EE;7=LHJASe-jSL+}UuiIQt(RMnyGqS>3hX^DupkQt zmEcKB_v)JSsIWD?UCxddZbU--<>jQ|%Qs1P(;GglU zAxA!1;z*3rSfNxZ6fKq_i+F_6Z{o2(LrBMu;^bhBj91 z9%lW`B53@fT|ESD?*zsm0j*@tt<9hC1Hgo}0825UEZ*tHCHfBz{44^O2>>^cwT=oA+JLB^J`!67V9rp2|M$+e-!Vg9&92L>*QZBUOwE@ zC`F&%_(dGb@QXK|MoW#xJ#fCj<*hwkymwDKWsr>xT?b7zAb$YKEEJel$)KP>)Tosq zvMARKSW+1^ElhqyBY!hY`}@N^9+H34Z1qd_w%6vCu1OWbHjTNoc))kZ7^f-JZH zYFM3FoC{OPHF-e*So7%Wjcz|WnmRG@^rO#rOSkkGZF`ui`87B!(TB zR0W0*Uw!y4%b0$WR6C*T0S+K+9hjKl7P+2jbGf%{n%3qlNRAw*$IgVa8i$7#pK8QP zDpgByJcC4u&son(*_u;6A;S&ZH_7Jd#?z;b;=-;{Qg#-!`DT%O%KPU1Qje;I?Uc~N zyw6uKd1=8^Fg$pI6+2sZO3qqVZui1#XxZz7#Oon#;?fQ+lHhT`;W7fJ6ns~Z9;4W@EQ+?({gmaR!9ye)uyX*??MkdpTWhN%X>ak3$z9%FE!5!1@ z#FUl8N_IuxUWt(ySs`29RzG|q>2gPiS>u?ip*Jb4^bzN0c||FgBc!Hr=r!C&{~@06 zB0Sii%k^_AgnlYVtC@Ime9%ra%ub5hhDPIu6{^h%l0mp9hRqnfVa5mE(^V9B!ek%>_G0COi6aBr;`6Dlz zzhMygg#kzMPDbr#K5A4_*v2jZkXL*9cH*2pZNKQqxU|18khz<3u-j@M9_wp8W>32= zrthWg&Wz)NHaI}Ic4%(2g|=hS<1kQ#)uZTeh&q*^X)%RHMnWcbts9cT;y~-?YMR|M z7gzU6cn0^6o@uq=ZzdFxkW0Z-D#-DY<>9SG2yT6o;8y%jhYeN6vw9_aI6OJ1=uz-E zk2iLcd2nf|Tuqzva->|yt-}q`(`1cz_yazt!)4|oo>~JtF?K#&pM@(VlZhli2aWkl zHASgqa(eaR#bHzV-~oKv-P+;A26Jje1x`}c`w!Q10`o3@woho19j;zx*~qFbbP7#= zs?TL6>7CWhWWLgfc#LYX5L-s6qQwTR68n4H4pp2#mW8kr493iL-fXV%W|dXPhC!0a zPEYx{>JHx9sdBE#scfdoX;wC0SR|Aq4I|ga&rK&{xyGDre?KK! zeUq$}DMn00F$55n{e6h(TrfROrFwe6pe?bo*BF+4ruOLed+&YtBwjG!Q#lsRfS4ml z7R)Ztc{oaAR>xD9E?yWmSF@`NlHDbiH3*Hw+};NB61NH2s~#BuW0n;y7F{R2#cL7- zpHC31-u}}N8%+-M1)uSe{6fb^GDb0fuy+aH2otBLd!G*)Yht-3wfS5 zBzA~r*)~fZjyL#hHcgJtLH)Iakh2bU3fk!Kkg86NjUx=WKxb0%vooV|Et5omA5~R7 z%;pa_DOFX?e!oH_N%625fFVl^Ed-fR)7jgEgBf2}+05|f?tbt=o!r*WuCFsQnC)HY zM<7FHm6F-%QcpI^yeV{Q`pm_dS1tqs;{&~umzn8|X6d(*S~-*4-^Wm>g;Ae~zr3@s za1X7voG4Y$&Xn%&7o7kJhDrN;$g->7~;)l`enm*`XzzP%*-8e@7CipL^KQpF&bF2 z6^mkhp}ugJ<3oFa-4@FHcjMXLgY^6DCX3P_<>;O#U?$9_zrhnZ5Q;~O#Hrd%VR!o{ zy)F>i`DyO5-)nb(f+LF9aYG_|m|(LeQT6+SUMrJ5!n#am$55^99)iQh^sK=dn^Lb6 z(H0m5S|T7hBuV6re024}14?UIqru7c=1+FXfpv}6vz?!`%VIgfjAG)3L7_K*8mJd+ z28LNf6s2-}3zR2e7+kel2@2IStnyxrHE%-UQ#S`(vh9ATG#8J_=Dt&tHy z3^O~CFfrx^K&2~0!~pFH^mqu9+$4#EdG4zpY(=*Z>hJ|pNaiDizQI{t*0BFUjKE3! zITw5MeuB6!oIB$o@rMtzH<=jFXndou-e`7tDwC2Oy{KWYV+&Q=PL%9+M-dWp=CxX2 zUaX-9!(WTg@@1Vk#38#wR+3*|Tg?#WoS(U_U1N;G@Nl~pQ*G>@+h!w@KZxMYW{G~V zzaQNPjGTW6w}>F9LYN1Nz!j#A+MN68S{#NqK>imdh9DyC86LKRT1ZzAE@#sb3G3<2 zn>NP@T&7a&+XkO8!NBnUAdLUqy>s_8r55vJhCilL8aab*33Jom?wm(t?LGq{%q%7{)t6%-^%E=c$=_)q=PU*WQeRjGb{psas3xz9jI~Jq(6+a$Os&Xs+l{PjKy-< zd)Z>iXxt@oD~w~v2=GGPxKq`#v}Ca^FIz3;vPJtQTdh^=7r*8yo*qdJo6Wl|6 zlt0||uQ0B%V6~~%(HAaVIptUNs)^n4ow|JGm6?!Q+j+F`aI?y`Xf(`RW0;N1!gn(h zXGyiv(CiN$t!!p}=Pz8uidf!Wc&LrnYs`C$D3?}m-T3z798@Hp{(z}gS-*Yz?s{4F zOuhKh%jW{JHqPYF4TBQuoce~MMNTMJ?ogfJ!^K4>>7LXE)SksxTtOh|d zQh>lY-}G`s(OI;ry`gmWoy>NRqeN$rBFw~?({z_X!L$fzc&%of%r zR`FUDjiBV>JD|7g@p9PvbU&U!=IJ;b9g}i=9rt(Qx$wx-z2p0*dOb{3Vew%5$JsqW z#`k;d90wJKYHBc*gwqa{9H?gV5EEB`F_mEwtkU#Z4EVyHCNo@|@SU4CPuS^@v^Gb)h+R8>(0nT>vqHR_PY`%yj#6b>%x9CnYi}Xy0U1(1ePgo(DSWZ*;CYp?7vvZ~zVWmVF z_dwE`s4;T+^2v9hXWZP}ZREZET38kyKU{D~dnwJ7DV4^?22JP8JGiZ%I(shRzUtCW z)J5i{58nNNc?;B@#UYz&4gHntuUxz+idq*Ex%+L0!?VA=Gw3TC8mWb$-8kh4RnnR% z7Tfg%Lr)qbb!Mj{VFRB0FyTHv;Smx2VmX`s*FWjN(f9VB{MVUtnw6eCdw6*69DVR0 z5P+q&)kvxr?iJj`UATKegU~su?EBGwv5j(Ai^W8u2`O~B%w|Kgn#RxFeq1mLkMEuxR~jcU!2=$L&1x|VGA(2V zCIWh97bc95>6%O%dz@<9da4bKpPo8>dVGBB)Oq-0S4(xlWRZA*RC4f4Je6LxYj#@K zL4Rt3ZD71XL`4Z(IgzX852Fq%SB+At4RDo0D!O|6!|y)W+)TjiC@;AO&R)23=9J6I zOMO%JXWBc6N}3bzzwg=E@!X8ZZ)zO3GO6**EKidq(h})QaQ*c!5 zH#R-yvu)cRJrGUO17|{Z1$N`a&E``x!}<|7j!1}t1s-nPRZLo*S%yUD(zvE9T)(a; z3*@DjG=2}{B0?|R)joczAF>o7ZR{=df+;6UWLzx2J^em;UkvS$3*>HhKI1l9p)fuZ zwK0cUi3GL)OLNKx1_;;(?--k!eET+~7cY*E%{@P#gt>1=-4O#(GESC6<@&-)O?c8;z?pz>YOuDe?0oiT;a~br5wV@XosWlc* z?eg?=`8v@A$9Jz>{E&fK4>V`qn(@wjwWTgo0jZb6x(;h%{0gsrUESHEE4M6^~;jmTm|)s_(p0 z)uid#O|N%r>m-d$Aq_KPw+|3HzTBKHvjP^nwY9lf@$LmS6ma9Em&ljCbTVI;V}%}q zE0c^HhQ0harAfuwYsys^bWwm?cHe(h8UMb)I*l`Ge-i6Snh zZ*HNeC*LqFn1bA91u1e@oRdmglk~69eg7*K+|mDQ@~v&RcGBC_Qzn{cl61|)t;Aw0 z+(a-q0gBC}2tv~>zsWlRL9ZA4CGMohsByo4oIumNJZF0HWMH5?F!1Dwp(#u~$L585 z&gAt*qm5|P>owZ)cVFjZJ|~X}Es7)Ot*iHlxN1E&V!bbk4opzo&MjDmriaAo+`_tb zsF~*n$n!(SyGVStM1aVnrEJ}1tyZ#}V3i7mvc+61=aqUnZ!nQo!i$Re765$qy8Cs|sznVo@yRe9>H1l}1jNZS_)4wVd8il}bL#n^+-;Y~%Ae3CWlWEz9LRD2=KV zkg3$jRzxc(R-V{2e@*8J;1m!8m_=g9R#lLy1}{tDYi5%Q>MJsrSiHpq08qmazzjmV z%S&}$0=HKyl_*!w*CmOsS4#zhl42bYB@x#1HA1CIg~^g@+BFqP*90P{%+H%>YH+m% zry@mcc7=M?tWtxR>mtRwirFI64H+5bi&c)6i-j5|OPpLa!aYUgP~#cr*UFX{f>ES__dceMs1Kv;k2PdRm%u`3xCj_%;{G=3UPbUR>a3TeEBtJ`lDMX477rK-i`b)>UZBHA43SZU5`S9o5BKuPC$#ctOuKv!5)p41C@n@yRs7V6mA z$<0_V6xvj1vUOsgMP<$kJBPTbkZ2IJ4_^naK-KqjTd`DcH0q_I%}QufJKuiNT7xCF z+1#|=k!5PFa~7wCQ)N_MmesBk`DX=Dv6-Z>In?XGwBs1kB#foM$Y}v6jJ-e>`FsrC zisnJUUPOY?asU7$YGCt`FO&%<2&7TdL4d4sLkrZZwGy7J*Cm$=sBj-r@H!kavm1M! z_mh1$^M0bnPFVa~v7jYSt{F%QNPWVgCM_-H^MH7^-?-E{ zjf+$5H9*igMsqovRnMf@zOmNO{8q_GW`IURM_Ft}gA}U<0j;!ZLOr@C@L@+8KbHAQ z$rWVhd^;sx^Y3T!4ktV7LJ_JJi6_vNRr0a@{gd`XRv&`jx|K-6sYNQA&w&lDaGKX8 zp?$duF)6iT3O^kjs8+0CUZ%Fk#@>$h_Ie?GVjE0>YF@no9-5A)JQi~ zXlg z#=^oz-i&COni{m=E5jaP%twT#>)tR(UBtw&VJ&3T++VO$bRgG08;XGfwf`R&XuC!L z004La49P=a9#9Yj;F3JM z6;K#LUsp*GWl-NXLKEA}k7$7&wiia&F_>m&V7Xn1wRSyr*j>11AK-<3g?IJ?3hgia z107{;c~-VnS}Za&6FA9E=Qnow|#k}$Dp3+ zndet}1?i36gZiqkHd2u`N>ToeQLIf;lFd*Cf&m5y2FeEh*Gv{idjmlbZLyh|nXf(@ zLU43nI1b}yHZzH(_8Y^hdTNK>Qt1{im>}sGx`rMoRhk{oPD|O@?6L}_R9?xhOUyEQ z{%6YUCjE!$SG+j(5|%BzRE(#5S_BOz@q`$Xzeg=9ysD$#)y;@93Pc7kc6HCobmsVj zTW{0dlRw~D6|6G2{uME1bb2OwAP8|D52~;`Itn58PdBKBdc>{7OvEetN9q#1eKxa` z{zwf~u#Qs6X<`L;Ds618BYNo0CYtIXnMS3~6F=uZXcB&?@DCMyu}TB!HqpaWd`Gnh z)QWr5ekHJHTZuRQUT6FTzm9YIC$YgFbt?WSo3*px#@V6|Rh&3MnR2)-^dYi*r5=0F zqxR_-XW8!&?n$h@qub1nlM%|?(>GC*DM8#gO8o*2P>%Xn><@aU!<_mEUJW<6G@*ZE} zeszlc9oIUAF5@3%orF913jaB=g5HGe>)#f!N9A|{Op^t0Tt^ayzki;!Cq1op*H0@5 znNeImGt11(%uXT*Gcz+YGc$8yI%ej}F*ECCTJo#xRQGhhrmt#x5fIbKt%}U5S*&C`i`mKh zY~n-q`uhERk$3qr-)0}*<>!2fUrKyWk(Tf`eNR8r4E@`mMQ)@!PK(_M?gU-s9(GUY zYWI|TS~t4q+)KLIz2&~4JKVS2clEOSzWb$KcYlqX_C&p-{`zV(F#5DU#(jcO#wcTy zG0GTaj507J%F3+9gM6DFziG#0zg0_NWfjqN!SXNLpobm3=>|ZQWZjnJQ>HPlJf7qE*YaN~^U-Yqee*v{75MRok>(yR=(J zt4;0d(CIouXX-4St#fp~F4kqbTvzByU90PLgKpGKx>dL7cHN=7bhqx&{dzzT>LER> z$Muw+(X)C>@9I6huMhN*_Up6yvc96P>TCMCzCmm5cu)b9vD+m6M|rMnP`m0&NPl<&)K^Q|+7Yd$33D%G{lL z8T2IBy$5o8a^EfgRqngtb~7M|z7F~!=vPp6qo4C+?&bU}2vX5ru`S!_?JQ)^_A(Om zFBgYAcc}MgVC=5Wjr6^&KGYFuR&;gz&5B*Ya(m*>+qWU%e}h@k)x;HZfI;@gqb*`q z`r36CIXvBl`tDs#{RZ>v-JZ%nVHRXBHLD@b8E~%oY0rV?x41nO-CMrceVbzOQnM1` z;xM4aa=QImV1)UN?%QP}iet@6C|3Rt`{r}z0b?y^NvNs(DbQ;E*mUl+ZVroo2uwGB zpi6ScR=()1A-J+{Tkhm;A& zWxj)!K;OVOjMK<6$d29{Dj}>bNo)~=o|bl^O;N!gnpqvSQddt5Mc*XU&ng5HMppf6=t590n(@~=A1c_;D+sC z2boWHkkm0RlGlk;_ac8}IE&{=1?Q8(G&_e&*g4^r1I$ITb{LT+qP|co^6}gw(a|_ZQHiGYwGkWzgpDS^{;j(-EnuY@E5_L zvRkd!G2BlSv;?NcIQHM2(}lZ(@(ke_K0Z@;o{!HG9u)pENJ+_T;ep`+OL<_9Wtdx~ zGEa%BMV#C_i$N-Ps`V;ef6VWIg%Y_p`~`K(3eNK_w@YpYKuerg&qo#|k*|wHxp}~1 z$NbXPack-^8yRXNcjbl<@;9HeOmZfH@^ax0Hs`|B$R>1hvOb+Yo7PmfwkFZS!2t&0Js#T;{QuP)pl zlv^ch8r-5;%_S?HlzLT#upc|~687==+IynEaO_T86AOFgTD=)Q7Iup6P_Je5H|w1i zh zGHi-f6}%*>URC$G)W0CPWt=r>EeoohM!6tGpeGN>IK$X@8zxB?g)^<&1w@+v3G1D^J(s^GOP2=?S)|(zY zMj`9!t**VYWm3<{z=0SSalK0a4rr_U&*o&FaGuZUBstrFzKKS1mH_>P7XbxyuEUm@ zF|JHB1As%KX=VHOtIQ(xevsKGd*U(3Z1LU@H!d69lUbnNrc8(A1z-+ItsUIFX9A$( zai?-;!Vp}jd#g5e(^oqWRI@)u>m8E*Oub&|+pSk&y$R`;)Ekz*I9VUfEW}`>Ejd}i z25=q(%Sg^hZ9CR!KqqOTfp4+1o(k8OZqDs&bHpMciM=@;dXoadFd67X%|dOrRgU8$dH$@ddx7})xbe)rVIFo8K3Ojsl!%V35B%UMks-?tWV9v6_~ zNuH&KF{X?<_I>g#8k+uQFpb6){fuuJ1Y4Df20F{w$_P% za2lQE71*CUc#u)1+~k>JTA6;#w__N>Rx`{DXPX&m#<0VTH{;o3CYvej#mG19em*H> zCR4&1o?yjNrrAk+PD$%#)|9Ye=1>XyMM?WdNjtlw&5_!DeNIOh^zb`;Y>eglp2rDi zoQL(yPkiKuvE!#b|H!iZ5}+$S*)sfC@>_e=c*(k$hN_w%s)?fN;#HGG^@-=7NId2F zr^3}d|IG67yJ-lsWH;3(Ag!nG`_{_j+?C6@%gVW{A?L1+oV&Vu;zFKrp8~-c;Eyph zVuV@``*()575qhQ2j4@@(&=iK>!(#D{r-iFsG(!?0r2x=UWH!(et8r>0Q^ey{}a9u z_>J(qV2#e(Z!N>`r1V#!`Umi9;lBv~0{Fe~pM?(rf3RFm9z%qYnW~SWDKiK#VZoj} zFwP?d)YiWZfwmaa0lA<1S#K(}FZ0~YvLTh+0e_5fW|S(FiyWmB8C7)BF%-n08L_iyaI@PX0k^0EkiBYn-Ps|&Jg|H$1)7iem$o8 z2BPmRrGb>XS{n+dysD9?y2gA1y=Y^8004LajM4*a1qmF);hFzF)#jmWjHd#D@07ChilML(X8CnsMvy+?6BNi) zCucXqQPb0Ni#TEZrO9cWHoMUVlQ?H~VR{yq{AaKFLvL_<+rrY!Jnq?aqxtpm$flc? zmE$S30cdr=0gZk)A5g#(Hh#*~6Rao$~JHy&!Nw;JUzLf%if@AtfO_p`Os>(6Z10 zIKNy=+Yi&Y4-ernJcZ}*5?;ewcn=@p3w(ngX!J3ZcQBH%Ok^sTX9javz!Fxlh7D|C z4~ICxRk=3T=PZ}F6?fon+>871ARfkJcmhx189a{{@iJb;8+eQEb`KxmBYc9-@CClY zH~0=e;1~SP%mNl^@s?_7mSaU$W>r>aP1a^z)@MUDW-HpNwx+FXGq$14+M;b{TiJHD zlkH}EfgA^MupA?ixn0Wchh!?g~QBjiYFklkeuIZF1Fy<~6MMLd|2Pn$IdYEMPU;U@T;fTEtqln00Ci>(x>=fNYlz>69)Q z9%i>zkMv3(3{SCNt5KSy8OBVuXthd~OvnI;A3=I$P=;h!Mr2gR;F#ZH_$~B3TdW#l zacZc=t6`R)hFhWCsD@cV@f|!QEk9aJH<&ljX&AuVGtu&6{}%&tbui~K4!5c zw#TkG5GUY7oP?8c3QomoI2~u;Oq_*_a5b*M9qvE;r?$!g# znBzWTHiZ&*E^X+}YPNeuC;GcHy&24CCfi?RTIt>WJFr>=)<}W1$^siO3ic0SgJ?@v zS+XqbvQV4cyKU*+Ce5$b>fMv5ZZsLj=n3ZD9j418gejp>6$V}$5R6{95T}2He3moBCbQf{vdG&1MQbb4S>ry%X6Gmy*9#3M(H{tRb4(<8$#o#W9z)m`>}OC;VWH38!gb5psOjQ_w_{8PB&ACoQt|AswnD;^nY_@ z%IT`Wa$QFj9yg@E+?1-lCFOi;V7YFOYPaZ)z%t$C_^Ipf#?k5WsO4JZQErTm+!ph? zGbR;%VK5^Z&s05>eD4jP`;Z>h{o(UK_&ive?!!ox7+qsuF3=*a&`S5&GiF)zOg;_$ zu5anGRy)o!alDtup_TmLkXKOiANjP9@5=!>x#;PdtGJqLxR&dukMku#L9KHrp24YTInP zR%?ycYMs_=gEnfDHfN)<(b>$naFa^+ZDL%tt+@;K(EnVkAM>|q_d66f$1hH+s)k~i zRbX_-=m;S-Cwb&AO15&HSjbnQS&-Ajb+H|`)BJ}~h&^~OE&l>0;q(`H0Zodv6#_v3 zME~sKZaErW0hBHOz6o*a=wfh8txO1xk3- zY0zT8h7&#lkeI+XTdpn#jM^nasUV(f%*)S z000000RR91000313BUlr0M%91RqCtis{jB101V9x%^8{*nkHr@W-~K0Ge7`90002Q CLkb=M literal 0 HcmV?d00001 diff --git a/1-xcm-hyperbridge/frontend/app/fonts/GeistVF.woff b/1-xcm-hyperbridge/frontend/app/fonts/GeistVF.woff new file mode 100644 index 0000000000000000000000000000000000000000..1b62daacff96dad6584e71cd962051b82957c313 GIT binary patch literal 66268 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 >-Aun5A4Gp>4U0IQJ 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 G)cz05(PHWV literal 0 HcmV?d00001 diff --git a/1-xcm-hyperbridge/frontend/app/globals.css b/1-xcm-hyperbridge/frontend/app/globals.css new file mode 100644 index 00000000..25035d19 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/globals.css @@ -0,0 +1,81 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +body { + font-family: Arial, Helvetica, sans-serif; +} + +@layer utilities { + .text-balance { + text-wrap: balance; + } +} + + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 240 10% 3.9%; + --card: 0 0% 100%; + --card-foreground: 240 10% 3.9%; + --popover: 0 0% 100%; + --popover-foreground: 240 10% 3.9%; + --primary: 340 100% 57%; + --primary-foreground: 355.7 100% 97.3%; + --secondary: 240 4.8% 95.9%; + --secondary-foreground: 240 5.9% 10%; + --muted: 240 4.8% 95.9%; + --muted-foreground: 240 3.8% 46.1%; + --accent: 240 4.8% 95.9%; + --accent-foreground: 240 5.9% 10%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 0 0% 98%; + --border: 240 5.9% 90%; + --input: 240 5.9% 90%; + --ring: 346.8 77.2% 49.8%; + --radius: 0.5rem; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + } + + .dark { + --background: 20 14.3% 4.1%; + --foreground: 0 0% 95%; + --card: 24 9.8% 10%; + --card-foreground: 0 0% 95%; + --popover: 0 0% 9%; + --popover-foreground: 0 0% 95%; + --primary: 346.8 77.2% 49.8%; + --primary-foreground: 355.7 100% 97.3%; + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + --muted: 0 0% 15%; + --muted-foreground: 240 5% 64.9%; + --accent: 12 6.5% 15.1%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 85.7% 97.3%; + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --ring: 346.8 77.2% 49.8%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } +} + + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/1-xcm-hyperbridge/frontend/app/layout.tsx b/1-xcm-hyperbridge/frontend/app/layout.tsx new file mode 100644 index 00000000..db98252b --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/layout.tsx @@ -0,0 +1,36 @@ +import type { Metadata } from "next"; +import { Unbounded } from "next/font/google"; +import "./globals.css"; +import '@rainbow-me/rainbowkit/styles.css'; +import { Providers } from '@/app/providers'; + +const unbounded = Unbounded({ + subsets: ['latin'], + weight: ['400', '700'], + display: 'swap', +}) + +export const metadata: Metadata = { + title: "DOT UI kit", + description: "a UI kit for Polkadot DApps", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + +
+ {children} +
+
+ + + ); +} diff --git a/1-xcm-hyperbridge/frontend/app/mint-redeem-lst-bifrost/loading.tsx b/1-xcm-hyperbridge/frontend/app/mint-redeem-lst-bifrost/loading.tsx new file mode 100644 index 00000000..64936374 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/mint-redeem-lst-bifrost/loading.tsx @@ -0,0 +1,17 @@ +import { Skeleton } from "@/components/ui/skeleton" + +export default function Loading() { + // You can add any UI inside Loading, including a Skeleton. + return ( +
+ +
+ + + + +
+ +
+ ) +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/frontend/app/mint-redeem-lst-bifrost/page.tsx b/1-xcm-hyperbridge/frontend/app/mint-redeem-lst-bifrost/page.tsx new file mode 100644 index 00000000..aa53c211 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/mint-redeem-lst-bifrost/page.tsx @@ -0,0 +1,15 @@ +"use client"; +import MintRedeemLstBifrost from "@/components/mint-redeem-lst-bifrost"; +import SigpassKit from "@/components/sigpasskit"; +import Navbar from "@/components/navbar"; + +export default function MintRedeemLstBifrostPage() { + return ( +
+ + +

Mint/Redeem LST Bifrost

+ +
+ ); +} diff --git a/1-xcm-hyperbridge/frontend/app/page.tsx b/1-xcm-hyperbridge/frontend/app/page.tsx new file mode 100644 index 00000000..6b80bf06 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/page.tsx @@ -0,0 +1,87 @@ +import Image from "next/image"; +import Link from "next/link"; +import { Globe, AppWindowMac, File, Rocket } from 'lucide-react'; + +export default function Home() { + return ( +
+ ); +} diff --git a/1-xcm-hyperbridge/frontend/app/providers.tsx b/1-xcm-hyperbridge/frontend/app/providers.tsx new file mode 100644 index 00000000..91243fe9 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/providers.tsx @@ -0,0 +1,108 @@ +'use client'; + +import * as React from 'react'; +import { + RainbowKitProvider, + getDefaultWallets, + getDefaultConfig, +} from '@rainbow-me/rainbowkit'; +import { + phantomWallet, + trustWallet, + ledgerWallet, +} from '@rainbow-me/rainbowkit/wallets'; +import { + manta, + moonbaseAlpha, + moonbeam +} from 'wagmi/chains'; +import { defineChain } from 'viem'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { WagmiProvider, http, createConfig } from 'wagmi'; +import { Provider as JotaiProvider } from 'jotai'; +// import according to docs + +export const westendAssetHub = defineChain({ + id: 420420421, + name: "Westend AssetHub", + nativeCurrency: { + decimals: 18, + name: 'Westend', + symbol: 'WND', + }, + rpcUrls: { + default: { + http: ['https://westend-asset-hub-eth-rpc.polkadot.io'], + webSocket: ['wss://westend-asset-hub-eth-rpc.polkadot.io'], + }, + }, + blockExplorers: { + default: { name: 'Explorer', url: 'https://assethub-westend.subscan.io' }, + }, + contracts: { + multicall3: { + address: '0x5545dec97cb957e83d3e6a1e82fabfacf9764cf1', + blockCreated: 10174702, + }, + }, +}) + +export const localConfig = createConfig({ + chains: [ + westendAssetHub, + manta, + moonbaseAlpha, + moonbeam, + ], + transports: { + [westendAssetHub.id]: http(), + [manta.id]: http(), + [moonbaseAlpha.id]: http(), + [moonbeam.id]: http(), + }, + ssr: true, +}); + +const { wallets } = getDefaultWallets(); +// initialize and destructure wallets object + +const config = getDefaultConfig({ + appName: "DOTUI", // Name your app + projectId: "ddf8cf3ee0013535c3760d4c79c9c8b9", // Enter your WalletConnect Project ID here + wallets: [ + ...wallets, + { + groupName: 'Other', + wallets: [phantomWallet, trustWallet, ledgerWallet], + }, + ], + chains: [ + westendAssetHub, + moonbeam, + moonbaseAlpha, + manta + ], + transports: { + [westendAssetHub.id]: http(), + [moonbeam.id]: http(), + [moonbaseAlpha.id]: http(), + [manta.id]: http(), + }, + ssr: true, // Because it is Nextjs's App router, you need to declare ssr as true +}); + +const queryClient = new QueryClient(); + +export function Providers({ children }: { children: React.ReactNode }) { + return ( + + + + + {children} + + + + + ); +} diff --git a/1-xcm-hyperbridge/frontend/app/send-transaction/loading.tsx b/1-xcm-hyperbridge/frontend/app/send-transaction/loading.tsx new file mode 100644 index 00000000..64936374 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/send-transaction/loading.tsx @@ -0,0 +1,17 @@ +import { Skeleton } from "@/components/ui/skeleton" + +export default function Loading() { + // You can add any UI inside Loading, including a Skeleton. + return ( +
+ +
+ + + + +
+ +
+ ) +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/frontend/app/send-transaction/page.tsx b/1-xcm-hyperbridge/frontend/app/send-transaction/page.tsx new file mode 100644 index 00000000..80b85dc5 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/send-transaction/page.tsx @@ -0,0 +1,15 @@ +"use client"; +import SendTransaction from "@/components/send-transaction"; +import SigpassKit from "@/components/sigpasskit"; +import Navbar from "@/components/navbar"; + +export default function SendTransactionPage() { + return ( +
+ + +

Send Transaction

+ +
+ ); +} diff --git a/1-xcm-hyperbridge/frontend/app/wallet/loading.tsx b/1-xcm-hyperbridge/frontend/app/wallet/loading.tsx new file mode 100644 index 00000000..64936374 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/wallet/loading.tsx @@ -0,0 +1,17 @@ +import { Skeleton } from "@/components/ui/skeleton" + +export default function Loading() { + // You can add any UI inside Loading, including a Skeleton. + return ( +
+ +
+ + + + +
+ +
+ ) +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/frontend/app/wallet/page.tsx b/1-xcm-hyperbridge/frontend/app/wallet/page.tsx new file mode 100644 index 00000000..b77996d8 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/wallet/page.tsx @@ -0,0 +1,18 @@ +"use client"; +import SigpassKit from "@/components/sigpasskit"; +import Link from "next/link"; + +export default function WalletPage() { + return ( +
+
+ Home + Wallet + Send transaction + Write contract +
+

Wallet

+ +
+ ); +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/frontend/app/write-contract/loading.tsx b/1-xcm-hyperbridge/frontend/app/write-contract/loading.tsx new file mode 100644 index 00000000..64936374 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/write-contract/loading.tsx @@ -0,0 +1,17 @@ +import { Skeleton } from "@/components/ui/skeleton" + +export default function Loading() { + // You can add any UI inside Loading, including a Skeleton. + return ( +
+ +
+ + + + +
+ +
+ ) +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/frontend/app/write-contract/page.tsx b/1-xcm-hyperbridge/frontend/app/write-contract/page.tsx new file mode 100644 index 00000000..1947eea3 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/app/write-contract/page.tsx @@ -0,0 +1,15 @@ +"use client"; +import WriteContract from "@/components/write-contract"; +import SigpassKit from "@/components/sigpasskit"; +import Navbar from "@/components/navbar"; + +export default function SendTransactionPage() { + return ( +
+ + +

Write Contract

+ +
+ ); +} diff --git a/1-xcm-hyperbridge/frontend/components.json b/1-xcm-hyperbridge/frontend/components.json new file mode 100644 index 00000000..d9ef0ae5 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/components.json @@ -0,0 +1,21 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.ts", + "css": "app/globals.css", + "baseColor": "neutral", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + }, + "iconLibrary": "lucide" +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/frontend/components/copy-button.tsx b/1-xcm-hyperbridge/frontend/components/copy-button.tsx new file mode 100644 index 00000000..89ec8426 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/components/copy-button.tsx @@ -0,0 +1,27 @@ +import { Button } from "@/components/ui/button"; +import { Copy, Check } from "lucide-react"; +import { useState } from "react"; +import { Address } from "viem"; + +export default function CopyButton({ + copyText +}: { + copyText: Address | string | null; +}) { + const [isCopied, setIsCopied] = useState(false); + + const copy = async () => { + await navigator.clipboard.writeText(copyText ? copyText : ""); + setIsCopied(true); + + setTimeout(() => { + setIsCopied(false); + }, 1000); + }; + + return ( + + ) +} diff --git a/1-xcm-hyperbridge/frontend/components/mint-redeem-lst-bifrost.tsx b/1-xcm-hyperbridge/frontend/components/mint-redeem-lst-bifrost.tsx new file mode 100644 index 00000000..54672c7c --- /dev/null +++ b/1-xcm-hyperbridge/frontend/components/mint-redeem-lst-bifrost.tsx @@ -0,0 +1,649 @@ +"use client"; + +// React +import { useState, useEffect } from "react"; + +// Wagmi +import { + type BaseError, + useWaitForTransactionReceipt, + useConfig, + useWriteContract, + useReadContracts, + useAccount +} from "wagmi"; + +// viem +import { parseUnits, formatUnits } from "viem"; + +// Lucide (for icons) +import { + Ban, + ExternalLink, + ChevronDown, + X, + Hash, + LoaderCircle, + CircleCheck, + WalletMinimal, + HandCoins, +} from "lucide-react"; + +// zod (for form validation) +import { z } from "zod"; +import { zodResolver } from "@hookform/resolvers/zod"; + +// react-hook-form (for form handling) +import { useForm } from "react-hook-form"; + +// UI components +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { + Select, + SelectContent, + SelectGroup, + SelectItem, + SelectLabel, + SelectTrigger, + SelectValue, +} from "@/components/ui/select"; +import { Input } from "@/components/ui/input"; +import { useMediaQuery } from "@/hooks/use-media-query"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogFooter, + DialogTitle, + DialogTrigger, + DialogClose, +} from "@/components/ui/dialog"; +import { + Drawer, + DrawerClose, + DrawerContent, + DrawerDescription, + DrawerFooter, + DrawerHeader, + DrawerTitle, + DrawerTrigger, +} from "@/components/ui/drawer"; +import { Skeleton } from "@/components/ui/skeleton"; + +// utils imports +import { truncateHash } from "@/lib/utils"; + +// components imports +import CopyButton from "@/components/copy-button"; +import { getSigpassWallet } from "@/lib/sigpass"; + +// jotai for state management +import { useAtomValue } from "jotai"; +import { addressAtom } from "@/components/sigpasskit"; + +// config +import { localConfig } from "@/app/providers"; + +// abi for the Moonbeam SLPX contract and ERC20 token +import {erc20Abi , moonbeamSlpxAbi} from "@/lib/abi"; + +export default function MintRedeemLstBifrost() { + // useConfig hook to get config + const config = useConfig(); + + // useAccount hook to get account + const account = useAccount(); + + // useMediaQuery hook to check if the screen is desktop + const isDesktop = useMediaQuery("(min-width: 768px)"); + // useState hook to open/close dialog/drawer + const [open, setOpen] = useState(false); + + // get the address from session storage + const address = useAtomValue(addressAtom); + + // useWriteContract hook to write contract + const { + data: hash, + error, + isPending, + writeContractAsync, + } = useWriteContract({ + config: address ? localConfig : config, + }); + + const XCDOT_CONTRACT_ADDRESS = "0xFfFFfFff1FcaCBd218EDc0EbA20Fc2308C778080"; + const XCASTR_CONTRACT_ADDRESS = "0xFfFFFfffA893AD19e540E172C10d78D4d479B5Cf"; + + // GLMR is both the native token of Moonbeam and an ERC20 token + const GLMR_CONTRACT_ADDRESS = "0x0000000000000000000000000000000000000802"; + const BIFROST_SLPX_CONTRACT_ADDRESS = + "0xF1d4797E51a4640a76769A50b57abE7479ADd3d8"; + + // Get the contract address based on selected token + const getContractAddress = (token: string) => { + switch (token) { + case "xcdot": + return XCDOT_CONTRACT_ADDRESS; + case "xcastr": + return XCASTR_CONTRACT_ADDRESS; + case "glmr": + return GLMR_CONTRACT_ADDRESS; + default: + return XCDOT_CONTRACT_ADDRESS; + } + }; + + // form schema for sending transaction + const formSchema = z.object({ + // token is a required field selected from a list + token: z.enum(["xcdot", "glmr", "xcastr"], { + required_error: "Please select a token", + }), + // amount is a required field + amount: z + .string() + .refine((val) => !isNaN(parseFloat(val)) && parseFloat(val) > 0, { + message: "Amount must be a positive number", + }) + .refine((val) => /^\d*\.?\d{0,18}$/.test(val), { + message: "Amount cannot have more than 18 decimal places", + }) + .superRefine((val, ctx) => { + if (!maxBalance || !decimals) return; + + const inputAmount = parseUnits(val, decimals as number); + + if (inputAmount > (maxBalance as bigint)) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: "Amount exceeds available balance", + }); + } + }), + }); + + // 1. Define your form. + const form = useForm>({ + // resolver is zodResolver + resolver: zodResolver(formSchema), + // default values for address and amount + defaultValues: { + token: "xcdot", + amount: "", + }, + }); + + + // Extract the token value using watch instead of getValues + const selectedToken = form.watch("token"); + + + + // useReadContracts hook to read contract + const { data, refetch: refetchBalance } = useReadContracts({ + contracts: [ + { + // get the balance of the selected token + address: getContractAddress(selectedToken), + abi: erc20Abi, + functionName: "balanceOf", + args: [address ? address : account.address], + }, + { + // get the symbol of the selected token + address: getContractAddress(selectedToken), + abi: erc20Abi, + functionName: "symbol", + }, + { + // get the decimals of the selected token + address: getContractAddress(selectedToken), + abi: erc20Abi, + functionName: "decimals", + }, + { + // get the allowance of the selected token + address: getContractAddress(selectedToken), + abi: erc20Abi, + functionName: "allowance", + args: [ + address ? address : account.address, + BIFROST_SLPX_CONTRACT_ADDRESS, + ], + }, + ], + config: address ? localConfig : config, + }); + + + // extract the data from the read contracts hook + const maxBalance = data?.[0]?.result as bigint | undefined; // balance of the selected token + const symbol = data?.[1]?.result as string | undefined; // symbol of the selected token + const decimals = data?.[2]?.result as number | undefined; // decimals of the selected token + const mintAllowance = data?.[3]?.result as bigint | undefined; // allowance of the selected token + + // extract the amount value from the form + const amount = form.watch("amount"); + + // check if the amount is greater than the mint allowance + const needsApprove = mintAllowance !== undefined && + amount ? + mintAllowance < parseUnits(amount, decimals || 18) : + false; + + + // 2. Define a submit handler. + async function onSubmit(values: z.infer) { + // if the user has a sigpass wallet, and the token is not GLMR, approve the token + if (address) { + if (needsApprove) { + writeContractAsync({ + account: await getSigpassWallet(), + address: getContractAddress(values.token), + abi: erc20Abi, + functionName: "approve", + args: [BIFROST_SLPX_CONTRACT_ADDRESS, parseUnits(values.amount, decimals as number)], + }); + } + } + + // if the user does not have a sigpass wallet, and the token is not GLMR, mint the token + if (!address) { + if (needsApprove) { + writeContractAsync({ + address: getContractAddress(values.token), + abi: erc20Abi, + functionName: "approve", + args: [BIFROST_SLPX_CONTRACT_ADDRESS, parseUnits(values.amount, decimals as number)], + }); + } + } + + /** + * @dev Create order to mint vAsset or redeem vAsset on bifrost chain + * @param assetAddress The address of the asset to mint or redeem + * @param amount The amount of the asset to mint or redeem + * @param dest_chain_id When order is executed on Bifrost, Asset/vAsset will be transferred to this chain + * @param receiver The receiver address on the destination chain, 20 bytes for EVM, 32 bytes for Substrate + * @param remark The remark of the order, less than 32 bytes. For example, "OmniLS" + * @param channel_id The channel id of the order, you can set it. Bifrost chain will use it to share reward. + **/ + if (!address && !needsApprove && selectedToken !== "glmr") { + writeContractAsync({ + address: BIFROST_SLPX_CONTRACT_ADDRESS, + abi: moonbeamSlpxAbi, + functionName: "create_order", + args: [ + getContractAddress(values.token), + parseUnits(values.amount, decimals as number), + 1284, // Moonbeam chain id + account.address, // receiver + "dotui", // remark + 0, // channel_id + ], + }); + } + + if (!address && !needsApprove && selectedToken === "glmr") { + writeContractAsync({ + address: BIFROST_SLPX_CONTRACT_ADDRESS, + abi: moonbeamSlpxAbi, + functionName: "create_order", + args: [ + getContractAddress(values.token), + parseUnits(values.amount, decimals as number), + 1284, // Moonbeam chain id + account.address, // receiver + "dotui", // remark + 0, // channel_id + ], + value: parseUnits(values.amount, decimals as number), + }); + } + } + + // Watch for transaction hash and open dialog/drawer when received + useEffect(() => { + if (hash) { + setOpen(true); + } + }, [hash]); + + // useWaitForTransactionReceipt hook to wait for transaction receipt + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + config: address ? localConfig : config, + }); + + // when isConfirmed, refetch the balance of the address + useEffect(() => { + if (isConfirmed) { + refetchBalance(); + } + }, [isConfirmed, refetchBalance]); + + // Find the chain ID from the connected account + const chainId = account.chainId; + + // Get the block explorer URL for the current chain using the config object + function getBlockExplorerUrl(chainId: number | undefined): string | undefined { + const chain = config.chains?.find(chain => chain.id === chainId); + return chain?.blockExplorers?.default?.url || config.chains?.[0]?.blockExplorers?.default?.url; + } + + return ( + + + Mint + Redeem + + +
+
+ + ( + + Token + + + + The token to mint + + + )} + /> + ( + +
+ Amount +
+ {" "} + { + maxBalance !== undefined ? ( + formatUnits(maxBalance as bigint, decimals as number) + ) : ( + + ) + }{" "} + { + symbol ? ( + symbol + ) : ( + + ) + } +
+
+ + {isDesktop ? ( + + ) : ( + + )} + + + The amount of {selectedToken === "glmr" ? "GLMR" : symbol} to mint + + +
+ )} + /> +
+

Token allowance

+
+ {" "} + { + mintAllowance !== undefined ? ( + formatUnits(mintAllowance as bigint, decimals as number) + ) : ( + + ) + }{" "} + { + symbol ? ( + symbol + ) : ( + + ) + } +
+
+
+

You are about to mint this token

+
+ { + selectedToken === "glmr" ? ( + "xcvGLMR" + ) : selectedToken === "xcdot" ? ( + "xcvDOT" + ) : selectedToken === "xcastr" ? ( + "xcvASTR" + ) : ( + + ) + } +
+
+
+ { + isPending ? ( + + ) : needsApprove ? ( + + ) : ( + + ) + } + {isPending ? ( + + ) : needsApprove ? ( + + ) : ( + + )} +
+ + + + { + // Desktop would be using dialog + isDesktop ? ( + + + + + + + Transaction status + + + Follow the transaction status below. + +
+ {hash ? ( +
+ + Transaction Hash + + {truncateHash(hash)} + + + +
+ ) : ( +
+ + No transaction hash +
+ )} + {!isPending && !isConfirmed && !isConfirming && ( +
+ No transaction submitted +
+ )} + {isConfirming && ( +
+ {" "} + Waiting for confirmation... +
+ )} + {isConfirmed && ( +
+ Transaction + confirmed! +
+ )} + {error && ( +
+ Error:{" "} + {(error as BaseError).shortMessage || error.message} +
+ )} +
+ + + + + +
+
+ ) : ( + // Mobile would be using drawer + + + + + + + Transaction status + + Follow the transaction status below. + + +
+ {hash ? ( +
+ + Transaction Hash + + {truncateHash(hash)} + + + +
+ ) : ( +
+ + No transaction hash +
+ )} + {!isPending && !isConfirmed && !isConfirming && ( +
+ No transaction submitted +
+ )} + {isConfirming && ( +
+ {" "} + Waiting for confirmation... +
+ )} + {isConfirmed && ( +
+ Transaction + confirmed! +
+ )} + {error && ( +
+ Error:{" "} + {(error as BaseError).shortMessage || error.message} +
+ )} +
+ + + + + +
+
+ ) + } +
+
+ placeholder +
+ ); +} + diff --git a/1-xcm-hyperbridge/frontend/components/navbar.tsx b/1-xcm-hyperbridge/frontend/components/navbar.tsx new file mode 100644 index 00000000..d2121695 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/components/navbar.tsx @@ -0,0 +1,32 @@ +import Link from "next/link"; + +export default function Navbar() { + return ( +
+ + Home + + + Wallet + + + Send transaction + + + Write contract + + + Mint/Redeem LST Bifrost + +
+ ); +} diff --git a/1-xcm-hyperbridge/frontend/components/portfolio-card.tsx b/1-xcm-hyperbridge/frontend/components/portfolio-card.tsx new file mode 100644 index 00000000..588ebe7e --- /dev/null +++ b/1-xcm-hyperbridge/frontend/components/portfolio-card.tsx @@ -0,0 +1,17 @@ +import { useBalance } from 'wagmi'; +import { formatEther } from 'viem'; +import { Button } from '@/components/ui/button'; +import { RefreshCcw } from 'lucide-react'; + +export default function PortfolioCard() { + const { data: balance, refetch } = useBalance(); + return ( +
+

Balance

+

{balance?.value ? formatEther(balance.value) : '0'}

+ +
+ ) +} \ No newline at end of file diff --git a/1-xcm-hyperbridge/frontend/components/send-transaction.tsx b/1-xcm-hyperbridge/frontend/components/send-transaction.tsx new file mode 100644 index 00000000..edff6a04 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/components/send-transaction.tsx @@ -0,0 +1,346 @@ +"use client"; + +import { useState, useEffect } from "react"; +import { + type BaseError, + useSendTransaction, + useWaitForTransactionReceipt, + useConfig +} from "wagmi"; +import { parseEther, isAddress, Address } from "viem"; +import { + Ban, + ExternalLink, + ChevronDown, + X, + Hash, + LoaderCircle, + CircleCheck, +} from "lucide-react"; +import { z } from "zod"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { useForm } from "react-hook-form"; +import { Button } from "@/components/ui/button"; +import { + Form, + FormControl, + FormDescription, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { useMediaQuery } from "@/hooks/use-media-query"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogFooter, + DialogTitle, + DialogTrigger, + DialogClose, +} from "@/components/ui/dialog"; +import { + Drawer, + DrawerClose, + DrawerContent, + DrawerDescription, + DrawerFooter, + DrawerHeader, + DrawerTitle, + DrawerTrigger, +} from "@/components/ui/drawer"; +import { truncateHash } from "@/lib/utils"; +import CopyButton from "@/components/copy-button"; +import { getSigpassWallet } from "@/lib/sigpass"; +import { westendAssetHub } from "@/app/providers"; +import { useAtomValue } from 'jotai'; +import { addressAtom } from '@/components/sigpasskit'; +import { localConfig } from '@/app/providers'; + +// form schema for sending transaction +const formSchema = z.object({ + // address is a required field + address: z + .string() + .min(2) + .max(50) + .refine((val) => val === "" || isAddress(val), { + message: "Invalid Ethereum address format", + }) as z.ZodType
, + // amount is a required field + amount: z + .string() + .refine((val) => !isNaN(parseFloat(val)) && parseFloat(val) > 0, { + message: "Amount must be a positive number", + }) + .refine((val) => /^\d*\.?\d{0,18}$/.test(val), { + message: "Amount cannot have more than 18 decimal places", + }), +}); + +export default function SendTransaction() { + + // useConfig hook to get config + const config = useConfig(); + + // useMediaQuery hook to check if the screen is desktop + const isDesktop = useMediaQuery("(min-width: 768px)"); + // useState hook to open/close dialog/drawer + const [open, setOpen] = useState(false); + + // get the address from session storage + const address = useAtomValue(addressAtom) + + // useSendTransaction hook to send transaction + const { + data: hash, + error, + isPending, + sendTransactionAsync, + } = useSendTransaction({ + config: address ? localConfig : config, + }); + + + // 1. Define your form. + const form = useForm>({ + // resolver is zodResolver + resolver: zodResolver(formSchema), + // default values for address and amount + defaultValues: { + address: "", + amount: "", + }, + }); + + + // 2. Define a submit handler. + async function onSubmit(values: z.infer) { + if (address) { + sendTransactionAsync({ + account: await getSigpassWallet(), + to: values.address as Address, + value: parseEther(values.amount), + chainId: westendAssetHub.id, + }); + } else { + // Fallback to connected wallet + sendTransactionAsync({ + to: values.address as Address, + value: parseEther(values.amount), + }); + } + } + + // Watch for transaction hash and open dialog/drawer when received + useEffect(() => { + if (hash) { + setOpen(true); + } + }, [hash]); + + + // useWaitForTransactionReceipt hook to wait for transaction receipt + const { isLoading: isConfirming, isSuccess: isConfirmed } = + useWaitForTransactionReceipt({ + hash, + config: address ? localConfig : config, + }); + + + return ( +
+
+ + ( + + Receiving Address + + + + The address to send WND to. + + + )} + /> + ( + + Amount + + {isDesktop ? ( + + ) : ( + + )} + + The amount of WND to send. + + + )} + /> + { + isPending ? ( + + ) : ( + + ) + } + + + { + // Desktop would be using dialog + isDesktop ? ( + + + + + + + Transaction status + + + Follow the transaction status below. + +
+ {hash ? ( +
+ + Transaction Hash + + {truncateHash(hash)} + + + +
+ ) : ( +
+ + No transaction hash +
+ )} + { + !isPending && !isConfirmed && !isConfirming && ( +
+ No transaction submitted +
+ ) + } + {isConfirming && ( +
+ Waiting + for confirmation... +
+ )} + {isConfirmed && ( +
+ Transaction confirmed! +
+ )} + {error && ( +
+ Error:{" "} + {(error as BaseError).shortMessage || error.message} +
+ )} +
+ + + + + +
+
+ ) : ( + // Mobile would be using drawer + + + + + + + Transaction status + + Follow the transaction status below. + + +
+ {hash ? ( +
+ + Transaction Hash + + {truncateHash(hash)} + + + +
+ ) : ( +
+ + No transaction hash +
+ )} + { + !isPending && !isConfirmed && !isConfirming && ( +
+ No transaction submitted +
+ ) + } + {isConfirming && ( +
+ Waiting + for confirmation... +
+ )} + {isConfirmed && ( +
+ Transaction confirmed! +
+ )} + {error && ( +
+ Error:{" "} + {(error as BaseError).shortMessage || error.message} +
+ )} +
+ + + + + +
+
+ ) + } +
+ ); +} diff --git a/1-xcm-hyperbridge/frontend/components/sigpasskit.tsx b/1-xcm-hyperbridge/frontend/components/sigpasskit.tsx new file mode 100644 index 00000000..d655b4af --- /dev/null +++ b/1-xcm-hyperbridge/frontend/components/sigpasskit.tsx @@ -0,0 +1,381 @@ +"use client"; + +import { useState, useEffect } from "react"; +import '@rainbow-me/rainbowkit/styles.css'; +import { useMediaQuery } from "@/hooks/use-media-query"; +import { Skeleton } from "@/components/ui/skeleton"; +import { Button } from "@/components/ui/button"; +import { Copy, Check, KeyRound, Ban, ExternalLink, LogOut, ChevronDown, X } from 'lucide-react'; +import { formatEther, Address } from 'viem'; +import { createSigpassWallet, getSigpassWallet, checkSigpassWallet, checkBrowserWebAuthnSupport } from "@/lib/sigpass"; +import { ConnectButton } from '@rainbow-me/rainbowkit'; +import { useAccount, useBalance, createConfig, http, useConfig } from 'wagmi'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogFooter, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog" +import { + Drawer, + DrawerClose, + DrawerContent, + DrawerDescription, + DrawerFooter, + DrawerHeader, + DrawerTitle, + DrawerTrigger, +} from "@/components/ui/drawer" +import Image from 'next/image'; +import { useAtom } from 'jotai'; +import { atomWithStorage, RESET } from 'jotai/utils'; +import { westendAssetHub } from '@/app/providers'; + + +// Set the string key and the initial value +export const addressAtom = atomWithStorage
('SIGPASS_ADDRESS', undefined) + +// create a local config for the wallet +const localConfig = createConfig({ + chains: [westendAssetHub], + transports: { + [westendAssetHub.id]: http(), + }, + ssr: true, +}); + +export default function SigpassKit() { + const [wallet, setWallet] = useState(false); + const [open, setOpen] = useState(false); + const [webAuthnSupport, setWebAuthnSupport] = useState(false); + const isDesktop = useMediaQuery("(min-width: 768px)") + const account = useAccount(); + const [address, setAddress] = useAtom(addressAtom); + const [isCopied, setIsCopied] = useState(false); + const config = useConfig(); + const { data: balance } = useBalance({ + address: address, + chainId: westendAssetHub.id, + config: address ? localConfig : config, + }); + + // check if the wallet is already created + useEffect(() => { + async function fetchWalletStatus() { + const status = await checkSigpassWallet(); + setWallet(status); + } + fetchWalletStatus(); + }, []); + + // check if the browser supports WebAuthn + useEffect(() => { + const support = checkBrowserWebAuthnSupport(); + setWebAuthnSupport(support); + }, []); + + // get the wallet + async function getWallet() { + const account = await getSigpassWallet(); + if (account) { + setAddress(account.address); + } else { + console.error('Issue getting wallet'); + } + } + + // create a wallet + async function createWallet() { + const account = await createSigpassWallet("dapp"); + if (account) { + setOpen(false); + setWallet(true); + } + } + + // truncate address to 6 characters and add ... at the end + function truncateAddress(address: Address, length: number = 4) { + return `${address.slice(0, length)}...${address.slice(-length)}`; + } + + // copy the address to the clipboard + function copyAddress() { + if (address) { + navigator.clipboard.writeText(address ? address : ""); + setIsCopied(true); + setTimeout(() => { + setIsCopied(false); + }, 1000); + } + } + + // disconnect the wallet + function disconnect() { + setAddress(undefined); + setOpen(false); + setAddress(RESET); + } + + + if (isDesktop) { + return ( +
+ {!wallet && !account.isConnected && !address ? ( + + + + + + + Create Wallet + + Instantly get a wallet with Passkey + + +
+
+

What is a Wallet?

+
+ icon-1 +
+

A Home for your Digital Assets

+

Wallets are used to send, receive, store, and display digital assets like Polkadot and NFTs.

+
+
+
+ icon-2 +
+

A new way to Log In

+

Instead of creating new accounts and passwords on every website, just connect your wallet.

+
+
+
+
+ +
+ Learn more + { + webAuthnSupport ? ( + + ) : ( + + ) + } +
+
+
+ Powered by Sigpass +
+
+
+ ) : wallet && !account.isConnected && address === undefined ? ( + + ) : wallet && !account.isConnected && address ? + + + + + + + Wallet + + + {truncateAddress(address, 4)} + +
+ {balance ? `${formatEther(balance.value)} WND` : } +
+
+ + +
+
+
+ : null} + { + !address ? : null + } +
+ ) + } + + return ( +
+ {(!wallet && !account.isConnected && !address) ? ( + + + + + + + Create Wallet + + Instantly get a wallet with Passkey + + +
+
+

What is a Wallet?

+
+ icon-1 +
+

A Home for your Digital Assets

+

Wallets are used to send, receive, store, and display digital assets like Polkadot and NFTs.

+
+
+
+ icon-2 +
+

A new way to Log In

+

Instead of creating new accounts and passwords on every website, just connect your wallet.

+
+
+ Learn more +
+
+ + {webAuthnSupport ? ( + + ) : ( + + )} + + + +
+ Powered by Sigpass +
+
+
+
+ ) : wallet && !account.isConnected && address === undefined ? ( + + ) : wallet && !account.isConnected && address ? ( + + + + + + +
+ Wallet + + + +
+ + {truncateAddress(address, 4)} + +
+
+
+ {balance ? `${formatEther(balance.value)} WND` : } +
+
+ + +
+
+
+
+ ) : null} + {!address ? : null} +
+ ) +} + diff --git a/1-xcm-hyperbridge/frontend/components/string-copy-button.tsx b/1-xcm-hyperbridge/frontend/components/string-copy-button.tsx new file mode 100644 index 00000000..7909de41 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/components/string-copy-button.tsx @@ -0,0 +1,42 @@ +"use client"; + +import { useState } from "react"; +import { Copy, Check } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { Address as EvmAddress } from "viem"; + + +export default function StringCopyButton({ + copyText, + buttonTitle, +}: { + copyText: EvmAddress | string | null; + buttonTitle: string; +}) { + const [isCopied, setIsCopied] = useState(false); + + const copy = async () => { + await navigator.clipboard.writeText(copyText ? copyText : ""); + setIsCopied(true); + + setTimeout(() => { + setIsCopied(false); + }, 1000); + }; + + return ( + + ); +} diff --git a/1-xcm-hyperbridge/frontend/components/ui/button.tsx b/1-xcm-hyperbridge/frontend/components/ui/button.tsx new file mode 100644 index 00000000..36496a28 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/components/ui/button.tsx @@ -0,0 +1,56 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", + { + variants: { + variant: { + default: "bg-primary text-primary-foreground hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground hover:bg-destructive/90", + outline: + "border border-input bg-background hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-10 px-4 py-2", + sm: "h-9 rounded-md px-3", + lg: "h-11 rounded-md px-8", + icon: "h-10 w-10", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/1-xcm-hyperbridge/frontend/components/ui/dialog.tsx b/1-xcm-hyperbridge/frontend/components/ui/dialog.tsx new file mode 100644 index 00000000..01ff19c7 --- /dev/null +++ b/1-xcm-hyperbridge/frontend/components/ui/dialog.tsx @@ -0,0 +1,122 @@ +"use client" + +import * as React from "react" +import * as DialogPrimitive from "@radix-ui/react-dialog" +import { X } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Dialog = DialogPrimitive.Root + +const DialogTrigger = DialogPrimitive.Trigger + +const DialogPortal = DialogPrimitive.Portal + +const DialogClose = DialogPrimitive.Close + +const DialogOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogOverlay.displayName = DialogPrimitive.Overlay.displayName + +const DialogContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + + {children} + + + Close + + + +)) +DialogContent.displayName = DialogPrimitive.Content.displayName + +const DialogHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DialogHeader.displayName = "DialogHeader" + +const DialogFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DialogFooter.displayName = "DialogFooter" + +const DialogTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogTitle.displayName = DialogPrimitive.Title.displayName + +const DialogDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DialogDescription.displayName = DialogPrimitive.Description.displayName + +export { + Dialog, + DialogPortal, + DialogOverlay, + DialogClose, + DialogTrigger, + DialogContent, + DialogHeader, + DialogFooter, + DialogTitle, + DialogDescription, +} diff --git a/1-xcm-hyperbridge/frontend/components/ui/drawer.tsx b/1-xcm-hyperbridge/frontend/components/ui/drawer.tsx new file mode 100644 index 00000000..6a0ef53d --- /dev/null +++ b/1-xcm-hyperbridge/frontend/components/ui/drawer.tsx @@ -0,0 +1,118 @@ +"use client" + +import * as React from "react" +import { Drawer as DrawerPrimitive } from "vaul" + +import { cn } from "@/lib/utils" + +const Drawer = ({ + shouldScaleBackground = true, + ...props +}: React.ComponentProps) => ( + +) +Drawer.displayName = "Drawer" + +const DrawerTrigger = DrawerPrimitive.Trigger + +const DrawerPortal = DrawerPrimitive.Portal + +const DrawerClose = DrawerPrimitive.Close + +const DrawerOverlay = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DrawerOverlay.displayName = DrawerPrimitive.Overlay.displayName + +const DrawerContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + + +
+ {children} + + +)) +DrawerContent.displayName = "DrawerContent" + +const DrawerHeader = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DrawerHeader.displayName = "DrawerHeader" + +const DrawerFooter = ({ + className, + ...props +}: React.HTMLAttributes) => ( +
+) +DrawerFooter.displayName = "DrawerFooter" + +const DrawerTitle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DrawerTitle.displayName = DrawerPrimitive.Title.displayName + +const DrawerDescription = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +DrawerDescription.displayName = DrawerPrimitive.Description.displayName + +export { + Drawer, + DrawerPortal, + DrawerOverlay, + DrawerTrigger, + DrawerClose, + DrawerContent, + DrawerHeader, + DrawerFooter, + DrawerTitle, + DrawerDescription, +} diff --git a/1-xcm-hyperbridge/frontend/components/ui/form.tsx b/1-xcm-hyperbridge/frontend/components/ui/form.tsx new file mode 100644 index 00000000..ce264aef --- /dev/null +++ b/1-xcm-hyperbridge/frontend/components/ui/form.tsx @@ -0,0 +1,178 @@ +"use client" + +import * as React from "react" +import * as LabelPrimitive from "@radix-ui/react-label" +import { Slot } from "@radix-ui/react-slot" +import { + Controller, + ControllerProps, + FieldPath, + FieldValues, + FormProvider, + useFormContext, +} from "react-hook-form" + +import { cn } from "@/lib/utils" +import { Label } from "@/components/ui/label" + +const Form = FormProvider + +type FormFieldContextValue< + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath +> = { + name: TName +} + +const FormFieldContext = React.createContext( + {} as FormFieldContextValue +) + +const FormField = < + TFieldValues extends FieldValues = FieldValues, + TName extends FieldPath = FieldPath +>({ + ...props +}: ControllerProps) => { + return ( + + + + ) +} + +const useFormField = () => { + const fieldContext = React.useContext(FormFieldContext) + const itemContext = React.useContext(FormItemContext) + const { getFieldState, formState } = useFormContext() + + const fieldState = getFieldState(fieldContext.name, formState) + + if (!fieldContext) { + throw new Error("useFormField should be used within ") + } + + const { id } = itemContext + + return { + id, + name: fieldContext.name, + formItemId: `${id}-form-item`, + formDescriptionId: `${id}-form-item-description`, + formMessageId: `${id}-form-item-message`, + ...fieldState, + } +} + +type FormItemContextValue = { + id: string +} + +const FormItemContext = React.createContext( + {} as FormItemContextValue +) + +const FormItem = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => { + const id = React.useId() + + return ( + +
+ + ) +}) +FormItem.displayName = "FormItem" + +const FormLabel = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => { + const { error, formItemId } = useFormField() + + return ( +