From ae3568a6fd5847e6b96ee6e252f5affc9c94d114 Mon Sep 17 00:00:00 2001 From: Nelito Junior Date: Sat, 29 Aug 2026 08:05:54 -0300 Subject: [PATCH 1/2] chore: remove the Postgres API and syncer, serve the explorer from api-lite - delete the graphql package's server, syncer, cosmos worker, pm2 configs, Postgres DAOs, migrations and tests; keep schemas, generated SDK, domain layer and value objects as a library - delete the helm chart, cluster/minikube scripts, Tiltfile, deployment/Dockerfile, the docker-publish and helm-publish workflows and the run/setup backend scripts - drop the Postgres service and indexer env from docker/docker-compose.yml - graphql package dependencies 36 to 9, devDependencies 31 to 21 --- .github/workflows/docker-publish.yml | 47 - .github/workflows/helm-publish.yml | 42 - Tiltfile | 78 - cluster/chart/Chart.lock | 12 - cluster/chart/Chart.yaml | 19 - cluster/chart/templates/env-configmap.yaml | 30 - cluster/chart/templates/env-secrets.yaml | 7 - cluster/chart/values.yaml | 51 - cluster/scripts/build-image.sh | 32 - cluster/scripts/setup-minikube.sh | 27 - deployment/Dockerfile | 53 - docker/docker-compose.yml | 48 - docker/envs/global.env | 10 - docker/envs/indexer.env | 11 - docs/GETTING_STARTED.md | 3 +- helm/fuel-explorer/.helmignore | 23 - helm/fuel-explorer/Chart.yaml | 6 - helm/fuel-explorer/templates/NOTES.txt | 22 - helm/fuel-explorer/templates/_helpers.tpl | 62 - .../templates/api/deployment.yaml | 104 - helm/fuel-explorer/templates/api/hpa.yaml | 34 - helm/fuel-explorer/templates/api/ingress.yaml | 65 - helm/fuel-explorer/templates/api/service.yaml | 20 - .../templates/serviceaccount.yaml | 12 - .../templates/servicemonitor.yaml | 15 - .../templates/syncer/deployment.yaml | 104 - .../templates/tests/test-connection.yaml | 15 - helm/fuel-explorer/values.yaml | 143 - package.json | 4 - packages/graphql/.env.example | 12 +- packages/graphql/.env.production | 19 - packages/graphql/.swcrc | 18 - packages/graphql/API.md | 89 - packages/graphql/ASSETS.md | 65 - packages/graphql/MIGRATION_GUIDE.md | 50 - packages/graphql/README.md | 564 +-- .../001_create_schema_and_base_tables.sql | 82 - .../002_create_assets_contracts.sql | 14 - .../003_add_assets_contracts_columns.sql | 8 - .../004_add_owner_to_assets_contracts.sql | 3 - .../005_add_metadata_to_assets_contracts.sql | 2 - .../migrations/006_ensure_migration_table.sql | 4 - ...7_add_total_supply_to_assets_contracts.sql | 2 - .../migrations/008_create_nft_collections.sql | 17 - .../009_add_transactions_count_to_blocks.sql | 2 - .../010_create_asset_rate_tables.sql | 86 - .../migrations/011_add_nft_collections.sql | 3 - .../migrations/012_create_balance_tables.sql | 21 - .../013_create_l1_contract_tables.sql | 59 - .../migrations/014_create_cosmos_tables.sql | 36 - .../015_add_total_fee_and_timestamptz.sql | 4 - .../migrations/016_create_receipts_tables.sql | 50 - .../017_add_da_height_to_blocks.sql | 2 - .../018_convert_timestamps_create_ro_user.sql | 7 - .../019_create_staking_mvs_and_jobs.sql | 194 - .../020_receipts_id_to_bigserial.sql | 10 - .../021_balance_id_to_bigserial.sql | 7 - .../022_l1_index_id_to_bigserial.sql | 7 - .../023_l1_logs_id_to_bigserial.sql | 7 - .../024_l1_args_id_to_bigserial.sql | 7 - .../025_cosmos_responses_id_to_bigserial.sql | 7 - .../026_cosmos_events_id_to_bigserial.sql | 7 - .../027_receipts_data_id_to_bigserial.sql | 7 - .../migrations/028_add_vacuum_jobs.sql | 32 - .../migrations/029_add_search_indexes.sql | 9 - .../030_create_recent_transactions_mv.sql | 34 - .../migrations/031_add_statistics_indexes.sql | 20 - .../032_create_hourly_statistics_mv.sql | 44 - .../migrations/033_add_moor_token.sql | 10 - .../034_drop_unused_receipts_indexes.sql | 26 - .../035_add_receipts_vacuum_job.sql | 20 - .../036_optimize_hourly_statistics_mv.sql | 35 - .../037_outputs_id_to_bigserial.sql | 7 - .../migrations/038_inputs_id_to_bigserial.sql | 6 - .../039_predicates_id_to_bigserial.sql | 6 - .../040_contracts_id_to_bigserial.sql | 6 - .../migrations/041_optimize_staking_mvs.sql | 30 - .../migrations/042_drop_unused_indexes.sql | 35 - ...43_replace_staking_mvs_with_agg_tables.sql | 177 - .../044_optimize_storage_drop_unused_data.sql | 46 - .../migrations/045_vacuum_receipts.sql | 16 - ...ce_hourly_statistics_mv_with_agg_table.sql | 46 - .../migrations/047_optimize_balance_index.sql | 17 - ..._unused_recent_account_transactions_mv.sql | 11 - .../049_drop_unused_redundant_indexes.sql | 25 - .../050_tune_autovacuum_large_tables.sql | 31 - packages/graphql/ecosystem-dev.config.cjs | 77 - .../graphql/ecosystem-prod-api.config.cjs | 10 - .../graphql/ecosystem-prod-syncer.config.cjs | 40 - packages/graphql/ecosystem.config.cjs | 22 - .../explorer_backend_indexer_architecture.png | Bin 166121 -> 0 bytes packages/graphql/jest.config.ts | 23 - packages/graphql/logs/empty | 0 packages/graphql/package.json | 63 +- packages/graphql/scripts/migrate.ts | 322 -- packages/graphql/scripts/run.sh | 9 - packages/graphql/scripts/setup-migrations.ts | 128 - packages/graphql/src/app.ts | 34 - .../src/application/uc/GetAccountAssets.ts | 59 - .../src/application/uc/GetAssetsRate.ts | 26 - .../graphql/src/application/uc/GetMetrics.ts | 73 - .../src/application/uc/GetTransaction.ts | 131 - .../uc/IndexAsset/GetAssetDetails.ts | 110 - .../application/uc/IndexAsset/IndexAsset.ts | 162 - .../uc/IndexAsset/IndexAssetsRate.ts | 124 - .../application/uc/IndexAsset/NFTIndexer.ts | 25 - .../src/application/uc/IndexBalance.ts | 147 - .../graphql/src/application/uc/IndexCosmos.ts | 143 - .../application/uc/IndexL1/IndexL1.test.ts | 151 - .../src/application/uc/IndexL1/IndexL1.ts | 189 - .../uc/IndexL1/L1ReorgSentinel.test.ts | 139 - .../application/uc/IndexL1/L1ReorgSentinel.ts | 117 - .../application/uc/IndexL1/abi/AbiFactory.ts | 42 - .../IndexL1/abi/mainnet/fuelChainStateAbi.ts | 581 --- .../abi/mainnet/fuelERC20GatewayV4Abi.ts | 923 ----- .../abi/mainnet/fuelMessagePortalAbi.ts | 1169 ------ .../uc/IndexL1/abi/mainnet/fuelStreamXAbi.ts | 1293 ------- .../abi/mainnet/rewardsDistributorAbi.ts | 721 ---- .../IndexL1/abi/mainnet/sequencerProxyAbi.ts | 1048 ------ .../uc/IndexL1/abi/mainnet/tokenAbi.ts | 1549 -------- .../IndexL1/abi/testnet/fuelChainStateAbi.ts | 577 --- .../abi/testnet/fuelERC20GatewayV4Abi.ts | 917 ----- .../abi/testnet/fuelMessagePortalAbi.ts | 1165 ------ .../uc/IndexL1/abi/testnet/fuelStreamXAbi.ts | 1275 ------- .../abi/testnet/rewardsDistributorAbi.ts | 721 ---- .../IndexL1/abi/testnet/sequencerProxyAbi.ts | 1049 ------ .../uc/IndexL1/abi/testnet/tokenAbi.ts | 1538 -------- .../uc/IndexL1/createL1Provider.ts | 10 - .../src/application/uc/IndexReceipt.ts | 122 - .../src/application/uc/NewAddBlockRange.ts | 470 --- .../src/application/uc/RunDatabaseJobs.ts | 59 - packages/graphql/src/assets.ts | 15 - packages/graphql/src/balance.ts | 15 - packages/graphql/src/config.ts | 25 - packages/graphql/src/constants/staking.ts | 22 - packages/graphql/src/core/Resolver.ts | 16 - packages/graphql/src/cosmos.ts | 14 - .../src/domain/Block/vo/BlockProducer.ts | 14 - packages/graphql/src/execute-contract.ts | 2872 --------------- packages/graphql/src/generated/mocks.ts | 964 ----- packages/graphql/src/generated/types.ts | 1890 ---------- .../graphql/src/graphql/GraphQLContext.ts | 38 - packages/graphql/src/graphql/GraphQLSDK.ts | 21 - packages/graphql/src/graphql/GraphQLServer.ts | 34 - .../src/graphql/resolvers/APYResolver.ts | 53 - .../src/graphql/resolvers/AssetResolver.ts | 50 - .../src/graphql/resolvers/BalanceResolver.ts | 149 - .../src/graphql/resolvers/BlockResolver.ts | 257 -- .../src/graphql/resolvers/BridgeResolver.ts | 46 - .../src/graphql/resolvers/ChainResolver.ts | 25 - .../src/graphql/resolvers/ContractResolver.ts | 97 - .../src/graphql/resolvers/NodeResolver.ts | 29 - .../graphql/resolvers/PredicateResolver.ts | 25 - .../src/graphql/resolvers/PublicResolver.ts | 26 - .../src/graphql/resolvers/SearchResolver.ts | 126 - .../src/graphql/resolvers/StakingResolver.ts | 50 - .../graphql/resolvers/TransactionResolver.ts | 165 - .../graphql/src/graphql/resolvers/index.ts | 58 - packages/graphql/src/index-nft-collections.ts | 48 - packages/graphql/src/index-total-supply.ts | 41 - packages/graphql/src/infra/abi/BridgeAbi.ts | 825 ----- packages/graphql/src/infra/abi/SRC7Abi.ts | 2833 --------------- .../graphql/src/infra/auth/GraphQLAuth.ts | 20 - .../graphql/src/infra/cache/AssetMetadata.ts | 797 ----- packages/graphql/src/infra/dao/AssetDAO.ts | 174 - packages/graphql/src/infra/dao/BalanceDAO.ts | 40 - packages/graphql/src/infra/dao/BlockDAO.ts | 333 -- packages/graphql/src/infra/dao/BridgeDAO.ts | 735 ---- .../graphql/src/infra/dao/BridgeDAO.types.ts | 157 - packages/graphql/src/infra/dao/Contract.ts | 20 - packages/graphql/src/infra/dao/ContractDAO.ts | 98 - packages/graphql/src/infra/dao/CosmosDAO.ts | 17 - packages/graphql/src/infra/dao/L1DAO.ts | 22 - packages/graphql/src/infra/dao/Predicate.ts | 18 - .../graphql/src/infra/dao/PredicateDAO.ts | 29 - packages/graphql/src/infra/dao/StakingDAO.ts | 1620 --------- .../graphql/src/infra/dao/StakingDAO.types.ts | 198 -- .../graphql/src/infra/dao/TEMP_StakingDAO.ts | 589 ---- .../graphql/src/infra/dao/TransactionDAO.ts | 372 -- packages/graphql/src/infra/dao/utils.test.ts | 64 - packages/graphql/src/infra/dao/utils.ts | 64 - .../src/infra/database/DatabaseConnection.ts | 124 - .../database/DatabaseConnectionReplica.ts | 115 - .../graphql/src/infra/gateway/AssetGateway.ts | 108 - .../src/infra/paginator/PaginatedParams.ts | 24 - packages/graphql/src/infra/server/App.ts | 401 --- packages/graphql/src/infra/timer/Timer.ts | 8 - packages/graphql/src/infra/util/util.ts | 48 - packages/graphql/src/jobs.ts | 14 - packages/graphql/src/l1.ts | 16 - packages/graphql/src/migrate-receipts.ts | 37 - packages/graphql/src/migrate-timestamp.ts | 24 - packages/graphql/src/recover.ts | 35 - packages/graphql/src/schemas/fuelcore.graphql | 0 packages/graphql/src/services/extends.graphql | 170 - packages/graphql/src/sync-block-range.ts | 14 - packages/graphql/src/syncer.ts | 221 -- packages/graphql/tsconfig.json | 4 +- packages/graphql/tsup.config.mjs | 7 - pnpm-lock.yaml | 3137 ++--------------- scripts/run-backend.sh | 5 - scripts/setup-backend.sh | 223 -- 202 files changed, 306 insertions(+), 41452 deletions(-) delete mode 100644 .github/workflows/docker-publish.yml delete mode 100644 .github/workflows/helm-publish.yml delete mode 100644 Tiltfile delete mode 100644 cluster/chart/Chart.lock delete mode 100644 cluster/chart/Chart.yaml delete mode 100644 cluster/chart/templates/env-configmap.yaml delete mode 100644 cluster/chart/templates/env-secrets.yaml delete mode 100644 cluster/chart/values.yaml delete mode 100755 cluster/scripts/build-image.sh delete mode 100755 cluster/scripts/setup-minikube.sh delete mode 100644 deployment/Dockerfile delete mode 100644 docker/envs/indexer.env delete mode 100644 helm/fuel-explorer/.helmignore delete mode 100644 helm/fuel-explorer/Chart.yaml delete mode 100644 helm/fuel-explorer/templates/NOTES.txt delete mode 100644 helm/fuel-explorer/templates/_helpers.tpl delete mode 100644 helm/fuel-explorer/templates/api/deployment.yaml delete mode 100644 helm/fuel-explorer/templates/api/hpa.yaml delete mode 100644 helm/fuel-explorer/templates/api/ingress.yaml delete mode 100644 helm/fuel-explorer/templates/api/service.yaml delete mode 100644 helm/fuel-explorer/templates/serviceaccount.yaml delete mode 100644 helm/fuel-explorer/templates/servicemonitor.yaml delete mode 100644 helm/fuel-explorer/templates/syncer/deployment.yaml delete mode 100644 helm/fuel-explorer/templates/tests/test-connection.yaml delete mode 100644 helm/fuel-explorer/values.yaml delete mode 100644 packages/graphql/.env.production delete mode 100644 packages/graphql/.swcrc delete mode 100644 packages/graphql/API.md delete mode 100644 packages/graphql/ASSETS.md delete mode 100644 packages/graphql/MIGRATION_GUIDE.md delete mode 100644 packages/graphql/database/migrations/001_create_schema_and_base_tables.sql delete mode 100644 packages/graphql/database/migrations/002_create_assets_contracts.sql delete mode 100644 packages/graphql/database/migrations/003_add_assets_contracts_columns.sql delete mode 100644 packages/graphql/database/migrations/004_add_owner_to_assets_contracts.sql delete mode 100644 packages/graphql/database/migrations/005_add_metadata_to_assets_contracts.sql delete mode 100644 packages/graphql/database/migrations/006_ensure_migration_table.sql delete mode 100644 packages/graphql/database/migrations/007_add_total_supply_to_assets_contracts.sql delete mode 100644 packages/graphql/database/migrations/008_create_nft_collections.sql delete mode 100644 packages/graphql/database/migrations/009_add_transactions_count_to_blocks.sql delete mode 100644 packages/graphql/database/migrations/010_create_asset_rate_tables.sql delete mode 100644 packages/graphql/database/migrations/011_add_nft_collections.sql delete mode 100644 packages/graphql/database/migrations/012_create_balance_tables.sql delete mode 100644 packages/graphql/database/migrations/013_create_l1_contract_tables.sql delete mode 100644 packages/graphql/database/migrations/014_create_cosmos_tables.sql delete mode 100644 packages/graphql/database/migrations/015_add_total_fee_and_timestamptz.sql delete mode 100644 packages/graphql/database/migrations/016_create_receipts_tables.sql delete mode 100644 packages/graphql/database/migrations/017_add_da_height_to_blocks.sql delete mode 100644 packages/graphql/database/migrations/018_convert_timestamps_create_ro_user.sql delete mode 100644 packages/graphql/database/migrations/019_create_staking_mvs_and_jobs.sql delete mode 100644 packages/graphql/database/migrations/020_receipts_id_to_bigserial.sql delete mode 100644 packages/graphql/database/migrations/021_balance_id_to_bigserial.sql delete mode 100644 packages/graphql/database/migrations/022_l1_index_id_to_bigserial.sql delete mode 100644 packages/graphql/database/migrations/023_l1_logs_id_to_bigserial.sql delete mode 100644 packages/graphql/database/migrations/024_l1_args_id_to_bigserial.sql delete mode 100644 packages/graphql/database/migrations/025_cosmos_responses_id_to_bigserial.sql delete mode 100644 packages/graphql/database/migrations/026_cosmos_events_id_to_bigserial.sql delete mode 100644 packages/graphql/database/migrations/027_receipts_data_id_to_bigserial.sql delete mode 100644 packages/graphql/database/migrations/028_add_vacuum_jobs.sql delete mode 100644 packages/graphql/database/migrations/029_add_search_indexes.sql delete mode 100644 packages/graphql/database/migrations/030_create_recent_transactions_mv.sql delete mode 100644 packages/graphql/database/migrations/031_add_statistics_indexes.sql delete mode 100644 packages/graphql/database/migrations/032_create_hourly_statistics_mv.sql delete mode 100644 packages/graphql/database/migrations/033_add_moor_token.sql delete mode 100644 packages/graphql/database/migrations/034_drop_unused_receipts_indexes.sql delete mode 100644 packages/graphql/database/migrations/035_add_receipts_vacuum_job.sql delete mode 100644 packages/graphql/database/migrations/036_optimize_hourly_statistics_mv.sql delete mode 100644 packages/graphql/database/migrations/037_outputs_id_to_bigserial.sql delete mode 100644 packages/graphql/database/migrations/038_inputs_id_to_bigserial.sql delete mode 100644 packages/graphql/database/migrations/039_predicates_id_to_bigserial.sql delete mode 100644 packages/graphql/database/migrations/040_contracts_id_to_bigserial.sql delete mode 100644 packages/graphql/database/migrations/041_optimize_staking_mvs.sql delete mode 100644 packages/graphql/database/migrations/042_drop_unused_indexes.sql delete mode 100644 packages/graphql/database/migrations/043_replace_staking_mvs_with_agg_tables.sql delete mode 100644 packages/graphql/database/migrations/044_optimize_storage_drop_unused_data.sql delete mode 100644 packages/graphql/database/migrations/045_vacuum_receipts.sql delete mode 100644 packages/graphql/database/migrations/046_replace_hourly_statistics_mv_with_agg_table.sql delete mode 100644 packages/graphql/database/migrations/047_optimize_balance_index.sql delete mode 100644 packages/graphql/database/migrations/048_drop_unused_recent_account_transactions_mv.sql delete mode 100644 packages/graphql/database/migrations/049_drop_unused_redundant_indexes.sql delete mode 100644 packages/graphql/database/migrations/050_tune_autovacuum_large_tables.sql delete mode 100644 packages/graphql/ecosystem-dev.config.cjs delete mode 100644 packages/graphql/ecosystem-prod-api.config.cjs delete mode 100644 packages/graphql/ecosystem-prod-syncer.config.cjs delete mode 100644 packages/graphql/ecosystem.config.cjs delete mode 100644 packages/graphql/explorer_backend_indexer_architecture.png delete mode 100644 packages/graphql/jest.config.ts delete mode 100644 packages/graphql/logs/empty delete mode 100755 packages/graphql/scripts/migrate.ts delete mode 100755 packages/graphql/scripts/run.sh delete mode 100644 packages/graphql/scripts/setup-migrations.ts delete mode 100644 packages/graphql/src/app.ts delete mode 100644 packages/graphql/src/application/uc/GetAccountAssets.ts delete mode 100644 packages/graphql/src/application/uc/GetAssetsRate.ts delete mode 100644 packages/graphql/src/application/uc/GetMetrics.ts delete mode 100644 packages/graphql/src/application/uc/GetTransaction.ts delete mode 100644 packages/graphql/src/application/uc/IndexAsset/GetAssetDetails.ts delete mode 100644 packages/graphql/src/application/uc/IndexAsset/IndexAsset.ts delete mode 100644 packages/graphql/src/application/uc/IndexAsset/IndexAssetsRate.ts delete mode 100644 packages/graphql/src/application/uc/IndexAsset/NFTIndexer.ts delete mode 100644 packages/graphql/src/application/uc/IndexBalance.ts delete mode 100644 packages/graphql/src/application/uc/IndexCosmos.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/IndexL1.test.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/IndexL1.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/L1ReorgSentinel.test.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/L1ReorgSentinel.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/AbiFactory.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelChainStateAbi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelERC20GatewayV4Abi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelMessagePortalAbi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelStreamXAbi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/mainnet/rewardsDistributorAbi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/mainnet/sequencerProxyAbi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/mainnet/tokenAbi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelChainStateAbi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelERC20GatewayV4Abi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelMessagePortalAbi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelStreamXAbi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/testnet/rewardsDistributorAbi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/testnet/sequencerProxyAbi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/abi/testnet/tokenAbi.ts delete mode 100644 packages/graphql/src/application/uc/IndexL1/createL1Provider.ts delete mode 100644 packages/graphql/src/application/uc/IndexReceipt.ts delete mode 100644 packages/graphql/src/application/uc/NewAddBlockRange.ts delete mode 100644 packages/graphql/src/application/uc/RunDatabaseJobs.ts delete mode 100644 packages/graphql/src/assets.ts delete mode 100644 packages/graphql/src/balance.ts delete mode 100644 packages/graphql/src/constants/staking.ts delete mode 100644 packages/graphql/src/core/Resolver.ts delete mode 100644 packages/graphql/src/cosmos.ts delete mode 100644 packages/graphql/src/execute-contract.ts delete mode 100644 packages/graphql/src/generated/mocks.ts delete mode 100644 packages/graphql/src/generated/types.ts delete mode 100644 packages/graphql/src/graphql/GraphQLContext.ts delete mode 100644 packages/graphql/src/graphql/GraphQLSDK.ts delete mode 100644 packages/graphql/src/graphql/GraphQLServer.ts delete mode 100644 packages/graphql/src/graphql/resolvers/APYResolver.ts delete mode 100644 packages/graphql/src/graphql/resolvers/AssetResolver.ts delete mode 100644 packages/graphql/src/graphql/resolvers/BalanceResolver.ts delete mode 100644 packages/graphql/src/graphql/resolvers/BlockResolver.ts delete mode 100644 packages/graphql/src/graphql/resolvers/BridgeResolver.ts delete mode 100644 packages/graphql/src/graphql/resolvers/ChainResolver.ts delete mode 100644 packages/graphql/src/graphql/resolvers/ContractResolver.ts delete mode 100644 packages/graphql/src/graphql/resolvers/NodeResolver.ts delete mode 100644 packages/graphql/src/graphql/resolvers/PredicateResolver.ts delete mode 100644 packages/graphql/src/graphql/resolvers/PublicResolver.ts delete mode 100644 packages/graphql/src/graphql/resolvers/SearchResolver.ts delete mode 100644 packages/graphql/src/graphql/resolvers/StakingResolver.ts delete mode 100644 packages/graphql/src/graphql/resolvers/TransactionResolver.ts delete mode 100644 packages/graphql/src/graphql/resolvers/index.ts delete mode 100644 packages/graphql/src/index-nft-collections.ts delete mode 100644 packages/graphql/src/index-total-supply.ts delete mode 100644 packages/graphql/src/infra/abi/BridgeAbi.ts delete mode 100644 packages/graphql/src/infra/abi/SRC7Abi.ts delete mode 100644 packages/graphql/src/infra/auth/GraphQLAuth.ts delete mode 100644 packages/graphql/src/infra/cache/AssetMetadata.ts delete mode 100644 packages/graphql/src/infra/dao/AssetDAO.ts delete mode 100644 packages/graphql/src/infra/dao/BalanceDAO.ts delete mode 100644 packages/graphql/src/infra/dao/BlockDAO.ts delete mode 100644 packages/graphql/src/infra/dao/BridgeDAO.ts delete mode 100644 packages/graphql/src/infra/dao/BridgeDAO.types.ts delete mode 100644 packages/graphql/src/infra/dao/Contract.ts delete mode 100644 packages/graphql/src/infra/dao/ContractDAO.ts delete mode 100644 packages/graphql/src/infra/dao/CosmosDAO.ts delete mode 100644 packages/graphql/src/infra/dao/L1DAO.ts delete mode 100644 packages/graphql/src/infra/dao/Predicate.ts delete mode 100644 packages/graphql/src/infra/dao/PredicateDAO.ts delete mode 100644 packages/graphql/src/infra/dao/StakingDAO.ts delete mode 100644 packages/graphql/src/infra/dao/StakingDAO.types.ts delete mode 100644 packages/graphql/src/infra/dao/TEMP_StakingDAO.ts delete mode 100644 packages/graphql/src/infra/dao/TransactionDAO.ts delete mode 100644 packages/graphql/src/infra/dao/utils.test.ts delete mode 100644 packages/graphql/src/infra/database/DatabaseConnection.ts delete mode 100644 packages/graphql/src/infra/database/DatabaseConnectionReplica.ts delete mode 100644 packages/graphql/src/infra/gateway/AssetGateway.ts delete mode 100644 packages/graphql/src/infra/paginator/PaginatedParams.ts delete mode 100644 packages/graphql/src/infra/server/App.ts delete mode 100644 packages/graphql/src/infra/timer/Timer.ts delete mode 100644 packages/graphql/src/infra/util/util.ts delete mode 100644 packages/graphql/src/jobs.ts delete mode 100644 packages/graphql/src/l1.ts delete mode 100644 packages/graphql/src/migrate-receipts.ts delete mode 100644 packages/graphql/src/migrate-timestamp.ts delete mode 100644 packages/graphql/src/recover.ts delete mode 100644 packages/graphql/src/schemas/fuelcore.graphql delete mode 100644 packages/graphql/src/services/extends.graphql delete mode 100644 packages/graphql/src/sync-block-range.ts delete mode 100644 packages/graphql/src/syncer.ts delete mode 100755 scripts/run-backend.sh delete mode 100755 scripts/setup-backend.sh diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml deleted file mode 100644 index f2055fa0d..000000000 --- a/.github/workflows/docker-publish.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: Build and publish Docker image - -on: - workflow_dispatch: - push: - branches: - - main - pull_request: - types: [opened, synchronize] - release: - types: [published] - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -permissions: - contents: read - packages: write - id-token: write - -jobs: - build-and-publish-image: - uses: FuelLabs/github-actions/.github/workflows/docker-build-push.yml@master - if: | - (github.event_name == 'release' && github.event.action == 'published') || - github.ref == 'refs/heads/main' || - (github.event_name == 'pull_request' && - github.event.pull_request.head.repo.full_name == github.repository) || - github.event_name == 'workflow_dispatch' - secrets: - REGISTRY_USERNAME: ${{ github.repository_owner }} - REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} - with: - auth-mode: registry-login - registry: ghcr.io - build-backend: native - platforms: linux/amd64,linux/arm64 - runs-on-amd64: ubuntu-latest - runs-on-arm64: ubuntu-24.04-arm - dockerfile: deployment/Dockerfile - docker-context: . - image: ghcr.io/fuellabs/fuel-explorer - tags: | - type=ref,event=branch - type=sha,prefix= - type=semver,pattern={{raw}} diff --git a/.github/workflows/helm-publish.yml b/.github/workflows/helm-publish.yml deleted file mode 100644 index 6a501c2ec..000000000 --- a/.github/workflows/helm-publish.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Build and publish Helm Chart - -on: - workflow_dispatch: - push: - branches: - - main - paths: - - "helm/fuel-explorer/Chart.yaml" - pull_request: - types: [ opened, synchronize ] - release: - types: [ published ] - -permissions: - contents: read - -jobs: - helm-release: - name: Build Helm Chart - runs-on: warp-ubuntu-latest-x64-4x - if: | - (github.event_name == 'release' && github.event.action == 'published') || - github.ref == 'refs/heads/main' || github.event_name == 'pull_request' || - github.event_name == 'workflow_dispatch' - permissions: - contents: read - packages: write - - steps: - - name: Check out code - uses: actions/checkout@v3 - - - name: Package and Push Charts - uses: bsord/helm-push@v4.1.0 - with: - useOCIRegistry: true - registry-url: oci://ghcr.io/fuellabs/helmcharts - username: ${{ github.repository_owner }} - access-token: ${{ secrets.GITHUB_TOKEN }} - force: true - chart-folder: ./helm/fuel-explorer diff --git a/Tiltfile b/Tiltfile deleted file mode 100644 index b7f183fbb..000000000 --- a/Tiltfile +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python -load('ext://restart_process', 'docker_build_with_restart') -load('ext://color', 'color') -load('ext://dotenv', 'dotenv') - -analytics_settings(True) # Enable telemetry dialogue in web UI -disable_snapshots() # Disable TiltCloud Snapshots -version_settings(True) # Enable 'new version' banner - -# Load environment variables from .env file -dotenv() - -# Allow users to run `tilt up --stream` for better log handling -allow_k8s_contexts('minikube') - -# Build the Docker image -custom_build( - ref='fuel-explorer:local', - command=[ - './cluster/scripts/build-image.sh', - '--image-name', 'fuel-explorer', - '--dockerfile', './deployment/Dockerfile', - ], - deps=[ - 'deployment/Dockerfile', - 'packages', - 'pnpm-lock.yaml', - 'pnpm-workspace.yaml' - ], - live_update=[ - sync('packages', '/app'), - sync('pnpm-lock.yaml', '/app/pnpm-lock.yaml'), - sync('pnpm-workspace.yaml', '/app/pnpm-workspace.yaml'), - run('pnpm install --frozen-lockfile', trigger=['pnpm-lock.yaml']), - run('pnpm build:lib', trigger=['packages']), - ], - ignore=['node_modules'] -) - -# Create namespace -k8s_yaml(blob(""" -apiVersion: v1 -kind: Namespace -metadata: - name: fuel-explorer -""")) - -# Deploy Helm chart -k8s_yaml(helm( - 'cluster/chart', - values=['cluster/chart/values.yaml'], - name='fuel-explorer-local', - namespace='fuel-explorer' -)) - -# Port forwards for services -k8s_resource( - 'fuel-explorer-local-api', - port_forwards=['3000:3000'] -) - -k8s_resource( - 'fuel-explorer-local-syncer', - port_forwards=['3001:3001'] -) - -# Resource grouping for better UI organization -k8s_resource( - 'fuel-explorer-local-postgresql', - new_name='postgresql', - port_forwards=['5432:5432'] -) - -k8s_resource( - 'fuel-explorer-local-rabbitmq', - new_name='rabbitmq', - port_forwards=['5672:5672'] -) diff --git a/cluster/chart/Chart.lock b/cluster/chart/Chart.lock deleted file mode 100644 index fd204ddb6..000000000 --- a/cluster/chart/Chart.lock +++ /dev/null @@ -1,12 +0,0 @@ -dependencies: -- name: postgresql - repository: https://charts.bitnami.com/bitnami - version: 12.12.10 -- name: rabbitmq - repository: https://charts.bitnami.com/bitnami - version: 11.16.2 -- name: fuel-explorer - repository: file://../../helm/fuel-explorer - version: 0.2.6 -digest: sha256:716fdd5b77743a2a312b2d87d51d02f4dada7341634f785f2ff9afc116137048 -generated: "2024-12-18T21:56:35.478468-03:00" diff --git a/cluster/chart/Chart.yaml b/cluster/chart/Chart.yaml deleted file mode 100644 index 69af351df..000000000 --- a/cluster/chart/Chart.yaml +++ /dev/null @@ -1,19 +0,0 @@ -apiVersion: v2 -name: fuel-explorer-local -type: application -version: 0.2.5 -appVersion: "0.1.0" - -dependencies: - - name: postgresql - version: "12.x.x" - repository: "https://charts.bitnami.com/bitnami" - condition: postgresql.enabled - - name: rabbitmq - version: "11.x.x" - repository: "https://charts.bitnami.com/bitnami" - condition: rabbitmq.enabled - - name: fuel-explorer - version: "0.2.6" - repository: "file://../../helm/fuel-explorer" - condition: fuel-explorer.enabled diff --git a/cluster/chart/templates/env-configmap.yaml b/cluster/chart/templates/env-configmap.yaml deleted file mode 100644 index 969696804..000000000 --- a/cluster/chart/templates/env-configmap.yaml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: fuel-explorer-local -data: - NODE_TLS_REJECT_UNAUTHORIZED: "0" - LOG_DIR: "/tmp" - SERVER_PORT: "3000" - SERVER_API_KEY: "nZ9GZayrd8" - SYNCER_PORT: "3001" - SYNC_MISSING: "true" - SERVER_BUILD: "true" - SYNC_OFFSET: "10" - SYNC_LIMIT: "100" - QUEUE_CONCURRENCY: "5" - WATCH_INTERVAL: "5000" - FUEL_PROVIDER: "http://testnet.fuel.network/v1/graphql" - DB_HOST: "fuel-explorer-local-postgres" - DB_PORT: "5432" - DB_USER: "postgres" - DB_NAME: "fuel_explorer" - DB_HOST_REPLICA: "fuel-explorer-local-postgres" - DB_PORT_REPLICA: "5432" - DB_USER_REPLICA: "postgres" - DB_NAME_REPLICA: "fuel_explorer" - RABBITMQ_HOST: "fuel-explorer-local-rabbitmq" - RABBITMQ_PORT: "5672" - RABBITMQ_USER: "rabbitmq" - SSL: "false" - DEBUG: "true" diff --git a/cluster/chart/templates/env-secrets.yaml b/cluster/chart/templates/env-secrets.yaml deleted file mode 100644 index e15999ff4..000000000 --- a/cluster/chart/templates/env-secrets.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: fuel-explorer-local -stringData: - DB_PASS: postgres - RABBITMQ_PASS: password diff --git a/cluster/chart/values.yaml b/cluster/chart/values.yaml deleted file mode 100644 index 4f8e5def3..000000000 --- a/cluster/chart/values.yaml +++ /dev/null @@ -1,51 +0,0 @@ -fuel-explorer: - healthcheck: - enabled: false - - app: - serviceMonitor: - enabled: false - - api: - enabled: true - ingress: - enabled: false - service: - type: ClusterIP - port: 3000 - image: - repository: fuel-explorer - tag: local - pullPolicy: IfNotPresent - livenessProbe: {} - readinessProbe: {} - - syncer: - enabled: true - service: - type: ClusterIP - port: 3001 - image: - repository: fuel-explorer - tag: local - pullPolicy: IfNotPresent - -postgresql: - enabled: true - auth: - username: fuel-explorer - password: fuel-explorer - database: fuel-explorer - primary: - persistence: - enabled: true - size: 1Gi - -rabbitmq: - enabled: true - auth: - username: fuel-explorer - password: fuel-explorer - persistence: - enabled: true - size: 1Gi diff --git a/cluster/scripts/build-image.sh b/cluster/scripts/build-image.sh deleted file mode 100755 index 402e57e2c..000000000 --- a/cluster/scripts/build-image.sh +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env bash - -# Default values -IMAGE_NAME="fuel-explorer" -DOCKERFILE="deployment/Dockerfile" -TAG=${EXPECTED_TAG:-"local"} # From environment variable with default - -# Parse named arguments -while [[ $# -gt 0 ]]; do - case $1 in - --image-name) - IMAGE_NAME="$2" - shift 2 - ;; - --dockerfile) - DOCKERFILE="$2" - shift 2 - ;; - --tag) - TAG="$2" - shift 2 - ;; - *) - echo "Error: Unknown argument '$1'" - usage - ;; - esac -done - -echo "Using docker host: $DOCKER_HOST" -eval $(minikube docker-env) -docker build -t "${IMAGE_NAME}:${TAG}" -f "${DOCKERFILE}" . diff --git a/cluster/scripts/setup-minikube.sh b/cluster/scripts/setup-minikube.sh deleted file mode 100755 index 720370726..000000000 --- a/cluster/scripts/setup-minikube.sh +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env bash - -[[ $DEBUG = true ]] && set -x -set -euo pipefail - -# Delete any existing minikube cluster -minikube delete - -# Set disk and memory size, using defaults if not provided -DISK_SIZE=${1:-'50000mb'} -MEMORY=${2:-'12000mb'} - -# Start minikube with specified resources -minikube start \ - --driver=docker \ - --disk-size="$DISK_SIZE" \ - --memory="$MEMORY" \ - --cpus 8 - -minikube addons enable registry -minikube addons enable registry-aliases - -# Display minikube status -echo -e "\n\033[1;33mMinikube Status:\033[0m" -minikube status - -cd cluster/chart && helm dependency update \ No newline at end of file diff --git a/deployment/Dockerfile b/deployment/Dockerfile deleted file mode 100644 index 678653d5d..000000000 --- a/deployment/Dockerfile +++ /dev/null @@ -1,53 +0,0 @@ -# This image contains the graphql server -# built for the fuel-explorer -FROM node:20 AS base - -ENV DEBIAN_FRONTEND=noninteractive -RUN apt update && apt install -y postgresql-client - -# Expose the ENVs to the env of the container -ENV PNPM_HOME="/pnpm" -ENV PATH="$PNPM_HOME:$PATH" -ENV SERVER_PORT="${SERVER_PORT:-3000}" -ENV SYNCER_PORT="${SYNCER_PORT:-3001}" -ENV FUEL_PROVIDER="${FUEL_PROVIDER:-https://testnet.fuel.network/v1/graphql}" -ENV SERVER_BUILD=true -ENV SYNC_MISSING=true -ENV DB_HOST="${DB_HOST}" -ENV DB_PORT="${DB_PORT}" -ENV DB_NAME="${DB_NAME}" -ENV DB_USER="${DB_USER}" -ENV DB_PASS="${DB_PASS}" -ENV DB_HOST_REPLICA="${DB_HOST_REPLICA}" -ENV DB_PORT_REPLICA="${DB_PORT_REPLICA}" -ENV DB_NAME_REPLICA="${DB_NAME_REPLICA}" -ENV DB_USER_REPLICA="${DB_USER_REPLICA}" -ENV DB_PASS_REPLICA="${DB_PASS_REPLICA}" -ENV RABBITMQ_HOST="${RABBITMQ_HOST}" -ENV RABBITMQ_PORT="${RABBITMQ_PORT}" -ENV RABBITMQ_USER="${RABBITMQ_USER}" -ENV RABBITMQ_PASS="${RABBITMQ_PASS}" -ENV SERVICE="${SERVICE:-api}" - -# RUN corepack enable -# RUN corepack prepare pnpm@9.5.0 --activate - -RUN npm install pnpm@9.5.0 -g - -FROM base AS build -COPY . /app -WORKDIR /app -RUN pnpm install --frozen-lockfile - -FROM base AS explorer -COPY --from=build /app /app-explorer - -WORKDIR /app-explorer/packages/app-commons -RUN pnpm build:lib - -WORKDIR /app-explorer/packages/graphql -RUN pnpm build:lib - -EXPOSE ${SERVER_PORT} - -CMD sh ./scripts/run.sh $SERVICE \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 0b1c6a887..e387fd65d 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -90,53 +90,5 @@ services: networks: - app-network - fuel_explorer_pgsql: - profiles: - - all - - indexer - - indexer-local - image: postgres:latest - platform: linux/amd64 - container_name: fuel_explorer_pgsql - ports: - - "5435:5432" - volumes: - - fuel_explorer_pgsql-db:/usr/local/postgres - env_file: - - ./envs/indexer.env - environment: - - POSTGRES_DB={DB_NAME:-postgres} - - POSTGRES_USER=${DB_USER:-postgres} - - POSTGRES_PASSWORD=${DB_PASS:-postgres} - healthcheck: - test: ["CMD-SHELL", "pg_isready", "-U", "${DB_USER}", "-d", "${DB_NAME}"] - interval: 5s - timeout: 5s - retries: 5 - networks: - - app-network - - # fuel_indexer_graphql: - # profiles: - # - all - # - indexer - # depends_on: - # fuel_explorer_pgsql: - # condition: service_healthy - # build: - # context: ../ - # dockerfile: ./deployment/Dockerfile - # env_file: - # - ./envs/global.env - # - ./envs/indexer.env - # ports: - # - "${INDEXER_GRAPHQL_PORT:-3004}:${SERVER_PORT:-3004}" - # - "${INDEXER_SYNCER_PORT:-3005}:${SYNCER_PORT:-3005}" - # networks: - # - app-network - -volumes: - fuel_explorer_pgsql-db: - networks: app-network: diff --git a/docker/envs/global.env b/docker/envs/global.env index fce74d0c5..2d1cb5448 100644 --- a/docker/envs/global.env +++ b/docker/envs/global.env @@ -5,13 +5,3 @@ CONSENSUS_KEY_SECRET="0xa449b1ffee0e2205fa924c6740cc48b3b473aa28587df6dab12abc24 # Ports to expose DEPLOYMENTS_PORT=8080 FUEL_CORE_HTTP_PORT=4000 -INDEXER_GRAPHQL_PORT=3004 -INDEXER_SYNCER_PORT=3005 - -# Indexer envs -FUEL_PROVIDER=http://fuel_core:4000/v1/graphql -DB_HOST="fuel_explorer_pgsql" -DB_PORT=5432 -DB_USER=postgres -DB_PASS=postgres -DB_NAME=postgres diff --git a/docker/envs/indexer.env b/docker/envs/indexer.env deleted file mode 100644 index 937ae61c0..000000000 --- a/docker/envs/indexer.env +++ /dev/null @@ -1,11 +0,0 @@ -SERVER_PORT=3004 -SERVER_API_KEY=my-secret -SYNCER_PORT=3005 -SYNC_MISSING=true -SERVER_BUILD=true -SYNC_OFFSET=10 -SYNC_LIMIT=100000 -QUEUE_CONCURRENCY=50 -WATCH_INTERVAL=1000 -SSL=false -DEBUG=true diff --git a/docs/GETTING_STARTED.md b/docs/GETTING_STARTED.md index d52a9ec4b..8afc18902 100644 --- a/docs/GETTING_STARTED.md +++ b/docs/GETTING_STARTED.md @@ -35,7 +35,6 @@ This command will start essential development services; - `L1` local node (to handle ethereum blockchain); - `Fuel` local node (to handle L2 chain); -- `Postgres` database (that we use to index data); ``` pnpm node:start @@ -43,6 +42,8 @@ pnpm node:start > You can check more details in [docker-compose.yml](https://github.com/FuelLabs/fuel-explorer/blob/main/docker/docker-compose.yml) file. +The explorer no longer runs on a Postgres-backed API and syncer. It is served by `packages/api-lite`, which reads blocks from the S3 block recorder and fuel-core, with a sqlite index and no database to operate. See [`docker/vps/deploy.md`](https://github.com/FuelLabs/fuel-explorer/blob/main/docker/vps/deploy.md) for how it is deployed. + ### 💻 4. Run Web App Now that you have the local node running, you can start the frontend. diff --git a/helm/fuel-explorer/.helmignore b/helm/fuel-explorer/.helmignore deleted file mode 100644 index 0e8a0eb36..000000000 --- a/helm/fuel-explorer/.helmignore +++ /dev/null @@ -1,23 +0,0 @@ -# Patterns to ignore when building packages. -# This supports shell glob matching, relative path matching, and -# negation (prefixed with !). Only one pattern per line. -.DS_Store -# Common VCS dirs -.git/ -.gitignore -.bzr/ -.bzrignore -.hg/ -.hgignore -.svn/ -# Common backup files -*.swp -*.bak -*.tmp -*.orig -*~ -# Various IDEs -.project -.idea/ -*.tmproj -.vscode/ diff --git a/helm/fuel-explorer/Chart.yaml b/helm/fuel-explorer/Chart.yaml deleted file mode 100644 index 6eb05423a..000000000 --- a/helm/fuel-explorer/Chart.yaml +++ /dev/null @@ -1,6 +0,0 @@ -apiVersion: v2 -name: fuel-explorer -description: A Helm chart for Kubernetes -type: application -version: 0.3.0 -appVersion: "0.1.0" diff --git a/helm/fuel-explorer/templates/NOTES.txt b/helm/fuel-explorer/templates/NOTES.txt deleted file mode 100644 index e91dbecce..000000000 --- a/helm/fuel-explorer/templates/NOTES.txt +++ /dev/null @@ -1,22 +0,0 @@ -1. Get the application URL by running these commands: -{{- if .Values.api.ingress.enabled }} -{{- range $host := .Values.api.ingress.hosts }} - {{- range .paths }} - http{{ if $.Values.api.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} - {{- end }} -{{- end }} -{{- else if contains "NodePort" .Values.api.service.type }} - export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "fuel-explorer.fullname" . }}) - export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") - echo http://$NODE_IP:$NODE_PORT -{{- else if contains "LoadBalancer" .Values.api.service.type }} - NOTE: It may take a few minutes for the LoadBalancer IP to be available. - You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "fuel-explorer.fullname" . }}' - export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "fuel-explorer.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") - echo http://$SERVICE_IP:{{ .Values.api.service.port }} -{{- else if contains "ClusterIP" .Values.api.service.type }} - export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "fuel-explorer.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") - export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") - echo "Visit http://127.0.0.1:8080 to use your application" - kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT -{{- end }} diff --git a/helm/fuel-explorer/templates/_helpers.tpl b/helm/fuel-explorer/templates/_helpers.tpl deleted file mode 100644 index 32fe6abaf..000000000 --- a/helm/fuel-explorer/templates/_helpers.tpl +++ /dev/null @@ -1,62 +0,0 @@ -{{/* -Expand the name of the chart. -*/}} -{{- define "fuel-explorer.name" -}} -{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Create a default fully qualified app name. -We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). -If release name contains chart name it will be used as a full name. -*/}} -{{- define "fuel-explorer.fullname" -}} -{{- if .Values.fullnameOverride }} -{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- $name := default .Chart.Name .Values.nameOverride }} -{{- if contains $name .Release.Name }} -{{- .Release.Name | trunc 63 | trimSuffix "-" }} -{{- else }} -{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} -{{- end }} -{{- end }} -{{- end }} - -{{/* -Create chart name and version as used by the chart label. -*/}} -{{- define "fuel-explorer.chart" -}} -{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} -{{- end }} - -{{/* -Common labels -*/}} -{{- define "fuel-explorer.labels" -}} -helm.sh/chart: {{ include "fuel-explorer.chart" . }} -{{ include "fuel-explorer.selectorLabels" . }} -{{- if .Chart.AppVersion }} -app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} -{{- end }} -app.kubernetes.io/managed-by: {{ .Release.Service }} -{{- end }} - -{{/* -Selector labels -*/}} -{{- define "fuel-explorer.selectorLabels" -}} -app.kubernetes.io/name: {{ include "fuel-explorer.name" . }} -app.kubernetes.io/instance: {{ .Release.Name }} -{{- end }} - -{{/* -Create the name of the service account to use -*/}} -{{- define "fuel-explorer.serviceAccountName" -}} -{{- if .Values.serviceAccount.create }} -{{- default (include "fuel-explorer.fullname" .) .Values.serviceAccount.name }} -{{- else }} -{{- default "default" .Values.serviceAccount.name }} -{{- end }} -{{- end }} diff --git a/helm/fuel-explorer/templates/api/deployment.yaml b/helm/fuel-explorer/templates/api/deployment.yaml deleted file mode 100644 index 2d304ef4f..000000000 --- a/helm/fuel-explorer/templates/api/deployment.yaml +++ /dev/null @@ -1,104 +0,0 @@ -{{- $service := .Values.api -}} -{{- if $service.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "fuel-explorer.fullname" . }}-api - labels: - {{- include "fuel-explorer.labels" . | nindent 4 }} - app.kubernetes.io/service: {{ include "fuel-explorer.fullname" . }}-api -spec: - {{- if not $service.autoscaling.enabled }} - replicas: {{ $service.replicaCount }} - {{- end }} - selector: - matchLabels: - {{- include "fuel-explorer.selectorLabels" . | nindent 6 }} - app.kubernetes.io/service: {{ include "fuel-explorer.fullname" . }}-api - template: - metadata: - {{- with $service.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "fuel-explorer.selectorLabels" . | nindent 8 }} - app.kubernetes.io/service: {{ include "fuel-explorer.fullname" . }}-api - spec: - {{- if $service.imagePullSecrets }} - imagePullSecrets: - {{- toYaml $service.imagePullSecrets | nindent 8 }} - {{- end }} - {{- if $service.podSecurityContext }} - securityContext: - {{- toYaml $service.podSecurityContext | nindent 8 }} - {{- end }} - serviceAccountName: {{ include "fuel-explorer.serviceAccountName" . }} - containers: - - name: {{ include "fuel-explorer.fullname" . }}-api - {{- if $service.securityContext }} - securityContext: - {{- toYaml $service.securityContext | nindent 12 }} - {{- end }} - image: "{{ $service.image.repository }}:{{ $service.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ $service.image.pullPolicy }} - {{- if $service.image.args }} - args: - {{- toYaml $service.image.args | nindent 12 }} - {{- end }} - - env: - - name: SERVICE - value: api - - envFrom: - - configMapRef: - name: {{ include "fuel-explorer.fullname" . }} - - secretRef: - name: {{ include "fuel-explorer.fullname" . }} - ports: - - name: http - containerPort: {{ $service.service.port }} - protocol: TCP - - {{- if .Values.healthcheck.enabled }} - {{- if $service.livenessProbe }} - livenessProbe: - {{- toYaml $service.livenessProbe | nindent 12 }} - {{- end }} - {{- if $service.readinessProbe }} - readinessProbe: - {{- toYaml $service.readinessProbe | nindent 12 }} - {{- end }} - {{- end }} - - volumeMounts: - - mountPath: /home/node/.cache - name: node-cache - - mountPath: /home/node/.pm2 - name: pm2 - - mountPath: /tmp - name: tmp - resources: - {{- toYaml $service.resources | nindent 12 }} - volumes: - - name: node-cache - emptyDir: {} - - name: pm2 - emptyDir: {} - - name: tmp - emptyDir: {} - - {{- if $service.nodeSelector }} - nodeSelector: - {{- toYaml $service.nodeSelector | nindent 8 }} - {{- end }} - {{- if $service.affinity }} - affinity: - {{- toYaml $service.affinity | nindent 8 }} - {{- end }} - {{- if $service.tolerations }} - tolerations: - {{- toYaml $service.tolerations | nindent 8 }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/helm/fuel-explorer/templates/api/hpa.yaml b/helm/fuel-explorer/templates/api/hpa.yaml deleted file mode 100644 index 0233eafec..000000000 --- a/helm/fuel-explorer/templates/api/hpa.yaml +++ /dev/null @@ -1,34 +0,0 @@ -{{- $api := .Values.api -}} -{{- if $api.autoscaling.enabled }} -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: {{ include "fuel-explorer.fullname" . }}-api - labels: - {{- include "fuel-explorer.labels" . | nindent 4 }} - app.kubernetes.io/service: {{ include "fuel-explorer.fullname" . }}-api -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: {{ include "fuel-explorer.fullname" . }}-api - minReplicas: {{ $api.autoscaling.minReplicas }} - maxReplicas: {{ $api.autoscaling.maxReplicas }} - metrics: - {{- if $api.autoscaling.targetCPUUtilizationPercentage }} - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: {{ $api.autoscaling.targetCPUUtilizationPercentage }} - {{- end }} - {{- if $api.autoscaling.targetMemoryUtilizationPercentage }} - - type: Resource - resource: - name: memory - target: - type: Utilization - averageUtilization: {{ $api.autoscaling.targetMemoryUtilizationPercentage }} - {{- end }} -{{- end }} diff --git a/helm/fuel-explorer/templates/api/ingress.yaml b/helm/fuel-explorer/templates/api/ingress.yaml deleted file mode 100644 index 06f12015c..000000000 --- a/helm/fuel-explorer/templates/api/ingress.yaml +++ /dev/null @@ -1,65 +0,0 @@ -{{- $api := .Values.api -}} -{{- $svcPort := $api.service.port -}} -{{- $fullname := include "fuel-explorer.fullname" . }} - -{{- if $api.ingress.enabled -}} -{{- if and $api.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} - {{- if not (hasKey $api.ingress.annotations "kubernetes.io/ingress.class") }} - {{- $_ := set $api.ingress.annotations "kubernetes.io/ingress.class" $api.ingress.className}} - {{- end }} -{{- end }} - -{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} -apiVersion: networking.k8s.io/v1 -{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} -apiVersion: networking.k8s.io/v1beta1 -{{- else -}} -apiVersion: extensions/v1beta1 -{{- end }} -kind: Ingress -metadata: - name: {{ $fullname }}-api - labels: - {{- include "fuel-explorer.labels" . | nindent 4 }} - app.kubernetes.io/service: {{ $fullname }}-api - {{- with $api.ingress.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - {{- if and $api.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} - ingressClassName: {{ $api.ingress.className }} - {{- end }} - {{- if $api.ingress.tls }} - tls: - {{- range $api.ingress.tls }} - - hosts: - {{- range .hosts }} - - {{ . | quote }} - {{- end }} - secretName: {{ .secretName }} - {{- end }} - {{- end }} - rules: - {{- range $api.ingress.hosts }} - - host: {{ .host | quote }} - http: - paths: - {{- range .paths }} - - path: {{ .path }} - {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} - pathType: {{ .pathType }} - {{- end }} - backend: - {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} - service: - name: {{ $fullname }}-api - port: - number: {{ $svcPort }} - {{- else }} - serviceName: {{ $fullname }}-api - servicePort: {{ $svcPort }} - {{- end }} - {{- end }} - {{- end }} -{{- end }} diff --git a/helm/fuel-explorer/templates/api/service.yaml b/helm/fuel-explorer/templates/api/service.yaml deleted file mode 100644 index 5aebff272..000000000 --- a/helm/fuel-explorer/templates/api/service.yaml +++ /dev/null @@ -1,20 +0,0 @@ -{{- $api := .Values.api -}} -{{- if $api.service.enabled -}} -apiVersion: v1 -kind: Service -metadata: - name: {{ include "fuel-explorer.fullname" . }}-api - labels: - {{- include "fuel-explorer.labels" . | nindent 4 }} - app.kubernetes.io/service: {{ include "fuel-explorer.fullname" . }}-api -spec: - type: {{ $api.service.type }} - ports: - - port: {{ $api.service.port }} - targetPort: http - protocol: TCP - name: http - selector: - {{- include "fuel-explorer.selectorLabels" . | nindent 4 }} - app.kubernetes.io/service: {{ include "fuel-explorer.fullname" . }}-api -{{- end }} \ No newline at end of file diff --git a/helm/fuel-explorer/templates/serviceaccount.yaml b/helm/fuel-explorer/templates/serviceaccount.yaml deleted file mode 100644 index a86ae0d0c..000000000 --- a/helm/fuel-explorer/templates/serviceaccount.yaml +++ /dev/null @@ -1,12 +0,0 @@ -{{- if .Values.serviceAccount.create -}} -apiVersion: v1 -kind: ServiceAccount -metadata: - name: {{ include "fuel-explorer.serviceAccountName" . }} - labels: - {{- include "fuel-explorer.labels" . | nindent 4 }} - {{- with .Values.serviceAccount.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -{{- end }} diff --git a/helm/fuel-explorer/templates/servicemonitor.yaml b/helm/fuel-explorer/templates/servicemonitor.yaml deleted file mode 100644 index 62f88095a..000000000 --- a/helm/fuel-explorer/templates/servicemonitor.yaml +++ /dev/null @@ -1,15 +0,0 @@ -{{- if .Values.app.serviceMonitor.enabled }} -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - name: {{ include "fuel-explorer.fullname" . }} - labels: - release: {{ .Values.app.serviceMonitor.prometheusRelease }} -spec: - selector: - matchLabels: - {{- include "fuel-explorer.labels" . | nindent 4 }} - endpoints: - - path: /metrics - port: http -{{- end }} diff --git a/helm/fuel-explorer/templates/syncer/deployment.yaml b/helm/fuel-explorer/templates/syncer/deployment.yaml deleted file mode 100644 index b9fd2119d..000000000 --- a/helm/fuel-explorer/templates/syncer/deployment.yaml +++ /dev/null @@ -1,104 +0,0 @@ -{{- $service := .Values.syncer -}} -{{- if $service.enabled }} -apiVersion: apps/v1 -kind: Deployment -metadata: - name: {{ include "fuel-explorer.fullname" . }}-syncer - labels: - {{- include "fuel-explorer.labels" . | nindent 4 }} - app.kubernetes.io/service: {{ include "fuel-explorer.fullname" . }}-syncer -spec: - {{- if not $service.autoscaling.enabled }} - replicas: {{ $service.replicaCount }} - {{- end }} - selector: - matchLabels: - {{- include "fuel-explorer.selectorLabels" . | nindent 6 }} - app.kubernetes.io/service: {{ include "fuel-explorer.fullname" . }}-syncer - template: - metadata: - {{- with $service.podAnnotations }} - annotations: - {{- toYaml . | nindent 8 }} - {{- end }} - labels: - {{- include "fuel-explorer.selectorLabels" . | nindent 8 }} - app.kubernetes.io/service: {{ include "fuel-explorer.fullname" . }}-syncer - spec: - {{- if $service.imagePullSecrets }} - imagePullSecrets: - {{- toYaml $service.imagePullSecrets | nindent 8 }} - {{- end }} - {{- if $service.podSecurityContext }} - securityContext: - {{- toYaml $service.podSecurityContext | nindent 8 }} - {{- end }} - serviceAccountName: {{ include "fuel-explorer.serviceAccountName" . }} - containers: - - name: {{ include "fuel-explorer.fullname" . }}-syncer - {{- if $service.securityContext }} - securityContext: - {{- toYaml $service.securityContext | nindent 12 }} - {{- end }} - image: "{{ $service.image.repository }}:{{ $service.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ $service.image.pullPolicy }} - {{- if $service.image.args }} - args: - {{- toYaml $service.image.args | nindent 12 }} - {{- end }} - - env: - - name: SERVICE - value: syncer - - envFrom: - - configMapRef: - name: {{ include "fuel-explorer.fullname" . }} - - secretRef: - name: {{ include "fuel-explorer.fullname" . }} - ports: - - name: http - containerPort: {{ $service.service.port }} - protocol: TCP - - {{- if .Values.healthcheck.enabled }} - {{- if $service.livenessProbe }} - livenessProbe: - {{- toYaml $service.livenessProbe | nindent 12 }} - {{- end }} - {{- if $service.readinessProbe }} - readinessProbe: - {{- toYaml $service.readinessProbe | nindent 12 }} - {{- end }} - {{- end }} - - volumeMounts: - - mountPath: /home/node/.cache - name: node-cache - - mountPath: /home/node/.pm2 - name: pm2 - - mountPath: /tmp - name: tmp - resources: - {{- toYaml $service.resources | nindent 12 }} - volumes: - - name: node-cache - emptyDir: {} - - name: pm2 - emptyDir: {} - - name: tmp - emptyDir: {} - - {{- if $service.nodeSelector }} - nodeSelector: - {{- toYaml $service.nodeSelector | nindent 8 }} - {{- end }} - {{- if $service.affinity }} - affinity: - {{- toYaml $service.affinity | nindent 8 }} - {{- end }} - {{- if $service.tolerations }} - tolerations: - {{- toYaml $service.tolerations | nindent 8 }} - {{- end }} -{{- end }} \ No newline at end of file diff --git a/helm/fuel-explorer/templates/tests/test-connection.yaml b/helm/fuel-explorer/templates/tests/test-connection.yaml deleted file mode 100644 index c39f7c240..000000000 --- a/helm/fuel-explorer/templates/tests/test-connection.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: "{{ include "fuel-explorer.fullname" . }}-test-connection" - labels: - {{- include "fuel-explorer.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": test -spec: - containers: - - name: wget - image: busybox - command: ['wget'] - args: ['{{ include "fuel-explorer.fullname" . }}:{{ .Values.api.service.port }}'] - restartPolicy: Never diff --git a/helm/fuel-explorer/values.yaml b/helm/fuel-explorer/values.yaml deleted file mode 100644 index 89f4fd143..000000000 --- a/helm/fuel-explorer/values.yaml +++ /dev/null @@ -1,143 +0,0 @@ -# Default values for fuel-explorer. -# This is a YAML-formatted file. -# Declare variables to be passed into your templates. - -# ------------------------------------------------------------------------------ -# Global configurations -# ------------------------------------------------------------------------------ - -nameOverride: "" -fullnameOverride: "" - -healthcheck: - enabled: true - -serviceAccount: - # Specifies whether a service account should be created - create: true - # Annotations to add to the service account - annotations: {} - # The name of the service account to use. - # If not set and create is true, a name is generated using the fullname template - name: "" - -app: - serviceMonitor: - enabled: true - prometheusRelease: kube-prometheus - -# ------------------------------------------------------------------------------ -# Syncer configurations -# ------------------------------------------------------------------------------ - -syncer: - enabled: true - service: - type: ClusterIP - port: 3001 - - imagePullSecrets: [] - image: - repository: ghcr.io/fuellabs/fuel-explorer - pullPolicy: Always - tag: "af1e196" - args: [] - - podAnnotations: {} - podSecurityContext: {} - nodeSelector: {} - tolerations: [] - affinity: {} - resources: {} - - securityContext: - capabilities: - drop: - - ALL - readOnlyRootFilesystem: false - runAsNonRoot: true - runAsUser: 1000 - - replicaCount: 1 - autoscaling: - enabled: false - minReplicas: 1 - maxReplicas: 100 - targetCPUUtilizationPercentage: 80 - targetMemoryUtilizationPercentage: 80 - -# ------------------------------------------------------------------------------ -# API configurations -# ------------------------------------------------------------------------------ - -api: - enabled: true - service: - type: ClusterIP - port: 3000 - - imagePullSecrets: [] - image: - repository: ghcr.io/fuellabs/fuel-explorer - pullPolicy: Always - # Overrides the image tag whose default is the chart appVersion. - tag: "af1e196" - args: [] - - podAnnotations: {} - podSecurityContext: {} - nodeSelector: {} - tolerations: [] - affinity: {} - resources: {} - - securityContext: - capabilities: - drop: - - ALL - readOnlyRootFilesystem: false - runAsNonRoot: true - runAsUser: 1000 - - livenessProbe: - httpGet: - path: /health - port: http - initialDelaySeconds: 10 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 3 - - readinessProbe: - httpGet: - path: /health - port: http - initialDelaySeconds: 5 - periodSeconds: 10 - timeoutSeconds: 5 - failureThreshold: 3 - - replicaCount: 1 - autoscaling: - enabled: false - minReplicas: 1 - maxReplicas: 100 - targetCPUUtilizationPercentage: 80 - targetMemoryUtilizationPercentage: 80 - - ingress: - enabled: true - className: "" - annotations: - {} - # kubernetes.io/ingress.class: nginx - # kubernetes.io/tls-acme: "true" - hosts: - - host: chart-example.local - paths: - - path: / - pathType: ImplementationSpecific - tls: [] - # - secretName: chart-example-tls - # hosts: - # - chart-example.local diff --git a/package.json b/package.json index 468be1758..c4ebd688d 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,6 @@ "dev:explorer:prod": "pnpm --filter=app-explorer start", "dev:explorer": "pnpm --filter=app-explorer run dev", "dev:portal": "pnpm --filter=app-portal dev", - "dev:graphql": "pnpm --filter=graphql dev:graphql", - "dev:graphql:all": "pnpm --filter=graphql run-dev:all", "lint": "biome check --apply-unsafe .", "format": "biome format --write .", "node:clean": "make -C ./docker clean", @@ -40,9 +38,7 @@ "node:stop": "make -C ./docker stop", "node:restart": "make -C ./docker restart", "prepare": "husky install", - "run:backend": "./scripts/run-backend.sh", "start": "pnpm turbo:run start", - "setup:backend": "./scripts/setup-backend.sh", "test": "pnpm turbo:run test", "test:all": "run-p test test:e2e", "test:e2e": "playwright test --config=packages/e2e-tests/playwright.config.ts", diff --git a/packages/graphql/.env.example b/packages/graphql/.env.example index 952824b11..50a77619f 100644 --- a/packages/graphql/.env.example +++ b/packages/graphql/.env.example @@ -1,13 +1,3 @@ FUEL_PROVIDER=https://testnet.fuel.network/v1/graphql -SERVER_PORT=3004 -SERVER_API_KEY=your-secret-key -DB_HOST="127.0.0.1" -DB_PORT=5435 -DB_USER=postgres -DB_PASS=postgres -DB_NAME=postgres -SSL=false -DEBUG=true FUEL_CHAIN=testnet # options: mainnet, testnet -COINGECKO_API_KEY= # used to fetch token prices -ALCHEMY_API_KEY= \ No newline at end of file +DEBUG=true diff --git a/packages/graphql/.env.production b/packages/graphql/.env.production deleted file mode 100644 index 0cd3e1016..000000000 --- a/packages/graphql/.env.production +++ /dev/null @@ -1,19 +0,0 @@ -LOG_DIR="/var/logs" -FUEL_PROVIDER=http://localhost:4000/v1/graphql -SERVER_PORT=3004 -SERVER_API_KEY=your-secret-key -SYNCER_PORT=3005 - -DB_HOST="127.0.0.1" -DB_PORT=5435 -DB_USER=postgres -DB_PASS=postgres -DB_NAME=postgres -SYNC_MISSING=true -SERVER_BUILD=true -SYNC_OFFSET=10 -SYNC_LIMIT=100000 -WATCH_INTERVAL=5000 -SSL=true -DEBUG=false -DEBUG_PAYLOAD=false diff --git a/packages/graphql/.swcrc b/packages/graphql/.swcrc deleted file mode 100644 index fb03f0550..000000000 --- a/packages/graphql/.swcrc +++ /dev/null @@ -1,18 +0,0 @@ -{ - "jsc": { - "parser": { - "syntax": "typescript", - "tsx": false, - "decorators": true - }, - "target": "es2017", - "keepClassNames": true, - "transform": { - "legacyDecorator": true, - "decoratorMetadata": true - } - }, - "module": { - "type": "commonjs" - } -} diff --git a/packages/graphql/API.md b/packages/graphql/API.md deleted file mode 100644 index 55417c28e..000000000 --- a/packages/graphql/API.md +++ /dev/null @@ -1,89 +0,0 @@ -# Fuel Explorer Indexer - API -### Instructions for consuming Assets data from Indexer API - -API endpoint: -`/assets/` - get information about any asset (including NFTs) - -URLs to consume: -- Mainnet: https://mainnet-explorer.fuel.network -- Testnet: https://explorer-indexer-testnet.fuel.network - - -`curl` example of usage -``` -curl 'https://mainnet-explorer.fuel.network/assets/0x44b09d7143aa7b1aac7844ee9cfc38893b12d20c3822ecb18dbf2c6846ea63f0' -``` - - -the result contains a JSON with the asset information, here are the details about each prop: -| Property | Description | -|----------|-------------| -| assetId | Actual ID of the asset | -| contractId | Contract ID that minted the asset | -| subId | SubId used to calculate the assetId | -| name | Asset name | -| symbol | Asset symbol | -| decimals | Asset decimals configuration | -| suspicious | true if symbol matches any verified asset symbols | -| metadata | Key-value object with SRC7/SRC9 standard metadata | -| isNFT | true if asset is NFT ( [supply=1, decimals=0](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/#non-fungible-asset-restrictions) )| -| verified | true if asset is in Fuel's verified assets list | -| owner | Current assetId owner (NFTs only) | -| uri | Parsed URL from “metadata.uri” or “metadata.URI”. Some [logic](https://github.com/FuelLabs/fuel-ex-demo/blob/ee73408a0ef0323eeb92414d5ed92d65e3f3f78f/packages/graphql/src/infra/gateway/AssetGateway.ts#L63-L95) is applied to try defining a reasonable uri for the API consumer | - -### Instructions for consuming Assets data owned by an Account from Indexer API - -API endpoint: -`/accounts/
/assets?last=` - get assets owned by an account (including NFTs) - -URLs to consume: -- Mainnet: https://mainnet-explorer.fuel.network -- Testnet: https://explorer-indexer-testnet.fuel.network - - -`curl` example of usage -``` -curl 'https://mainnet-explorer.fuel.network/accounts/0x196a68Ba237e921FeC5F01552E5e4df60b2619900254DD4cDe42557814508F57/assets?last=10' -``` - - -the result contains a JSON with an array of asset information and balance of each asset, here are the details about each prop: -| Property | Description | -|----------|-------------| -| balance | Balance of the asset owner by account | -| assetId | Actual ID of the asset | -| contractId | Contract ID that minted the asset | -| subId | SubId used to calculate the assetId | -| name | Asset name | -| symbol | Asset symbol | -| decimals | Asset decimals configuration | -| suspicious | true if symbol matches any verified asset symbols | -| metadata | Key-value object with SRC7/SRC9 standard metadata | -| isNFT | true if asset is NFT ( [supply=1, decimals=0](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/#non-fungible-asset-restrictions) )| -| verified | true if asset is in Fuel's verified assets list | -| owner | Current assetId owner (NFTs only) | -| uri | Parsed URL from “metadata.uri” or “metadata.URI”. Some [logic](https://github.com/FuelLabs/fuel-ex-demo/blob/ee73408a0ef0323eeb92414d5ed92d65e3f3f78f/packages/graphql/src/infra/gateway/AssetGateway.ts#L63-L95) is applied to try defining a reasonable uri for the API consumer | - -### Instructions for consuming Blocks data from Indexer API - -API endpoint: -`/blocks/` - get information about any block - -URLs to consume: -- Mainnet: https://mainnet-explorer.fuel.network -- Testnet: https://explorer-indexer-testnet.fuel.network - - -`curl` example of usage -``` -curl 'https://mainnet-explorer.fuel.network/blocks/4000000' -``` - -the result contains a JSON with an array of block information: -| Property | Description | -|----------|-------------| -| id | Actual ID of the Block | -| header | Contains the header information of the block | -| height | Height of the Block | -| consensus | Consensus informations of the Block | -| transactions | Transactions of the Block | \ No newline at end of file diff --git a/packages/graphql/ASSETS.md b/packages/graphql/ASSETS.md deleted file mode 100644 index db50b6277..000000000 --- a/packages/graphql/ASSETS.md +++ /dev/null @@ -1,65 +0,0 @@ -# Fuel Explorer Indexer - Assets API -### Instructions for consuming Assets data from Indexer API - -API endpoint: -`/assets/` - get information about any asset (including NFTs) - -URLs to consume: -- Mainnet: https://mainnet-explorer.fuel.network -- Testnet: https://explorer-indexer-testnet.fuel.network - - -`curl` example of usage -``` -curl 'https://mainnet-explorer.fuel.network/assets/0x44b09d7143aa7b1aac7844ee9cfc38893b12d20c3822ecb18dbf2c6846ea63f0' -``` - - -the result contains a JSON with the asset information, here are the details about each prop: -| Property | Description | -|----------|-------------| -| assetId | Actual ID of the asset | -| contractId | Contract ID that minted the asset | -| subId | SubId used to calculate the assetId | -| name | Asset name | -| symbol | Asset symbol | -| decimals | Asset decimals configuration | -| suspicious | true if symbol matches any verified asset symbols | -| metadata | Key-value object with SRC7/SRC9 standard metadata | -| isNFT | true if asset is NFT ( [supply=1, decimals=0](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/#non-fungible-asset-restrictions) )| -| verified | true if asset is in Fuel's verified assets list | -| owner | Current assetId owner (NFTs only) | -| uri | Parsed URL from “metadata.uri” or “metadata.URI”. Some [logic](https://github.com/FuelLabs/fuel-ex-demo/blob/ee73408a0ef0323eeb92414d5ed92d65e3f3f78f/packages/graphql/src/infra/gateway/AssetGateway.ts#L63-L95) is applied to try defining a reasonable uri for the API consumer | - -### Instructions for consuming Assets data owned by an Account from Indexer API - -API endpoint: -`/accounts/
/assets?last=` - get assets owned by an account (including NFTs) - -URLs to consume: -- Mainnet: https://mainnet-explorer.fuel.network -- Testnet: https://explorer-indexer-testnet.fuel.network - - -`curl` example of usage -``` -curl 'https://mainnet-explorer.fuel.network/accounts/0x196a68Ba237e921FeC5F01552E5e4df60b2619900254DD4cDe42557814508F57/assets?last=10' -``` - - -the result contains a JSON with an array of asset information and balance of each asset, here are the details about each prop: -| Property | Description | -|----------|-------------| -| balance | Balance of the asset owner by account | -| assetId | Actual ID of the asset | -| contractId | Contract ID that minted the asset | -| subId | SubId used to calculate the assetId | -| name | Asset name | -| symbol | Asset symbol | -| decimals | Asset decimals configuration | -| suspicious | true if symbol matches any verified asset symbols | -| metadata | Key-value object with SRC7/SRC9 standard metadata | -| isNFT | true if asset is NFT ( [supply=1, decimals=0](https://docs.fuel.network/docs/sway-standards/src-20-native-asset/#non-fungible-asset-restrictions) )| -| verified | true if asset is in Fuel's verified assets list | -| owner | Current assetId owner (NFTs only) | -| uri | Parsed URL from “metadata.uri” or “metadata.URI”. Some [logic](https://github.com/FuelLabs/fuel-ex-demo/blob/ee73408a0ef0323eeb92414d5ed92d65e3f3f78f/packages/graphql/src/infra/gateway/AssetGateway.ts#L63-L95) is applied to try defining a reasonable uri for the API consumer | diff --git a/packages/graphql/MIGRATION_GUIDE.md b/packages/graphql/MIGRATION_GUIDE.md deleted file mode 100644 index a033e89aa..000000000 --- a/packages/graphql/MIGRATION_GUIDE.md +++ /dev/null @@ -1,50 +0,0 @@ -# Database Migration Guide - -## Commands - -```bash -pnpm db:migrate # Run pending migrations -pnpm db:migrate:dry # Preview without executing -pnpm db:migrate:status # Show migration status -pnpm db:migrate:setup # Setup _migrations table (production upgrade only) -``` - -## Creating Migrations - -1. Create file in `database/migrations/` with format `{NNN}_{description}.sql` -2. Write idempotent SQL (use `IF NOT EXISTS`, `IF EXISTS`) -3. Test with `pnpm db:migrate:dry` then `pnpm db:migrate` - -## Production Deployment - -### First-Time (Existing Database) - -```bash -# Connect to production -kubectl port-forward -n fuel-explorer svc/postgresql 5432:5432 - -# Set env vars -export DB_HOST=localhost DB_PORT=5432 DB_USER=explorer DB_PASS= DB_NAME=explorer - -# Setup _migrations table (marks existing as applied without re-running) -cd packages/graphql && pnpm db:migrate:setup -``` - -### Standard Deployment - -```bash -pnpm db:migrate:status # Check pending -pnpm db:migrate:dry # Preview -pnpm db:migrate # Execute -``` - -## Environment Variables - -| Variable | Default | -|----------|---------| -| `DB_SCHEMA` | `indexer` | -| `DB_HOST` | `localhost` | -| `DB_PORT` | `5435` | -| `DB_USER` | `postgres` | -| `DB_PASS` | `postgres` | -| `DB_NAME` | `postgres` | diff --git a/packages/graphql/README.md b/packages/graphql/README.md index dd4cc6b55..86ccc1be0 100644 --- a/packages/graphql/README.md +++ b/packages/graphql/README.md @@ -1,563 +1,5 @@ -# Fuel Explorer Backend +# @fuel-explorer/graphql -This document provides a comprehensive overview of the Fuel Explorer Backend, covering its architecture details, installation steps, execution workflows, and ongoing maintenance procedures. +This package no longer runs a standalone API or syncer. It is a shared library: GraphQL schemas, generated SDK types, the domain layer that turns fuel-core JSON into explorer fields, and a handful of value objects and DAOs, imported by both the frontend (`packages/app-explorer`, via the `@fuel-explorer/graphql` and `@fuel-explorer/graphql/sdk` exports) and the API server in `packages/api-lite`. -- [Introduction](#introduction) - - [System Design](#system-design) - - [Syncer Execution Flow](#syncer-execution-flow) - - [API Execution Flow](#api-execution-flow) - - [Public Endpoints](#public-endpoints) -- [Environment](#environment) - - [Node](#node) - - [PNPM](#pnpm) - - [Docker Desktop](#docker-desktop) - - [AWS CLI](#aws-cli) - - [Kubernetes CLI](#kubernetes-cli) - - [Lens](#lens) -- [Project Setup](#project-setup) - - [Cloning Project](#cloning-project) - - [Installing Dependencies](#installing-dependencies) - - [Environment Variables](#environment-variables) - - [Running the API](#running-the-api) - - [Running Syncer with PM2](#running-syncer-with-pm2) - - [Running the Database](#running-the-database) - - [Using local database](#using-local-database) - - [Using remote database](#using-remote-database) - - [Syncing Blocks](#syncing-blocks) - - [Password Management](#password-management) -- [Common Issues](#common-issues) - - [Fuel Core endpoint is not available](#fuel-core-endpoint-is-not-available) - - [Contract ABI is out of date](#contract-abi-is-out-of-date) - - [NFT not being indexed](#nft-not-being-indexed) - - [Wrong password on PostgreSQL or RabbitMQ](#wrong-password-on-postgresql-or-rabbitmq) - - [Deadlock on database tables](#deadlock-on-database-tables) -- [Observability and Troubleshooting](#observability-and-troubleshooting) - - [AWS Console](#aws-console) - - [Logs](#logs) - - [Metrics](#metrics) - - [Alerts](#alerts) - - [Bash access](#bash) -- [Deployment](#deployment) - - [Flux](#flux) - - [release.yaml](#releaseyaml) - - [env-configmap.yaml](#env-configmapyaml) - - [env-secrets.yaml](#env-secretsyaml) - - [Helm Template](#helm-template) - - [Chart.yaml](#chartyaml) - - [values.yaml](#valuesyaml) -- [Maintenance Tasks](#maintenance-tasks) - - [Stop services](#stop-services) - - [Apply migrations](#apply-migrations) - - [Process past data](#process-past-data) - - -## Introduction - -The Fuel Explorer Backend serves two core functions: - -API Provider for the Frontend: - -It delivers a rich REST and GraphQL interface that exposes detailed data on blocks, transactions, inputs, outputs, contracts, predicates, accounts, and receipts. The API features robust pagination and aggregated endpoints tailored to power explorer charts and visualizations. - -Blockchain Indexer & Data Processor: - -It ingests and persists data from both L1 and L2 networks, then enriches it by computing account balances, tracking NFT ownership, supporting bridge and staking workflows, converting asset values to USD, and performing other crucial transformations—ensuring the frontend receives fully processed, ready-to-use information. - -### System Design - - - -### Syncer Execution Flow - -The syncer continuously polls Fuel Core for the latest block height and compares it against the highest height already indexed. Whenever there’s a gap, it publishes RabbitMQ messages in batches of ten blocks. Six consumer instances then dequeue these messages, fetch each full block from Fuel Core, extract all relevant data—transactions, inputs, outputs, contracts, predicates, and receipts—and write them into the database. - -Meanwhile, supporting side‐processes run in parallel to: - -* Index L1 and Cosmos networks -* Calculate and update account balances -* Persist up-to-date exchange rates -* Execute periodic jobs (for example, rebuilding materialized views) - -### API Execution Flow - -The API layer runs eight stateless instances behind a load‐balancer, each handling incoming frontend requests by querying the database for the required data. When traffic spikes, a Kubernetes replica set automatically scales the number of pods in the cluster to maintain performance and availability. - -### Public Endpoints - -Here are the environment-specific endpoints: - -``` -https://explorer-indexer-devnet.fuel.network -https://explorer-indexer-testnet.fuel.network -https://explorer-indexer-mainnet.fuel.network -``` - -## Environment - -To run the backend locally, ensure you have Node.js, PNPM, Docker, AWS CLI, Kubernetes CLI or Lens installed and configured. Other dependencies like PostgreSQL and RabbitMQ will be provisioned via Docker. - -### Node - -In production we are using Node.js 20, to install: - -``` -brew install node@20 -``` - -or, use NVM to have more flexibility: - -``` -curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash -nvm install 20 -nvm use 20 -``` - -### PNPM - -The project uses pnpm, a high-performance Node.js package manager that hard-links dependencies from a global content-addressable store into isolated node_modules, drastically reducing disk usage, preventing phantom packages, and speeding up installs. - -To install pnpm: - -``` -npm install -g pnpm -``` - -or, if you’re on Node.js v16.9+ with Corepack enabled: - -``` -corepack enable -corepack prepare pnpm@latest --activate -``` - -### Docker Desktop - -To install Docker Desktop on OSX, download the installer on Docker's website: - -``` -https://docs.docker.com/desktop/setup/install/mac-install -``` - -### AWS CLI - -To install AWS CLI on OSX use the command: - -``` -brew install awscli -``` - -After that you need to login to the AWS account: - -``` -aws configure sso --profile fuel-dev - -SSO session name (Recommended): fuel-dev -SSO start URL [None]: https://fuelsh.awsapps.com/start -SSO region [None]: us-east-1 -SSO registration scopes [sso:account:access]: sso:account:access -Attempting to automatically open the SSO authorization page in your default browser. -If the browser does not open or you wish to use a different device to authorize this request, open the following URL: - -https://device.sso.us-east-1.amazonaws.com/ - -Then enter the code: - -XXXX-YYYY -``` - -You'll be prompted to open the AWS SSO and login using you Fuel account. After successfully login, you need to select the account, be sure to select the correct one, where the cluster environment is running. In general we use 3 accounts: devnet (249945542445), testnet (533267304813), mainnet (767398027608). - -Remember to always login before use Kubernetes CLI, otherwise it's gonna show an error. - -### Kubernetes CLI - -To install Kubernetes CLI on OSX use the command: - -``` -brew install kubectl -``` - -Since kubectl is just a client for the Kubernetes API, you must configure its context and credentials for the specific environment you’ll be working in (e.g. dev, testnet, or mainnet) before running any commands: - -``` -aws eks update-kubeconfig --name fuel-dev-2 --region us-east-1 --profile fuel-dev -aws eks update-kubeconfig --name fuel-prod-testnet --region us-east-1 --profile fuel-dev -aws eks update-kubeconfig --name fuel-prod-mainnet --region us-east-1 --profile fuel-dev -``` - -Always identify which namespace to use since namespace naming isn’t standardized and can vary by environment, so always verify the exact namespace before running any commands: - -``` -kubectl get namespaces -``` - -This error means that you are logged in one account and pointing your kubectl config to the wrong cluster: - -``` -Unhandled Error err=couldn't get current server API group list: the server has asked for the client to provide credentials -``` - -Use this command to identify which cluster are available in the account: - -``` -aws eks list-clusters --profile fuel-dev -``` - -### Lens - -Alternatively, you can use a GUI tool like Lens to explore your cluster’s configuration, though it may not support every advanced operation. - -``` -https://k8slens.dev -``` - -## Project Setup - -### Cloning Project - -To get started, clone the repository by running: - -``` -git clone https://github.com/FuelLabs/fuel-explorer -``` - -Because our codebase is organized as a monorepo with multiple projects, the backend’s working directory is located at: - -``` -packages/graphql -``` - -### Installing Dependencies - -Once you’ve cloned the repository, install all dependencies by running: - -``` -pnpm install -``` - -### Environment Variables - -You’ll need to configure numerous environment variables, and their values will differ depending on how you run the project—whether against a local database or via RabbitMQ. - -``` -FUEL_PROVIDER: fuel core endpoint -SERVER_PORT: backend port -SERVER_API_KEY: backend api key -DB_HOST: database host -DB_PORT: database port -DB_USER: database user -DB_PASS: database password -DB_NAME: database name -RABBITMQ_HOST: rabbitmq host -RABBITMQ_PORT: rabbitmq port -RABBITMQ_USER: rabbitmq user -RABBITMQ_PASS: rabbitmq password -QUEUE_CONCURRENCY: amount of processes that rabbitmq use to consume queue -SSL: enable SSL on database and rabbitmq -DEBUG: debug mode -``` - -Recommend get the .env file with other team member. - -### Running the API - -First, build the project from the root directory: - -``` -pnpm build:prod -``` - -To run you can use the script or running the file directly: - -``` -pnpm run-start -``` - -or - -``` -npx tsx src/app.ts -``` - -### Running Syncer with PM2 - -In production environment we are using PM2 to manage Node.js processes. You don't need to use it locally, however, depending on the task you need to perform could be easier to use PM2 to start processes like syncer, consumer, api and other. - -``` -pnpm dev:syncer -``` - -### Running the Database - -First step is to run the explorer locally and there are different strategies to do that: - -#### Using remote database - -If you just need to create a new endpoint, return more informations from database or even change the payload, sometimes is easier to just point to the devnet or testnet database and run the backend with this database, otherwise you will need to sync blocks manually in order to have data to implement and testing. - -In order to use the remote database, you need to make a port-forward on the Kubernetes cluster. Please check the correct namespace on the cluster. - -``` -kubectl port-forward deploy/db-proxy-explorer 5432 -n -``` - -You need to use the cluster configuration on .env file: - -``` -DB_HOST="127.0.0.1" -DB_PORT=5432 -DB_USER=explorer -DB_PASS= -DB_NAME=explorer -``` - -Remember to avoid using index commands on remote database, unless you know what you are doing. - -#### Using local database - -This approach is recommended when you need to add or modify index behavior or analyze problems with this process. - -First you need to start the database on Docker: - -``` -docker compose up fuel_explorer_pgsql -d -``` - -You need to use the local configuration on .env file: - -``` -DB_HOST="127.0.0.1" -DB_PORT=5435 -DB_USER=postgres -DB_PASS=postgres -DB_NAME=postgres -``` - -Apply the migrations by running the setup tool: - -``` -pnpm setup:backend -``` - -### Syncing blocks - -By running the local database you need to sync blocks: - -``` -npx tsx src/sync-block-range 2000000 2000010 -``` - -### Password Management - -The password are kept in BitWarden or could be requested directly to the DevOps team. - -## Common issues - -### Fuel core endpoint is not available: - -Fuel Core can become unavailable due to cluster network issues, leading to sync failures and API errors from missing chain data. If this occurs, first verify Fuel Core’s status by checking the logs or running a curl request from within the cluster. Then escalate to DevOps with your findings so they can diagnose and restore connectivity. - -### Contract ABI is out of date: - -Occasionally a contract’s ABI will change, which can break event synchronization. Logs will pinpoint the affected contract; to resolve the issue, update its ABI. Once corrected, event processing will automatically resume from the block where it stopped. - -### NFT not being indexed: - -Thunder collections use a dedicated metadata configuration mechanism—unlike the Fuel Network NFT standard, which relies on LOG_DATA events. As a result, we need to define the collection’s URL pattern so we can correctly extract its metadata and insert it into the collection table. - -### Wrong password on PostgreSQL or RabbitMQ - -We’ve previously run into issues where service passwords were changed but not updated in the Fuel Explorer service’s env-secrets.yaml, causing authentication failures. - -### Deadlock on database tables - -Be cautious when running heavy queries—especially ALTER TABLE statements—as they can lock the entire table and lead to application downtime. If you detect a lock or performance degradation, immediately cancel the query and use an alternative approach (for example, an online schema-change tool or rolling migration) to make your schema changes. - -## Observability and Troubleshooting - -### AWS Console - -You can monitor resources like PostgreSQL directly in the AWS Console, just search for “RDS” and select the explorer database. We’re running Aurora RDS v2, which is fully elastic: it automatically scales under heavy load and exposes detailed charts for metrics like CPU utilization, I/O, and slow queries. - -### Logs - -Logs can be accessed in OpenSearch at the following endpoint: - -Devnet: - -``` -https://grafana-fuel-prod-2.fuel.network -username: admin -password: -``` - -Testnet: - -``` -https://search-fuel-prod-testnet-trl5zlea2v7wvzy57ggryh6uqm.us-east-1.es.amazonaws.com/_dashboards -username: fuel-elastic -password: -``` - -Mainnet: - -``` -https://search-fuel-prod-mainnet-ca-qix4o6twktwywwjdqueqxz2umy.ca-central-1.es.amazonaws.com/_dashboards -username: fuel-elastic -password: -``` - -You can also stream the pod’s logs directly from its stdout by running the following command: - -``` -kubectl logs pod -n namespace -``` - -### Metrics - -Grafana offers intuitive, real-time dashboards that visualize key metrics: - -Devnet: - -``` -https://grafana-fuel-dev-2.swayswap.io -username: admin -password: -``` - -Testnet: - -``` -https://grafana-fuel-prod-testnet.fuel.network -username: admin -password: -``` - -Mainnet: - -``` -https://grafana-fuel-prod-mainnet-ca.fuel.network -username: admin -password: -``` - -Check the password for OpenSearch and Grafana on https://github.com/fuelLabs/fuel-deployment-v2 - -### Alerts - -We’ve set up both PagerDuty and a dedicated Slack integration to ensure immediate visibility—and rapid response—whenever our sync process fails. The alerts are triggered based on exported metrics: - -Devnet: - -``` -https://explorer-indexer-devnet.fuel.network/metrics -``` - -Testnet: - -``` -https://explorer-indexer-testnet.fuel.network/metrics -``` - -Mainnet: - -``` -https://explorer-indexer-mainnet.fuel.network/metrics -``` - -### Bash - -At times, you’ll need to inspect running processes or run local tests (for example, with curl). To get a shell inside the pod, run: - -``` -kubectl exec -it pod -n namespace -- /bin/bash -``` - -## Deployment - -### Flux - -We manage all deployments through Flux, which is a GitOps operator, separated by environments: - -#### Deployment on Devnet - -``` -https://github.com/FuelLabs/fuel-deployment-v2/tree/master/kustomize/environments/fuel-dev-2/fuel-apps/explorer -``` - -#### Deployment on Testnet - -``` -https://github.com/FuelLabs/fuel-deployment-v2/tree/master/kustomize/environments/fuel-prod-testnet/fuel-apps/explorer -``` - -#### Deployment on Mainnet - -``` -https://github.com/FuelLabs/fuel-deployment-v2/tree/master/kustomize/environments/fuel-prod-mainnet/fuel-apps/mainnet/fuel-explorer-backend-indexer -``` - -### Configuration - -There are 3 important files: release.yaml, env-configmap.yaml and env-secret.yaml - -#### release.yaml - -Deployments are split into two pods: api and syncer. To release a new version, set the image:tag property to your commit hash. This manifest also specifies key settings like CPU and memory requests/limits and DNS configuration. - -#### env-configmap.yaml - -This file contains all of the production environment variables, mirroring the settings you use in your local .env file. - -#### env-secrets.yaml - -This file stores only the PostgreSQL and RabbitMQ passwords encrypted with SOPS by the DevOps team, who manage the required encryption keys. - -### Helm Template - -Our deployment pipeline leverages Helm to render Kubernetes manifests from our charts—providing consistent templating, configurable values overrides, and seamless release rollbacks. - -Everytime that the Helm template changes you need to dump the version, which is deployed by a GitHub Action: - -``` -helm/fuel-explorer -``` - -The most important files are Chart.yaml and values.yaml - -#### Chart.yaml - -This file specifies the version that our GitHub Actions workflow will deploy (and inject into deployment.yaml); only update it when you’ve modified any Helm configurations. - -#### values.yaml - -This file defines high-level Helm template settings—volumes, probes, and other critical configurations, so always review any changes with the DevOps team before modifying it. - -## Maintenance Tasks - -Here are the Explorer Backend’s most frequently performed maintenance tasks: - -### Stop services - -Kubernetes uses ReplicaSets to maintain a desired number of pod replicas, since you can’t explicitly start or stop pods, you scale them with the kubectl scale command: - -``` -kubectl scale deployment service --replicas=0 -n namespace -``` - -### Apply migrations - -Before applying migrations, tunnel the database port with kubectl port-forward and then run the migration commands manually against the forwarded endpoint: - -``` -kubectl port-forward deploy/db-proxy-explorer 5432 -n testnet -``` - -### Process past data - -The indexer processes only new data by default; whenever you add a column or introduce a new table, you must reprocess the historical data to incorporate those schema changes. - -In general, this process is done by creating a Node.js script and run that on the database. It could be done locally or inside the cluster, like testnet or mainnet. If the amount of data are not that big, is possible to use port-forward in order the database and process the data, otherwise is better to execute inside the cluster through the bash. The command to acess the bash is: - -``` -kubectl exec -it pod -n namespace -- /bin/bash -``` +The explorer's Postgres-backed API and syncer, and the Postgres database itself, were removed. The explorer now runs on `packages/api-lite`, which serves the same GraphQL schema from the S3 block recorder and fuel-core, with a sqlite index, and no database to operate. See `docker/vps/deploy.md` for how it is deployed. diff --git a/packages/graphql/database/migrations/001_create_schema_and_base_tables.sql b/packages/graphql/database/migrations/001_create_schema_and_base_tables.sql deleted file mode 100644 index 0228f6e87..000000000 --- a/packages/graphql/database/migrations/001_create_schema_and_base_tables.sql +++ /dev/null @@ -1,82 +0,0 @@ -CREATE SCHEMA IF NOT EXISTS indexer; - -CREATE TABLE IF NOT EXISTS indexer.blocks ( - _id integer PRIMARY KEY, - id character varying(66) NOT NULL UNIQUE, - timestamp timestamp without time zone NOT NULL, - data jsonb NOT NULL, - gas_used character varying(66), - producer character varying(66) -); - -CREATE INDEX IF NOT EXISTS blocks_id_idx ON indexer.blocks(_id); -CREATE INDEX IF NOT EXISTS blocks_hash_idx ON indexer.blocks(id); -CREATE INDEX IF NOT EXISTS blocks_timestamp_idx ON indexer.blocks(timestamp); - -CREATE TABLE IF NOT EXISTS indexer.transactions ( - _id character varying(66) PRIMARY KEY, - tx_hash character varying(66) NOT NULL UNIQUE, - timestamp timestamp without time zone, - data jsonb NOT NULL, - block_id integer NOT NULL REFERENCES indexer.blocks(_id) -); - -CREATE INDEX IF NOT EXISTS transactions_id_idx ON indexer.transactions(_id); -CREATE INDEX IF NOT EXISTS transactions_hash_idx ON indexer.transactions(tx_hash); -CREATE INDEX IF NOT EXISTS transactions_timestamp_idx ON indexer.transactions(timestamp); -CREATE INDEX IF NOT EXISTS transactions_block_id_idx ON indexer.transactions(block_id); - -CREATE TABLE IF NOT EXISTS indexer.contracts ( - _id SERIAL PRIMARY KEY, - contract_hash character varying(66) NOT NULL UNIQUE, - data jsonb NOT NULL -); - -CREATE INDEX IF NOT EXISTS contracts_id_idx ON indexer.contracts(_id); -CREATE INDEX IF NOT EXISTS contracts_hash_idx ON indexer.contracts(contract_hash); - -CREATE TABLE IF NOT EXISTS indexer.inputs ( - _id SERIAL PRIMARY KEY, - data jsonb NOT NULL, - transaction_id character varying(66) NOT NULL REFERENCES indexer.transactions(_id) -); - -CREATE INDEX IF NOT EXISTS inputs_id_idx ON indexer.inputs(_id); -CREATE INDEX IF NOT EXISTS inputs_transaction_id_idx ON indexer.inputs(transaction_id); - -CREATE TABLE IF NOT EXISTS indexer.outputs ( - _id SERIAL PRIMARY KEY, - data jsonb NOT NULL, - transaction_id character varying(66) NOT NULL REFERENCES indexer.transactions(_id) -); - -CREATE INDEX IF NOT EXISTS outputs_id_idx ON indexer.outputs(_id); -CREATE INDEX IF NOT EXISTS outputs_transaction_id_idx ON indexer.outputs(transaction_id); - -CREATE TABLE IF NOT EXISTS indexer.predicates ( - _id SERIAL PRIMARY KEY, - bytecode text NOT NULL, - address character varying(66) NOT NULL UNIQUE -); - -CREATE INDEX IF NOT EXISTS predicates_id_idx ON indexer.predicates(_id); -CREATE INDEX IF NOT EXISTS predicates_address_idx ON indexer.predicates(address); - -CREATE TABLE IF NOT EXISTS indexer.transactions_accounts ( - _id text not null, - block_id integer not null, - tx_hash text not null, - account_hash text not null, - primary key (_id, block_id, tx_hash, account_hash) -); - -CREATE INDEX IF NOT EXISTS transactions_accounts_id_idx ON indexer.transactions_accounts (_id); -CREATE INDEX IF NOT EXISTS transactions_accounts_block_id_idx ON indexer.transactions_accounts (block_id); -CREATE INDEX IF NOT EXISTS transactions_accounts_tx_hash_idx ON indexer.transactions_accounts (tx_hash); -CREATE INDEX IF NOT EXISTS transactions_accounts_account_hash_idx ON indexer.transactions_accounts (account_hash); - -CREATE TABLE IF NOT EXISTS indexer.migration ( - version integer not null -); - -INSERT INTO indexer.migration (version) SELECT 0 WHERE NOT EXISTS (SELECT 1 FROM indexer.migration); diff --git a/packages/graphql/database/migrations/002_create_assets_contracts.sql b/packages/graphql/database/migrations/002_create_assets_contracts.sql deleted file mode 100644 index d7ae6dbf6..000000000 --- a/packages/graphql/database/migrations/002_create_assets_contracts.sql +++ /dev/null @@ -1,14 +0,0 @@ -create table if not exists indexer.assets_contracts ( - asset_id text not null, - contract_id text not null, - transaction_id text not null, - sub_id text, - name text, - symbol text, - decimals integer, - error text, - primary key (asset_id, contract_id) -); -create index if not exists assets_contracts_asset_id_idx on indexer.assets_contracts (asset_id); -create index if not exists assets_contracts_contract_id_idx on indexer.assets_contracts (contract_id); -update indexer.migration set version = 1; diff --git a/packages/graphql/database/migrations/003_add_assets_contracts_columns.sql b/packages/graphql/database/migrations/003_add_assets_contracts_columns.sql deleted file mode 100644 index 26785a651..000000000 --- a/packages/graphql/database/migrations/003_add_assets_contracts_columns.sql +++ /dev/null @@ -1,8 +0,0 @@ -alter table indexer.assets_contracts add column block_id integer null; -alter table indexer.assets_contracts add column _id text null; - -create index on indexer.assets_contracts (_id); -create index on indexer.assets_contracts (transaction_id); -create index on indexer.assets_contracts (sub_id); -create index on indexer.assets_contracts (block_id); -update indexer.migration set version = 2; diff --git a/packages/graphql/database/migrations/004_add_owner_to_assets_contracts.sql b/packages/graphql/database/migrations/004_add_owner_to_assets_contracts.sql deleted file mode 100644 index 03cc65b2c..000000000 --- a/packages/graphql/database/migrations/004_add_owner_to_assets_contracts.sql +++ /dev/null @@ -1,3 +0,0 @@ -alter table indexer.assets_contracts add column owner text null; -create index on indexer.assets_contracts (owner); -update indexer.migration set version = 3; diff --git a/packages/graphql/database/migrations/005_add_metadata_to_assets_contracts.sql b/packages/graphql/database/migrations/005_add_metadata_to_assets_contracts.sql deleted file mode 100644 index cbad69709..000000000 --- a/packages/graphql/database/migrations/005_add_metadata_to_assets_contracts.sql +++ /dev/null @@ -1,2 +0,0 @@ -alter table indexer.assets_contracts add column metadata jsonb default '{}'; -update indexer.migration set version = 4; diff --git a/packages/graphql/database/migrations/006_ensure_migration_table.sql b/packages/graphql/database/migrations/006_ensure_migration_table.sql deleted file mode 100644 index 56c61881c..000000000 --- a/packages/graphql/database/migrations/006_ensure_migration_table.sql +++ /dev/null @@ -1,4 +0,0 @@ -create table if not exists indexer.migration ( - version integer not null -); -update indexer.migration set version = 5; diff --git a/packages/graphql/database/migrations/007_add_total_supply_to_assets_contracts.sql b/packages/graphql/database/migrations/007_add_total_supply_to_assets_contracts.sql deleted file mode 100644 index d12ca6138..000000000 --- a/packages/graphql/database/migrations/007_add_total_supply_to_assets_contracts.sql +++ /dev/null @@ -1,2 +0,0 @@ -alter table indexer.assets_contracts add column total_supply numeric default null; -update indexer.migration set version = 6; diff --git a/packages/graphql/database/migrations/008_create_nft_collections.sql b/packages/graphql/database/migrations/008_create_nft_collections.sql deleted file mode 100644 index 4743aba65..000000000 --- a/packages/graphql/database/migrations/008_create_nft_collections.sql +++ /dev/null @@ -1,17 +0,0 @@ -create table if not exists indexer.collections ( - contract_id text not null, - name text, - url text, - primary key (contract_id) -); -insert into indexer.collections (contract_id, name, url) values ('0x45c964371490bdfc2610ca116853d22a9b6e0de1abb67f61b81ab9d291b0015c', 'Fuel Pumps', 'https://ipfs.io/ipfs/QmXyd5j7dDaYDuXZZ62uqh5CsrG9nUXNy7eQmedxEEwU25/{subId}.json') on conflict (contract_id) do nothing; -insert into indexer.collections (contract_id, name, url) values ('0x3f3f87bb15c693784e90521c64bac855ce23d971356a6ccd57aa92e02e696432', 'Executoors', 'https://ipfs.io/ipfs/bafybeif44cbambuyvtfhk6lbaozshy4xs3p4saeqnizxlon4age6pkr2ua/{subId}.json') on conflict (contract_id) do nothing; -insert into indexer.collections (contract_id, name, url) values ('0x0d34ec513cbaf7e15737120725cd3e235a8fd1716fa0eedc5da4a64c182e5a9f', 'FuelMonkees', 'https://gateway.lighthouse.storage/ipfs/bafybeidfwggiv7mjxbrrtpozsdhknl3hyhwyzmzesqiulvflpehhxdsjii/Monkee%20{subId}.json') on conflict (contract_id) do nothing; -insert into indexer.collections (contract_id, name, url) values ('0xaa919d413a57cb6c577b2e172480cbe2f88df0e28203fed52249cabca6cee74a', 'Fuel Pengus', 'https://ipfs.io/ipfs/QmNZqtRxyyuh1nbXUapSgCmGTW2GofXERZzkLBmwVxjmES/{subId}.json') on conflict (contract_id) do nothing; -insert into indexer.collections (contract_id, name, url) values ('0x65aa85875bf92fb5b487ade154f88507d74b233ef901b4a172f4616b527a4784', 'Fuel Dudes', 'https://ipfs.io/ipfs/QmYvaFhBXHXDiccmZnh17gPCT8R62EyY1KWyLz7Zz6dJd4/{subId}.json') on conflict (contract_id) do nothing; -insert into indexer.collections (contract_id, name, url) values ('0x4365ec565b25febe517770709edb54f081fc67fbb4f561ac53b2b608371079db', 'Fuel Rocks', 'https://ipfs.io/ipfs/bafybeie5loshrrqky4boemlnxc5fzsoc4c7cs6gqgbwvt6r7h56nre7oj4/{subId}.json') on conflict (contract_id) do nothing; -insert into indexer.collections (contract_id, name, url) values ('0xb03ec5c6eeaf6d09ed6755e21dff896234c8f509b813f3ff17ef14a436fa8462', 'Sangoro', 'https://ipfs.io/ipfs/QmQJjbRChfHyaYPutY2ZBuJqByfseVNG5bwz7gSuQeYESU/{subId}.json') on conflict (contract_id) do nothing; -insert into indexer.collections (contract_id, name, url) values ('0x59b10bd361740618f12bba00f1083ef304a294b37ed7a8756c1b9cfc9b491b16', 'Fuel BomBa', 'https://ipfs.io/ipfs/QmSY7YZGZtY6nWsAm7Wr9bgA36ZahPxYiYBA241m3BFyyS/{subId}.json') on conflict (contract_id) do nothing; -insert into indexer.collections (contract_id, name, url) values ('0x0c10a1c5ef62b346a27a16cc4c270f5e74c1c94a7f8233fcf0223716b6c9f326', 'Griffy Amplify', 'https://api.thundernft.market/v1/metadata/griffy/{subId}') on conflict (contract_id) do nothing; -insert into indexer.collections (contract_id, name, url) values ('0xf0b6e2320caccb9071e45b1150b4da6f5edf74e7375ac6c87084822a87832de2', 'BearBros', 'https://ipfs.io/ipfs/bafybeihaphqpylne3ft7dlfh4qlisscgn7osd7d7avhgvcpfiskia6fx5i/{subId}.json') on conflict (contract_id) do nothing; -update indexer.migration set version = 7; diff --git a/packages/graphql/database/migrations/009_add_transactions_count_to_blocks.sql b/packages/graphql/database/migrations/009_add_transactions_count_to_blocks.sql deleted file mode 100644 index bf7e44106..000000000 --- a/packages/graphql/database/migrations/009_add_transactions_count_to_blocks.sql +++ /dev/null @@ -1,2 +0,0 @@ -alter table indexer.blocks add column transactions_count integer null; -update indexer.migration set version = 8; diff --git a/packages/graphql/database/migrations/010_create_asset_rate_tables.sql b/packages/graphql/database/migrations/010_create_asset_rate_tables.sql deleted file mode 100644 index 07f9ff8bb..000000000 --- a/packages/graphql/database/migrations/010_create_asset_rate_tables.sql +++ /dev/null @@ -1,86 +0,0 @@ -create table if not exists indexer.assets_rate_provider ( - asset_id text not null, - symbol text not null, - value text not null, - provider text not null, - primary key (symbol) -); - --- network independent -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x', 'BTC', 'bitcoin', 'coingecko') on conflict (symbol) do nothing; - --- mainnet -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07', 'ETH', 'ethereum', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x1d5d97005e41cae2187a895fd8eab0506111e0e2f3331cd3912c15c24e3c1d82', 'FUEL', 'fuel', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xa38a5a8beeb08d95744bc7f58528073f4052b254def59eba20c99c202b5acaa3', 'WETH', 'weth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x239ed6e12b7ce4089ee245244e3bf906999a6429c2a9a445a1e1faf56914a4ab', 'weETH', 'wrapped-eeth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xbae80f7fb8aa6b90d9b01ef726ec847cc4f59419c4d5f2ea88fec785d1b0e849', 'rsETH', 'kelp-dao-restaked-eth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xf3f9a0ed0ce8eac5f89d6b83e41b3848212d5b5f56108c54a205bb228ca30c16', 'rETH', 'reth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x7843c74bef935e837f2bcf67b5d64ecb46dd53ff86375530b0caf3699e8ffafe', 'wbETH', 'wrapped-beacon-eth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xaf3111a248ff7a3238cdeea845bb2d43cf3835f1f6b8c9d28360728b55b9ce5b', 'Manta mBTC', 'manta-mbtc', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xafd219f513317b1750783c6581f55530d6cf189a5863fd18bd1b3ffcec1714b4', 'Manta mETH', 'manta-meth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x89cb9401e55d49c3269654dd1cdfb0e80e57823a4a7db98ba8fc5953b120fef4', 'Manta mUSD', 'manta-musd', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x0aa5eb2bb97ca915288b653a2529355d4dc66de2b37533213f0e4aeee3d3421f', 'pumpBTC', 'pumpbtc', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xb5ecb0a1e08e2abbabf624ffea089df933376855f468ade35c6375b00c33996a', 'FBTC', 'ignition-fbtc', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x1186afea9affb88809c210e13e2330b5258c2cef04bb8fff5eff372b7bd3f40f', 'SolvBTC', 'solv-btc', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x7a4f087c957d30218223c2baaaa365355c9ca81b6ea49004cfb1590a5399216f', 'SolvBTC.BBN', 'solv-protocol-solvbtc-bbn', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x9e46f919fbf978f3cad7cd34cca982d5613af63ff8aab6c379e4faa179552958', 'sDAI', 'savings-dai', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xa0265fb5c32f6e8db3197af3c7eb05c48ae373605b8165b6f4a51c5b0ba4812e', 'USDT', 'tether', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x286c479da40dc953bddc3bb4c453b608bba2e0ac483b077bd475174115395e6b', 'USDC', 'usd-coin', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xb6133b2ef9f6153eb869125d23dcf20d1e735331b5e41b15a6a7a6cec70e8651', 'USDe', 'usde', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xd05563025104fc36496c15c7021ad6b31034b0e89a356f4f818045d1f48808bc', 'sUSDe', 'ethena-staked-usde', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x1a7815cc9f75db5c24a5b0814bfb706bb9fe485333e98254015de8f48f84c67b', 'wstETH', 'wrapped-steth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x91b3559edb2619cde8ffb2aa7b3c3be97efd794ea46700db7092abeee62281b0', 'ezETH', 'everclear-bridged-ezeth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x1493d4ec82124de8f9b625682de69dcccda79e882b89a55a8c737b12de67bd68', 'pzETH', 'renzo-restaked-lst', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x4fc8ac9f101df07e2c2dec4a53c8c42c439bdbe5e36ea2d863a61ff60afafc30', 'steakLRT', 'steakhouse-resteaking-vault', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x33a6d90877f12c7954cca6d65587c25e9214c7bed2231c188981c7114c1bdb78', 'USDF', 'usdf', 'coingecko') on conflict (symbol) do nothing; --- insert into indexer.assets_rate_provider (asset_id, symbol, coingecko_id) values ('0x642a5db59ec323c2f846d4d4cf3e58d78aff64accf4f8f6455ba0aa3ef000a3b', 'Mantle mETH', ''); --- insert into indexer.assets_rate_provider (asset_id, symbol, coingecko_id) values ('0x78d4522ec607f6e8efb66ea49439d1ee48623cf763f9688a8eada025def033d9', 'rsUSDe', ''); --- insert into indexer.assets_rate_provider (asset_id, symbol, coingecko_id) values ('0x962792286fbc9b1d5860b4551362a12249362c21594c77abf4b3fe2bbe8d977a', 'rstETH', ''); --- insert into indexer.assets_rate_provider (asset_id, symbol, coingecko_id) values ('0x05fc623e57bd7bc1258efa8e4f62b05af5471d73df6f2c2dc11ecc81134c4f36', 'amphrETH', ''); --- insert into indexer.assets_rate_provider (asset_id, symbol, coingecko_id) values ('0xf2fc648c23a5db24610a1cf696acc4f0f6d9a7d6028dd9944964ab23f6e35995', 'Re7LRT', ''); - --- testnet - -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07', 'ETH', 'ethereum', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x324d0c35a4299ef88138a656d5272c5a3a9ccde2630ae055dacaf9d13443d53b', 'FUEL', 'fuel', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xa38a5a8beeb08d95744bc7f58528073f4052b254def59eba20c99c202b5acaa3', 'WETH', 'weth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x239ed6e12b7ce4089ee245244e3bf906999a6429c2a9a445a1e1faf56914a4ab', 'weETH', 'wrapped-eeth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xbae80f7fb8aa6b90d9b01ef726ec847cc4f59419c4d5f2ea88fec785d1b0e849', 'rsETH', 'kelp-dao-restaked-eth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xf3f9a0ed0ce8eac5f89d6b83e41b3848212d5b5f56108c54a205bb228ca30c16', 'rETH', 'reth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x7843c74bef935e837f2bcf67b5d64ecb46dd53ff86375530b0caf3699e8ffafe', 'wbETH', 'wrapped-beacon-eth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xaf3111a248ff7a3238cdeea845bb2d43cf3835f1f6b8c9d28360728b55b9ce5b', 'Manta mBTC', 'manta-mbtc', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xafd219f513317b1750783c6581f55530d6cf189a5863fd18bd1b3ffcec1714b4', 'Manta mETH', 'manta-meth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x89cb9401e55d49c3269654dd1cdfb0e80e57823a4a7db98ba8fc5953b120fef4', 'Manta mUSD', 'manta-musd', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x0aa5eb2bb97ca915288b653a2529355d4dc66de2b37533213f0e4aeee3d3421f', 'pumpBTC', 'pumpbtc', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xb5ecb0a1e08e2abbabf624ffea089df933376855f468ade35c6375b00c33996a', 'FBTC', 'ignition-fbtc', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x1186afea9affb88809c210e13e2330b5258c2cef04bb8fff5eff372b7bd3f40f', 'SolvBTC', 'solv-btc', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x7a4f087c957d30218223c2baaaa365355c9ca81b6ea49004cfb1590a5399216f', 'SolvBTC.BBN', 'solv-protocol-solvbtc-bbn', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x9e46f919fbf978f3cad7cd34cca982d5613af63ff8aab6c379e4faa179552958', 'sDAI', 'savings-dai', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xa0265fb5c32f6e8db3197af3c7eb05c48ae373605b8165b6f4a51c5b0ba4812e', 'USDT', 'tether', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xc26c91055de37528492e7e97d91c6f4abe34aae26f2c4d25cff6bfe45b5dc9a9', 'USDC', 'usd-coin', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x86a1beb50c844f5eff9afd21af514a13327c93f76edb89333af862f70040b107', 'USDe', 'usde', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xd2886b34454e2e0de47a82d8e6314b26e1e1312519247e8e2ef137672a909aeb', 'sUSDe', 'ethena-staked-usde', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0xb42cd9ddf61898da1701adb3a003b0cf4ca6df7b5fe490ec2c295b1ca43b33c8', 'wstETH', 'wrapped-steth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x91b3559edb2619cde8ffb2aa7b3c3be97efd794ea46700db7092abeee62281b0', 'ezETH', 'everclear-bridged-ezeth', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x1493d4ec82124de8f9b625682de69dcccda79e882b89a55a8c737b12de67bd68', 'pzETH', 'renzo-restaked-lst', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x4fc8ac9f101df07e2c2dec4a53c8c42c439bdbe5e36ea2d863a61ff60afafc30', 'steakLRT', 'steakhouse-resteaking-vault', 'coingecko') on conflict (symbol) do nothing; -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) values ('0x33a6d90877f12c7954cca6d65587c25e9214c7bed2231c188981c7114c1bdb78', 'USDF', 'usdf', 'coingecko') on conflict (symbol) do nothing; - -create index if not exists assets_rate_provider_asset_id_idx on indexer.assets_rate_provider (asset_id); -create index if not exists assets_rate_provider_symbol_idx on indexer.assets_rate_provider (symbol); - -create table if not exists indexer.assets_rates ( - _id serial, - asset_id text not null, - symbol text not null, - rate numeric not null, - timestamp timestamp without time zone NOT NULL, - primary key (_id) -); - -create index if not exists assets_rates_id_idx on indexer.assets_rates (_id); -create index if not exists assets_rates_asset_id_idx on indexer.assets_rates (asset_id); -create index if not exists assets_rates_symbol_idx on indexer.assets_rates (symbol); - -update indexer.migration set version = 9; diff --git a/packages/graphql/database/migrations/011_add_nft_collections.sql b/packages/graphql/database/migrations/011_add_nft_collections.sql deleted file mode 100644 index b39e413c2..000000000 --- a/packages/graphql/database/migrations/011_add_nft_collections.sql +++ /dev/null @@ -1,3 +0,0 @@ -insert into indexer.collections (contract_id, name, url) values ('0x202b55f66b8bafaf3b4fdf0653f1a4320607781dbd368bb576bc09250dd7dbbe', 'Koby', 'https://bafybeibspxhadwg2hfces4h5pdxd2qo5bdic4kbxsif66jn423adlivmpu.ipfs.w3s.link/{subId}.json') on conflict (contract_id) do nothing; -insert into indexer.collections (contract_id, name, url) values ('0x5d0188a9f77c4e5e48c459b5d02ccedac1a26d45b9f9c9e886f8563395bad32d', 'AI Quantum Flux', 'https://bafybeia65kpvylfbv7t2tg2qy54ivgckp3dhvcx7zbqvvn7xiedjbcbf6m.ipfs.dweb.link/{subId}_AQF.json') on conflict (contract_id) do nothing; -insert into indexer.collections (contract_id, name, url) values ('0xc5c219d360dcddbdaad2e0a33afc3550794ed4dfc484efb13562023189a08851', 'Alien Inva NFT', 'https://bafybeib4owydunce3koezxs7odwoemxydgfahizxqxylrbmcycj54rrpw4.ipfs.4everland.io/{subId}.json') on conflict (contract_id) do nothing; diff --git a/packages/graphql/database/migrations/012_create_balance_tables.sql b/packages/graphql/database/migrations/012_create_balance_tables.sql deleted file mode 100644 index 2375e3f3a..000000000 --- a/packages/graphql/database/migrations/012_create_balance_tables.sql +++ /dev/null @@ -1,21 +0,0 @@ -create table if not exists indexer.balance_index ( - block_height integer not null -); - -insert into indexer.balance_index (block_height) select 1 where not exists (select 1 from indexer.balance_index); - -create table if not exists indexer.balance ( - _id serial not null, - block_height integer not null, - tx_hash text not null, - account_hash text not null, - asset_id text not null, - balance text not null, - primary key (_id) -); - -create index if not exists balance_block_height_idx on indexer.balance (block_height); -create index if not exists balance_tx_hash_idx on indexer.balance (tx_hash); -create index if not exists balance_account_hash_idx on indexer.balance (account_hash); -create index if not exists balance_asset_id_idx on indexer.balance (asset_id); -create unique index if not exists balance_unique_idx on indexer.balance (tx_hash, account_hash, asset_id); diff --git a/packages/graphql/database/migrations/013_create_l1_contract_tables.sql b/packages/graphql/database/migrations/013_create_l1_contract_tables.sql deleted file mode 100644 index 0c6fe8ee1..000000000 --- a/packages/graphql/database/migrations/013_create_l1_contract_tables.sql +++ /dev/null @@ -1,59 +0,0 @@ -drop table if exists indexer.contract_l1_logs; -drop table if exists indexer.contract_l1_args; -drop table if exists indexer.contract_l1_index; - -create table if not exists indexer.contract_l1_index ( - _id serial primary key, - contract_hash text unique, - block_height int, - name text, - status text, - network text -); - -create index if not exists contract_l1_index_contract_hash_idx on indexer.contract_l1_index (contract_hash); - -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0xBa0e6bF94580D49B5Aaaa54279198D424B23eCC3', 21220898, 'SequencerProxy', 'active', 'mainnet') on conflict (contract_hash) do nothing; -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0x481aeEB9bdFe08f050d22F0b352356691c4B0b59', 21220911, 'FuelStreamX', 'active', 'mainnet') on conflict (contract_hash) do nothing; -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0xC20c2EA5fC5f26200f3339512f336c2ecE41FC18', 21414415, 'RewardDistribution', 'active', 'mainnet') on conflict (contract_hash) do nothing; -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf', 21039400, 'FuelMessagePortal', 'active', 'mainnet') on conflict (contract_hash) do nothing; -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0xa4cA04d02bfdC3A2DF56B9b6994520E69dF43F67', 20678194, 'FuelERC20GatewayV4', 'active', 'mainnet') on conflict (contract_hash) do nothing; -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0xf3D20Db1D16A4D0ad2f280A5e594FF3c7790f130', 20620432, 'FuelChainState', 'active', 'mainnet') on conflict (contract_hash) do nothing; -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0x675B68AA4d9c2d3BB3F0397048e62E6B7192079c', 21213754, 'Token', 'active', 'mainnet') on conflict (contract_hash) do nothing; - -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0x0E5CAcD6899a1E2a4B4E6e0c8a1eA7feAD3E25eD', 7203292, 'SequencerProxy', 'active', 'testnet') on conflict (contract_hash) do nothing; -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0x130F143e0F6d87371ca510e11340C2F3cD407a2b', 7203302, 'FuelStreamX', 'active', 'testnet') on conflict (contract_hash) do nothing; -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0x7c8deB33b992629130CE160f766881A191d874ce', 7334044, 'RewardDistribution', 'active', 'testnet') on conflict (contract_hash) do nothing; -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0x01855B78C1f8868DE70e84507ec735983bf262dA', 6339191, 'FuelMessagePortal', 'active', 'testnet') on conflict (contract_hash) do nothing; -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0xd1d5a4379dccC46D5c8D1c6c2656ce705698e359', 6626184, 'FuelERC20GatewayV4', 'active', 'testnet') on conflict (contract_hash) do nothing; -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0xf38F1e65adc58fc74BaaA132f645Aa5307F2d304', 6505507, 'FuelChainState', 'active', 'testnet') on conflict (contract_hash) do nothing; -insert into indexer.contract_l1_index (contract_hash, block_height, name, status, network) values ('0xd7Fc4e8FB2c05567C313f4C9b9e07641a361a550', 7203281, 'Token', 'active', 'testnet') on conflict (contract_hash) do nothing; - - -create table if not exists indexer.contract_l1_logs ( - _id serial primary key, - contract_hash text, - block_height int, - tx_hash text, - event text, - signature text, - raw_log jsonb default '{}', - decoded_args jsonb default '{}', - decoded_data jsonb default '{}', - timestamp timestamp without time zone, - log_index int -); - -create index if not exists contract_l1_logs_contract_hash_idx on indexer.contract_l1_logs (contract_hash); -create index if not exists contract_l1_logs_event_idx on indexer.contract_l1_logs (event); -create unique index if not exists contract_l1_logs_block_log_idx on indexer.contract_l1_logs (block_height, log_index); - -create table if not exists indexer.contract_l1_args ( - _id serial primary key, - contract_l1_log_id int, - key text, - value text -); - -create index if not exists contract_l1_args_key_value_idx on indexer.contract_l1_args (key, value); -create unique index if not exists contract_l1_args_log_key_idx on indexer.contract_l1_args (contract_l1_log_id, key); diff --git a/packages/graphql/database/migrations/014_create_cosmos_tables.sql b/packages/graphql/database/migrations/014_create_cosmos_tables.sql deleted file mode 100644 index 835e65b0b..000000000 --- a/packages/graphql/database/migrations/014_create_cosmos_tables.sql +++ /dev/null @@ -1,36 +0,0 @@ -drop table if exists indexer.cosmos_events; -drop table if exists indexer.cosmos_responses; -drop table if exists indexer.cosmos_index; - -create table if not exists indexer.cosmos_index ( - block_height int -); - -create table if not exists indexer.cosmos_responses ( - _id serial primary key, - block_height int, - tx_hash text, - data text, - timestamp timestamp without time zone -); - -create index if not exists cosmos_responses_block_height_idx on indexer.cosmos_responses (block_height); -create index if not exists cosmos_responses_tx_hash_idx on indexer.cosmos_responses (tx_hash); -create index if not exists cosmos_responses_timestamp_idx on indexer.cosmos_responses (timestamp); - -create table if not exists indexer.cosmos_events ( - _id serial primary key, - cosmos_response_id int, - type text, - key text, - value text, - index int -); - -create index if not exists cosmos_events_response_id_idx on indexer.cosmos_events (cosmos_response_id); -create index if not exists cosmos_events_type_idx on indexer.cosmos_events (type); -create index if not exists cosmos_events_key_idx on indexer.cosmos_events (key); -create index if not exists cosmos_events_value_idx on indexer.cosmos_events (value); -create index if not exists cosmos_events_type_key_value_idx on indexer.cosmos_events (type, key, value); - -insert into indexer.cosmos_index (block_height) select 1 where not exists (select 1 from indexer.cosmos_index); diff --git a/packages/graphql/database/migrations/015_add_total_fee_and_timestamptz.sql b/packages/graphql/database/migrations/015_add_total_fee_and_timestamptz.sql deleted file mode 100644 index dbadba227..000000000 --- a/packages/graphql/database/migrations/015_add_total_fee_and_timestamptz.sql +++ /dev/null @@ -1,4 +0,0 @@ -ALTER TABLE indexer.blocks -ADD COLUMN total_fee character varying(66); -ALTER TABLE indexer.contract_l1_logs ALTER COLUMN timestamp TYPE TIMESTAMPTZ USING timestamp AT TIME ZONE 'UTC'; -ALTER TABLE indexer.cosmos_responses ALTER COLUMN timestamp TYPE TIMESTAMPTZ USING timestamp AT TIME ZONE 'UTC'; diff --git a/packages/graphql/database/migrations/016_create_receipts_tables.sql b/packages/graphql/database/migrations/016_create_receipts_tables.sql deleted file mode 100644 index 46a58fe14..000000000 --- a/packages/graphql/database/migrations/016_create_receipts_tables.sql +++ /dev/null @@ -1,50 +0,0 @@ -create table if not exists indexer.receipts ( - _id serial primary key, - block_id integer, - transaction_id text, - tx_hash text, - indent int, - receipt_amount text, - receipt_asset_id text, - receipt_contract_id text, - receipt_data text, - receipt_digest text, - receipt_gas text, - receipt_gas_used text, - receipt_id text, - receipt_is text, - receipt_len text, - receipt_nonce text, - receipt_param1 text, - receipt_param2 text, - receipt_pc text, - receipt_ptr text, - receipt_ra text, - receipt_rb text, - receipt_rc text, - receipt_rd text, - receipt_reason text, - receipt_type text, - receipt_recipient text, - receipt_result text, - receipt_sender text, - receipt_sub_id text, - receipt_to text, - receipt_to_address text, - receipt_val text -); - -create index if not exists receipts_tx_hash_idx on indexer.receipts (tx_hash); -create index if not exists receipts_transaction_id_idx on indexer.receipts (transaction_id); -create index if not exists receipts_block_id_idx on indexer.receipts (block_id); -create index if not exists receipts_receipt_type_idx on indexer.receipts (receipt_type); - -create table if not exists indexer.receipts_data ( - _id serial primary key, - receipt_id int, - key text, - value text -); - -create index if not exists receipts_data_key_idx on indexer.receipts_data (key); -create index if not exists receipts_data_value_idx on indexer.receipts_data (value); diff --git a/packages/graphql/database/migrations/017_add_da_height_to_blocks.sql b/packages/graphql/database/migrations/017_add_da_height_to_blocks.sql deleted file mode 100644 index c4abfb198..000000000 --- a/packages/graphql/database/migrations/017_add_da_height_to_blocks.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE indexer.blocks ADD COLUMN da_height text; -create index on indexer.blocks (da_height); \ No newline at end of file diff --git a/packages/graphql/database/migrations/018_convert_timestamps_create_ro_user.sql b/packages/graphql/database/migrations/018_convert_timestamps_create_ro_user.sql deleted file mode 100644 index 7e7410d7f..000000000 --- a/packages/graphql/database/migrations/018_convert_timestamps_create_ro_user.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Convert timestamps to timestamptz -ALTER TABLE indexer.blocks ALTER COLUMN timestamp TYPE TIMESTAMPTZ USING timestamp AT TIME ZONE 'UTC'; -ALTER TABLE indexer.transactions ALTER COLUMN timestamp TYPE TIMESTAMPTZ USING timestamp AT TIME ZONE 'UTC'; - --- Grant permissions to read-only user (user may not exist in dev, that's ok) -GRANT USAGE ON SCHEMA indexer TO explorer_ro; -GRANT SELECT ON ALL TABLES IN SCHEMA indexer TO explorer_ro; diff --git a/packages/graphql/database/migrations/019_create_staking_mvs_and_jobs.sql b/packages/graphql/database/migrations/019_create_staking_mvs_and_jobs.sql deleted file mode 100644 index c0c54c829..000000000 --- a/packages/graphql/database/migrations/019_create_staking_mvs_and_jobs.sql +++ /dev/null @@ -1,194 +0,0 @@ --- daily_staked_mv -CREATE MATERIALIZED VIEW IF NOT EXISTS indexer.daily_staked_mv AS -SELECT - DATE_TRUNC('day', t."timestamp") AS day, - SUM(CAST(r.receipt_amount AS BIGINT)) AS daily_staked -FROM - indexer.transactions_accounts ta -JOIN - indexer.transactions t - ON ta.tx_hash = t.tx_hash - AND t."timestamp" > (NOW() - INTERVAL '60 days') - AND t."data"->>'scriptData' LIKE '%76465706f736974%' -JOIN - indexer.receipts r - ON r.tx_hash = t.tx_hash - AND r.receipt_type = 'CALL' - AND r.receipt_to = '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c' - AND CAST(r.receipt_amount AS BIGINT) > 0 -WHERE - ta.account_hash = '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c' -GROUP BY - day -WITH DATA; - -CREATE UNIQUE INDEX IF NOT EXISTS daily_staked_mv_day_idx ON indexer.daily_staked_mv(day); -GRANT SELECT ON indexer.daily_staked_mv TO explorer_ro; - --- daily_unbond_mv -CREATE MATERIALIZED VIEW IF NOT EXISTS indexer.daily_unbond_mv AS -SELECT - DATE_TRUNC('day', t."timestamp") AS day, - SUM(CAST(r.receipt_amount AS BIGINT)) AS daily_unbond -FROM - indexer.transactions_accounts ta -JOIN - indexer.transactions t - on ta.tx_hash = t.tx_hash - and t."timestamp" > (now() - INTERVAL '60 days') - and t."data"->>'scriptData' like '%87769746864726177%' -JOIN - indexer.receipts r - on r.tx_hash = ta.tx_hash - and r.receipt_type = 'TRANSFER_OUT' - and r.receipt_asset_id = '0x1d5d97005e41cae2187a895fd8eab0506111e0e2f3331cd3912c15c24e3c1d82' - and CAST(r.receipt_amount AS BIGINT) > 0 -WHERE - ta.account_hash = '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c' -GROUP BY - day -WITH DATA; - -CREATE UNIQUE INDEX IF NOT EXISTS daily_unbond_mv_day_idx ON indexer.daily_unbond_mv(day); -GRANT SELECT ON indexer.daily_unbond_mv TO explorer_ro; - --- total_staking_mv -CREATE MATERIALIZED VIEW IF NOT EXISTS indexer.total_staking_mv AS -SELECT - l1.day AS day, - (l1.daily_staked + l2.daily_staked) AS daily_staked -FROM ( - SELECT - DATE_TRUNC('day', cr."timestamp") AS day, - SUM(CAST(regexp_replace(ce2.value, '[^0-9]', '', 'g') AS BIGINT)) AS daily_staked - FROM - indexer.cosmos_responses cr - LEFT JOIN - indexer.cosmos_events ce - ON ce.cosmos_response_id = cr._id - AND ce."type" = 'delegate' - AND ce."key" = 'delegator' - AND ce."value" != '0x85308a35b3ad660213ea91a5d37bbf9620708ecc' - JOIN - indexer.cosmos_events ce2 - ON ce2.cosmos_response_id = cr._id - AND ce2."type" = 'delegate' - AND ce2."key" = 'amount' - AND ce2."index" = ce."index" - WHERE - cr."timestamp" > (now() - INTERVAL '60 days') - GROUP BY - day -) l1 -JOIN ( - SELECT - DATE_TRUNC('day', t."timestamp") AS day, - SUM(CAST(r.receipt_amount AS BIGINT)) AS daily_staked - FROM - indexer.transactions_accounts ta - JOIN - indexer.transactions t - ON ta.tx_hash = t.tx_hash - AND t."timestamp" > (now() - INTERVAL '60 days') - AND t."data"->>'scriptData' LIKE '%76465706f736974%' - JOIN - indexer.receipts r - ON r.tx_hash = ta.tx_hash - AND r.receipt_type = 'CALL' - AND r.receipt_to = '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c' - AND CAST(r.receipt_amount AS BIGINT) > 0 - WHERE - ta.account_hash = '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c' - GROUP BY - day -) l2 -ON l2.day = l1.day -WITH DATA; - -CREATE UNIQUE INDEX IF NOT EXISTS total_staking_mv_day_idx ON indexer.total_staking_mv(day); -GRANT SELECT ON indexer.total_staking_mv TO explorer_ro; - --- daily_claims_mv -CREATE MATERIALIZED VIEW IF NOT EXISTS indexer.daily_claims_mv AS -SELECT - DATE_TRUNC('day', t."timestamp") AS day, - (SUM(CAST(r.receipt_amount AS BIGINT)) / 1000000000) AS daily_claims -FROM - indexer.transactions_accounts ta -JOIN - indexer.transactions t - on ta.tx_hash = t.tx_hash - and t."timestamp" > (now() - INTERVAL '60 days') - and t."data"->>'scriptData' like '%d636c61696d5f72657761726473%' -JOIN - indexer.receipts r - on r.tx_hash = ta.tx_hash - and r.receipt_type = 'TRANSFER_OUT' - and r.receipt_asset_id = '0x1d5d97005e41cae2187a895fd8eab0506111e0e2f3331cd3912c15c24e3c1d82' - and CAST(r.receipt_amount AS BIGINT) > 0 -WHERE - ta.account_hash = '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c' -GROUP BY - day -WITH DATA; - -CREATE UNIQUE INDEX IF NOT EXISTS daily_claims_mv_day_idx ON indexer.daily_claims_mv(day); -GRANT SELECT ON indexer.daily_claims_mv TO explorer_ro; - --- inflows_mv -CREATE MATERIALIZED VIEW IF NOT EXISTS indexer.inflows_mv AS -select - sum((i.data->>'amount')::numeric) as amount, - DATE_TRUNC('day', t."timestamp") as day -from - indexer.transactions_accounts a - join indexer.transactions t on (a.tx_hash = t.tx_hash) - join indexer.outputs i on (i.transaction_id = t._id) -where - account_hash in ('0xdb491b442f68ebaa785f077805158ebfddeede7063f16d5a26e1073ff6987601', '0xafdda1cd084ed0f56d35f570b2e9d34e7c7380191058e2a2fb16e0c58cbbc7c2') - and i.data->>'assetId' = '0x1d5d97005e41cae2187a895fd8eab0506111e0e2f3331cd3912c15c24e3c1d82' - and i.data->>'to' not in ('0xdb491b442f68ebaa785f077805158ebfddeede7063f16d5a26e1073ff6987601', '0xafdda1cd084ed0f56d35f570b2e9d34e7c7380191058e2a2fb16e0c58cbbc7c2') - and i.data->>'__typename' = 'CoinOutput' -group by day -WITH DATA; - -CREATE UNIQUE INDEX IF NOT EXISTS inflows_mv_day_idx ON indexer.inflows_mv(day); -GRANT SELECT ON indexer.inflows_mv TO explorer_ro; - --- outflows_mv -CREATE MATERIALIZED VIEW IF NOT EXISTS indexer.outflows_mv AS -select - sum((i.data->>'amount')::numeric) as amount, - DATE_TRUNC('day', t."timestamp") as day -from - indexer.transactions_accounts a - join indexer.transactions t on (a.tx_hash = t.tx_hash) - join indexer.outputs i on (i.transaction_id = t._id) -where - account_hash in ('0xdb491b442f68ebaa785f077805158ebfddeede7063f16d5a26e1073ff6987601', '0xafdda1cd084ed0f56d35f570b2e9d34e7c7380191058e2a2fb16e0c58cbbc7c2') - and i.data->>'assetId' = '0x1d5d97005e41cae2187a895fd8eab0506111e0e2f3331cd3912c15c24e3c1d82' - and i.data->>'to' in ('0xdb491b442f68ebaa785f077805158ebfddeede7063f16d5a26e1073ff6987601', '0xafdda1cd084ed0f56d35f570b2e9d34e7c7380191058e2a2fb16e0c58cbbc7c2') - and i.data->>'__typename' = 'CoinOutput' -group by day -WITH DATA; - -CREATE UNIQUE INDEX IF NOT EXISTS outflows_mv_day_idx ON indexer.outflows_mv(day); -GRANT SELECT ON indexer.outflows_mv TO explorer_ro; - --- database_jobs table -create table if not exists indexer.database_jobs ( - _id serial, - query text UNIQUE, - recurrent boolean not null default FALSE, - interval_seconds integer, - status text, - last_run TIMESTAMPTZ, - error_message text -); - -insert into indexer.database_jobs (query, recurrent, interval_seconds, status) values ('REFRESH MATERIALIZED VIEW CONCURRENTLY indexer.daily_staked_mv', true, 86400, 'pending') on conflict (query) do nothing; -insert into indexer.database_jobs (query, recurrent, interval_seconds, status) values ('REFRESH MATERIALIZED VIEW CONCURRENTLY indexer.daily_unbond_mv', true, 86400, 'pending') on conflict (query) do nothing; -insert into indexer.database_jobs (query, recurrent, interval_seconds, status) values ('REFRESH MATERIALIZED VIEW CONCURRENTLY indexer.total_staking_mv', true, 86400, 'pending') on conflict (query) do nothing; -insert into indexer.database_jobs (query, recurrent, interval_seconds, status) values ('REFRESH MATERIALIZED VIEW CONCURRENTLY indexer.daily_claims_mv', true, 86400, 'pending') on conflict (query) do nothing; -insert into indexer.database_jobs (query, recurrent, interval_seconds, status) values ('REFRESH MATERIALIZED VIEW CONCURRENTLY indexer.inflows_mv', true, 86400, 'pending') on conflict (query) do nothing; -insert into indexer.database_jobs (query, recurrent, interval_seconds, status) values ('REFRESH MATERIALIZED VIEW CONCURRENTLY indexer.outflows_mv', true, 86400, 'pending') on conflict (query) do nothing; diff --git a/packages/graphql/database/migrations/020_receipts_id_to_bigserial.sql b/packages/graphql/database/migrations/020_receipts_id_to_bigserial.sql deleted file mode 100644 index ee8017038..000000000 --- a/packages/graphql/database/migrations/020_receipts_id_to_bigserial.sql +++ /dev/null @@ -1,10 +0,0 @@ -BEGIN; --- Change serial to bigserial (preserves auto-increment behavior) -ALTER TABLE indexer.receipts ALTER COLUMN _id TYPE bigint USING _id::bigint; - --- Update the sequence to use bigint values -ALTER SEQUENCE indexer.receipts__id_seq AS bigint; - --- Update foreign key column in receipts_data table (this table actually exists) -ALTER TABLE indexer.receipts_data ALTER COLUMN receipt_id TYPE bigint; -COMMIT; \ No newline at end of file diff --git a/packages/graphql/database/migrations/021_balance_id_to_bigserial.sql b/packages/graphql/database/migrations/021_balance_id_to_bigserial.sql deleted file mode 100644 index a2fab2f24..000000000 --- a/packages/graphql/database/migrations/021_balance_id_to_bigserial.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; --- Change serial to bigserial (preserves auto-increment behavior) -ALTER TABLE indexer.balance ALTER COLUMN _id TYPE bigint USING _id::bigint; - --- Update the sequence to use bigint values -ALTER SEQUENCE indexer.balance__id_seq AS bigint; -COMMIT; \ No newline at end of file diff --git a/packages/graphql/database/migrations/022_l1_index_id_to_bigserial.sql b/packages/graphql/database/migrations/022_l1_index_id_to_bigserial.sql deleted file mode 100644 index 304271901..000000000 --- a/packages/graphql/database/migrations/022_l1_index_id_to_bigserial.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; --- Change serial to bigserial (preserves auto-increment behavior) -ALTER TABLE indexer.contract_l1_index ALTER COLUMN _id TYPE bigint USING _id::bigint; - --- Update the sequence to use bigint values -ALTER SEQUENCE indexer.contract_l1_index__id_seq AS bigint; -COMMIT; \ No newline at end of file diff --git a/packages/graphql/database/migrations/023_l1_logs_id_to_bigserial.sql b/packages/graphql/database/migrations/023_l1_logs_id_to_bigserial.sql deleted file mode 100644 index e83ce33b7..000000000 --- a/packages/graphql/database/migrations/023_l1_logs_id_to_bigserial.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; --- Change serial to bigserial (preserves auto-increment behavior) -ALTER TABLE indexer.contract_l1_logs ALTER COLUMN _id TYPE bigint USING _id::bigint; - --- Update the sequence to use bigint values -ALTER SEQUENCE indexer.contract_l1_logs__id_seq AS bigint; -COMMIT; \ No newline at end of file diff --git a/packages/graphql/database/migrations/024_l1_args_id_to_bigserial.sql b/packages/graphql/database/migrations/024_l1_args_id_to_bigserial.sql deleted file mode 100644 index 67ce15301..000000000 --- a/packages/graphql/database/migrations/024_l1_args_id_to_bigserial.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; --- Change serial to bigserial (preserves auto-increment behavior) -ALTER TABLE indexer.contract_l1_args ALTER COLUMN _id TYPE bigint USING _id::bigint; - --- Update the sequence to use bigint values -ALTER SEQUENCE indexer.contract_l1_args__id_seq AS bigint; -COMMIT; \ No newline at end of file diff --git a/packages/graphql/database/migrations/025_cosmos_responses_id_to_bigserial.sql b/packages/graphql/database/migrations/025_cosmos_responses_id_to_bigserial.sql deleted file mode 100644 index 5168344ca..000000000 --- a/packages/graphql/database/migrations/025_cosmos_responses_id_to_bigserial.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; --- Change serial to bigserial (preserves auto-increment behavior) -ALTER TABLE indexer.cosmos_responses ALTER COLUMN _id TYPE bigint USING _id::bigint; - --- Update the sequence to use bigint values -ALTER SEQUENCE indexer.cosmos_responses__id_seq AS bigint; -COMMIT; \ No newline at end of file diff --git a/packages/graphql/database/migrations/026_cosmos_events_id_to_bigserial.sql b/packages/graphql/database/migrations/026_cosmos_events_id_to_bigserial.sql deleted file mode 100644 index 7dd51177c..000000000 --- a/packages/graphql/database/migrations/026_cosmos_events_id_to_bigserial.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; --- Change serial to bigserial (preserves auto-increment behavior) -ALTER TABLE indexer.cosmos_events ALTER COLUMN _id TYPE bigint USING _id::bigint; - --- Update the sequence to use bigint values -ALTER SEQUENCE indexer.cosmos_events__id_seq AS bigint; -COMMIT; \ No newline at end of file diff --git a/packages/graphql/database/migrations/027_receipts_data_id_to_bigserial.sql b/packages/graphql/database/migrations/027_receipts_data_id_to_bigserial.sql deleted file mode 100644 index a6b50c98a..000000000 --- a/packages/graphql/database/migrations/027_receipts_data_id_to_bigserial.sql +++ /dev/null @@ -1,7 +0,0 @@ -BEGIN; --- Change serial to bigserial (preserves auto-increment behavior) -ALTER TABLE indexer.receipts_data ALTER COLUMN _id TYPE bigint USING _id::bigint; - --- Update the sequence to use bigint values -ALTER SEQUENCE indexer.receipts_data__id_seq AS bigint; -COMMIT; \ No newline at end of file diff --git a/packages/graphql/database/migrations/028_add_vacuum_jobs.sql b/packages/graphql/database/migrations/028_add_vacuum_jobs.sql deleted file mode 100644 index a55af0e8a..000000000 --- a/packages/graphql/database/migrations/028_add_vacuum_jobs.sql +++ /dev/null @@ -1,32 +0,0 @@ --- Add VACUUM ANALYZE maintenance jobs for database optimization --- These jobs reclaim dead rows, update statistics, and improve query planner decisions - --- Hot tables (frequently updated during indexing) - run daily -insert into indexer.database_jobs (query, recurrent, interval_seconds, status) -values ('VACUUM ANALYZE indexer.transactions', true, 86400, 'pending') -on conflict (query) do nothing; - -insert into indexer.database_jobs (query, recurrent, interval_seconds, status) -values ('VACUUM ANALYZE indexer.transactions_accounts', true, 86400, 'pending') -on conflict (query) do nothing; - -insert into indexer.database_jobs (query, recurrent, interval_seconds, status) -values ('VACUUM ANALYZE indexer.contracts', true, 86400, 'pending') -on conflict (query) do nothing; - --- Less frequently updated tables - run weekly -insert into indexer.database_jobs (query, recurrent, interval_seconds, status) -values ('VACUUM ANALYZE indexer.blocks', true, 604800, 'pending') -on conflict (query) do nothing; - -insert into indexer.database_jobs (query, recurrent, interval_seconds, status) -values ('VACUUM ANALYZE indexer.outputs', true, 604800, 'pending') -on conflict (query) do nothing; - -insert into indexer.database_jobs (query, recurrent, interval_seconds, status) -values ('VACUUM ANALYZE indexer.inputs', true, 604800, 'pending') -on conflict (query) do nothing; - -insert into indexer.database_jobs (query, recurrent, interval_seconds, status) -values ('VACUUM ANALYZE indexer.predicates', true, 604800, 'pending') -on conflict (query) do nothing; diff --git a/packages/graphql/database/migrations/029_add_search_indexes.sql b/packages/graphql/database/migrations/029_add_search_indexes.sql deleted file mode 100644 index 0a2ddab93..000000000 --- a/packages/graphql/database/migrations/029_add_search_indexes.sql +++ /dev/null @@ -1,9 +0,0 @@ --- Add composite indexes for search query performance optimization --- These indexes optimize queries that filter by account_hash and order by _id - --- Composite index for getRecentTransactionsByOwner query (account_hash, _id DESC) --- This allows the query to use index-only scan when fetching recent transactions for an account -CREATE INDEX CONCURRENTLY ON indexer.transactions_accounts (account_hash, _id DESC); - --- Index on asset_id for fast asset lookups -CREATE INDEX CONCURRENTLY ON indexer.assets_contracts (asset_id); diff --git a/packages/graphql/database/migrations/030_create_recent_transactions_mv.sql b/packages/graphql/database/migrations/030_create_recent_transactions_mv.sql deleted file mode 100644 index 7fb77bc56..000000000 --- a/packages/graphql/database/migrations/030_create_recent_transactions_mv.sql +++ /dev/null @@ -1,34 +0,0 @@ --- Create materialized view for recent account transactions (last 7 days) --- This optimizes searches for accounts with many transactions by avoiding full table scans --- Joins with transactions table to filter by timestamp - -CREATE MATERIALIZED VIEW IF NOT EXISTS indexer.recent_account_transactions_mv AS -SELECT - ta.account_hash, - ta.tx_hash, - ta._id, - ta.block_id, - t.timestamp -FROM - indexer.transactions_accounts ta - INNER JOIN indexer.transactions t ON ta.tx_hash = t.tx_hash -WHERE - t.timestamp > NOW() - INTERVAL '7 days' -WITH DATA; - --- Create unique index for concurrent refresh (required for CONCURRENTLY keyword) -CREATE UNIQUE INDEX IF NOT EXISTS recent_account_transactions_mv_idx -ON indexer.recent_account_transactions_mv(account_hash, _id DESC); - --- Grant read access to explorer_ro user -GRANT SELECT ON indexer.recent_account_transactions_mv TO explorer_ro; - --- Add to database jobs for periodic refresh (every 4 hours to keep data fresh) -INSERT INTO indexer.database_jobs (query, recurrent, interval_seconds, status) -VALUES ( - 'REFRESH MATERIALIZED VIEW CONCURRENTLY indexer.recent_account_transactions_mv', - true, - 14400, - 'pending' -) -ON CONFLICT (query) DO NOTHING; diff --git a/packages/graphql/database/migrations/031_add_statistics_indexes.sql b/packages/graphql/database/migrations/031_add_statistics_indexes.sql deleted file mode 100644 index abf6f50d8..000000000 --- a/packages/graphql/database/migrations/031_add_statistics_indexes.sql +++ /dev/null @@ -1,20 +0,0 @@ --- Add indexes for statistics queries optimization --- These queries scan the full transactions/blocks table filtered by timestamp --- Without these indexes, AWS RDS performs expensive sequential scans - --- Index on transactions.timestamp for getTotalFee() and other statistics queries --- This is critical because getTotalFee scans all transactions from the last 24 hours -CREATE INDEX ON indexer.transactions ("timestamp" DESC); - --- Index on blocks.timestamp for tps(), getMaxTps(), and other block statistics --- Queries filter by timestamp range to get last 24 hours of data -CREATE INDEX ON indexer.blocks ("timestamp" DESC); - --- Add to maintenance jobs for periodic ANALYZE to update index statistics -INSERT INTO indexer.database_jobs (query, recurrent, interval_seconds, status) -VALUES ('ANALYZE indexer.transactions', true, 86400, 'pending') -ON CONFLICT (query) DO NOTHING; - -INSERT INTO indexer.database_jobs (query, recurrent, interval_seconds, status) -VALUES ('ANALYZE indexer.blocks', true, 86400, 'pending') -ON CONFLICT (query) DO NOTHING; diff --git a/packages/graphql/database/migrations/032_create_hourly_statistics_mv.sql b/packages/graphql/database/migrations/032_create_hourly_statistics_mv.sql deleted file mode 100644 index e346a1f4f..000000000 --- a/packages/graphql/database/migrations/032_create_hourly_statistics_mv.sql +++ /dev/null @@ -1,44 +0,0 @@ --- Create materialized view for hourly statistics to eliminate expensive JSON extraction --- getTotalFee() query was taking 11+ seconds due to full table scan + JSON extraction --- This view pre-computes hourly aggregations and refreshes every 10 minutes - --- Force drop if exists (handle stuck migrations) -DROP MATERIALIZED VIEW IF EXISTS indexer.hourly_statistics CASCADE; -DROP INDEX IF EXISTS hourly_statistics_hour_idx; - --- Create the materialized view -CREATE MATERIALIZED VIEW indexer.hourly_statistics AS -SELECT - date_trunc('hour', t."timestamp") AS hour, - SUM((t.data->'status'->>'totalFee')::numeric) AS total_fee, - SUM((t.data->'status'->>'gasUsed')::bigint) AS total_gas_used -FROM indexer.transactions t -WHERE t."timestamp" > NOW() - INTERVAL '7 days' -GROUP BY date_trunc('hour', t."timestamp"); - --- Create unique index for concurrent refresh (required for CONCURRENTLY keyword) -CREATE UNIQUE INDEX hourly_statistics_hour_idx -ON indexer.hourly_statistics(hour); - --- Grant read access to explorer_ro user -GRANT SELECT ON indexer.hourly_statistics TO explorer_ro; - --- Schedule periodic refresh every 10 minutes (600 seconds) -INSERT INTO indexer.database_jobs (query, recurrent, interval_seconds, status) -VALUES ( - 'REFRESH MATERIALIZED VIEW CONCURRENTLY indexer.hourly_statistics', - true, - 1800, - 'pending' -) -ON CONFLICT (query) DO NOTHING; - --- Add ANALYZE job for this view (daily) -INSERT INTO indexer.database_jobs (query, recurrent, interval_seconds, status) -VALUES ( - 'ANALYZE indexer.hourly_statistics', - true, - 86400, - 'pending' -) -ON CONFLICT (query) DO NOTHING; diff --git a/packages/graphql/database/migrations/033_add_moor_token.sql b/packages/graphql/database/migrations/033_add_moor_token.sql deleted file mode 100644 index c3719f78c..000000000 --- a/packages/graphql/database/migrations/033_add_moor_token.sql +++ /dev/null @@ -1,10 +0,0 @@ --- Migration 32: Add MOOR token rate provider (CMC DEX) --- MOOR is the governance token of the Moor protocol on Fuel Network - --- Add MOOR token for mainnet using CMC DEX as price source -insert into indexer.assets_rate_provider (asset_id, symbol, value, provider) -values ('0xa9d7987a3f2c2fb02b287c3a2ef619046e930848c6050d31efef48ad6d3bdee8', 'MOOR', 'Fuel Network', 'cmc-dex') -on conflict (symbol) do update set asset_id = excluded.asset_id, value = excluded.value, provider = excluded.provider; - --- Update migration version -UPDATE indexer.migration SET version = 32; diff --git a/packages/graphql/database/migrations/034_drop_unused_receipts_indexes.sql b/packages/graphql/database/migrations/034_drop_unused_receipts_indexes.sql deleted file mode 100644 index 86eb4c5ca..000000000 --- a/packages/graphql/database/migrations/034_drop_unused_receipts_indexes.sql +++ /dev/null @@ -1,26 +0,0 @@ --- Migration 33: Drop unused indexes on receipts table --- --- Analysis: Performance Insights showed INSERT INTO indexer.receipts was 73% of DB load --- Index usage stats revealed 3 indexes with 0 scans consuming ~28 GB --- --- Findings: --- receipts_transaction_id_idx: 0 scans, 11 GB - no code queries by transaction_id --- receipts_receipt_type_idx: 0 scans, 8.3 GB - filter applied after tx_hash join --- receipts_receipt_to_idx: 0 scans, 8.5 GB - filter applied after tx_hash join --- --- Expected impact: --- - ~40% reduction in INSERT latency (3 fewer indexes to maintain) --- - ~28 GB disk space savings --- --- NOTE: For production, run DROP INDEX CONCURRENTLY manually (cannot run in transaction): --- DROP INDEX CONCURRENTLY IF EXISTS indexer.receipts_transaction_id_idx; --- DROP INDEX CONCURRENTLY IF EXISTS indexer.receipts_receipt_type_idx; --- DROP INDEX CONCURRENTLY IF EXISTS indexer.receipts_receipt_to_idx; - --- For dev/local environments (small tables, ok to lock briefly): -DROP INDEX IF EXISTS indexer.receipts_transaction_id_idx; -DROP INDEX IF EXISTS indexer.receipts_receipt_type_idx; -DROP INDEX IF EXISTS indexer.receipts_receipt_to_idx; - --- Update migration version -UPDATE indexer.migration SET version = 33; diff --git a/packages/graphql/database/migrations/035_add_receipts_vacuum_job.sql b/packages/graphql/database/migrations/035_add_receipts_vacuum_job.sql deleted file mode 100644 index 776a56bff..000000000 --- a/packages/graphql/database/migrations/035_add_receipts_vacuum_job.sql +++ /dev/null @@ -1,20 +0,0 @@ --- Migration 34: Add VACUUM job for receipts table --- --- After dropping 3 unused indexes (migration 33), add recurring VACUUM --- to maintain table health and reclaim dead tuple space. --- --- VACUUM ANALYZE: --- - Reclaims space from dead tuples (from updates/deletes) --- - Updates statistics for query planner --- - Does NOT lock the table (safe for production) - --- Add VACUUM ANALYZE job for receipts (every 12 hours = 43200 seconds) --- This is more frequent than other tables due to high INSERT volume (~195/sec) -INSERT INTO indexer.database_jobs (query, recurrent, interval_seconds, status) -SELECT 'VACUUM ANALYZE indexer.receipts', true, 43200, 'pending' -WHERE NOT EXISTS ( - SELECT 1 FROM indexer.database_jobs WHERE query = 'VACUUM ANALYZE indexer.receipts' -); - --- Update migration version -UPDATE indexer.migration SET version = 34; \ No newline at end of file diff --git a/packages/graphql/database/migrations/036_optimize_hourly_statistics_mv.sql b/packages/graphql/database/migrations/036_optimize_hourly_statistics_mv.sql deleted file mode 100644 index c4c0153bb..000000000 --- a/packages/graphql/database/migrations/036_optimize_hourly_statistics_mv.sql +++ /dev/null @@ -1,35 +0,0 @@ --- Migration 35: Optimize hourly_statistics MV from 7 days to 24 hours --- --- Analysis: AWS Performance Insights showed hourly_statistics refresh was 36% of DB load --- The API only queries 24 hours of data (BlockDAO.ts getTotalFee), but MV stored 7 days --- --- Before: 7 days of data refreshed every 30 minutes --- After: 24 hours of data refreshed every 30 minutes --- --- Expected impact: --- - ~7x reduction in refresh query cost --- - ~7x reduction in MV storage size --- - Faster refresh completion time - --- Recreate the materialized view with 24-hour window -DROP MATERIALIZED VIEW IF EXISTS indexer.hourly_statistics CASCADE; - -CREATE MATERIALIZED VIEW indexer.hourly_statistics AS -SELECT - date_trunc('hour', t."timestamp") AS hour, - SUM((t.data->'status'->>'totalFee')::numeric) AS total_fee, - SUM((t.data->'status'->>'gasUsed')::bigint) AS total_gas_used -FROM indexer.transactions t -WHERE t."timestamp" > NOW() - INTERVAL '24 hours' -GROUP BY date_trunc('hour', t."timestamp"); - --- Recreate unique index for concurrent refresh -CREATE UNIQUE INDEX hourly_statistics_hour_idx -ON indexer.hourly_statistics(hour); - --- Grant read access to explorer_ro user -GRANT SELECT ON indexer.hourly_statistics TO explorer_ro; - --- Update migration version -UPDATE indexer.migration SET version = 35; - diff --git a/packages/graphql/database/migrations/037_outputs_id_to_bigserial.sql b/packages/graphql/database/migrations/037_outputs_id_to_bigserial.sql deleted file mode 100644 index 20b126972..000000000 --- a/packages/graphql/database/migrations/037_outputs_id_to_bigserial.sql +++ /dev/null @@ -1,7 +0,0 @@ --- Change serial to bigserial (preserves auto-increment behavior) --- The outputs table hit the max value of its int4 sequence (2,147,483,647) --- This was missed in the original bigserial migrations (020-027) -ALTER TABLE indexer.outputs ALTER COLUMN _id TYPE bigint USING _id::bigint; - --- Update the sequence to use bigint values -ALTER SEQUENCE indexer.outputs__id_seq AS bigint; diff --git a/packages/graphql/database/migrations/038_inputs_id_to_bigserial.sql b/packages/graphql/database/migrations/038_inputs_id_to_bigserial.sql deleted file mode 100644 index efefb116d..000000000 --- a/packages/graphql/database/migrations/038_inputs_id_to_bigserial.sql +++ /dev/null @@ -1,6 +0,0 @@ --- Preventive migration: inputs table also uses SERIAL (int4) --- Converting to bigserial before hitting the max value limit -ALTER TABLE indexer.inputs ALTER COLUMN _id TYPE bigint USING _id::bigint; - --- Update the sequence to use bigint values -ALTER SEQUENCE indexer.inputs__id_seq AS bigint; diff --git a/packages/graphql/database/migrations/039_predicates_id_to_bigserial.sql b/packages/graphql/database/migrations/039_predicates_id_to_bigserial.sql deleted file mode 100644 index c0f6b77ba..000000000 --- a/packages/graphql/database/migrations/039_predicates_id_to_bigserial.sql +++ /dev/null @@ -1,6 +0,0 @@ --- Preventive migration: predicates table also uses SERIAL (int4) --- Converting to bigserial before hitting the max value limit -ALTER TABLE indexer.predicates ALTER COLUMN _id TYPE bigint USING _id::bigint; - --- Update the sequence to use bigint values -ALTER SEQUENCE indexer.predicates__id_seq AS bigint; diff --git a/packages/graphql/database/migrations/040_contracts_id_to_bigserial.sql b/packages/graphql/database/migrations/040_contracts_id_to_bigserial.sql deleted file mode 100644 index fb1674895..000000000 --- a/packages/graphql/database/migrations/040_contracts_id_to_bigserial.sql +++ /dev/null @@ -1,6 +0,0 @@ --- Preventive migration: contracts table also uses SERIAL (int4) --- Converting to bigserial before hitting the max value limit -ALTER TABLE indexer.contracts ALTER COLUMN _id TYPE bigint USING _id::bigint; - --- Update the sequence to use bigint values -ALTER SEQUENCE indexer.contracts__id_seq AS bigint; diff --git a/packages/graphql/database/migrations/041_optimize_staking_mvs.sql b/packages/graphql/database/migrations/041_optimize_staking_mvs.sql deleted file mode 100644 index 90c373692..000000000 --- a/packages/graphql/database/migrations/041_optimize_staking_mvs.sql +++ /dev/null @@ -1,30 +0,0 @@ --- Migration 041: Add statement_timeout protection and composite index --- --- Adds statement_timeout to all MV refresh jobs to prevent runaway queries, --- and a composite index on cosmos_events for efficient delegate joins. - --- ============================================================ --- 1. Add composite index on cosmos_events for the delegate join pattern --- (cosmos_response_id, type, key, index) covers the delegate join --- ============================================================ -CREATE INDEX CONCURRENTLY IF NOT EXISTS cosmos_events_resp_type_key_idx_idx -ON indexer.cosmos_events (cosmos_response_id, type, key, index); - --- ============================================================ --- 2. Add statement_timeout to heavy MV refresh jobs --- Using CHR(59) to represent semicolons inside the query strings, --- since the migration runner splits on literal semicolons. --- ============================================================ - --- hourly_statistics -UPDATE indexer.database_jobs -SET query = 'SET statement_timeout = ''10min''' || CHR(59) || ' REFRESH MATERIALIZED VIEW CONCURRENTLY indexer.hourly_statistics' || CHR(59) || ' RESET statement_timeout' || CHR(59) -WHERE query = 'REFRESH MATERIALIZED VIEW CONCURRENTLY indexer.hourly_statistics'; - --- recent_account_transactions_mv -UPDATE indexer.database_jobs -SET query = 'SET statement_timeout = ''30min''' || CHR(59) || ' REFRESH MATERIALIZED VIEW CONCURRENTLY indexer.recent_account_transactions_mv' || CHR(59) || ' RESET statement_timeout' || CHR(59) -WHERE query = 'REFRESH MATERIALIZED VIEW CONCURRENTLY indexer.recent_account_transactions_mv'; - --- Update migration version -UPDATE indexer.migration SET version = 41; diff --git a/packages/graphql/database/migrations/042_drop_unused_indexes.sql b/packages/graphql/database/migrations/042_drop_unused_indexes.sql deleted file mode 100644 index 7d9d544a3..000000000 --- a/packages/graphql/database/migrations/042_drop_unused_indexes.sql +++ /dev/null @@ -1,35 +0,0 @@ --- Migration 042: Drop unused and redundant indexes --- --- Analysis from pg_stat_user_indexes (0 scans = never used by any query): --- --- transactions_hash_idx (148 MB prod est.) - 0 scans, redundant with transactions_tx_hash_key (UNIQUE) --- blocks_hash_idx (147 MB prod est.) - 0 scans, redundant with blocks_id_key (UNIQUE) --- transactions_timestamp_idx (27 MB) - 0 scans, superseded by transactions_timestamp_idx1 (DESC) --- blocks_da_height_idx (8.7 MB) - 0 scans, no code references --- cosmos_events_type_idx - 2 scans, fully covered by (type, key, value) composite --- cosmos_events_key_idx - 0 scans, fully covered by (type, key, value) composite --- cosmos_events_value_idx - 0 scans, rarely queried standalone --- --- Expected savings: ~330 MB+ on production (proportional to table growth) --- Additional benefit: faster INSERT/UPDATE on these tables (fewer indexes to maintain) --- --- NOTE: For production, run DROP INDEX CONCURRENTLY manually outside a transaction: --- DROP INDEX CONCURRENTLY IF EXISTS indexer.transactions_hash_idx; --- DROP INDEX CONCURRENTLY IF EXISTS indexer.blocks_hash_idx; --- DROP INDEX CONCURRENTLY IF EXISTS indexer.transactions_timestamp_idx; --- DROP INDEX CONCURRENTLY IF EXISTS indexer.blocks_da_height_idx; --- DROP INDEX CONCURRENTLY IF EXISTS indexer.cosmos_events_type_idx; --- DROP INDEX CONCURRENTLY IF EXISTS indexer.cosmos_events_key_idx; --- DROP INDEX CONCURRENTLY IF EXISTS indexer.cosmos_events_value_idx; - --- For dev/local environments: -DROP INDEX IF EXISTS indexer.transactions_hash_idx; -DROP INDEX IF EXISTS indexer.blocks_hash_idx; -DROP INDEX IF EXISTS indexer.transactions_timestamp_idx; -DROP INDEX IF EXISTS indexer.blocks_da_height_idx; -DROP INDEX IF EXISTS indexer.cosmos_events_type_idx; -DROP INDEX IF EXISTS indexer.cosmos_events_key_idx; -DROP INDEX IF EXISTS indexer.cosmos_events_value_idx; - --- Update migration version -UPDATE indexer.migration SET version = 42; diff --git a/packages/graphql/database/migrations/043_replace_staking_mvs_with_agg_tables.sql b/packages/graphql/database/migrations/043_replace_staking_mvs_with_agg_tables.sql deleted file mode 100644 index 47d9105aa..000000000 --- a/packages/graphql/database/migrations/043_replace_staking_mvs_with_agg_tables.sql +++ /dev/null @@ -1,177 +0,0 @@ --- Migration 043: Replace staking materialized views with aggregate tables --- --- Problem: The 6 staking materialized views (daily_staked_mv, daily_unbond_mv, --- daily_claims_mv, total_staking_mv, inflows_mv, outflows_mv) refresh daily by --- scanning millions of rows. The total_staking_mv alone was taking 8+ hours, --- locking tables and degrading page loads. --- --- Solution: Replace all MVs with regular aggregate tables that will be --- incrementally updated during indexing. This eliminates the expensive full-table --- scans and lock contention. - --- ============================================================================ --- Step 1: Create aggregate tables --- ============================================================================ - -CREATE TABLE IF NOT EXISTS indexer.daily_staked_agg ( - day DATE PRIMARY KEY, - daily_staked NUMERIC NOT NULL DEFAULT 0 -); - -CREATE TABLE IF NOT EXISTS indexer.daily_unbond_agg ( - day DATE PRIMARY KEY, - daily_unbond NUMERIC NOT NULL DEFAULT 0 -); - -CREATE TABLE IF NOT EXISTS indexer.daily_claims_agg ( - day DATE PRIMARY KEY, - daily_claims NUMERIC NOT NULL DEFAULT 0 -); - -CREATE TABLE IF NOT EXISTS indexer.total_staking_agg ( - day DATE PRIMARY KEY, - l1_staked NUMERIC NOT NULL DEFAULT 0, - l2_staked NUMERIC NOT NULL DEFAULT 0 -); - -CREATE TABLE IF NOT EXISTS indexer.daily_inflows_agg ( - day DATE PRIMARY KEY, - amount NUMERIC NOT NULL DEFAULT 0 -); - -CREATE TABLE IF NOT EXISTS indexer.daily_outflows_agg ( - day DATE PRIMARY KEY, - amount NUMERIC NOT NULL DEFAULT 0 -); - --- ============================================================================ --- Step 2: Grant SELECT to explorer_ro --- ============================================================================ - -GRANT SELECT ON indexer.daily_staked_agg TO explorer_ro; -GRANT SELECT ON indexer.daily_unbond_agg TO explorer_ro; -GRANT SELECT ON indexer.daily_claims_agg TO explorer_ro; -GRANT SELECT ON indexer.total_staking_agg TO explorer_ro; -GRANT SELECT ON indexer.daily_inflows_agg TO explorer_ro; -GRANT SELECT ON indexer.daily_outflows_agg TO explorer_ro; - --- ============================================================================ --- Step 3: Backfill aggregate tables from existing data --- ============================================================================ - --- Backfill daily_staked_agg (L2 fuel staking deposits) -INSERT INTO indexer.daily_staked_agg (day, daily_staked) -SELECT DATE_TRUNC('day', t."timestamp")::date AS day, SUM(CAST(r.receipt_amount AS BIGINT)) -FROM indexer.transactions_accounts ta -JOIN indexer.transactions t ON ta.tx_hash = t.tx_hash AND t."data"->>'scriptData' LIKE '%76465706f736974%' -JOIN indexer.receipts r ON r.tx_hash = t.tx_hash AND r.receipt_type = 'CALL' AND r.receipt_to = '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c' AND CAST(r.receipt_amount AS BIGINT) > 0 -WHERE ta.account_hash = '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c' -GROUP BY day -ON CONFLICT (day) DO UPDATE SET daily_staked = EXCLUDED.daily_staked; - --- Backfill daily_unbond_agg -INSERT INTO indexer.daily_unbond_agg (day, daily_unbond) -SELECT DATE_TRUNC('day', t."timestamp")::date AS day, SUM(CAST(r.receipt_amount AS BIGINT)) -FROM indexer.transactions_accounts ta -JOIN indexer.transactions t ON ta.tx_hash = t.tx_hash AND t."data"->>'scriptData' LIKE '%87769746864726177%' -JOIN indexer.receipts r ON r.tx_hash = ta.tx_hash AND r.receipt_type = 'TRANSFER_OUT' AND r.receipt_asset_id = '0x1d5d97005e41cae2187a895fd8eab0506111e0e2f3331cd3912c15c24e3c1d82' AND CAST(r.receipt_amount AS BIGINT) > 0 -WHERE ta.account_hash = '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c' -GROUP BY day -ON CONFLICT (day) DO UPDATE SET daily_unbond = EXCLUDED.daily_unbond; - --- Backfill daily_claims_agg -INSERT INTO indexer.daily_claims_agg (day, daily_claims) -SELECT DATE_TRUNC('day', t."timestamp")::date AS day, SUM(CAST(r.receipt_amount AS BIGINT)) -FROM indexer.transactions_accounts ta -JOIN indexer.transactions t ON ta.tx_hash = t.tx_hash AND t."data"->>'scriptData' LIKE '%d636c61696d5f72657761726473%' -JOIN indexer.receipts r ON r.tx_hash = ta.tx_hash AND r.receipt_type = 'TRANSFER_OUT' AND r.receipt_asset_id = '0x1d5d97005e41cae2187a895fd8eab0506111e0e2f3331cd3912c15c24e3c1d82' AND CAST(r.receipt_amount AS BIGINT) > 0 -WHERE ta.account_hash = '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c' -GROUP BY day -ON CONFLICT (day) DO UPDATE SET daily_claims = EXCLUDED.daily_claims; - --- Backfill total_staking_agg - L1 cosmos side -INSERT INTO indexer.total_staking_agg (day, l1_staked, l2_staked) -SELECT DATE_TRUNC('day', cr."timestamp")::date AS day, SUM(CAST(regexp_replace(ce_amount.value, '[^0-9]', '', 'g') AS NUMERIC)), 0 -FROM indexer.cosmos_responses cr -JOIN indexer.cosmos_events ce_del ON ce_del.cosmos_response_id = cr._id AND ce_del."type" = 'delegate' AND ce_del."key" = 'delegator' AND ce_del."value" != '0x85308a35b3ad660213ea91a5d37bbf9620708ecc' -JOIN indexer.cosmos_events ce_amount ON ce_amount.cosmos_response_id = cr._id AND ce_amount."type" = 'delegate' AND ce_amount."key" = 'amount' AND ce_amount."index" = ce_del."index" -GROUP BY day -ON CONFLICT (day) DO UPDATE SET l1_staked = EXCLUDED.l1_staked; - --- Backfill total_staking_agg - L2 fuel side -INSERT INTO indexer.total_staking_agg (day, l1_staked, l2_staked) -SELECT DATE_TRUNC('day', t."timestamp")::date AS day, 0, SUM(CAST(r.receipt_amount AS BIGINT)) -FROM indexer.transactions_accounts ta -JOIN indexer.transactions t ON ta.tx_hash = t.tx_hash AND t."data"->>'scriptData' LIKE '%76465706f736974%' -JOIN indexer.receipts r ON r.tx_hash = ta.tx_hash AND r.receipt_type = 'CALL' AND r.receipt_to = '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c' AND CAST(r.receipt_amount AS BIGINT) > 0 -WHERE ta.account_hash = '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c' -GROUP BY day -ON CONFLICT (day) DO UPDATE SET l2_staked = EXCLUDED.l2_staked; - --- Backfill daily_inflows_agg -INSERT INTO indexer.daily_inflows_agg (day, amount) -SELECT DATE_TRUNC('day', t."timestamp")::date AS day, SUM((i.data->>'amount')::numeric) -FROM indexer.transactions_accounts a -JOIN indexer.transactions t ON a.tx_hash = t.tx_hash -JOIN indexer.outputs i ON i.transaction_id = t._id -WHERE account_hash IN ('0xdb491b442f68ebaa785f077805158ebfddeede7063f16d5a26e1073ff6987601', '0xafdda1cd084ed0f56d35f570b2e9d34e7c7380191058e2a2fb16e0c58cbbc7c2') -AND i.data->>'assetId' = '0x1d5d97005e41cae2187a895fd8eab0506111e0e2f3331cd3912c15c24e3c1d82' -AND i.data->>'to' NOT IN ('0xdb491b442f68ebaa785f077805158ebfddeede7063f16d5a26e1073ff6987601', '0xafdda1cd084ed0f56d35f570b2e9d34e7c7380191058e2a2fb16e0c58cbbc7c2') -AND i.data->>'__typename' = 'CoinOutput' -GROUP BY day -ON CONFLICT (day) DO UPDATE SET amount = EXCLUDED.amount; - --- Backfill daily_outflows_agg -INSERT INTO indexer.daily_outflows_agg (day, amount) -SELECT DATE_TRUNC('day', t."timestamp")::date AS day, SUM((i.data->>'amount')::numeric) -FROM indexer.transactions_accounts a -JOIN indexer.transactions t ON a.tx_hash = t.tx_hash -JOIN indexer.outputs i ON i.transaction_id = t._id -WHERE account_hash IN ('0xdb491b442f68ebaa785f077805158ebfddeede7063f16d5a26e1073ff6987601', '0xafdda1cd084ed0f56d35f570b2e9d34e7c7380191058e2a2fb16e0c58cbbc7c2') -AND i.data->>'assetId' = '0x1d5d97005e41cae2187a895fd8eab0506111e0e2f3331cd3912c15c24e3c1d82' -AND i.data->>'to' IN ('0xdb491b442f68ebaa785f077805158ebfddeede7063f16d5a26e1073ff6987601', '0xafdda1cd084ed0f56d35f570b2e9d34e7c7380191058e2a2fb16e0c58cbbc7c2') -AND i.data->>'__typename' = 'CoinOutput' -GROUP BY day -ON CONFLICT (day) DO UPDATE SET amount = EXCLUDED.amount; - --- ============================================================================ --- Step 4: Drop old materialized views --- ============================================================================ - -DROP MATERIALIZED VIEW IF EXISTS indexer.total_staking_mv CASCADE; -DROP MATERIALIZED VIEW IF EXISTS indexer.cosmos_daily_staked_mv CASCADE; -DROP MATERIALIZED VIEW IF EXISTS indexer.fuel_daily_staked_mv CASCADE; -DROP MATERIALIZED VIEW IF EXISTS indexer.daily_staked_mv CASCADE; -DROP MATERIALIZED VIEW IF EXISTS indexer.daily_unbond_mv CASCADE; -DROP MATERIALIZED VIEW IF EXISTS indexer.daily_claims_mv CASCADE; -DROP MATERIALIZED VIEW IF EXISTS indexer.inflows_mv CASCADE; -DROP MATERIALIZED VIEW IF EXISTS indexer.outflows_mv CASCADE; - --- ============================================================================ --- Step 5: Delete MV refresh jobs from database_jobs --- ============================================================================ - -DELETE FROM indexer.database_jobs WHERE query LIKE '%daily_staked_mv%'; -DELETE FROM indexer.database_jobs WHERE query LIKE '%daily_unbond_mv%'; -DELETE FROM indexer.database_jobs WHERE query LIKE '%daily_claims_mv%'; -DELETE FROM indexer.database_jobs WHERE query LIKE '%total_staking_mv%'; -DELETE FROM indexer.database_jobs WHERE query LIKE '%inflows_mv%'; -DELETE FROM indexer.database_jobs WHERE query LIKE '%outflows_mv%'; -DELETE FROM indexer.database_jobs WHERE query LIKE '%cosmos_daily_staked_mv%'; -DELETE FROM indexer.database_jobs WHERE query LIKE '%fuel_daily_staked_mv%'; - --- ============================================================================ --- Step 6: Add cleanup job for rows older than 90 days --- ============================================================================ - -INSERT INTO indexer.database_jobs (query, recurrent, interval_seconds, status) -VALUES ( - 'DELETE FROM indexer.daily_staked_agg WHERE day < NOW() - INTERVAL ''90 days''' || CHR(59) || ' DELETE FROM indexer.daily_unbond_agg WHERE day < NOW() - INTERVAL ''90 days''' || CHR(59) || ' DELETE FROM indexer.daily_claims_agg WHERE day < NOW() - INTERVAL ''90 days''' || CHR(59) || ' DELETE FROM indexer.total_staking_agg WHERE day < NOW() - INTERVAL ''90 days''' || CHR(59) || ' DELETE FROM indexer.daily_inflows_agg WHERE day < NOW() - INTERVAL ''90 days''' || CHR(59) || ' DELETE FROM indexer.daily_outflows_agg WHERE day < NOW() - INTERVAL ''90 days''' || CHR(59), - true, 86400, 'pending' -) ON CONFLICT (query) DO NOTHING; - --- ============================================================================ --- Step 7: Update migration version --- ============================================================================ - -UPDATE indexer.migration SET version = 43; diff --git a/packages/graphql/database/migrations/044_optimize_storage_drop_unused_data.sql b/packages/graphql/database/migrations/044_optimize_storage_drop_unused_data.sql deleted file mode 100644 index 68c860877..000000000 --- a/packages/graphql/database/migrations/044_optimize_storage_drop_unused_data.sql +++ /dev/null @@ -1,46 +0,0 @@ --- Migration 044: Optimize storage by removing unused data --- --- Problem: Three tables store data the API never reads, consuming ~53GB locally --- and likely 500GB+ in production: --- - outputs (6.4GB): Never read by any DAO or resolver --- - receipts (37GB): Only 42 MESSAGE_OUT rows out of 86M are ever read --- - inputs (9.6GB): Only the nonce field is read (for bridge withdrawals) --- --- Solution: Truncate outputs, delete non-MESSAGE_OUT receipts, extract nonce --- from inputs JSON and drop the data column. - --- ============================================================================ --- Step 1: Truncate outputs table (never read by API) --- ============================================================================ - -TRUNCATE indexer.outputs; - --- ============================================================================ --- Step 2: Delete non-MESSAGE_OUT receipts (only type read by BridgeDAO) --- ============================================================================ - -DELETE FROM indexer.receipts WHERE receipt_type != 'MESSAGE_OUT'; - --- ============================================================================ --- Step 3: Truncate receipts_data (write-only, never read by API) --- ============================================================================ - -TRUNCATE indexer.receipts_data; - --- ============================================================================ --- Step 4: Extract nonce from inputs JSON, drop data column --- ============================================================================ - -ALTER TABLE indexer.inputs ADD COLUMN IF NOT EXISTS nonce TEXT; - -UPDATE indexer.inputs SET nonce = data->>'nonce' WHERE data IS NOT NULL; - -ALTER TABLE indexer.inputs DROP COLUMN IF EXISTS data; - -CREATE INDEX IF NOT EXISTS idx_inputs_nonce ON indexer.inputs (nonce) WHERE nonce IS NOT NULL; - --- ============================================================================ --- Step 5: Update migration version --- ============================================================================ - -UPDATE indexer.migration SET version = 44; diff --git a/packages/graphql/database/migrations/045_vacuum_receipts.sql b/packages/graphql/database/migrations/045_vacuum_receipts.sql deleted file mode 100644 index 3f4bcfe43..000000000 --- a/packages/graphql/database/migrations/045_vacuum_receipts.sql +++ /dev/null @@ -1,16 +0,0 @@ --- Migration 045: Reclaim disk space from deleted receipts --- --- Migration 044 deleted ~86M non-MESSAGE_OUT rows from indexer.receipts using DELETE. --- DELETE marks rows as dead tuples but doesn't release disk space. --- VACUUM FULL rewrites the table, reclaiming all dead tuple space. --- --- WARNING: VACUUM FULL takes an exclusive lock on the table. --- Run during a maintenance window when the syncer is stopped. --- Expected to reclaim ~37GB in production. - -VACUUM FULL indexer.receipts; - --- Also vacuum inputs after dropping the data column in migration 044 -VACUUM FULL indexer.inputs; - -UPDATE indexer.migration SET version = 45; diff --git a/packages/graphql/database/migrations/046_replace_hourly_statistics_mv_with_agg_table.sql b/packages/graphql/database/migrations/046_replace_hourly_statistics_mv_with_agg_table.sql deleted file mode 100644 index d3c1ee368..000000000 --- a/packages/graphql/database/migrations/046_replace_hourly_statistics_mv_with_agg_table.sql +++ /dev/null @@ -1,46 +0,0 @@ --- Migration 046: Replace hourly_statistics MV with aggregate table --- --- Problem: REFRESH MATERIALIZED VIEW was the top DB query at 201,290ms latency --- It does a full seq scan of all 24h transactions every 30 minutes. --- --- Solution: Incremental aggregate table updated per-batch during indexing. --- Each batch recomputes only the affected hours (typically 1-2 hours), --- reducing cost from full 24h scan to a narrow timestamp index scan. --- --- Benchmark (local, 17k blocks): --- Before: 2,132ms (full seq scan + disk sort) --- After: ~25ms (index scan on timestamp for affected hours only) - --- Create the aggregate table -CREATE TABLE IF NOT EXISTS indexer.hourly_statistics_agg ( - hour TIMESTAMPTZ NOT NULL, - total_fee NUMERIC NOT NULL DEFAULT 0, - total_gas_used BIGINT NOT NULL DEFAULT 0, - PRIMARY KEY (hour) -); - --- Grant read access -GRANT SELECT ON indexer.hourly_statistics_agg TO explorer_ro; - --- Backfill from blocks table (source of truth). --- Avoids using the MV which had incorrect total_gas_used and could be stale --- by up to 30 minutes (its refresh interval). --- NOTE: this is a full seq scan of indexer.blocks — expected to take several --- minutes on large databases. Migration runs offline so this is acceptable. -INSERT INTO indexer.hourly_statistics_agg (hour, total_fee, total_gas_used) -SELECT date_trunc('hour', timestamp), SUM(total_fee::numeric), SUM(gas_used::numeric) -FROM indexer.blocks -GROUP BY 1 -ON CONFLICT (hour) DO UPDATE - SET total_fee = excluded.total_fee, - total_gas_used = excluded.total_gas_used; - --- Remove the old MV refresh jobs (query strings include SET/RESET statement_timeout wrappers) -DELETE FROM indexer.database_jobs -WHERE query LIKE '%REFRESH MATERIALIZED VIEW CONCURRENTLY indexer.hourly_statistics%'; - -DELETE FROM indexer.database_jobs -WHERE query LIKE '%ANALYZE indexer.hourly_statistics%'; - --- Drop the old MV -DROP MATERIALIZED VIEW IF EXISTS indexer.hourly_statistics CASCADE; diff --git a/packages/graphql/database/migrations/047_optimize_balance_index.sql b/packages/graphql/database/migrations/047_optimize_balance_index.sql deleted file mode 100644 index eb77bcbd4..000000000 --- a/packages/graphql/database/migrations/047_optimize_balance_index.sql +++ /dev/null @@ -1,17 +0,0 @@ --- Migration 047: Add composite index for balance lookups --- --- Problem: IndexBalance fetches the latest balance per (account_hash, asset_id) pair. --- The new batched LATERAL query and the old per-pair query both use: --- WHERE account_hash = $1 AND asset_id = $2 ORDER BY _id DESC LIMIT 1 --- Without a composite index, PostgreSQL uses separate single-column indexes and --- must filter/sort remaining rows, leading to excessive I/O on the 96M+ row table. --- --- Solution: Composite index on (account_hash, asset_id, _id DESC) so each lookup --- becomes a single index seek returning exactly 1 row with no post-filter sort. --- --- Benchmark (testnet, 96M rows, 20 pairs): --- Before (per-pair loop, no composite index): ~N × index scan + sort per pair --- After (batched LATERAL + this index): 0.3ms, 1 row fetched per pair, no sort - -CREATE INDEX CONCURRENTLY IF NOT EXISTS balance_account_asset_id_idx -ON indexer.balance (account_hash, asset_id, _id DESC); diff --git a/packages/graphql/database/migrations/048_drop_unused_recent_account_transactions_mv.sql b/packages/graphql/database/migrations/048_drop_unused_recent_account_transactions_mv.sql deleted file mode 100644 index b9badc410..000000000 --- a/packages/graphql/database/migrations/048_drop_unused_recent_account_transactions_mv.sql +++ /dev/null @@ -1,11 +0,0 @@ --- Migration 048: Drop unused recent_account_transactions_mv --- --- This MV was created in migration 030 to optimize account transaction searches. --- It is not queried anywhere in the codebase — confirmed by grep of all source files. --- The 4-hour refresh job scans 7 days of transactions_accounts + transactions --- and shows up as the #3 load query in Performance Insights despite zero consumers. - -DELETE FROM indexer.database_jobs -WHERE query LIKE '%recent_account_transactions_mv%'; - -DROP MATERIALIZED VIEW IF EXISTS indexer.recent_account_transactions_mv CASCADE; diff --git a/packages/graphql/database/migrations/049_drop_unused_redundant_indexes.sql b/packages/graphql/database/migrations/049_drop_unused_redundant_indexes.sql deleted file mode 100644 index 1dcdc2d48..000000000 --- a/packages/graphql/database/migrations/049_drop_unused_redundant_indexes.sql +++ /dev/null @@ -1,25 +0,0 @@ --- Migration 049: Drop unused redundant indexes --- --- Each index below has 0 (or 1) scans in pg_stat_user_indexes, is not backed --- by a UNIQUE/PK constraint, and is either an exact-column duplicate of --- another index or fully covered as a leading-column prefix of a wider --- composite. Dropping them changes no current query plan and removes the --- corresponding write amplification. - --- Non-unique duplicate of UNIQUE blocks_id_key (constraint). -DROP INDEX CONCURRENTLY IF EXISTS indexer.blocks_id_idx1; - --- Single-column (_id) covered by leading column of the composite PK --- (_id, block_id, tx_hash, account_hash). -DROP INDEX CONCURRENTLY IF EXISTS indexer.transactions_accounts__id_idx; - --- Non-unique duplicate of inputs_pkey on (_id). -DROP INDEX CONCURRENTLY IF EXISTS indexer.inputs__id_idx1; - --- Single-column (tx_hash) covered by leading column of the composite UNIQUE --- balance_tx_hash_account_hash_asset_id_idx (tx_hash, account_hash, asset_id). -DROP INDEX CONCURRENTLY IF EXISTS indexer.balance_tx_hash_idx; - --- Identical column definition to balance_account_asset_id_idx2 --- on (account_hash, asset_id, _id DESC) — the latter is the one in active use. -DROP INDEX CONCURRENTLY IF EXISTS indexer.balance_account_hash_asset_id__id_idx; diff --git a/packages/graphql/database/migrations/050_tune_autovacuum_large_tables.sql b/packages/graphql/database/migrations/050_tune_autovacuum_large_tables.sql deleted file mode 100644 index 3294b4ef7..000000000 --- a/packages/graphql/database/migrations/050_tune_autovacuum_large_tables.sql +++ /dev/null @@ -1,31 +0,0 @@ --- Migration 050: Tune autovacuum thresholds for large tables --- --- The default autovacuum scale factors (vacuum=0.1, analyze=0.05) require --- autovacuum to wait for ~10% of the table to change before vacuuming and ~5% --- before analyzing. On tables with hundreds of millions to billions of rows --- this means autovacuum and autoanalyze rarely (or never) fire on the normal --- write churn pattern, leaving stats stale and dead tuples accumulating. --- --- Per-table overrides below scale the trigger thresholds proportionally to --- table size so they fire on a more reasonable absolute change. - --- 1.92B rows, default analyze trigger ~96M rows of churn. -ALTER TABLE indexer.transactions_accounts - SET (autovacuum_vacuum_scale_factor = 0.005, - autovacuum_analyze_scale_factor = 0.001); - --- 5.01B rows, default analyze trigger ~250M rows of churn. -ALTER TABLE indexer.inputs - SET (autovacuum_vacuum_scale_factor = 0.005, - autovacuum_analyze_scale_factor = 0.001); - --- 548M rows, default analyze trigger ~27M rows of churn. -ALTER TABLE indexer.transactions - SET (autovacuum_vacuum_scale_factor = 0.005, - autovacuum_analyze_scale_factor = 0.001); - --- 462M rows with steady UPDATE churn (1%+ dead tuples observed) — slightly --- looser than the insert-mostly tables above. -ALTER TABLE indexer.balance - SET (autovacuum_vacuum_scale_factor = 0.01, - autovacuum_analyze_scale_factor = 0.005); diff --git a/packages/graphql/ecosystem-dev.config.cjs b/packages/graphql/ecosystem-dev.config.cjs deleted file mode 100644 index cdd016afc..000000000 --- a/packages/graphql/ecosystem-dev.config.cjs +++ /dev/null @@ -1,77 +0,0 @@ -const IS_DEBUG = process.env.DEBUG; -const APP = process.env.APP; - -const commonOptions = { - interpreter: 'tsx', - node_args: IS_DEBUG ? ['--inspect-brk'] : [], - // watch: true, - ignore_watch: ['node_modules', './src/**/*.gen.js'], -}; - -module.exports = { - apps: [ - ...(APP === 'graphql' - ? [ - { - ...commonOptions, - name: 'graphql', - script: './src/app.ts', - }, - ] - : []), - ...(APP === 'syncer' - ? [ - { - ...commonOptions, - name: 'syncer', - script: './src/syncer.ts', - }, - ] - : []), - ...(APP === 'assets' - ? [ - { - ...commonOptions, - name: 'assets', - script: './src/assets.ts', - }, - ] - : []), - ...(APP === 'balance' - ? [ - { - ...commonOptions, - name: 'balance', - script: './src/balance.ts', - }, - ] - : []), - ...(APP === 'l1' - ? [ - { - ...commonOptions, - name: 'l1', - script: './src/l1.ts', - }, - ] - : []), - ...(APP === 'cosmos' - ? [ - { - ...commonOptions, - name: 'cosmos', - script: './src/cosmos.ts', - }, - ] - : []), - ...(APP === 'jobs' - ? [ - { - ...commonOptions, - name: 'jobs', - script: './src/jobs.ts', - }, - ] - : []), - ], -}; diff --git a/packages/graphql/ecosystem-prod-api.config.cjs b/packages/graphql/ecosystem-prod-api.config.cjs deleted file mode 100644 index 27b7f040a..000000000 --- a/packages/graphql/ecosystem-prod-api.config.cjs +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = { - apps: [ - { - name: 'graphql', - script: './dist/app.js', - mode: 'cluster', - instances: '8', - }, - ], -}; diff --git a/packages/graphql/ecosystem-prod-syncer.config.cjs b/packages/graphql/ecosystem-prod-syncer.config.cjs deleted file mode 100644 index b8750d5fa..000000000 --- a/packages/graphql/ecosystem-prod-syncer.config.cjs +++ /dev/null @@ -1,40 +0,0 @@ -module.exports = { - apps: [ - { - name: 'syncer', - script: './dist/syncer.js', - mode: 'cluster', - instances: '1', - }, - { - name: 'assets', - script: './dist/assets.js', - mode: 'cluster', - instances: '1', - }, - { - name: 'balance', - script: './dist/balance.js', - mode: 'cluster', - instances: '1', - }, - { - name: 'l1', - script: './dist/l1.js', - mode: 'cluster', - instances: '1', - }, - { - name: 'cosmos', - script: './dist/cosmos.js', - mode: 'cluster', - instances: '1', - }, - { - name: 'jobs', - script: './dist/jobs.js', - mode: 'cluster', - instances: '1', - }, - ], -}; diff --git a/packages/graphql/ecosystem.config.cjs b/packages/graphql/ecosystem.config.cjs deleted file mode 100644 index c29608c5a..000000000 --- a/packages/graphql/ecosystem.config.cjs +++ /dev/null @@ -1,22 +0,0 @@ -module.exports = { - apps: [ - { - name: 'graphql', - script: './dist/app.js', - mode: 'cluster', - instances: '8', - }, - { - name: 'syncer', - script: './dist/syncer.js', - mode: 'cluster', - instances: '1', - }, - { - name: 'timer', - script: './dist/timer.js', - mode: 'cluster', - instances: '1', - }, - ], -}; diff --git a/packages/graphql/explorer_backend_indexer_architecture.png b/packages/graphql/explorer_backend_indexer_architecture.png deleted file mode 100644 index 91ef13fc82e92ac6a66f92b3d4d155570a84f7c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 166121 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 z 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 z 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 R!3?T3hI%G@3U)jF{$D|^DN+Cc diff --git a/packages/graphql/jest.config.ts b/packages/graphql/jest.config.ts deleted file mode 100644 index 98f0d96be..000000000 --- a/packages/graphql/jest.config.ts +++ /dev/null @@ -1,23 +0,0 @@ -import type { Config } from '@jest/types'; - -const config: Config.InitialOptions = { - testEnvironment: 'node', - roots: ['/src'], - testMatch: [ - '**/__tests__/**/*.+(ts|tsx|js)', - '**/?(*.)+(spec|test).+(ts|tsx|js)', - ], - transform: { - '^.+\\.(t|j)sx?$': '@swc/jest', - }, - moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], - collectCoverage: false, - coverageDirectory: 'coverage', - coverageReporters: ['text', 'lcov'], - verbose: true, - moduleNameMapper: { - '^~/(.*)$': '/src/$1', - }, -}; - -export default config; diff --git a/packages/graphql/logs/empty b/packages/graphql/logs/empty deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/graphql/package.json b/packages/graphql/package.json index 53ec21995..68caa560b 100644 --- a/packages/graphql/package.json +++ b/packages/graphql/package.json @@ -24,30 +24,8 @@ "build:sdk": "tsup", "ts:check": "tsc --noEmit", "codegen": "run-s codegen:*", - "run-dev": "npx tsx watch src/app.ts", - "run-dev:syncer": "npx tsx watch src/syncer.ts", - "run-dev:cosmos": "npx tsx watch src/cosmos.ts", - "run-dev:all": "run-p run-dev run-dev:syncer run-dev:cosmos", - "run-start": "npx tsx src/app.ts", "codegen:gql-fuelcore": "gqlg --schemaFilePath ./src/graphql/schemas/fuelcore.graphql --destDirPath ./src/graphql/generated/fuelcore --ext graphql --includeCrossReferences --depthLimit 6", - "codegen:sdk": "gql-gen -r dotenv/config --config codegen.sdk.ts", - "dev:graphql": "APP=graphql pm2 start ecosystem-dev.config.cjs", - "dev:syncer": "APP=syncer pm2 start ecosystem-dev.config.cjs", - "dev:timer": "APP=timer pm2 start ecosystem-dev.config.cjs", - "pm2:start": "pm2 start ecosystem.config.cjs --update-env", - "pm2:restart": "pm2 restart ecosystem.config.cjs --update-env", - "pm2:reset": "pm2 delete ecosystem.config.cjs && pnpm server:start", - "pm2:stop": "pm2 stop ecosystem.config.cjs", - "pm2:delete": "pm2 delete ecosystem.config.cjs", - "server:start": "pm2-runtime ecosystem.config.cjs", - "start:api": "pm2-runtime ecosystem-prod-api.config.cjs", - "start:syncer": "pm2-runtime ecosystem-prod-syncer.config.cjs", - "db:migrate": "tsx ./scripts/migrate.ts", - "db:migrate:dry": "tsx ./scripts/migrate.ts --dry-run", - "db:migrate:status": "tsx ./scripts/migrate.ts --status", - "db:migrate:setup": "tsx ./scripts/setup-migrations.ts", - "test": "jest --config jest.config.ts", - "test:watch": "jest --config jest.config.ts --watch" + "codegen:sdk": "gql-gen -r dotenv/config --config codegen.sdk.ts" }, "peerDependencies": { "graphql": ">=16.10.0", @@ -55,42 +33,15 @@ "graphql-tag": ">=2.12.6" }, "dependencies": { - "app-commons": "workspace:*", - "@fuel-infrastructure/fuelsequencerjs": "0.0.14", - "@graphql-tools/load": "8.0.2", - "@graphql-tools/load-files": "7.0.0", - "@graphql-tools/merge": "9.0.4", - "@graphql-tools/schema": "10.0.4", - "@graphql-tools/stitch": "^9.2.10", - "@graphql-tools/utils": "^10.2.3", - "@types/cors": "^2.8.17", - "bignumber.js": "9.1.2", - "commander": "12.1.0", - "cors": "^2.8.5", "dayjs": "1.11.11", "dotenv": "16.4.5", "drizzle-orm": "^0.31.2", - "ethers": "^6.13.1", - "express": "5.0.0", "graphql": "16.10.0", - "graphql-yoga": "5.6.0", - "kafkajs": "2.2.4", "lodash": "^4.17.21", - "node-fetch": "3.3.2", "npm-run-all": "^4.1.5", - "pg": "^8.12.0", - "pg-boss": "9.0.3", - "pg-promise": "11.9.1", - "pino": "9.2.0", - "pino-pretty": "11.2.1", - "pm2": "^5.4.1", "shallow-equal-object": "1.1.1", "tai64": "^1.0.0", - "winston": "3.13.0", - "xstate": "^5.14.0", - "yargs": "17.7.2", - "zod": "3.23.8", - "bech32": "2.0.0" + "zod": "3.23.8" }, "devDependencies": { "@fuels/ts-config": "0.26.0", @@ -101,17 +52,9 @@ "@graphql-codegen/typescript-graphql-request": "^6.2.0", "@graphql-codegen/typescript-operations": "^4.2.2", "@graphql-tools/graphql-file-loader": "8.0.1", - "@swc/core": "1.4.1", - "@swc/jest": "0.2.36", - "@testcontainers/postgresql": "10.10.0", "@types/fs-extra": "11.0.4", - "@types/jest": "29.5.12", "@types/lodash": "4.17.6", "@types/node": "^20.14.9", - "@types/pg": "^8.11.6", - "@types/yargs": "17.0.32", - "chalk": "5.3.0", - "drizzle-kit": "^0.22.8", "fs-extra": "11.2.0", "gql-generator": "2.0.0", "graphql": "16.10.0", @@ -119,8 +62,6 @@ "graphql-config": "5.0.3", "graphql-request": "6.1.0", "graphql-tag": "^2.12.6", - "jest": "29.7.0", - "testcontainers": "10.10.0", "tsup": "8.1.0", "tsx": "4.16.0", "typescript": "^5.5.2" diff --git a/packages/graphql/scripts/migrate.ts b/packages/graphql/scripts/migrate.ts deleted file mode 100755 index 2989ddab7..000000000 --- a/packages/graphql/scripts/migrate.ts +++ /dev/null @@ -1,322 +0,0 @@ -#!/usr/bin/env tsx -/** - * Database Migration Runner - * - * Reads all .sql files from database/migrations/ and executes pending ones. - * Tracks executed migrations in {schema}._migrations table. - * Statements execute individually (like psql -f), with graceful error handling. - */ - -import fs from 'node:fs'; -import path from 'node:path'; -import { DatabaseConnection } from '../src/infra/database/DatabaseConnection'; - -interface MigrationRecord { - id: number; - filename: string; - executed_at: Date; -} - -export const DB_SCHEMA = process.env.DB_SCHEMA || 'indexer'; -export const MIGRATIONS_DIR = path.join(__dirname, '../database/migrations'); - -export class MigrationRunner { - private db: DatabaseConnection; - - constructor() { - this.db = DatabaseConnection.getInstance(); - } - - /** - * Ensure migrations tracking table exists - */ - async ensureMigrationsTable(): Promise { - // Check if schema exists first (don't create - let migrations handle it) - const schemaExists = await this.db.query( - 'SELECT 1 FROM information_schema.schemata WHERE schema_name = $1', - [DB_SCHEMA], - ); - - if (schemaExists.length === 0) { - // Schema doesn't exist yet - will be created by first migration - return; - } - - const sql = ` - CREATE TABLE IF NOT EXISTS ${DB_SCHEMA}._migrations ( - id SERIAL PRIMARY KEY, - filename VARCHAR(255) NOT NULL UNIQUE, - executed_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP - ); - `; - await this.db.query(sql, []); - } - - /** - * Get list of executed migrations - */ - async getExecutedMigrations(): Promise> { - try { - // Check if schema exists first - const schemaExists = await this.db.query( - 'SELECT 1 FROM information_schema.schemata WHERE schema_name = $1', - [DB_SCHEMA], - ); - if (schemaExists.length === 0) { - return new Set(); - } - - const result = await this.db.query( - `SELECT filename FROM ${DB_SCHEMA}._migrations ORDER BY filename`, - [], - ); - return new Set(result.map((r: MigrationRecord) => r.filename)); - } catch { - return new Set(); - } - } - - /** - * Get all migration files sorted by filename - */ - async getAllMigrationFiles(): Promise { - // Check if migrations directory exists - if (!fs.existsSync(MIGRATIONS_DIR)) { - console.log(`Creating migrations directory: ${MIGRATIONS_DIR}`); - fs.mkdirSync(MIGRATIONS_DIR, { recursive: true }); - return []; - } - - const files = fs - .readdirSync(MIGRATIONS_DIR) - .filter((file) => file.endsWith('.sql')) - .sort(); // Lexicographic sort (001, 002, etc.) - - return files; - } - - /** - * Get pending migrations - */ - async getPendingMigrations(): Promise { - const executed = await this.getExecutedMigrations(); - const allFiles = await this.getAllMigrationFiles(); - return allFiles.filter((file) => !executed.has(file)); - } - - /** - * Execute a single migration with schema replacement - */ - async executeMigration(filename: string, dryRun = false): Promise { - const filePath = path.join(MIGRATIONS_DIR, filename); - let sql = fs.readFileSync(filePath, 'utf-8'); - - // Replace schema references if DB_SCHEMA is different - if (DB_SCHEMA !== 'indexer') { - sql = sql.replace(/\bindexer\./g, `${DB_SCHEMA}.`); - sql = sql.replace( - /CREATE SCHEMA IF NOT EXISTS indexer/g, - `CREATE SCHEMA IF NOT EXISTS ${DB_SCHEMA}`, - ); - } - - if (dryRun) { - console.log(`\n[DRY RUN] Would execute: ${filename}`); - console.log('─'.repeat(80)); - console.log(sql.slice(0, 500) + (sql.length > 500 ? '...' : '')); - console.log('─'.repeat(80)); - return; - } - - // Split into statements and execute individually (like psql -f) - const statements = sql - .split(';') - .map((s) => s.trim()) - .filter((s) => { - if (s.length === 0) return false; - // Remove pure comment blocks (all lines start with --) - const lines = s - .split('\n') - .map((l) => l.trim()) - .filter((l) => l.length > 0); - return lines.some((line) => !line.startsWith('--')); - }); - - const total = statements.length; - for (let i = 0; i < statements.length; i++) { - const statement = statements[i]; - const preview = statement.replace(/\s+/g, ' ').slice(0, 60); - process.stdout.write(` [${i + 1}/${total}] ${preview}...`); - const stmtStart = Date.now(); - try { - await this.db.query(statement, []); - console.log(` ${Date.now() - stmtStart}ms`); - } catch (error: any) { - // Ignore common non-fatal errors (match psql -f behavior) - const ignorable = - error.code === '23505' || // duplicate key - error.code === '42P07' || // relation already exists - error.code === '42710' || // object already exists - error.code === '42704' || // role/object does not exist (for GRANT) - error.code === '42P01' || // relation does not exist - error.code === '0A000' || // cannot alter type used by view - error.message?.includes('already exists') || - error.message?.includes('does not exist') || - error.message?.includes('cannot alter type'); - if (ignorable) { - console.log(` skipped (${error.code || 'exists'})`); - } else { - console.log(' FAILED'); - throw new Error(`Failed to execute ${filename}: ${error.message}`); - } - } - } - - // Ensure _migrations table exists (schema should exist now after first migration) - await this.ensureMigrationsTable(); - - // Record successful migration - await this.db.query( - `INSERT INTO ${DB_SCHEMA}._migrations (filename) VALUES ($1)`, - [filename], - ); - } - - /** - * Run all pending migrations - */ - async run(dryRun = false): Promise { - console.log('🔍 Checking for pending migrations...\n'); - - await this.ensureMigrationsTable(); - const pending = await this.getPendingMigrations(); - - if (pending.length === 0) { - console.log('✅ No pending migrations\n'); - return; - } - - console.log(`Found ${pending.length} pending migration(s):\n`); - for (const file of pending) { - console.log(` - ${file}`); - } - console.log(''); - - if (dryRun) { - console.log('🔍 DRY RUN MODE - No changes will be made\n'); - } - - for (let i = 0; i < pending.length; i++) { - const file = pending[i]; - const startTime = Date.now(); - - console.log(`[${i + 1}/${pending.length}] Running ${file}...`); - - try { - await this.executeMigration(file, dryRun); - const duration = Date.now() - startTime; - console.log(`✅ Completed in ${duration}ms\n`); - } catch (error: any) { - console.error(`❌ Failed: ${error.message}\n`); - process.exit(1); - } - } - - if (!dryRun) { - console.log(`✅ Successfully executed ${pending.length} migration(s)\n`); - } else { - console.log( - `🔍 DRY RUN: ${pending.length} migration(s) would be executed\n`, - ); - } - } - - /** - * Show migration status - */ - async status(): Promise { - await this.ensureMigrationsTable(); - - const executed = await this.getExecutedMigrations(); - const allFiles = await this.getAllMigrationFiles(); - const pending = allFiles.filter((f) => !executed.has(f)); - - console.log('\n=== Migration Status ===\n'); - console.log(`Schema: ${DB_SCHEMA}`); - console.log(`Total migrations: ${allFiles.length}`); - console.log(`Executed: ${executed.size}`); - console.log(`Pending: ${pending.length}\n`); - - if (allFiles.length > 0) { - console.log('Migrations:'); - console.log('─'.repeat(80)); - console.log( - `${'Filename'.padEnd(50)} ${'Status'.padEnd(15)} ${'Executed'}`, - ); - console.log('─'.repeat(80)); - - for (const file of allFiles) { - const status = executed.has(file) ? '✅ executed' : '⏳ pending'; - console.log( - `${file.padEnd(50)} ${status.padEnd(15)} ${executed.has(file) ? 'Yes' : 'No'}`, - ); - } - - console.log('─'.repeat(80)); - } - - console.log(''); - } -} - -// CLI -async function main() { - const args = process.argv.slice(2); - const dryRun = args.includes('--dry-run'); - const showStatus = args.includes('--status'); - const showHelp = args.includes('--help') || args.includes('-h'); - - if (showHelp) { - console.log(` -Database Migration Runner - -Usage: - tsx scripts/migrate.ts [options] - -Options: - --dry-run Preview pending migrations without executing - --status Show migration status - --help, -h Show this help message - -Environment Variables: - DB_SCHEMA Schema to use (default: indexer) - DB_HOST Database host - DB_PORT Database port - DB_USER Database user - DB_PASS Database password - DB_NAME Database name - -Examples: - tsx scripts/migrate.ts Run pending migrations - tsx scripts/migrate.ts --dry-run Preview pending migrations - tsx scripts/migrate.ts --status Show migration status -`); - process.exit(0); - } - - const runner = new MigrationRunner(); - - try { - if (showStatus) { - await runner.status(); - } else { - await runner.run(dryRun); - } - process.exit(0); - } catch (error: any) { - console.error(`\n❌ Migration failed: ${error.message}\n`); - process.exit(1); - } -} - -main(); diff --git a/packages/graphql/scripts/run.sh b/packages/graphql/scripts/run.sh deleted file mode 100755 index d27f05cd0..000000000 --- a/packages/graphql/scripts/run.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -if [ "$1" = "api" ]; then - echo "Running API" - pnpm start:api -elif [ "$1" = "syncer" ]; then - echo "Running Syncer" - pnpm start:syncer -fi diff --git a/packages/graphql/scripts/setup-migrations.ts b/packages/graphql/scripts/setup-migrations.ts deleted file mode 100644 index cd8736549..000000000 --- a/packages/graphql/scripts/setup-migrations.ts +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/env tsx -/** - * Setup _migrations table for production deployment - * - * This script populates the _migrations table with existing migration filenames - * WITHOUT re-running them. It reads the current version from the old migration - * system (indexer.migration.version) and marks migrations up to that version as applied. - * - * Usage: - * pnpm db:migrate:setup - * - * This should be run ONCE during the migration system upgrade, before - * running any new migrations with `pnpm db:migrate`. - */ - -import fs from 'node:fs'; -import { DatabaseConnection } from '../src/infra/database/DatabaseConnection'; -import { DB_SCHEMA, MIGRATIONS_DIR, MigrationRunner } from './migrate'; - -async function setupMigrations(): Promise { - const db = DatabaseConnection.getInstance(); - const runner = new MigrationRunner(); - - console.log('🔧 Setting up _migrations table...\n'); - console.log(`Schema: ${DB_SCHEMA}`); - console.log(`Migrations directory: ${MIGRATIONS_DIR}\n`); - - // Check if schema exists - const schemaExists = await db.query( - 'SELECT 1 FROM information_schema.schemata WHERE schema_name = $1', - [DB_SCHEMA], - ); - - if (schemaExists.length === 0) { - console.error(`❌ Schema "${DB_SCHEMA}" does not exist.`); - console.error( - 'Run migrations first or ensure the database has been initialized.\n', - ); - process.exit(1); - } - - // Get current version from old migration system - let currentVersion = -1; - try { - const versionResult = await db.query( - `SELECT version FROM ${DB_SCHEMA}.migration LIMIT 1`, - [], - ); - if (versionResult.length > 0) { - currentVersion = versionResult[0].version; - console.log( - `📊 Current migration version (old system): ${currentVersion}`, - ); - } - } catch { - console.log('📊 No old migration table found, will mark all as applied'); - } - - // Ensure _migrations table exists - await runner.ensureMigrationsTable(); - - // Get all migration files - const files = fs - .readdirSync(MIGRATIONS_DIR) - .filter((file) => file.endsWith('.sql')) - .sort(); - - console.log(`Found ${files.length} migration files\n`); - - // Check which are already set up - const existing = await db.query( - `SELECT filename FROM ${DB_SCHEMA}._migrations`, - [], - ); - const existingSet = new Set(existing.map((r: any) => r.filename)); - - let added = 0; - let skipped = 0; - let pending = 0; - - for (const file of files) { - // Extract migration number from filename (e.g., "001" from "001_create_schema.sql") - const match = file.match(/^(\d+)_/); - if (!match) { - console.log(`⚠️ Skipping ${file} (invalid filename format)`); - continue; - } - - const migrationNum = Number.parseInt(match[1], 10); - // Old version N corresponds to new migration N+1 - // e.g., version 31 = migrations 001-032 have been run - const maxMigrationToSetup = currentVersion + 1; - - if (existingSet.has(file)) { - console.log(`⏭️ Skipping ${file} (already exists)`); - skipped++; - } else if (currentVersion >= 0 && migrationNum > maxMigrationToSetup) { - console.log( - `⏸️ Pending ${file} (not yet applied, version ${currentVersion})`, - ); - pending++; - } else { - await db.query( - `INSERT INTO ${DB_SCHEMA}._migrations (filename) VALUES ($1)`, - [file], - ); - console.log(`✅ Added ${file}`); - added++; - } - } - - console.log( - `\n✅ Done! Added ${added}, skipped ${skipped}, pending ${pending}\n`, - ); - - if (pending > 0) { - console.log( - `Run 'pnpm db:migrate' to apply the ${pending} pending migration(s).\n`, - ); - } - - process.exit(0); -} - -setupMigrations().catch((error) => { - console.error(`\n❌ Setup failed: ${error.message}\n`); - process.exit(1); -}); diff --git a/packages/graphql/src/app.ts b/packages/graphql/src/app.ts deleted file mode 100644 index e00da295d..000000000 --- a/packages/graphql/src/app.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { env } from './config'; -import { logger } from './core/Logger'; -import { GraphQLServer } from './graphql/GraphQLServer'; -import { DatabaseConnection } from './infra/database/DatabaseConnection'; -import { DatabaseConnectionReplica } from './infra/database/DatabaseConnectionReplica'; -import { Server } from './infra/server/App'; - -(async () => { - const port = Number(env.get('SERVER_PORT')); - const graphQLServer = new GraphQLServer(); - const schema = graphQLServer.schema(); - const yoga = graphQLServer.setup(schema); - const httpServer = new Server(); - const app = await httpServer.setup(); - DatabaseConnection.getInstance(); - DatabaseConnectionReplica.getInstance(); - - app.use(yoga.graphqlEndpoint, yoga); - httpServer.listen(app, port).then(async () => { - logger.info( - 'GraphQL', - `Server is running on http://localhost:${port}${yoga.graphqlEndpoint}`, - ); - - const others = ['SIGINT', 'SIGUSR1', 'SIGUSR2', 'SIGTERM']; - //biome-ignore lint/complexity/noForEach: - others.forEach((eventType) => { - process.on(eventType, async (err) => { - logger.error('GraphQL', 'GraphQL shutdown error', err); - process.exit(1); - }); - }); - }); -})(); diff --git a/packages/graphql/src/application/uc/GetAccountAssets.ts b/packages/graphql/src/application/uc/GetAccountAssets.ts deleted file mode 100644 index f9f7c3980..000000000 --- a/packages/graphql/src/application/uc/GetAccountAssets.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { bn } from 'fuels'; -import { client } from '~/graphql/GraphQLSDK'; -import { convertToUsd } from '~/infra/dao/utils'; -import AssetGateway from '~/infra/gateway/AssetGateway'; - -export default class GetAccountAssets { - async execute(input: Input): Promise { - const assetGateway = new AssetGateway(); - const { data } = (await client.sdk.balances({ - filter: { owner: input.accountId }, - last: input.last, - })) as any; - const balances = data.balances; - const { data: chainData } = await client.sdk.chain(); - const chainId = Number(chainData.chain.consensusParameters.chainId); - const assets = []; - for (const balance of balances.nodes) { - const indexedAsset = await assetGateway.getAsset( - balance.assetId, - chainId, - ); - const asset = indexedAsset - ? Object.assign(balance, indexedAsset) - : balance; - asset.amountInUsd = asset.rate - ? convertToUsd(asset.amount, asset.decimals, asset.rate).formatted - : null; - assets.push(asset); - } - const _assets = assets.filter((asset) => !bn(asset.amount).isZero()); - return { - data: _assets, - pageInfo: { - count: _assets.length, - }, - }; - } -} - -type Input = { - accountId: string; - last: number; -}; - -type Output = { - data: { - assetId: string; - contractId: string; - amount: number; - owner: string; - symbol: string; - icon: string; - decimals: number; - suspicious: boolean; - verified: boolean; - network: []; - }[]; - pageInfo: {}; -}; diff --git a/packages/graphql/src/application/uc/GetAssetsRate.ts b/packages/graphql/src/application/uc/GetAssetsRate.ts deleted file mode 100644 index e757ff2c7..000000000 --- a/packages/graphql/src/application/uc/GetAssetsRate.ts +++ /dev/null @@ -1,26 +0,0 @@ -import DataCache from '~/infra/cache/DataCache'; -import AssetDAO from '~/infra/dao/AssetDAO'; - -export default class GetAssetsRate { - async execute(): Promise { - const assetDAO = new AssetDAO(); - const output = await assetDAO.getAssetsRate(); - return output; - } - - async executeCached(): Promise { - const cachedAssetsRate = DataCache.getInstance().get('assetsRate'); - if (cachedAssetsRate) { - return cachedAssetsRate; - } - - const output = await this.execute(); - DataCache.getInstance().save('assetsRate', 60000, output); - return output; - } -} - -type Output = { - symbol: string; - rate: number; -}; diff --git a/packages/graphql/src/application/uc/GetMetrics.ts b/packages/graphql/src/application/uc/GetMetrics.ts deleted file mode 100644 index faf130dbe..000000000 --- a/packages/graphql/src/application/uc/GetMetrics.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { setTimeout } from 'node:timers/promises'; -import { logger } from '~/core/Logger'; -import { client } from '~/graphql/GraphQLSDK'; -import BlockDAO from '~/infra/dao/BlockDAO'; - -const FUEL_CORE_TIMEOUT_MS = 5000; - -export default class GetMetrics { - private blockDAO = new BlockDAO(); - - async getFuelCoreLastBlockHeight() { - const startTime = Date.now(); - try { - const { data } = await client.sdk.blocks({ last: 1 }); - const latencyMs = Date.now() - startTime; - logger.debug('Metrics', `Fuel core response time: ${latencyMs}ms`); - const blocks = data.blocks; - const [lastBlock] = blocks.nodes; - const height = Number(lastBlock?.header.height ?? '0'); - return height; - } catch (e) { - const latencyMs = Date.now() - startTime; - logger.error('Metrics', `Fuel core request failed after ${latencyMs}ms`); - throw e; - } - } - - async getIndexerLastBlockHeight() { - return (await this.blockDAO.findLatestBlockHeight()) ?? 0; - } - - async execute(): Promise { - const indexerLastBlockHeight = await this.getIndexerLastBlockHeight(); - let fuelCoreLastBlockHeight = indexerLastBlockHeight; - let fuelCoreHealth = 1; - let fuelCoreLatencyMs = -1; - const startTime = Date.now(); - try { - const response = await Promise.race([ - this.getFuelCoreLastBlockHeight(), - setTimeout(FUEL_CORE_TIMEOUT_MS).then(() => null), - ]); - fuelCoreLatencyMs = Date.now() - startTime; - if (!response) { - logger.warn( - 'Metrics', - `Fuel core timeout after ${FUEL_CORE_TIMEOUT_MS}ms`, - ); - fuelCoreHealth = 0; - } else { - fuelCoreLastBlockHeight = response; - } - } catch (e: any) { - fuelCoreLatencyMs = Date.now() - startTime; - fuelCoreHealth = 0; - logger.error( - 'Metrics', - `Fuel core error after ${fuelCoreLatencyMs}ms: ${e.message}`, - ); - } - const indexerBlockHeightDelay = - fuelCoreLastBlockHeight - indexerLastBlockHeight; - const indexerHealth = indexerBlockHeightDelay < 100 ? 1 : 0; - return { - explorer_indexer_fuel_core_last_block_height: fuelCoreLastBlockHeight, - explorer_indexer_last_block_height_synced: indexerLastBlockHeight, - explorer_indexer_block_height_sync_delay: indexerBlockHeightDelay, - explorer_indexer_health: indexerHealth, - explorer_indexer_fuel_core_health: fuelCoreHealth, - explorer_indexer_fuel_core_latency_ms: fuelCoreLatencyMs, - }; - } -} diff --git a/packages/graphql/src/application/uc/GetTransaction.ts b/packages/graphql/src/application/uc/GetTransaction.ts deleted file mode 100644 index 2b961f989..000000000 --- a/packages/graphql/src/application/uc/GetTransaction.ts +++ /dev/null @@ -1,131 +0,0 @@ -import { concat, hash } from 'fuels'; -import type { GQLOperationReceipt } from '~/graphql/generated/sdk-provider'; -import TransactionDAO from '~/infra/dao/TransactionDAO'; -import { convertToUsd } from '~/infra/dao/utils'; -import AssetGateway from '~/infra/gateway/AssetGateway'; - -export default class GetTransaction { - assetGateway: AssetGateway; - - constructor() { - this.assetGateway = new AssetGateway(); - } - - async execute(id: string, chainId?: number, baseAssetId?: string) { - const transactionDAO = new TransactionDAO(); - const transaction = await transactionDAO.getByHash(id); - if (!transaction) return; - if (chainId === undefined || chainId === null) { - const output = transaction?.toGQLNode(); - return output; - } - for (const groupedInputs of transaction.groupedInputs) { - if (!groupedInputs.inputs) continue; - for (const input of groupedInputs.inputs) { - if (input.__typename === 'InputCoin') { - const asset = await this.assetGateway.getAsset( - input.assetId, - chainId, - ); - this.mergeAssetProps(input, asset); - } - } - } - for (const output of transaction.data.outputs) { - if ( - output && - (output.__typename === 'CoinOutput' || - output.__typename === 'ChangeOutput' || - output.__typename === 'VariableOutput') - ) { - const asset = await this.assetGateway.getAsset(output.assetId, chainId); - this.mergeAssetProps(output, asset); - } - } - for (const operation of transaction.operations) { - if (!operation.receipts) continue; - await this.parseOperationsR(operation.receipts, chainId); - } - if (transaction.data.isMint && transaction.data.mintAssetId) { - const asset = await this.assetGateway.getAsset( - transaction.data.mintAssetId, - chainId, - ); - - transaction.data.mintedAsset = { - __typename: 'Asset', - }; - this.mergeAssetProps(transaction.data.mintedAsset, asset); - } - const output = transaction?.toGQLNode(); - if (baseAssetId && output.gasCosts?.fee) { - const baseAsset = await this.assetGateway.getAsset(baseAssetId, chainId); - const feeInUsd = convertToUsd( - output.gasCosts.fee, - baseAsset.decimals, - baseAsset.rate, - ); - output.gasCosts.feeInUsd = feeInUsd?.formatted; - } - return output; - } - - mergeAssetProps(target: any, asset: Asset) { - if (!asset) return; - target.assetId = asset.assetId; - target.name = asset.name; - target.symbol = asset.symbol; - target.icon = asset.icon; - target.contractId = asset.contractId; - target.decimals = asset.decimals; - target.suspicious = asset.suspicious; - target.rate = asset.rate; - const usdAmount = convertToUsd( - target.amount, - Number(asset.decimals), - asset.rate, - ); - target.amountInUsd = usdAmount?.formatted; - } - - async parseOperationsR(receipts: GQLOperationReceipt[], chainId: number) { - if (!receipts) return; - for (const receipt of receipts) { - if ( - receipt.item && - receipt.item.receiptType === 'MINT' && - receipt.item.id && - receipt.item.subId - ) { - const assetId = hash(concat([receipt.item.id, receipt.item.subId])); - const asset = await this.assetGateway.getAsset(assetId, chainId); - this.mergeAssetProps(receipt.item, asset); - } - if ( - receipt.item && - receipt.item.receiptType === 'TRANSFER_OUT' && - receipt.item.assetId - ) { - const asset = await this.assetGateway.getAsset( - receipt.item.assetId, - chainId, - ); - this.mergeAssetProps(receipt.item, asset); - } - if (receipt.receipts) { - this.parseOperationsR(receipt.receipts, chainId); - } - } - } -} - -type Asset = { - assetId: string; - name: string; - symbol: string; - icon: string; - contractId: string; - decimals: string; - suspicious: boolean; - rate: number; -}; diff --git a/packages/graphql/src/application/uc/IndexAsset/GetAssetDetails.ts b/packages/graphql/src/application/uc/IndexAsset/GetAssetDetails.ts deleted file mode 100644 index e656d5ee7..000000000 --- a/packages/graphql/src/application/uc/IndexAsset/GetAssetDetails.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { env } from '~/config'; -import { logger } from '~/core/Logger'; -import DataCache from '~/infra/cache/DataCache'; -import { DatabaseConnection } from '~/infra/database/DatabaseConnection'; - -export interface AssetDetails { - market_cap: number; - circulating_supply: number; - total_supply: number; - max_supply: number; - fully_diluted_valuation: number; - description: string; - links: { - homepage: string[]; - whitepaper: string; - github: string[]; - reddit: string; - twitter: string; - official_forum: string[]; - }; - block_time_in_minutes: number; - hashing_algorithm: string; - genesis_date: string; -} - -export default class GetAssetDetails { - async execute(symbol: string): Promise { - logger.debug('GetAssetDetails', `Fetching details for asset: ${symbol}`); - - try { - // Get CoinGecko ID from database - const connection = DatabaseConnection.getInstance(); - const [mapping] = await connection.query( - 'select value from indexer.assets_rate_provider where symbol = $1', - [symbol], - ); - - if (!mapping) { - logger.error( - 'GetAssetDetails', - `Asset not found in rate provider: ${symbol}`, - ); - return null; - } - - const coingeckoId = mapping.value; - - const response = await fetch( - `https://pro-api.coingecko.com/api/v3/coins/${coingeckoId}`, - { - headers: { - Accept: 'application/json', - 'x-cg-pro-api-key': env.get('COINGECKO_API_KEY') || '', - }, - }, - ); - - if (!response.ok) { - logger.error( - 'GetAssetDetails', - `Failed to fetch asset details: ${response.status} ${response.statusText}`, - ); - return null; - } - - const rawData = await response.json(); - - // Filter and transform the response to only include requested fields - const filteredData: AssetDetails = { - market_cap: rawData.market_data?.market_cap?.usd || 0, - circulating_supply: rawData.market_data?.circulating_supply || 0, - total_supply: rawData.market_data?.total_supply || 0, - max_supply: rawData.market_data?.max_supply || 0, - fully_diluted_valuation: - rawData.market_data?.fully_diluted_valuation?.usd || 0, - description: rawData.description?.en || '', - links: { - homepage: rawData.links?.homepage || [], - whitepaper: rawData.links?.whitepaper || '', - github: rawData.links?.repos_url?.github || [], - reddit: rawData.links?.subreddit_url || '', - twitter: rawData.links?.twitter_screen_name || '', - official_forum: rawData.links?.official_forum_url || [], - }, - block_time_in_minutes: rawData.block_time_in_minutes || 0, - hashing_algorithm: rawData.hashing_algorithm || '', - genesis_date: rawData.genesis_date || '', - }; - - return filteredData; - } catch (error) { - logger.error('GetAssetDetails', `Error fetching asset details: ${error}`); - return null; - } - } - - async executeCached(assetId: string): Promise { - const cacheKey = `assetDetails_${assetId}`; - const cachedAssetDetails = DataCache.getInstance().get(cacheKey); - if (cachedAssetDetails) { - return cachedAssetDetails; - } - - const output = await this.execute(assetId); - if (output) { - DataCache.getInstance().save(cacheKey, 60000, output); - } - return output; - } -} diff --git a/packages/graphql/src/application/uc/IndexAsset/IndexAsset.ts b/packages/graphql/src/application/uc/IndexAsset/IndexAsset.ts deleted file mode 100644 index 2c284984c..000000000 --- a/packages/graphql/src/application/uc/IndexAsset/IndexAsset.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { Interface, concat, hash } from 'fuels'; -import { Contract, Provider } from 'fuels'; -import { bn } from 'fuels'; -import { env } from '~/config'; -import { abi } from '~/infra/abi/SRC7Abi'; -import type Transaction from '~/infra/dao/Transaction'; -import { DatabaseConnection } from '~/infra/database/DatabaseConnection'; -import NFTIndexer from './NFTIndexer'; - -export default class IndexAsset { - provider?: Provider; - loggedTypes = [ - '10032608944051208538', - '4237256875605624201', - '17462098202904023478', - '17188485204969729195', - '16139176946940135860', - '13791596350235125220', - '14321618427101975361', - '7845998088195677205', - '12152039456660331088', - '17415926155927968170', - '4571204900286667806', - '2161305517876418151', - '16280289466020123285', - ]; - - async execute(transaction: Transaction) { - if (!this.provider) { - const providerUrl = env.get('FUEL_PROVIDER'); - if (!providerUrl) { - throw new Error('FUEL_PROVIDER is not set'); - } - this.provider = new Provider(providerUrl); - } - let index = 1; - const connection = DatabaseConnection.getInstance(); - if (transaction.data.status?.receipts) { - for (const receipt of transaction.data.status.receipts) { - if (receipt.receiptType === 'MINT' && receipt.id && receipt.subId) { - const _id = `${transaction.id}-${new String(index++).padStart( - 8, - '0', - )}`; - const assetId = hash(concat([receipt.id, receipt.subId])); - const asset = { - assetId, - contractId: receipt.id, - transactionId: transaction.data.id, - subId: receipt.subId, - name: null, - symbol: null, - decimals: null, - totalSupply: null, - error: null, - blockId: transaction.blockId, - _id, - metadata: {} as any, - }; - const existingAssetContract = await connection.query( - 'select * from indexer.assets_contracts where asset_id = $1 and contract_id = $2', - [asset.assetId, asset.contractId], - ); - if (existingAssetContract.length > 0) { - continue; - } - try { - const contract = new Contract(receipt.id, abi, this.provider); - const assetBits = { bits: assetId }; - try { - const { value: results } = await contract - .multiCall([ - contract.functions.name(assetBits), - contract.functions.symbol(assetBits), - contract.functions.decimals(assetBits), - contract.functions.total_supply(assetBits), - contract.functions.metadata(assetBits, 'uri'), - ]) - .dryRun(); - asset.name = results[0]; - asset.symbol = results[1]; - asset.decimals = results[2]; - asset.totalSupply = bn(results[3]).toString() as any; - if (results[4]?.String) { - asset.metadata.uri = results[4].String; - } - } catch { - const [name, symbol, decimals, supply] = await Promise.allSettled( - [ - contract.functions.name(assetBits).dryRun(), - contract.functions.symbol(assetBits).dryRun(), - contract.functions.decimals(assetBits).dryRun(), - contract.functions.total_supply(assetBits).dryRun(), - ], - ); - if (name.status === 'fulfilled') asset.name = name.value.value; - if (symbol.status === 'fulfilled') - asset.symbol = symbol.value.value; - if (decimals.status === 'fulfilled') - asset.decimals = decimals.value.value; - if (supply.status === 'fulfilled') - asset.totalSupply = bn(supply.value.value).toString() as any; - try { - const { value } = await contract.functions - .metadata(assetBits, 'uri') - .dryRun(); - if (value?.String) asset.metadata.uri = value.String; - } catch {} - } - } catch (e: any) { - asset.error = e.message; - } - try { - await connection.query( - 'insert into indexer.assets_contracts (asset_id, contract_id, transaction_id, sub_id, name, symbol, decimals, error, block_id, _id, metadata, total_supply) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) on conflict do nothing', - [ - asset.assetId, - asset.contractId, - asset.transactionId, - asset.subId, - asset.name, - asset.symbol, - asset.decimals, - asset.error, - asset.blockId, - asset._id, - asset.metadata, - asset.totalSupply, - ], - ); - const nftIndexer = new NFTIndexer(); - await nftIndexer.execute(asset); - } catch (_e: any) {} - } - } - for (const receipt of transaction.data.status.receipts) { - if (receipt.receiptType === 'LOG_DATA') { - if (this.loggedTypes.includes(receipt.rb)) { - const contract = new Interface(abi); - const [log] = contract.decodeLog(receipt.data, receipt.rb); - if (log && Object.keys(log).includes('metadata')) { - const assetId = log.asset.bits; - const key = log.key; - const value = log.metadata.String; - const [asset] = await connection.query( - 'select contract_id, sub_id, metadata from indexer.assets_contracts where asset_id = $1', - [assetId], - ); - if (asset?.metadata) { - asset.metadata[key] = value; - } - await connection.query( - 'update indexer.assets_contracts set metadata = $1 where asset_id = $2', - [asset.metadata, assetId], - ); - } - } - } - } - } - } -} diff --git a/packages/graphql/src/application/uc/IndexAsset/IndexAssetsRate.ts b/packages/graphql/src/application/uc/IndexAsset/IndexAssetsRate.ts deleted file mode 100644 index 4eeeb84d2..000000000 --- a/packages/graphql/src/application/uc/IndexAsset/IndexAssetsRate.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { env } from '~/config'; -import { logger } from '~/core/Logger'; -import { DatabaseConnection } from '~/infra/database/DatabaseConnection'; - -export default class IndexAssetsRate { - async execute() { - logger.info('IndexAssetsRate', 'Starting rate indexing...'); - const connection = DatabaseConnection.getInstance(); - const mapping = await connection.query( - 'select * from indexer.assets_rate_provider', - [], - ); - logger.info( - 'IndexAssetsRate', - `Found ${mapping.length} assets in rate provider table`, - ); - - // Separate assets by provider - const coingeckoAssets = mapping.filter( - (m: any) => m.provider === 'coingecko', - ); - const cmcDexAssets = mapping.filter((m: any) => m.provider === 'cmc-dex'); - - logger.info( - 'IndexAssetsRate', - `CoinGecko: ${coingeckoAssets.length}, CMC DEX: ${cmcDexAssets.length}`, - ); - - // Fetch CoinGecko prices - if (coingeckoAssets.length > 0) { - await this.fetchCoingeckoPrices(connection, coingeckoAssets); - } - - // Fetch CMC DEX prices - if (cmcDexAssets.length > 0) { - await this.fetchCmcDexPrices(connection, cmcDexAssets); - } - - logger.info('IndexAssetsRate', 'Rate indexing complete'); - } - - private async fetchCoingeckoPrices(connection: any, assets: any[]) { - logger.info('IndexAssetsRate', 'Fetching CoinGecko prices...'); - const ids = assets.map((m: any) => m.value).join(','); - try { - const response = await fetch( - `https://pro-api.coingecko.com/api/v3/simple/price?vs_currencies=usd&ids=${ids}`, - { - headers: { - Accept: 'application/json', - 'x-cg-pro-api-key': env.get('COINGECKO_API_KEY') || '', - }, - }, - ); - const data = await response.json(); - logger.debug( - 'IndexAssetsRate', - `CoinGecko response: ${JSON.stringify(data).slice(0, 200)}...`, - ); - - let successCount = 0; - for (const asset of assets) { - const rate = data[asset.value]?.usd; - if (rate) { - await connection.query( - 'insert into indexer.assets_rates (asset_id, symbol, rate, timestamp) values ($1, $2, $3, $4)', - [asset.asset_id, asset.symbol, rate, new Date()], - ); - successCount++; - } - } - logger.info( - 'IndexAssetsRate', - `CoinGecko: saved ${successCount}/${assets.length} rates`, - ); - } catch (error) { - logger.error('IndexAssetsRate', `CoinGecko fetch failed: ${error}`); - } - } - - private async fetchCmcDexPrices(connection: any, assets: any[]) { - logger.info('IndexAssetsRate', 'Fetching CMC DEX prices...'); - for (const asset of assets) { - try { - const url = `https://dapi.coinmarketcap.com/u-kline/v1/k-line/candles?platform=${encodeURIComponent(asset.value)}&address=${asset.asset_id}&unit=usd&pm=p&interval=1h&limit=1`; - logger.debug( - 'IndexAssetsRate', - `CMC DEX request: ${asset.symbol} -> ${url}`, - ); - - const response = await fetch(url, { - headers: { - Accept: 'application/json', - }, - }); - const data = await response.json(); - logger.debug( - 'IndexAssetsRate', - `CMC DEX response for ${asset.symbol}: ${JSON.stringify(data)}`, - ); - - // Extract close price from the latest candle [open, high, low, close, volume, timestamp] - const rate = data?.data?.[0]?.[3]; - if (rate) { - await connection.query( - 'insert into indexer.assets_rates (asset_id, symbol, rate, timestamp) values ($1, $2, $3, $4)', - [asset.asset_id, asset.symbol, rate, new Date()], - ); - logger.info('IndexAssetsRate', `CMC DEX: ${asset.symbol} = $${rate}`); - } else { - logger.info( - 'IndexAssetsRate', - `CMC DEX: No rate found for ${asset.symbol}`, - ); - } - } catch (error) { - logger.error( - 'IndexAssetsRate', - `Failed to fetch CMC DEX price for ${asset.symbol}: ${error}`, - ); - } - } - } -} diff --git a/packages/graphql/src/application/uc/IndexAsset/NFTIndexer.ts b/packages/graphql/src/application/uc/IndexAsset/NFTIndexer.ts deleted file mode 100644 index 3cd2a4de1..000000000 --- a/packages/graphql/src/application/uc/IndexAsset/NFTIndexer.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { DatabaseConnection } from '~/infra/database/DatabaseConnection'; - -export default class NFTIndexer { - async execute(asset: any) { - const connection = DatabaseConnection.getInstance(); - try { - const [collection] = await connection.query( - 'select * from indexer.collections where contract_id = $1', - [asset.contractId], - ); - if (!collection) return; - const url = collection.url.replace('{subId}', Number(asset.subId)); - const response = await fetch(url); - const metadata = await response.json(); - asset.metadata = { - ...asset.metadata, - ...metadata, - }; - await connection.query( - 'update indexer.assets_contracts set metadata = $1 where asset_id = $2', - [asset.metadata, asset.assetId], - ); - } catch (_e: any) {} - } -} diff --git a/packages/graphql/src/application/uc/IndexBalance.ts b/packages/graphql/src/application/uc/IndexBalance.ts deleted file mode 100644 index 155b3c398..000000000 --- a/packages/graphql/src/application/uc/IndexBalance.ts +++ /dev/null @@ -1,147 +0,0 @@ -import BigNumber from 'bignumber.js'; -import { logger } from '~/core/Logger'; -import { DatabaseConnection } from '~/infra/database/DatabaseConnection'; - -export default class IndexBalance { - async execute() { - logger.debug('Balance', 'IndexBalance'); - const connection = DatabaseConnection.getInstance(); - const [data] = await connection.query( - 'select block_height as height from indexer.balance_index', - [], - ); - let height = data.height; - while (true) { - const [block] = await connection.query( - `select _id as height, data->'transactions' as transactions from indexer.blocks where _id > $1 and jsonb_array_length(data->'transactions') > 1 order by _id limit 1`, - [height], - ); - if (!block) { - return; - } - await connection.query( - 'delete from indexer.balance where block_height = $1', - [block.height], - ); - - // Collect all (account, asset) pairs across all transactions in this block - const pairs: { accountHash: string; assetId: string }[] = []; - for (const transaction of block.transactions) { - transaction.inputs = transaction.inputs || []; - transaction.outputs = transaction.outputs || []; - for (const input of transaction.inputs) { - if (input.__typename === 'InputCoin') { - pairs.push({ accountHash: input.owner, assetId: input.assetId }); - } - } - for (const output of transaction.outputs) { - if ( - ['ChangeOutput', 'CoinOutput', 'VariableOutput'].includes( - output.__typename, - ) - ) { - pairs.push({ accountHash: output.to, assetId: output.assetId }); - } - } - } - - // Batch fetch latest balance for all (account, asset) pairs in one query - const balanceMap = new Map(); - if (pairs.length > 0) { - const uniquePairs = [ - ...new Map( - pairs.map((p) => [`${p.accountHash}:${p.assetId}`, p]), - ).values(), - ]; - const accountHashes = uniquePairs.map((p) => p.accountHash); - const assetIds = uniquePairs.map((p) => p.assetId); - // JOIN (not LEFT JOIN): pairs with no balance history are absent from - // the result and correctly default to BigNumber(0) via ?? below. - const rows = await connection.query( - `SELECT t.account_hash, t.asset_id, b.balance - FROM unnest($1::text[], $2::text[]) AS t(account_hash, asset_id) - JOIN LATERAL ( - SELECT balance FROM indexer.balance - WHERE account_hash = t.account_hash AND asset_id = t.asset_id - ORDER BY _id DESC LIMIT 1 - ) b ON true`, - [accountHashes, assetIds], - ); - for (const row of rows) { - balanceMap.set( - `${row.account_hash}:${row.asset_id}`, - BigNumber(row.balance), - ); - } - } - - for (const transaction of block.transactions) { - const index: any = {}; - for (const input of transaction.inputs) { - if (input.__typename === 'InputCoin') { - const event = { - type: 'input', - accountHash: input.owner, - assetId: input.assetId, - amount: input.amount, - }; - index[event.accountHash] = index[event.accountHash] || {}; - index[event.accountHash][event.assetId] = - index[event.accountHash][event.assetId] || []; - index[event.accountHash][event.assetId].push(event); - } - } - for (const output of transaction.outputs) { - if ( - ['ChangeOutput', 'CoinOutput', 'VariableOutput'].includes( - output.__typename, - ) - ) { - const event = { - type: 'output', - accountHash: output.to, - assetId: output.assetId, - amount: output.amount, - }; - index[event.accountHash] = index[event.accountHash] || {}; - index[event.accountHash][event.assetId] = - index[event.accountHash][event.assetId] || []; - index[event.accountHash][event.assetId].push(event); - } - } - for (const accountHash in index) { - for (const assetId in index[accountHash]) { - const key = `${accountHash}:${assetId}`; - let balance = balanceMap.get(key) ?? BigNumber(0); - const events = index[accountHash][assetId]; - for (const event of events) { - if (event.type === 'input') { - balance = balance.minus(BigNumber(event.amount)); - } - if (event.type === 'output') { - balance = balance.plus(BigNumber(event.amount)); - } - } - // Update map so subsequent transactions in same block see updated balance - balanceMap.set(key, balance); - await connection.query( - 'insert into indexer.balance (block_height, tx_hash, account_hash, asset_id, balance) values ($1, $2, $3, $4, $5) on conflict do nothing', - [ - block.height, - transaction.id, - accountHash, - assetId, - balance.toString(), - ], - ); - } - } - } - await connection.query( - 'update indexer.balance_index set block_height = $1', - [block.height], - ); - height = block.height; - } - } -} diff --git a/packages/graphql/src/application/uc/IndexCosmos.ts b/packages/graphql/src/application/uc/IndexCosmos.ts deleted file mode 100644 index e59cba22e..000000000 --- a/packages/graphql/src/application/uc/IndexCosmos.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { setTimeout } from 'node:timers/promises'; -import { env } from '~/config'; -import { COSMOS_EXCLUDED_DELEGATOR } from '~/constants/staking'; -import { logger } from '~/core/Logger'; -import { DatabaseConnection } from '~/infra/database/DatabaseConnection'; - -export default class IndexCosmos { - async execute() { - const connection = DatabaseConnection.getInstance(); - const [cosmosIndex] = await connection.query( - 'select * from indexer.cosmos_index', - [], - ); - let height = cosmosIndex.block_height; - await connection.query( - 'delete from indexer.cosmos_events where cosmos_response_id in (select _id from indexer.cosmos_responses where block_height >= $1)', - [height], - ); - await connection.query( - 'delete from indexer.cosmos_responses where block_height >= $1', - [height], - ); - while (true) { - try { - const network = env.get('FUEL_CHAIN'); - const envPrefix = network === 'mainnet' ? 'mainnet' : 'testnet'; - const response = await fetch( - `https://rest.seq.${envPrefix}.fuel.network/cosmos/tx/v1beta1/txs?query=tx.height=${height}&limit=1000&offset=0`, - ); - const output = await response.json(); - if (output.total === '0') { - logger.debug('Cosmos', `Waiting for blocks #${height}`); - await setTimeout(5000); - continue; - } - logger.debug('Cosmos', `Indexing block #${height}`); - const tx_responses = output.tx_responses; - if (!Array.isArray(tx_responses)) { - logger.debug( - 'Cosmos', - `Invalid response for block #${height}, skipping`, - ); - height++; - await connection.query( - 'update indexer.cosmos_index set block_height = $1', - [height], - ); - continue; - } - // Skip if already indexed to prevent double-counting in aggregation tables - const alreadyIndexed = await connection.query( - 'SELECT 1 FROM indexer.cosmos_responses WHERE block_height = $1 LIMIT 1', - [height], - ); - if ((alreadyIndexed as any[]).length > 0) { - logger.debug('Cosmos', `Block #${height} already indexed, skipping`); - height++; - await connection.query( - 'update indexer.cosmos_index set block_height = $1', - [height], - ); - continue; - } - - for (const tx of tx_responses) { - const [cosmosResponse] = await connection.query( - 'insert into indexer.cosmos_responses (block_height, tx_hash, data, timestamp) values ($1, $2, $3, $4) returning _id', - [tx.height, tx.txhash, tx.data, tx.timestamp], - ); - - const eventRows: any[][] = []; - let index = 0; - for (const event of tx.events) { - for (const attribute of event.attributes) { - eventRows.push([ - cosmosResponse._id, - event.type, - attribute.key, - attribute.value, - index, - ]); - } - index++; - } - - if (eventRows.length > 0) { - const batchSize = 500; - for (let i = 0; i < eventRows.length; i += batchSize) { - const batch = eventRows.slice(i, i + batchSize); - const placeholders = batch - .map( - (_, idx) => - `($${idx * 5 + 1}, $${idx * 5 + 2}, $${idx * 5 + 3}, $${idx * 5 + 4}, $${idx * 5 + 5})`, - ) - .join(', '); - const params = batch.flat(); - await connection.query( - `INSERT INTO indexer.cosmos_events (cosmos_response_id, type, key, value, index) VALUES ${placeholders}`, - params, - ); - } - } - - // Aggregate L1 delegation events into total_staking_agg - for (const event of tx.events) { - if (event.type === 'delegate') { - const delegatorAttr = event.attributes.find( - (a: any) => a.key === 'delegator', - ); - const amountAttr = event.attributes.find( - (a: any) => a.key === 'amount', - ); - if ( - delegatorAttr && - amountAttr && - delegatorAttr.value !== COSMOS_EXCLUDED_DELEGATOR - ) { - const amount = amountAttr.value.replace(/[^0-9]/g, ''); - if (amount && BigInt(amount) > 0n) { - const day = new Date(tx.timestamp) - .toISOString() - .split('T')[0]; - await connection.query( - 'INSERT INTO indexer.total_staking_agg (day, l1_staked, l2_staked) VALUES ($1, $2, 0) ON CONFLICT (day) DO UPDATE SET l1_staked = indexer.total_staking_agg.l1_staked + $2', - [day, amount], - ); - } - } - } - } - } - height++; - await connection.query( - 'update indexer.cosmos_index set block_height = $1', - [height], - ); - } catch (error: any) { - logger.debug('Cosmos', `Error indexing ${error.message}`); - await setTimeout(5000); - } - } - } -} diff --git a/packages/graphql/src/application/uc/IndexL1/IndexL1.test.ts b/packages/graphql/src/application/uc/IndexL1/IndexL1.test.ts deleted file mode 100644 index 1af297b71..000000000 --- a/packages/graphql/src/application/uc/IndexL1/IndexL1.test.ts +++ /dev/null @@ -1,151 +0,0 @@ -import IndexL1 from './IndexL1'; - -jest.mock('~/config', () => ({ - env: { get: (k: string) => (k === 'FUEL_CHAIN' ? 'mainnet' : 'test-key') }, -})); - -jest.mock('~/core/Logger', () => ({ - logger: { debug: jest.fn(), error: jest.fn(), warn: jest.fn() }, -})); - -const queryMock = jest.fn().mockResolvedValue([]); -jest.mock('~/infra/database/DatabaseConnection', () => ({ - DatabaseConnection: { - getInstance: () => ({ - query: (...args: any[]) => queryMock(...args), - }), - }, -})); - -jest.mock('node:timers/promises', () => ({ - setTimeout: jest.fn().mockResolvedValue(undefined), -})); - -beforeEach(() => { - queryMock.mockReset(); - queryMock.mockResolvedValue([]); -}); - -describe('IndexL1', () => { - it('fetches the finalized block (not latest) to drive indexing window', async () => { - const getBlock = jest - .fn() - .mockImplementation(async (tag: string | number) => { - if (tag === 'finalized') - return { number: 1000, hash: '0xabc', timestamp: 1 }; - return { number: tag as number, hash: '0xdef', timestamp: 2 }; - }); - const getLogs = jest.fn().mockResolvedValue([]); - const getBlockNumber = jest.fn().mockResolvedValue(9999); - - const fakeProvider: any = { getBlock, getLogs, getBlockNumber }; - - class TestIndexL1 extends IndexL1 { - protected createProvider() { - return fakeProvider; - } - } - - const indexer = new TestIndexL1(); - await indexer.syncContract({ - _id: 1, - block_height: 500, - contract_hash: '0x0000000000000000000000000000000000000000', - name: 'FuelMessagePortal', - }); - - expect(getBlock).toHaveBeenCalledWith('finalized'); - expect(getBlockNumber).not.toHaveBeenCalled(); - }); - - it('does not request logs past the finalized block (no +1 off-by-one)', async () => { - const finalizedNumber = 1000; - const getBlock = jest - .fn() - .mockImplementation(async (tag: string | number) => { - if (tag === 'finalized') - return { number: finalizedNumber, hash: '0xabc', timestamp: 1 }; - return { number: tag as number, hash: '0xdef', timestamp: 2 }; - }); - const getLogs = jest.fn().mockResolvedValue([]); - const fakeProvider: any = { getBlock, getLogs, getBlockNumber: jest.fn() }; - - class TestIndexL1 extends IndexL1 { - protected createProvider() { - return fakeProvider; - } - } - - // block_height is close to finalized so the window clamps against finalized (not the +1000 cap) - await new TestIndexL1().syncContract({ - _id: 1, - block_height: finalizedNumber - 5, - contract_hash: '0x0000000000000000000000000000000000000000', - name: 'FuelMessagePortal', - }); - - if (getLogs.mock.calls.length > 0) { - const { toBlock } = getLogs.mock.calls[0][0]; - expect(toBlock).toBeLessThanOrEqual(finalizedNumber); - } - }); - - it('advances cursor to toBlock + 1 after a cycle (next cycle fromBlock is the next unprocessed block)', async () => { - const finalizedNumber = 1000; - const getBlock = jest - .fn() - .mockImplementation(async (tag: string | number) => { - if (tag === 'finalized') - return { number: finalizedNumber, hash: '0xabc', timestamp: 1 }; - return { number: tag as number, hash: '0xdef', timestamp: 2 }; - }); - const getLogs = jest.fn().mockResolvedValue([]); - const fakeProvider: any = { getBlock, getLogs, getBlockNumber: jest.fn() }; - - class TestIndexL1 extends IndexL1 { - protected createProvider() { - return fakeProvider; - } - } - - // Choose block_height close to finalized so toBlock clamps to finalizedNumber. - await new TestIndexL1().syncContract({ - _id: 42, - block_height: finalizedNumber - 5, - contract_hash: '0x0000000000000000000000000000000000000000', - name: 'FuelMessagePortal', - }); - - // Find the UPDATE call that advances the cursor in contract_l1_index. - const updateCall = queryMock.mock.calls.find( - (c) => - typeof c[0] === 'string' && - c[0].includes('update indexer.contract_l1_index'), - ); - expect(updateCall).toBeDefined(); - // Cursor must advance to toBlock + 1 = finalizedNumber + 1. - expect(updateCall?.[1]).toEqual([finalizedNumber + 1, 42]); - }); - - it('skips the cycle when the finalized block cannot be fetched', async () => { - const getBlock = jest.fn().mockRejectedValue(new Error('rpc down')); - const getLogs = jest.fn(); - const fakeProvider: any = { getBlock, getLogs, getBlockNumber: jest.fn() }; - - class TestIndexL1 extends IndexL1 { - protected createProvider() { - return fakeProvider; - } - } - - const indexer = new TestIndexL1(); - await indexer.syncContract({ - _id: 1, - block_height: 500, - contract_hash: '0x0000000000000000000000000000000000000000', - name: 'FuelMessagePortal', - }); - - expect(getLogs).not.toHaveBeenCalled(); - }); -}); diff --git a/packages/graphql/src/application/uc/IndexL1/IndexL1.ts b/packages/graphql/src/application/uc/IndexL1/IndexL1.ts deleted file mode 100644 index 42bcf4797..000000000 --- a/packages/graphql/src/application/uc/IndexL1/IndexL1.ts +++ /dev/null @@ -1,189 +0,0 @@ -import { setTimeout } from 'node:timers/promises'; -import { ethers } from 'ethers'; -import { type Abi, decodeEventLog } from 'viem'; -import { env } from '~/config'; -import { logger } from '~/core/Logger'; -import { DatabaseConnection } from '~/infra/database/DatabaseConnection'; -import { decodeMessage } from '~/infra/util/util'; -import AbiFactory from './abi/AbiFactory'; -import { createL1Provider } from './createL1Provider'; - -export default class IndexL1 { - protected createProvider(): ethers.JsonRpcProvider { - return createL1Provider(); - } - - async syncContract(contract: { - _id: number; - block_height: number; - contract_hash: string; - name: string; - }) { - const network = env.get('FUEL_CHAIN') || ''; - const connection = DatabaseConnection.getInstance(); - const provider = this.createProvider(); - let finalizedBlock: ethers.Block | null = null; - try { - finalizedBlock = await provider.getBlock('finalized'); - } catch (error: any) { - logger.warn( - 'Timer', - `Contract: ${contract.name} - Failed to fetch finalized block: ${error.message}`, - ); - } - if (!finalizedBlock) { - logger.debug( - 'Timer', - `Contract: ${contract.name} - Waiting for finalized block`, - ); - await setTimeout(10000); - return; - } - const lastBlockNumber = finalizedBlock.number; - if (contract.block_height > lastBlockNumber) { - logger.debug('Timer', `Contract: ${contract.name} - Waiting for block`); - await setTimeout(10000); - return; - } - const abi = AbiFactory.create(network, contract.name); - if (!abi) { - logger.error('Timer', 'ABI not found', contract); - return; - } - // block_height stored in DB is the next block to process (first unprocessed). - // toBlock is inclusive in eth_getLogs, so a window [X, X+999] covers 1000 blocks. - const options = { - fromBlock: contract.block_height, - toBlock: Math.min(lastBlockNumber, contract.block_height + 999), - }; - logger.debug( - 'Timer', - `Contract: ${contract.name} - from block #${options.fromBlock} - to #${options.toBlock}`, - ); - const api = new ethers.Contract(contract.contract_hash, abi, provider); - const logs = await provider.getLogs({ - address: contract.contract_hash, - topics: [], - fromBlock: options.fromBlock, - toBlock: options.toBlock, - }); - logger.debug( - 'Timer', - `Contract: ${contract.name} - Found ${logs.length} logs`, - ); - const blockIndex: { [blockNumber: number]: number } = {}; - for (const log of logs) { - const parsedLog = api.interface.parseLog({ - topics: log.topics, - data: log.data, - }); - logger.debug( - 'Timer', - `Contract: ${contract.name} - Parsed Log: ${parsedLog}`, - ); - const eventName = parsedLog?.name; - const eventSignature = parsedLog?.signature; - const data: { eventName: string; args: any } = decodeEventLog({ - abi: AbiFactory.create(network, contract.name) as Abi, - data: log.data as `0x${string}`, - topics: log.topics as [], - }); - logger.debug( - 'Timer', - `Contract: ${contract.name} - Decoded event Log: ${eventName}, ${data.args.data}`, - ); - - const decodedArgs = decodeMessage(data.args.data); - - logger.debug( - 'Timer', - `Contract: ${contract.name} - Decoded Args: ${decodedArgs}`, - ); - let blockTimestamp = 0; - if (!blockIndex[log.blockNumber]) { - // Retry logic with exponential backoff - let block = null; - const retries = 3; - for (let attempt = 1; attempt <= retries; attempt++) { - try { - block = await provider.getBlock(log.blockNumber); - break; // Success, exit retry loop - } catch (error: any) { - logger.debug( - 'Timer', - `Contract: ${contract.name} - Block fetch attempt ${attempt} failed for block ${log.blockNumber}: ${error.message}`, - ); - - if (attempt < retries) { - const delay = 2 ** attempt * 1000; // exponential backoff: 2s, 4s, 8s - await new Promise((resolve) => setTimeout(resolve as any, delay)); - } - } - } - - if (block) { - blockTimestamp = block.timestamp; - blockIndex[log.blockNumber] = block.timestamp; - } else { - // Use 0 as default timestamp when all retries fail - blockTimestamp = 0; - blockIndex[log.blockNumber] = 0; - logger.debug( - 'Timer', - `Using default timestamp 0 for block ${log.blockNumber} after max retries`, - ); - } - } else { - blockTimestamp = blockIndex[log.blockNumber]; - } - - logger.debug( - 'Timer', - `Contract: ${contract.name} Saving transaction ${log?.transactionHash}. Decoded Args: ${decodedArgs}`, - ); - const [contractL1Log] = await connection.query( - 'insert into indexer.contract_l1_logs (contract_hash, block_height, tx_hash, raw_log, event, signature, decoded_args, decoded_data, timestamp, log_index) values ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) on conflict (block_height, log_index) do update set log_index = EXCLUDED.log_index returning _id', - [ - contract.contract_hash, - log.blockNumber, - log.transactionHash, - log, - eventName, - eventSignature, - JSON.stringify(data.args, (_, v) => - typeof v === 'bigint' ? v.toString() : v, - ), - decodedArgs, - new Date(blockTimestamp * 1000), - log.index, - ], - ); - const args = { ...data.args, ...decodedArgs }; - for (const key in args) { - await connection.query( - 'insert into indexer.contract_l1_args (contract_l1_log_id, key, value) values ($1, $2, $3) on conflict do nothing', - [contractL1Log._id, key, args[key]], - ); - } - } - // Advance cursor past the last processed block so the next cycle starts fresh. - await connection.query( - 'update indexer.contract_l1_index set block_height = $1 where _id = $2', - [options.toBlock + 1, contract._id], - ); - } - - async execute() { - const connection = DatabaseConnection.getInstance(); - while (true) { - const contracts = await connection.query( - `select * from indexer.contract_l1_index where status = 'active' and network = $1`, - [env.get('FUEL_CHAIN')], - ); - await Promise.all( - contracts.map((contract) => this.syncContract(contract)), - ); - await setTimeout(1000); - } - } -} diff --git a/packages/graphql/src/application/uc/IndexL1/L1ReorgSentinel.test.ts b/packages/graphql/src/application/uc/IndexL1/L1ReorgSentinel.test.ts deleted file mode 100644 index 2c57a3964..000000000 --- a/packages/graphql/src/application/uc/IndexL1/L1ReorgSentinel.test.ts +++ /dev/null @@ -1,139 +0,0 @@ -import L1ReorgSentinel from './L1ReorgSentinel'; - -const loggerMock = { debug: jest.fn(), error: jest.fn(), warn: jest.fn() }; - -jest.mock('~/config', () => ({ - env: { get: (k: string) => (k === 'FUEL_CHAIN' ? 'mainnet' : 'test-key') }, -})); - -jest.mock('~/core/Logger', () => ({ - logger: { - debug: (...args: any[]) => loggerMock.debug(...args), - error: (...args: any[]) => loggerMock.error(...args), - warn: (...args: any[]) => loggerMock.warn(...args), - }, -})); - -const queryMock = jest.fn(); -jest.mock('~/infra/database/DatabaseConnection', () => ({ - DatabaseConnection: { getInstance: () => ({ query: queryMock }) }, -})); - -jest.mock('node:timers/promises', () => ({ - setTimeout: jest.fn().mockResolvedValue(undefined), -})); - -beforeEach(() => { - loggerMock.error.mockClear(); - loggerMock.debug.mockClear(); - loggerMock.warn.mockClear(); - queryMock.mockReset(); -}); - -function makeSentinel(provider: any) { - class TestSentinel extends L1ReorgSentinel { - protected createProvider() { - return provider; - } - } - return new TestSentinel(); -} - -describe('L1ReorgSentinel', () => { - it('does not log an error when stored hashes match canonical', async () => { - queryMock.mockResolvedValue([ - { block_height: 100, stored_hash: '0xaaa', contract_hash: '0xc1' }, - { block_height: 101, stored_hash: '0xbbb', contract_hash: '0xc1' }, - ]); - const provider = { - getBlock: jest.fn(async (n: number) => ({ - number: n, - hash: n === 100 ? '0xaaa' : '0xbbb', - })), - }; - - await makeSentinel(provider).checkOnce(); - - expect(loggerMock.error).not.toHaveBeenCalled(); - }); - - it('logs a structured error when a stored hash diverges from canonical', async () => { - queryMock.mockResolvedValue([ - { - block_height: 200, - stored_hash: '0xstale', - contract_hash: '0xcontract', - }, - ]); - const provider = { - getBlock: jest.fn(async () => ({ number: 200, hash: '0xcanonical' })), - }; - - await makeSentinel(provider).checkOnce(); - - expect(loggerMock.error).toHaveBeenCalledTimes(1); - const [tag, message, payload] = loggerMock.error.mock.calls[0]; - expect(tag).toBe('L1ReorgSentinel'); - // Alert prefix must be present so log-routing tooling can key on it. - expect(message).toMatch(/\[L1_REORG_ALERT\]/); - expect(payload).toEqual({ - block_height: 200, - stored_hash: '0xstale', - canonical_hash: '0xcanonical', - contract_hash: '0xcontract', - }); - }); - - it('logs a debug line and does not throw when the provider errors', async () => { - queryMock.mockResolvedValue([ - { block_height: 300, stored_hash: '0xaaa', contract_hash: '0xc1' }, - ]); - const provider = { - getBlock: jest.fn().mockRejectedValue(new Error('rpc failed')), - }; - - await expect(makeSentinel(provider).checkOnce()).resolves.not.toThrow(); - expect(loggerMock.debug).toHaveBeenCalled(); - }); - - it('warns when the provider returns no canonical block for a height we have stored rows for', async () => { - queryMock.mockResolvedValue([ - { block_height: 400, stored_hash: '0xsomething', contract_hash: '0xc1' }, - ]); - const provider = { - getBlock: jest.fn().mockResolvedValue(null), - }; - - await makeSentinel(provider).checkOnce(); - - expect(loggerMock.warn).toHaveBeenCalledTimes(1); - const [tag, message] = loggerMock.warn.mock.calls[0]; - expect(tag).toBe('L1ReorgSentinel'); - expect(message).toMatch(/no block at finalized-depth height 400/); - expect(loggerMock.error).not.toHaveBeenCalled(); - }); - - it('samples per contract (not just globally) so a busy contract cannot monopolize the window', async () => { - // Verify the SQL takes a per-contract partition approach (row_number() OVER partition). - queryMock.mockResolvedValue([]); - const provider = { getBlock: jest.fn() }; - await makeSentinel(provider).checkOnce(); - expect(queryMock).toHaveBeenCalledTimes(1); - const sql = queryMock.mock.calls[0][0] as string; - expect(sql).toMatch(/partition by [\w.]*contract_hash/i); - expect(sql).toMatch(/row_number\(\)/i); - }); - - it('scopes the sample to active contracts for the current network', async () => { - queryMock.mockResolvedValue([]); - const provider = { getBlock: jest.fn() }; - await makeSentinel(provider).checkOnce(); - const sql = queryMock.mock.calls[0][0] as string; - const params = queryMock.mock.calls[0][1] as unknown[]; - expect(sql).toMatch(/indexer\.contract_l1_index/); - expect(sql).toMatch(/status = 'active'/); - expect(sql).toMatch(/network = \$1/); - // First param must be the current FUEL_CHAIN — mocked to 'mainnet'. - expect(params[0]).toBe('mainnet'); - }); -}); diff --git a/packages/graphql/src/application/uc/IndexL1/L1ReorgSentinel.ts b/packages/graphql/src/application/uc/IndexL1/L1ReorgSentinel.ts deleted file mode 100644 index 11be6a9c9..000000000 --- a/packages/graphql/src/application/uc/IndexL1/L1ReorgSentinel.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { setTimeout } from 'node:timers/promises'; -import type { ethers } from 'ethers'; -import { env } from '~/config'; -import { logger } from '~/core/Logger'; -import { DatabaseConnection } from '~/infra/database/DatabaseConnection'; -import { createL1Provider } from './createL1Provider'; - -type RecentLogRow = { - block_height: number; - stored_hash: string | null; - contract_hash: string; -}; - -export default class L1ReorgSentinel { - protected createProvider(): ethers.JsonRpcProvider { - return createL1Provider(); - } - - // Sample up to this many most-recent rows per contract. Covers one-batch bursts - // on busy contracts (e.g. FuelMessagePortal) without over-sampling quiet ones. - // 20 rows × 7 active contracts ≈ 140 unique (block_height, contract) pairs per cycle. - protected readonly rowsPerContract = 20; - - async checkOnce(): Promise { - const connection = DatabaseConnection.getInstance(); - const network = env.get('FUEL_CHAIN') || ''; - // Per-contract sample, scoped to active contracts for the current network. - // Prevents (a) one busy contract monopolizing a global LIMIT window and - // (b) false positives from stale/inactive/cross-network rows in the table. - const rows = (await connection.query( - `select ranked.block_height, ranked.stored_hash, ranked.contract_hash - from ( - select l.block_height, - l.raw_log->>'blockHash' as stored_hash, - l.contract_hash, - row_number() over (partition by l.contract_hash order by l._id desc) as rn - from indexer.contract_l1_logs l - join indexer.contract_l1_index i - on i.contract_hash = l.contract_hash - where i.status = 'active' and i.network = $1 - ) ranked - where ranked.rn <= $2`, - [network, this.rowsPerContract], - )) as RecentLogRow[]; - - if (rows.length === 0) return; - - const provider = this.createProvider(); - // Bucket by (contract_hash, block_height) so we fetch each canonical block - // once even when a contract emits multiple logs at the same height. - const byHeight = new Map(); - for (const row of rows) { - const bucket = byHeight.get(row.block_height) ?? []; - bucket.push(row); - byHeight.set(row.block_height, bucket); - } - - for (const [height, group] of byHeight) { - let canonicalHash: string | null = null; - try { - const block = await provider.getBlock(height); - canonicalHash = block?.hash ?? null; - } catch (error: any) { - logger.debug( - 'L1ReorgSentinel', - `Failed to fetch canonical block ${height}: ${error.message}`, - ); - continue; - } - // Provider returned null for a block we have stored rows for. For a - // finalized-depth height this is itself suspicious — a truly absent - // block would mean the stored row references an orphaned chain. Upgrade - // severity from silent-skip to explicit warn so ops can spot it. - if (!canonicalHash) { - const storedHashes = group - .map((r) => r.stored_hash) - .filter((h): h is string => Boolean(h)); - if (storedHashes.length > 0) { - logger.warn( - 'L1ReorgSentinel', - `Provider returned no block at finalized-depth height ${height}; stored rows reference: ${storedHashes.join(', ')}`, - ); - } - continue; - } - - for (const row of group) { - if (!row.stored_hash) continue; - if (row.stored_hash.toLowerCase() === canonicalHash.toLowerCase()) - continue; - // Loud alert. Log routing / on-call tooling should key on the - // [L1_REORG_ALERT] literal or the "L1ReorgSentinel" tag. - logger.error( - 'L1ReorgSentinel', - '[L1_REORG_ALERT] Stored L1 block hash diverges from canonical', - { - block_height: row.block_height, - stored_hash: row.stored_hash, - canonical_hash: canonicalHash, - contract_hash: row.contract_hash, - }, - ); - } - } - } - - async execute(): Promise { - while (true) { - try { - await this.checkOnce(); - } catch (error: any) { - logger.debug('L1ReorgSentinel', `checkOnce threw: ${error.message}`); - } - await setTimeout(60000); - } - } -} diff --git a/packages/graphql/src/application/uc/IndexL1/abi/AbiFactory.ts b/packages/graphql/src/application/uc/IndexL1/abi/AbiFactory.ts deleted file mode 100644 index 660373d1a..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/AbiFactory.ts +++ /dev/null @@ -1,42 +0,0 @@ -import type { InterfaceAbi } from 'ethers'; -import { contract as fuelChainStateMainnet } from './mainnet/fuelChainStateAbi'; -import { contract as fuelERC20GatewayV4Mainnet } from './mainnet/fuelERC20GatewayV4Abi'; -import { contract as fuelMessagePortalAbiMainnet } from './mainnet/fuelMessagePortalAbi'; -import { contract as fuelStreamXAbiMainnet } from './mainnet/fuelStreamXAbi'; -import { contract as rewardsDistributorAbiMainnet } from './mainnet/rewardsDistributorAbi'; -import { contract as sequencerProxyAbiMainnet } from './mainnet/sequencerProxyAbi'; -import { contract as tokenMainnet } from './mainnet/tokenAbi'; -import { contract as fuelChainStateTestnet } from './testnet/fuelChainStateAbi'; -import { contract as fuelERC20GatewayV4Testnet } from './testnet/fuelERC20GatewayV4Abi'; -import { contract as fuelMessagePortalAbiTestnet } from './testnet/fuelMessagePortalAbi'; -import { contract as fuelStreamXAbiTestnet } from './testnet/fuelStreamXAbi'; -import { contract as rewardsDistributorAbiTestnet } from './testnet/rewardsDistributorAbi'; -import { contract as sequencerProxyAbiTestnet } from './testnet/sequencerProxyAbi'; -import { contract as tokenTestnet } from './testnet/tokenAbi'; - -export default class AbiFactory { - static create(network: string, contract: string) { - const ABI: { [network: string]: { [contract: string]: InterfaceAbi } } = { - mainnet: { - SequencerProxy: sequencerProxyAbiMainnet.abi, - FuelStreamX: fuelStreamXAbiMainnet.abi, - RewardDistribution: rewardsDistributorAbiMainnet.abi, - FuelMessagePortal: fuelMessagePortalAbiMainnet.abi, - FuelERC20GatewayV4: fuelERC20GatewayV4Mainnet.abi, - FuelChainState: fuelChainStateMainnet.abi, - Token: tokenMainnet.abi, - }, - testnet: { - SequencerProxy: sequencerProxyAbiTestnet.abi, - FuelStreamX: fuelStreamXAbiTestnet.abi, - RewardDistribution: rewardsDistributorAbiTestnet.abi, - FuelMessagePortal: fuelMessagePortalAbiTestnet.abi, - FuelERC20GatewayV4: fuelERC20GatewayV4Testnet.abi, - FuelChainState: fuelChainStateTestnet.abi, - Token: tokenTestnet.abi, - }, - }; - if (!ABI[network]) return; - return ABI[network][contract]; - } -} diff --git a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelChainStateAbi.ts b/packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelChainStateAbi.ts deleted file mode 100644 index 0b82a311f..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelChainStateAbi.ts +++ /dev/null @@ -1,581 +0,0 @@ -export const contract = { - address: '0xf3D20Db1D16A4D0ad2f280A5e594FF3c7790f130', - abi: [ - { - inputs: [ - { - internalType: 'uint256', - name: 'timeToFinalize', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'blocksPerCommitInterval', - type: 'uint256', - }, - { - internalType: 'uint32', - name: 'commitCooldown', - type: 'uint32', - }, - ], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'CannotRecommit', - type: 'error', - }, - { - inputs: [], - name: 'CommitCooldownTooLarge', - type: 'error', - }, - { - inputs: [], - name: 'FinalizationIsGtCooldown', - type: 'error', - }, - { - inputs: [], - name: 'TimeToFinalizeTooLarge', - type: 'error', - }, - { - inputs: [], - name: 'UnknownBlock', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'previousAdmin', - type: 'address', - }, - { - indexed: false, - internalType: 'address', - name: 'newAdmin', - type: 'address', - }, - ], - name: 'AdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'beacon', - type: 'address', - }, - ], - name: 'BeaconUpgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'commitHeight', - type: 'uint256', - }, - { - indexed: false, - internalType: 'bytes32', - name: 'blockHash', - type: 'bytes32', - }, - ], - name: 'CommitSubmitted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint8', - name: 'version', - type: 'uint8', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Paused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Unpaused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - inputs: [], - name: 'BLOCKS_PER_COMMIT_INTERVAL', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'COMMITTER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'COMMIT_COOLDOWN', - outputs: [ - { - internalType: 'uint32', - name: '', - type: 'uint32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'NUM_COMMIT_SLOTS', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'PAUSER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'TIME_TO_FINALIZE', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'commitHeight', - type: 'uint256', - }, - ], - name: 'blockHashAtCommit', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'blockHash', - type: 'bytes32', - }, - { - internalType: 'uint256', - name: 'commitHeight', - type: 'uint256', - }, - ], - name: 'commit', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'blockHash', - type: 'bytes32', - }, - { - internalType: 'uint256', - name: 'blockHeight', - type: 'uint256', - }, - ], - name: 'finalized', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - 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: [], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'pause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'paused', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - 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: 'unpause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - ], - name: 'upgradeTo', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - ], - numDeployments: 1, - linkedData: { - factory: 'FuelChainState', - constructorArgs: [604800, 10800, 604800], - }, - implementation: '0x725B2b1a15D818E1f25c68be77816802e6036559', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelERC20GatewayV4Abi.ts b/packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelERC20GatewayV4Abi.ts deleted file mode 100644 index 4c1a35be3..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelERC20GatewayV4Abi.ts +++ /dev/null @@ -1,923 +0,0 @@ -export const contract = { - address: '0xa4cA04d02bfdC3A2DF56B9b6994520E69dF43F67', - abi: [ - { - inputs: [], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'BridgeFull', - type: 'error', - }, - { - inputs: [], - name: 'CallerIsNotPortal', - type: 'error', - }, - { - inputs: [], - name: 'CannotDepositZero', - type: 'error', - }, - { - inputs: [], - name: 'CannotWithdrawZero', - type: 'error', - }, - { - inputs: [], - name: 'GlobalDepositLimit', - type: 'error', - }, - { - inputs: [], - name: 'InvalidAmount', - type: 'error', - }, - { - inputs: [], - name: 'InvalidAssetIssuerID', - type: 'error', - }, - { - inputs: [], - name: 'InvalidMessageSender', - type: 'error', - }, - { - inputs: [], - name: 'InvalidSender', - type: 'error', - }, - { - inputs: [], - name: 'RateLimitExceeded', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'previousAdmin', - type: 'address', - }, - { - indexed: false, - internalType: 'address', - name: 'newAdmin', - type: 'address', - }, - ], - name: 'AdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'beacon', - type: 'address', - }, - ], - name: 'BeaconUpgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'sender', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'Deposit', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint8', - name: 'version', - type: 'uint8', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Paused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - indexed: false, - internalType: 'bool', - name: 'status', - type: 'bool', - }, - ], - name: 'RateLimitStatusUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'RateLimitUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Unpaused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'recipient', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'Withdrawal', - type: 'event', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'FUEL_ASSET_DECIMALS', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'PAUSER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'SET_RATE_LIMITER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'assetIssuerId', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - name: 'currentPeriodAmount', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - name: 'currentPeriodEnd', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'to', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'deposit', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - ], - name: 'depositLimits', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'to', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'depositWithData', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - internalType: 'uint256', - name: 'l2BurntAmount', - type: 'uint256', - }, - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - name: 'finalizeWithdrawal', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'fuelMessagePortal', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - 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: 'contract FuelMessagePortal', - name: 'fuelMessagePortal', - type: 'address', - }, - ], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - name: 'limitAmount', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'pause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'paused', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - name: 'rateLimitDuration', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - name: 'rateLimitStatus', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bool', - name: 'value', - type: 'bool', - }, - ], - name: 'requireWhitelist', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'rescueETH', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_token', - type: 'address', - }, - { - internalType: 'uint256', - name: '_amount', - type: 'uint256', - }, - { - internalType: 'uint256', - name: '_rateLimitDuration', - type: 'uint256', - }, - ], - name: 'resetRateLimitAmount', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'revokeRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - ], - name: 'sendMetadata', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'id', - type: 'bytes32', - }, - ], - name: 'setAssetIssuerId', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'token', - type: 'address', - }, - { - internalType: 'uint256', - name: 'limit', - type: 'uint256', - }, - ], - name: 'setGlobalDepositLimit', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes4', - name: 'interfaceId', - type: 'bytes4', - }, - ], - name: 'supportsInterface', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - ], - name: 'tokensDeposited', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'unpause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_token', - type: 'address', - }, - { - internalType: 'bool', - name: '_rateLimitStatus', - type: 'bool', - }, - ], - name: 'updateRateLimitStatus', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - ], - name: 'upgradeTo', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'whitelistRequired', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - ], - numDeployments: 2, - linkedData: { - factory: 'FuelERC20GatewayV4', - constructorArgs: [], - }, - transactionHash: - '0x44c0654c83eff10b0126cc97f9d519ba8f1b4a41958886cb58eee3e939760c8e', - implementation: '0xdE2D792ca3C4d02DE3CE1cD1456d8D0990cC3fab', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelMessagePortalAbi.ts b/packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelMessagePortalAbi.ts deleted file mode 100644 index 4ee8242c8..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelMessagePortalAbi.ts +++ /dev/null @@ -1,1169 +0,0 @@ -export const contract = { - address: '0xAEB0c00D0125A8a788956ade4f4F12Ead9f65DDf', - abi: [ - { - inputs: [ - { - internalType: 'uint256', - name: '_depositLimitGlobal', - type: 'uint256', - }, - { - internalType: 'uint256', - name: '_rateLimitDuration', - type: 'uint256', - }, - ], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'AlreadyRelayed', - type: 'error', - }, - { - inputs: [], - name: 'AmountPrecisionIncompatibility', - type: 'error', - }, - { - inputs: [], - name: 'AmountTooBig', - type: 'error', - }, - { - inputs: [], - name: 'CurrentMessageSenderNotSet', - type: 'error', - }, - { - inputs: [], - name: 'GlobalDepositLimit', - type: 'error', - }, - { - inputs: [], - name: 'InvalidBlockInHistoryProof', - type: 'error', - }, - { - inputs: [], - name: 'InvalidMessageInBlockProof', - type: 'error', - }, - { - inputs: [], - name: 'MessageBlacklisted', - type: 'error', - }, - { - inputs: [], - name: 'MessageDataTooLarge', - type: 'error', - }, - { - inputs: [], - name: 'MessageRelayFailed', - type: 'error', - }, - { - inputs: [], - name: 'NotSupported', - type: 'error', - }, - { - inputs: [], - name: 'RateLimitExceeded', - type: 'error', - }, - { - inputs: [], - name: 'UnfinalizedBlock', - type: 'error', - }, - { - inputs: [], - name: 'WithdrawalsPaused', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'previousAdmin', - type: 'address', - }, - { - indexed: false, - internalType: 'address', - name: 'newAdmin', - type: 'address', - }, - ], - name: 'AdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'beacon', - type: 'address', - }, - ], - name: 'BeaconUpgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'oldValue', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'newValue', - type: 'address', - }, - ], - name: 'FuelChainStateUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint8', - name: 'version', - type: 'uint8', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'messageId', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'sender', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'recipient', - type: 'bytes32', - }, - { - indexed: false, - internalType: 'uint64', - name: 'amount', - type: 'uint64', - }, - ], - name: 'MessageRelayed', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'sender', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'recipient', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint64', - name: 'amount', - type: 'uint64', - }, - { - indexed: false, - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'MessageSent', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Paused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'bool', - name: 'status', - type: 'bool', - }, - ], - name: 'RateLimitStatusUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'ResetRateLimit', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Unpaused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'ETH_DECIMALS', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'FUEL_BASE_ASSET_DECIMALS', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'MAX_MESSAGE_DATA_SIZE', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'PAUSER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'PRECISION', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'RATE_LIMIT_DURATION', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'SET_RATE_LIMITER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'messageId', - type: 'bytes32', - }, - ], - name: 'addMessageToBlacklist', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'currentPeriodAmount', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'currentPeriodEnd', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'recipient', - type: 'bytes32', - }, - ], - name: 'depositETH', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'depositLimitGlobal', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'fuelBaseAssetDecimals', - outputs: [ - { - internalType: 'uint8', - name: '', - type: 'uint8', - }, - ], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [], - name: 'fuelChainStateContract', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'getNextOutgoingMessageNonce', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - 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: 'bytes32', - name: 'messageId', - type: 'bytes32', - }, - ], - name: 'incomingMessageSuccessful', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'contract FuelChainState', - name: '', - type: 'address', - }, - ], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'contract FuelChainState', - name: 'fuelChainState', - type: 'address', - }, - { - internalType: 'uint256', - name: '_limitAmount', - type: 'uint256', - }, - ], - name: 'initializerV3', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'limitAmount', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - name: 'messageIsBlacklisted', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'messageSender', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'pause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'pauseWithdrawals', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'paused', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'rateLimitEnabled', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '_limitAmount', - type: 'uint256', - }, - ], - name: 'reinitializeV3', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'bytes32', - name: 'sender', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 'recipient', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 'nonce', - type: 'bytes32', - }, - { - internalType: 'uint64', - name: 'amount', - type: 'uint64', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - internalType: 'struct Message', - name: 'message', - type: 'tuple', - }, - { - components: [ - { - internalType: 'bytes32', - name: 'prevRoot', - type: 'bytes32', - }, - { - internalType: 'uint32', - name: 'height', - type: 'uint32', - }, - { - internalType: 'uint64', - name: 'timestamp', - type: 'uint64', - }, - { - internalType: 'bytes32', - name: 'applicationHash', - type: 'bytes32', - }, - ], - internalType: 'struct FuelBlockHeaderLite', - name: 'rootBlockHeader', - type: 'tuple', - }, - { - components: [ - { - internalType: 'bytes32', - name: 'prevRoot', - type: 'bytes32', - }, - { - internalType: 'uint64', - name: 'timestamp', - type: 'uint64', - }, - { - internalType: 'uint64', - name: 'daHeight', - type: 'uint64', - }, - { - internalType: 'uint32', - name: 'outputMessagesCount', - type: 'uint32', - }, - { - internalType: 'uint32', - name: 'consensusParametersVersion', - type: 'uint32', - }, - { - internalType: 'uint32', - name: 'stateTransitionBytecodeVersion', - type: 'uint32', - }, - { - internalType: 'uint32', - name: 'height', - type: 'uint32', - }, - { - internalType: 'bytes32', - name: 'txRoot', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 'outputMessagesRoot', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 'eventInboxRoot', - type: 'bytes32', - }, - { - internalType: 'uint16', - name: 'txCount', - type: 'uint16', - }, - ], - internalType: 'struct FuelBlockHeader', - name: 'blockHeader', - type: 'tuple', - }, - { - components: [ - { - internalType: 'uint256', - name: 'key', - type: 'uint256', - }, - { - internalType: 'bytes32[]', - name: 'proof', - type: 'bytes32[]', - }, - ], - internalType: 'struct MerkleProof', - name: 'blockInHistoryProof', - type: 'tuple', - }, - { - components: [ - { - internalType: 'uint256', - name: 'key', - type: 'uint256', - }, - { - internalType: 'bytes32[]', - name: 'proof', - type: 'bytes32[]', - }, - ], - internalType: 'struct MerkleProof', - name: 'messageInBlockProof', - type: 'tuple', - }, - ], - name: 'relayMessage', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'messageId', - type: 'bytes32', - }, - ], - name: 'removeMessageFromBlacklist', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '_amount', - type: 'uint256', - }, - ], - name: 'resetRateLimitAmount', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'revokeRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'recipient', - type: 'bytes32', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'sendMessage', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newFuelChainState', - type: 'address', - }, - ], - name: 'setFuelChainState', - 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: 'totalDeposited', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'unpause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'unpauseWithdrawals', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bool', - name: 'value', - type: 'bool', - }, - ], - name: 'updateRateLimitStatus', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - ], - name: 'upgradeTo', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'withdrawalsPaused', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - ], - transactionHash: - '0xaaa628d33a2247ea28a9db05472e879c8aa63689a2561c947dfc8facac06ce11', - numDeployments: 4, - linkedData: { - factory: 'FuelMessagePortalV3', - constructorArgs: [ - '115792089237316195423570985008687907853269984665640564039457584007913129639935', - 604800, - ], - }, - implementation: '0x2C4df10a82CF077122eD99573acA6daCd76F2E67', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelStreamXAbi.ts b/packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelStreamXAbi.ts deleted file mode 100644 index ea45010a6..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/fuelStreamXAbi.ts +++ /dev/null @@ -1,1293 +0,0 @@ -export const contract = { - address: '0x481aeEB9bdFe08f050d22F0b352356691c4B0b59', - abi: [ - { - inputs: [], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'AccessControlBadConfirmation', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'neededRole', - type: 'bytes32', - }, - ], - name: 'AccessControlUnauthorizedAccount', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'target', - type: 'address', - }, - ], - name: 'AddressEmptyCode', - type: 'error', - }, - { - inputs: [], - name: 'BridgeCommitmentNotFound', - type: 'error', - }, - { - inputs: [], - name: 'CommitmentNotFinalized', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'ERC1967InvalidImplementation', - type: 'error', - }, - { - inputs: [], - name: 'ERC1967NonPayable', - type: 'error', - }, - { - inputs: [], - name: 'EnforcedPause', - type: 'error', - }, - { - inputs: [], - name: 'ExpectedPause', - type: 'error', - }, - { - inputs: [], - name: 'FailedInnerCall', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint8', - name: 'char', - type: 'uint8', - }, - ], - name: 'InvalidCharacter', - type: 'error', - }, - { - inputs: [], - name: 'InvalidCommitmentProof', - type: 'error', - }, - { - inputs: [], - name: 'InvalidExecTxResultCode', - type: 'error', - }, - { - inputs: [], - name: 'InvalidInitialization', - type: 'error', - }, - { - inputs: [ - { - internalType: 'string', - name: 's', - type: 'string', - }, - ], - name: 'InvalidIntString', - type: 'error', - }, - { - inputs: [], - name: 'InvalidProofNonce', - type: 'error', - }, - { - inputs: [], - name: 'InvalidStringLength', - type: 'error', - }, - { - inputs: [], - name: 'InvalidToken', - type: 'error', - }, - { - inputs: [], - name: 'InvalidTxResultProof', - type: 'error', - }, - { - inputs: [ - { - internalType: 'string', - name: 's', - type: 'string', - }, - ], - name: 'InvalidUintString', - type: 'error', - }, - { - inputs: [], - name: 'LatestHeaderNotFound', - type: 'error', - }, - { - inputs: [], - name: 'Missing0xPrefix', - type: 'error', - }, - { - inputs: [], - name: 'NonceAlreadyUsed', - type: 'error', - }, - { - inputs: [], - name: 'NotInitializing', - type: 'error', - }, - { - inputs: [], - name: 'TargetBlockNotInRange', - type: 'error', - }, - { - inputs: [], - name: 'TrustedHeaderNotFound', - type: 'error', - }, - { - inputs: [], - name: 'UUPSUnauthorizedCallContext', - type: 'error', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'slot', - type: 'bytes32', - }, - ], - name: 'UUPSUnsupportedProxiableUUID', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint256', - name: 'proofNonce', - type: 'uint256', - }, - { - indexed: true, - internalType: 'uint64', - name: 'startBlock', - type: 'uint64', - }, - { - indexed: true, - internalType: 'uint64', - name: 'endBlock', - type: 'uint64', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'bridgeCommitment', - type: 'bytes32', - }, - ], - name: 'BridgeCommitmentStored', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint64', - name: 'blockNumber', - type: 'uint64', - }, - { - indexed: false, - internalType: 'bytes32', - name: 'headerHash', - type: 'bytes32', - }, - ], - name: 'HeadUpdate', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'newHeaderRangeFunctionId', - type: 'bytes32', - }, - ], - name: 'HeaderRangeFunctionIdUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint64', - name: 'trustedBlock', - type: 'uint64', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'trustedHeader', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'uint64', - name: 'targetBlock', - type: 'uint64', - }, - ], - name: 'HeaderRangeRequested', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint64', - name: 'version', - type: 'uint64', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint64', - name: 'trustedBlock', - type: 'uint64', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'trustedHeader', - type: 'bytes32', - }, - ], - name: 'NextHeaderRequested', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Paused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - { - indexed: false, - internalType: 'int256', - name: 'delta', - type: 'int256', - }, - ], - name: 'SupplyDelta', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Unpaused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - { - indexed: true, - internalType: 'address', - name: 'recipient', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'WithdrawalProcessed', - type: 'event', - }, - { - inputs: [], - name: 'BRIDGE_COMMITMENT_MAX', - outputs: [ - { - internalType: 'uint64', - name: '', - type: 'uint64', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'GUARDIAN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'L2_ACCOUNT_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'L2_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'PAUSER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'UPGRADE_INTERFACE_VERSION', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'VERSION', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint64', - name: '', - type: 'uint64', - }, - ], - name: 'blockHeightToHeaderHash', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - name: 'commitmentTimestamp', - outputs: [ - { - internalType: 'uint32', - name: '', - type: 'uint32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'gateway', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'l2Account', - type: 'address', - }, - ], - name: 'grantL2AccountRole', - outputs: [], - stateMutability: 'nonpayable', - 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: [], - name: 'headerRangeFunctionId', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'address', - name: 'vault', - type: 'address', - }, - { - internalType: 'address', - name: 'gateway', - type: 'address', - }, - { - internalType: 'uint64', - name: 'height', - type: 'uint64', - }, - { - internalType: 'bytes32', - name: 'header', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 'nextHeaderFunctionId', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 'headerRangeFunctionId', - type: 'bytes32', - }, - { - internalType: 'string', - name: 'tokenCosmosDenomination', - type: 'string', - }, - ], - internalType: 'struct FuelStreamX.InitParameters', - name: '_params', - type: 'tuple', - }, - ], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'header', - type: 'bytes32', - }, - ], - name: 'initializeTrustedHeader', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'latestBlock', - outputs: [ - { - internalType: 'uint64', - name: '', - type: 'uint64', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'nextHeaderFunctionId', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'pause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'paused', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '_proofNonce', - type: 'uint256', - }, - { - components: [ - { - internalType: 'uint256', - name: 'height', - type: 'uint256', - }, - { - internalType: 'bytes32', - name: 'resultsHash', - type: 'bytes32', - }, - ], - internalType: 'struct BridgeCommitmentLeaf', - name: 'bridgeCommitmentLeaf', - type: 'tuple', - }, - { - components: [ - { - internalType: 'bytes32[]', - name: 'sideNodes', - type: 'bytes32[]', - }, - { - internalType: 'uint256', - name: 'key', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'numLeaves', - type: 'uint256', - }, - ], - internalType: 'struct BinaryMerkleProof', - name: 'bridgeCommitmentLeafProof', - type: 'tuple', - }, - { - internalType: 'bytes', - name: 'txResultMarshalled', - type: 'bytes', - }, - { - components: [ - { - internalType: 'bytes32[]', - name: 'sideNodes', - type: 'bytes32[]', - }, - { - internalType: 'uint256', - name: 'key', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'numLeaves', - type: 'uint256', - }, - ], - internalType: 'struct BinaryMerkleProof', - name: 'txResultProof', - type: 'tuple', - }, - ], - name: 'processSequencerSupplyUpdate', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '_proofNonce', - type: 'uint256', - }, - { - components: [ - { - internalType: 'uint256', - name: 'height', - type: 'uint256', - }, - { - internalType: 'bytes32', - name: 'resultsHash', - type: 'bytes32', - }, - ], - internalType: 'struct BridgeCommitmentLeaf', - name: 'bridgeCommitmentLeaf', - type: 'tuple', - }, - { - components: [ - { - internalType: 'bytes32[]', - name: 'sideNodes', - type: 'bytes32[]', - }, - { - internalType: 'uint256', - name: 'key', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'numLeaves', - type: 'uint256', - }, - ], - internalType: 'struct BinaryMerkleProof', - name: 'bridgeCommitmentLeafProof', - type: 'tuple', - }, - { - internalType: 'bytes', - name: 'txResultMarshalled', - type: 'bytes', - }, - { - components: [ - { - internalType: 'bytes32[]', - name: 'sideNodes', - type: 'bytes32[]', - }, - { - internalType: 'uint256', - name: 'key', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'numLeaves', - type: 'uint256', - }, - ], - internalType: 'struct BinaryMerkleProof', - name: 'txResultProof', - type: 'tuple', - }, - ], - name: 'processSequencerWithdrawalMessage', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'recoveryRegistry', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'callerConfirmation', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'revokeRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'string', - name: 'denomination', - type: 'string', - }, - ], - name: 'setCosmosTokenDenomination', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newRecoveryRegistry', - type: 'address', - }, - ], - name: 'setRecoveryRegistry', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 'roleAdmin', - type: 'bytes32', - }, - ], - name: 'setRoleAdmin', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint32', - name: 'newTimeToFinalize', - type: 'uint32', - }, - ], - name: 'setTimeToFinalize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - name: 'state_bridgeCommitments', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'state_proofNonce', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes4', - name: 'interfaceId', - type: 'bytes4', - }, - ], - name: 'supportsInterface', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'timeToFinalize', - outputs: [ - { - internalType: 'uint32', - name: '', - type: 'uint32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'tokenCosmosDenominationHash', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'unpause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint64', - name: '_targetBlock', - type: 'uint64', - }, - { - internalType: 'bytes32', - name: '_targetHeader', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: '_bridgeCommitment', - type: 'bytes32', - }, - ], - name: 'updateCommitHeaderRange', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint32', - name: '_height', - type: 'uint32', - }, - { - internalType: 'bytes32', - name: '_header', - type: 'bytes32', - }, - ], - name: 'updateGenesisState', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: '_headerRangeFunctionId', - type: 'bytes32', - }, - ], - name: 'updateHeaderRangeFunctionId', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - name: 'usedNonces', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'vault', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - ], - numDeployments: 2, - implementation: '0x6c644cf9B3ca2AFB11f2218ec4a9F2a561C99626', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/rewardsDistributorAbi.ts b/packages/graphql/src/application/uc/IndexL1/abi/mainnet/rewardsDistributorAbi.ts deleted file mode 100644 index 7d47a22a1..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/rewardsDistributorAbi.ts +++ /dev/null @@ -1,721 +0,0 @@ -export const contract = { - address: '0xC20c2EA5fC5f26200f3339512f336c2ecE41FC18', - abi: [ - { - inputs: [ - { - internalType: 'address', - name: '_sequencerInterface', - type: 'address', - }, - { - internalType: 'address', - name: '_fuelToken', - type: 'address', - }, - { - internalType: 'bytes32', - name: '_l2StakingContractId', - type: 'bytes32', - }, - { - internalType: 'address', - name: '_fuelERC20Gateway', - type: 'address', - }, - ], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'AccessControlBadConfirmation', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'neededRole', - type: 'bytes32', - }, - ], - name: 'AccessControlUnauthorizedAccount', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'target', - type: 'address', - }, - ], - name: 'AddressEmptyCode', - type: 'error', - }, - { - inputs: [], - name: 'CollateralLessThanUserDeposits', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'ERC1967InvalidImplementation', - type: 'error', - }, - { - inputs: [], - name: 'ERC1967NonPayable', - type: 'error', - }, - { - inputs: [], - name: 'ExceedsLimit', - type: 'error', - }, - { - inputs: [], - name: 'FailedInnerCall', - type: 'error', - }, - { - inputs: [], - name: 'InsufficientBalance', - type: 'error', - }, - { - inputs: [], - name: 'InvalidAmount', - type: 'error', - }, - { - inputs: [], - name: 'InvalidCaller', - type: 'error', - }, - { - inputs: [], - name: 'InvalidInitialization', - type: 'error', - }, - { - inputs: [], - name: 'InvalidInputs', - type: 'error', - }, - { - inputs: [], - name: 'NoRewardsToDistribute', - type: 'error', - }, - { - inputs: [], - name: 'NotAuthorized', - type: 'error', - }, - { - inputs: [], - name: 'NotInitializing', - type: 'error', - }, - { - inputs: [], - name: 'UUPSUnauthorizedCallContext', - type: 'error', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'slot', - type: 'bytes32', - }, - ], - name: 'UUPSUnsupportedProxiableUUID', - type: 'error', - }, - { - inputs: [], - name: 'UserDepositsHigherThanCollateral', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'CollateralUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: '_foundationAddress', - type: 'address', - }, - ], - name: 'FoundationAddressUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint64', - name: 'version', - type: 'uint64', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address[]', - name: 'validators', - type: 'address[]', - }, - { - indexed: true, - internalType: 'uint256', - name: 'withdrawAmount', - type: 'uint256', - }, - ], - name: 'RewardsClaimed', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'totalRewards', - type: 'uint256', - }, - { - indexed: true, - internalType: 'uint256', - name: 'userShare', - type: 'uint256', - }, - { - indexed: true, - internalType: 'uint256', - name: 'foundationShare', - type: 'uint256', - }, - ], - name: 'RewardsDistributed', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'UserDepositsUpdated', - type: 'event', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'OPERATOR_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'ORACLE_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'UPGRADE_INTERFACE_VERSION', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address[]', - name: 'validators', - type: 'address[]', - }, - { - internalType: 'uint256', - name: 'withdrawAmount', - type: 'uint256', - }, - ], - name: 'claim', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'collateral', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'distribute', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'foundationAddress', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'fuelERC20Gateway', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'fuelToken', - outputs: [ - { - internalType: 'contract IERC1363', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - 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: [], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'l2StakingContractId', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'callerConfirmation', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'revokeRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'sequencerInterface', - outputs: [ - { - internalType: 'contract ISequencerInterface', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_foundationAddress', - type: 'address', - }, - ], - name: 'setFoundationAddress', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: '_l2StakingContractId', - type: 'bytes32', - }, - ], - name: 'setL2StakingContractId', - 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: [ - { - internalType: 'uint256', - name: '_collateral', - type: 'uint256', - }, - ], - name: 'updateCollateral', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '_userDeposits', - type: 'uint256', - }, - ], - name: 'updateUserDeposits', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'userDeposits', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - ], - args: [ - '0xca0c6B264f0F9958Ec186eb2EAa208966187D866', - '0x675B68AA4d9c2d3BB3F0397048e62E6B7192079c', - '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c', - '0xa4cA04d02bfdC3A2DF56B9b6994520E69dF43F67', - ], - numDeployments: 1, - implementation: '0x1cD61731ce62e5691DE2e547fA740Bcd0663B1A8', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/sequencerProxyAbi.ts b/packages/graphql/src/application/uc/IndexL1/abi/mainnet/sequencerProxyAbi.ts deleted file mode 100644 index e2a8a5a59..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/sequencerProxyAbi.ts +++ /dev/null @@ -1,1048 +0,0 @@ -export const contract = { - address: '0xBa0e6bF94580D49B5Aaaa54279198D424B23eCC3', - abi: [ - { - inputs: [], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'AccessControlBadConfirmation', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'neededRole', - type: 'bytes32', - }, - ], - name: 'AccessControlUnauthorizedAccount', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'target', - type: 'address', - }, - ], - name: 'AddressEmptyCode', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'ERC1967InvalidImplementation', - type: 'error', - }, - { - inputs: [], - name: 'ERC1967NonPayable', - type: 'error', - }, - { - inputs: [], - name: 'EnforcedPause', - type: 'error', - }, - { - inputs: [], - name: 'ExpectedPause', - type: 'error', - }, - { - inputs: [], - name: 'FailedInnerCall', - type: 'error', - }, - { - inputs: [], - name: 'InvalidInitialization', - type: 'error', - }, - { - inputs: [], - name: 'NotInitializing', - type: 'error', - }, - { - inputs: [], - name: 'UUPSUnauthorizedCallContext', - type: 'error', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'slot', - type: 'bytes32', - }, - ], - name: 'UUPSUnsupportedProxiableUUID', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - indexed: false, - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'Authorize', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'validator', - type: 'address', - }, - ], - name: 'ClaimRewards', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'validator', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'Delegate', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'depositor', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'recipient', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'lockup', - type: 'uint256', - }, - ], - name: 'Deposit', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'granter', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'grantee', - type: 'address', - }, - { - indexed: false, - internalType: 'string', - name: 'msgTypeUrl', - type: 'string', - }, - { - indexed: false, - internalType: 'uint32', - name: 'expiration', - type: 'uint32', - }, - ], - name: 'Grant', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint64', - name: 'version', - type: 'uint64', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Paused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'srcValidator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'dstValidator', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'Redelegate', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'granter', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'grantee', - type: 'address', - }, - { - indexed: false, - internalType: 'string', - name: 'msgTypeUrl', - type: 'string', - }, - ], - name: 'Revoke', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'recipient', - type: 'address', - }, - ], - name: 'SetRewardRecipient', - 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: 'amount', - type: 'uint256', - }, - ], - name: 'Transfer', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'validator', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'Unbond', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Unpaused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'voter', - type: 'address', - }, - { - indexed: true, - internalType: 'uint64', - name: 'proposalId', - type: 'uint64', - }, - { - indexed: false, - internalType: 'uint32', - name: 'option', - type: 'uint32', - }, - { - indexed: false, - internalType: 'string', - name: 'metadata', - type: 'string', - }, - ], - name: 'Vote', - 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: 'amount', - type: 'uint256', - }, - ], - name: 'Withdraw', - type: 'event', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'INTERFACE_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'PAUSER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'UPGRADE_INTERFACE_VERSION', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'authorize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - internalType: 'address', - name: 'validator', - type: 'address', - }, - ], - name: 'claimRewards', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - internalType: 'address', - name: 'validator', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'delegate', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'depositor', - type: 'address', - }, - { - internalType: 'address', - name: 'recipient', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'lockup', - type: 'uint256', - }, - ], - name: 'deposit', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'granter', - type: 'address', - }, - { - internalType: 'address', - name: 'grantee', - type: 'address', - }, - { - internalType: 'string', - name: 'msgTypeUrl', - type: 'string', - }, - { - internalType: 'uint32', - name: 'expiration', - type: 'uint32', - }, - ], - name: 'grant', - outputs: [], - stateMutability: 'nonpayable', - 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: [], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'pause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'paused', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - internalType: 'address', - name: 'srcValidator', - type: 'address', - }, - { - internalType: 'address', - name: 'dstValidator', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'redelegate', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'callerConfirmation', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'granter', - type: 'address', - }, - { - internalType: 'address', - name: 'grantee', - type: 'address', - }, - { - internalType: 'string', - name: 'msgTypeUrl', - type: 'string', - }, - ], - name: 'revoke', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'revokeRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - internalType: 'address', - name: 'recipient', - type: 'address', - }, - ], - name: 'setRewardRecipient', - 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: [ - { - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - internalType: 'address', - name: 'recipient', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'transfer', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - internalType: 'address', - name: 'validator', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'unbond', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'unpause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'voter', - type: 'address', - }, - { - internalType: 'uint64', - name: 'proposalId', - type: 'uint64', - }, - { - internalType: 'uint32', - name: 'option', - type: 'uint32', - }, - { - internalType: 'string', - name: 'metadata', - type: 'string', - }, - ], - name: 'vote', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - internalType: 'address', - name: 'recipient', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'withdraw', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - ], - numDeployments: 1, - implementation: '0xD31F45Fb6c2011D41E489cb24B45810d578A3279', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/tokenAbi.ts b/packages/graphql/src/application/uc/IndexL1/abi/mainnet/tokenAbi.ts deleted file mode 100644 index d64b2f301..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/mainnet/tokenAbi.ts +++ /dev/null @@ -1,1549 +0,0 @@ -export const contract = { - address: '0x675B68AA4d9c2d3BB3F0397048e62E6B7192079c', - abi: [ - { - inputs: [], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'AccessControlBadConfirmation', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'neededRole', - type: 'bytes32', - }, - ], - name: 'AccessControlUnauthorizedAccount', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'target', - type: 'address', - }, - ], - name: 'AddressEmptyCode', - type: 'error', - }, - { - inputs: [], - name: 'CheckpointUnorderedInsertion', - type: 'error', - }, - { - inputs: [], - name: 'ECDSAInvalidSignature', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'length', - type: 'uint256', - }, - ], - name: 'ECDSAInvalidSignatureLength', - type: 'error', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 's', - type: 'bytes32', - }, - ], - name: 'ECDSAInvalidSignatureS', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'ERC1363ApproveFailed', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'receiver', - type: 'address', - }, - ], - name: 'ERC1363EOAReceiver', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - ], - name: 'ERC1363EOASpender', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'receiver', - type: 'address', - }, - ], - name: 'ERC1363InvalidReceiver', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'receiver', - type: 'address', - }, - ], - name: 'ERC1363InvalidReceiverRetVal', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - ], - name: 'ERC1363InvalidSpender', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - ], - name: 'ERC1363InvalidSpenderRetVal', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'ERC1363TransferFailed', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'from', - type: 'address', - }, - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'ERC1363TransferFromFailed', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'ERC1967InvalidImplementation', - type: 'error', - }, - { - inputs: [], - name: 'ERC1967NonPayable', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'increasedSupply', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'cap', - type: 'uint256', - }, - ], - name: 'ERC20ExceededSafeSupply', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - { - internalType: 'uint256', - name: 'allowance', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'needed', - type: 'uint256', - }, - ], - name: 'ERC20InsufficientAllowance', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - internalType: 'uint256', - name: 'balance', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'needed', - type: 'uint256', - }, - ], - name: 'ERC20InsufficientBalance', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'approver', - type: 'address', - }, - ], - name: 'ERC20InvalidApprover', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'receiver', - type: 'address', - }, - ], - name: 'ERC20InvalidReceiver', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'ERC20InvalidSender', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - ], - name: 'ERC20InvalidSpender', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'deadline', - type: 'uint256', - }, - ], - name: 'ERC2612ExpiredSignature', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'signer', - type: 'address', - }, - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - ], - name: 'ERC2612InvalidSigner', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'timepoint', - type: 'uint256', - }, - { - internalType: 'uint48', - name: 'clock', - type: 'uint48', - }, - ], - name: 'ERC5805FutureLookup', - type: 'error', - }, - { - inputs: [], - name: 'ERC6372InconsistentClock', - type: 'error', - }, - { - inputs: [], - name: 'FailedInnerCall', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'uint256', - name: 'currentNonce', - type: 'uint256', - }, - ], - name: 'InvalidAccountNonce', - type: 'error', - }, - { - inputs: [], - name: 'InvalidInitialization', - type: 'error', - }, - { - inputs: [], - name: 'NotInitializing', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint8', - name: 'bits', - type: 'uint8', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'SafeCastOverflowedUintDowncast', - type: 'error', - }, - { - inputs: [], - name: 'UUPSUnauthorizedCallContext', - type: 'error', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'slot', - type: 'bytes32', - }, - ], - name: 'UUPSUnsupportedProxiableUUID', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'expiry', - type: 'uint256', - }, - ], - name: 'VotesExpiredSignature', - 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: 'delegator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'fromDelegate', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'toDelegate', - type: 'address', - }, - ], - name: 'DelegateChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'delegate', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'previousVotes', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'newVotes', - type: 'uint256', - }, - ], - name: 'DelegateVotesChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [], - name: 'EIP712DomainChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint64', - name: 'version', - type: 'uint64', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - 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', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - inputs: [], - name: 'CLOCK_MODE', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'DOMAIN_SEPARATOR', - 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: [], - name: 'UPGRADE_INTERFACE_VERSION', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - 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: 'value', - type: 'uint256', - }, - ], - name: 'approve', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'approveAndCall', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'approveAndCall', - 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: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'burn', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'uint32', - name: 'pos', - type: 'uint32', - }, - ], - name: 'checkpoints', - outputs: [ - { - components: [ - { - internalType: 'uint48', - name: '_key', - type: 'uint48', - }, - { - internalType: 'uint208', - name: '_value', - type: 'uint208', - }, - ], - internalType: 'struct Checkpoints.Checkpoint208', - name: '', - type: 'tuple', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'clock', - outputs: [ - { - internalType: 'uint48', - name: '', - type: 'uint48', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'decimals', - outputs: [ - { - internalType: 'uint8', - name: '', - type: 'uint8', - }, - ], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegatee', - type: 'address', - }, - ], - name: 'delegate', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegatee', - type: 'address', - }, - { - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'expiry', - type: 'uint256', - }, - { - internalType: 'uint8', - name: 'v', - type: 'uint8', - }, - { - internalType: 'bytes32', - name: 'r', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 's', - type: 'bytes32', - }, - ], - name: 'delegateBySig', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'delegates', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'eip712Domain', - outputs: [ - { - internalType: 'bytes1', - name: 'fields', - type: 'bytes1', - }, - { - internalType: 'string', - name: 'name', - type: 'string', - }, - { - internalType: 'string', - name: 'version', - type: 'string', - }, - { - internalType: 'uint256', - name: 'chainId', - type: 'uint256', - }, - { - internalType: 'address', - name: 'verifyingContract', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'salt', - type: 'bytes32', - }, - { - internalType: 'uint256[]', - name: 'extensions', - type: 'uint256[]', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'timepoint', - type: 'uint256', - }, - ], - name: 'getPastTotalSupply', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'uint256', - name: 'timepoint', - type: 'uint256', - }, - ], - name: 'getPastVotes', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'getVotes', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - 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: 'string', - name: 'name', - type: 'string', - }, - { - internalType: 'string', - name: 'symbol', - type: 'string', - }, - ], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'mint', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'name', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - ], - name: 'nonces', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'numCheckpoints', - outputs: [ - { - internalType: 'uint32', - name: '', - type: 'uint32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'deadline', - type: 'uint256', - }, - { - internalType: 'uint8', - name: 'v', - type: 'uint8', - }, - { - internalType: 'bytes32', - name: 'r', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 's', - type: 'bytes32', - }, - ], - name: 'permit', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'callerConfirmation', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - 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: 'value', - type: 'uint256', - }, - ], - name: 'transfer', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'transferAndCall', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'transferAndCall', - 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: 'value', - type: 'uint256', - }, - ], - name: 'transferFrom', - 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: 'value', - type: 'uint256', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'transferFromAndCall', - 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: 'value', - type: 'uint256', - }, - ], - name: 'transferFromAndCall', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - ], - numDeployments: 1, - implementation: '0x4cED0596344b58Dd3b11FfC621DA85f7F57a5972', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelChainStateAbi.ts b/packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelChainStateAbi.ts deleted file mode 100644 index fef3f7bd9..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelChainStateAbi.ts +++ /dev/null @@ -1,577 +0,0 @@ -export const contract = { - address: '0xf38F1e65adc58fc74BaaA132f645Aa5307F2d304', - abi: [ - { - inputs: [ - { - internalType: 'uint256', - name: 'timeToFinalize', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'blocksPerCommitInterval', - type: 'uint256', - }, - { - internalType: 'uint32', - name: 'commitCooldown', - type: 'uint32', - }, - ], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'CannotRecommit', - type: 'error', - }, - { - inputs: [], - name: 'CommitCooldownTooLarge', - type: 'error', - }, - { - inputs: [], - name: 'FinalizationIsGtCooldown', - type: 'error', - }, - { - inputs: [], - name: 'TimeToFinalizeTooLarge', - type: 'error', - }, - { - inputs: [], - name: 'UnknownBlock', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'previousAdmin', - type: 'address', - }, - { - indexed: false, - internalType: 'address', - name: 'newAdmin', - type: 'address', - }, - ], - name: 'AdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'beacon', - type: 'address', - }, - ], - name: 'BeaconUpgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'commitHeight', - type: 'uint256', - }, - { - indexed: false, - internalType: 'bytes32', - name: 'blockHash', - type: 'bytes32', - }, - ], - name: 'CommitSubmitted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint8', - name: 'version', - type: 'uint8', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Paused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Unpaused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - inputs: [], - name: 'BLOCKS_PER_COMMIT_INTERVAL', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'COMMITTER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'COMMIT_COOLDOWN', - outputs: [ - { - internalType: 'uint32', - name: '', - type: 'uint32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'NUM_COMMIT_SLOTS', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'PAUSER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'TIME_TO_FINALIZE', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'commitHeight', - type: 'uint256', - }, - ], - name: 'blockHashAtCommit', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'blockHash', - type: 'bytes32', - }, - { - internalType: 'uint256', - name: 'commitHeight', - type: 'uint256', - }, - ], - name: 'commit', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'blockHash', - type: 'bytes32', - }, - { - internalType: 'uint256', - name: 'blockHeight', - type: 'uint256', - }, - ], - name: 'finalized', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - 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: [], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'pause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'paused', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - 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: 'unpause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - ], - name: 'upgradeTo', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - ], - numDeployments: 4, - implementation: '0xdCF1bdBF5341c15e9C1285202f6F6bEA70Db6172', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelERC20GatewayV4Abi.ts b/packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelERC20GatewayV4Abi.ts deleted file mode 100644 index 19995df04..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelERC20GatewayV4Abi.ts +++ /dev/null @@ -1,917 +0,0 @@ -export const contract = { - address: '0xd1d5a4379dccC46D5c8D1c6c2656ce705698e359', - abi: [ - { - inputs: [], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'BridgeFull', - type: 'error', - }, - { - inputs: [], - name: 'CallerIsNotPortal', - type: 'error', - }, - { - inputs: [], - name: 'CannotDepositZero', - type: 'error', - }, - { - inputs: [], - name: 'CannotWithdrawZero', - type: 'error', - }, - { - inputs: [], - name: 'GlobalDepositLimit', - type: 'error', - }, - { - inputs: [], - name: 'InvalidAmount', - type: 'error', - }, - { - inputs: [], - name: 'InvalidAssetIssuerID', - type: 'error', - }, - { - inputs: [], - name: 'InvalidMessageSender', - type: 'error', - }, - { - inputs: [], - name: 'InvalidSender', - type: 'error', - }, - { - inputs: [], - name: 'RateLimitExceeded', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'previousAdmin', - type: 'address', - }, - { - indexed: false, - internalType: 'address', - name: 'newAdmin', - type: 'address', - }, - ], - name: 'AdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'beacon', - type: 'address', - }, - ], - name: 'BeaconUpgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'sender', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'Deposit', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint8', - name: 'version', - type: 'uint8', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Paused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - indexed: false, - internalType: 'bool', - name: 'status', - type: 'bool', - }, - ], - name: 'RateLimitStatusUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'RateLimitUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Unpaused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'recipient', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'Withdrawal', - type: 'event', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'FUEL_ASSET_DECIMALS', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'PAUSER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'SET_RATE_LIMITER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'assetIssuerId', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - name: 'currentPeriodAmount', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - name: 'currentPeriodEnd', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'to', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'deposit', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - ], - name: 'depositLimits', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'to', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'depositWithData', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - { - internalType: 'uint256', - name: 'l2BurntAmount', - type: 'uint256', - }, - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - name: 'finalizeWithdrawal', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'fuelMessagePortal', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - 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: 'contract FuelMessagePortal', - name: 'fuelMessagePortal', - type: 'address', - }, - ], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - name: 'limitAmount', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'pause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'paused', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - name: 'rateLimitDuration', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - name: 'rateLimitStatus', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bool', - name: 'value', - type: 'bool', - }, - ], - name: 'requireWhitelist', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'rescueETH', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_token', - type: 'address', - }, - { - internalType: 'uint256', - name: '_amount', - type: 'uint256', - }, - { - internalType: 'uint256', - name: '_rateLimitDuration', - type: 'uint256', - }, - ], - name: 'resetRateLimitAmount', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'revokeRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - ], - name: 'sendMetadata', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'id', - type: 'bytes32', - }, - ], - name: 'setAssetIssuerId', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'token', - type: 'address', - }, - { - internalType: 'uint256', - name: 'limit', - type: 'uint256', - }, - ], - name: 'setGlobalDepositLimit', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes4', - name: 'interfaceId', - type: 'bytes4', - }, - ], - name: 'supportsInterface', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'tokenAddress', - type: 'address', - }, - ], - name: 'tokensDeposited', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'unpause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_token', - type: 'address', - }, - { - internalType: 'bool', - name: '_rateLimitStatus', - type: 'bool', - }, - ], - name: 'updateRateLimitStatus', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - ], - name: 'upgradeTo', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'whitelistRequired', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - ], - numDeployments: 2, - implementation: '0xEBFB69C26067777b262Ab5Da74A47e44bfc78EA4', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelMessagePortalAbi.ts b/packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelMessagePortalAbi.ts deleted file mode 100644 index 1a01ea50a..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelMessagePortalAbi.ts +++ /dev/null @@ -1,1165 +0,0 @@ -export const contract = { - address: '0x01855B78C1f8868DE70e84507ec735983bf262dA', - abi: [ - { - inputs: [ - { - internalType: 'uint256', - name: '_depositLimitGlobal', - type: 'uint256', - }, - { - internalType: 'uint256', - name: '_rateLimitDuration', - type: 'uint256', - }, - ], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'AlreadyRelayed', - type: 'error', - }, - { - inputs: [], - name: 'AmountPrecisionIncompatibility', - type: 'error', - }, - { - inputs: [], - name: 'AmountTooBig', - type: 'error', - }, - { - inputs: [], - name: 'CurrentMessageSenderNotSet', - type: 'error', - }, - { - inputs: [], - name: 'GlobalDepositLimit', - type: 'error', - }, - { - inputs: [], - name: 'InvalidBlockInHistoryProof', - type: 'error', - }, - { - inputs: [], - name: 'InvalidMessageInBlockProof', - type: 'error', - }, - { - inputs: [], - name: 'MessageBlacklisted', - type: 'error', - }, - { - inputs: [], - name: 'MessageDataTooLarge', - type: 'error', - }, - { - inputs: [], - name: 'MessageRelayFailed', - type: 'error', - }, - { - inputs: [], - name: 'NotSupported', - type: 'error', - }, - { - inputs: [], - name: 'RateLimitExceeded', - type: 'error', - }, - { - inputs: [], - name: 'ReentrancyGuardReentrantCall', - type: 'error', - }, - { - inputs: [], - name: 'UnfinalizedBlock', - type: 'error', - }, - { - inputs: [], - name: 'WithdrawalsPaused', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'previousAdmin', - type: 'address', - }, - { - indexed: false, - internalType: 'address', - name: 'newAdmin', - type: 'address', - }, - ], - name: 'AdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'beacon', - type: 'address', - }, - ], - name: 'BeaconUpgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'oldValue', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'newValue', - type: 'address', - }, - ], - name: 'FuelChainStateUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint8', - name: 'version', - type: 'uint8', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'messageId', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'sender', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'recipient', - type: 'bytes32', - }, - { - indexed: false, - internalType: 'uint64', - name: 'amount', - type: 'uint64', - }, - ], - name: 'MessageRelayed', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'sender', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'recipient', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint64', - name: 'amount', - type: 'uint64', - }, - { - indexed: false, - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'MessageSent', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Paused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'bool', - name: 'status', - type: 'bool', - }, - ], - name: 'RateLimitStatusUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'ResetRateLimit', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Unpaused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'ETH_DECIMALS', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'FUEL_BASE_ASSET_DECIMALS', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'MAX_MESSAGE_DATA_SIZE', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'PAUSER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'PRECISION', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'RATE_LIMIT_DURATION', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'SET_RATE_LIMITER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'messageId', - type: 'bytes32', - }, - ], - name: 'addMessageToBlacklist', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'currentPeriodAmount', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'currentPeriodEnd', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'recipient', - type: 'bytes32', - }, - ], - name: 'depositETH', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'depositLimitGlobal', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'fuelBaseAssetDecimals', - outputs: [ - { - internalType: 'uint8', - name: '', - type: 'uint8', - }, - ], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [], - name: 'fuelChainStateContract', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'getNextOutgoingMessageNonce', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - 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: 'bytes32', - name: 'messageId', - type: 'bytes32', - }, - ], - name: 'incomingMessageSuccessful', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'contract FuelChainState', - name: '', - type: 'address', - }, - ], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'contract FuelChainState', - name: 'fuelChainState', - type: 'address', - }, - { - internalType: 'uint256', - name: '_limitAmount', - type: 'uint256', - }, - ], - name: 'initializerV3', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'limitAmount', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - name: 'messageIsBlacklisted', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'messageSender', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'pause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'pauseWithdrawals', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'paused', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'rateLimitEnabled', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '_limitAmount', - type: 'uint256', - }, - ], - name: 'reinitializeV3', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'bytes32', - name: 'sender', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 'recipient', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 'nonce', - type: 'bytes32', - }, - { - internalType: 'uint64', - name: 'amount', - type: 'uint64', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - internalType: 'struct Message', - name: 'message', - type: 'tuple', - }, - { - components: [ - { - internalType: 'bytes32', - name: 'prevRoot', - type: 'bytes32', - }, - { - internalType: 'uint32', - name: 'height', - type: 'uint32', - }, - { - internalType: 'uint64', - name: 'timestamp', - type: 'uint64', - }, - { - internalType: 'bytes32', - name: 'applicationHash', - type: 'bytes32', - }, - ], - internalType: 'struct FuelBlockHeaderLite', - name: 'rootBlockHeader', - type: 'tuple', - }, - { - components: [ - { - internalType: 'bytes32', - name: 'prevRoot', - type: 'bytes32', - }, - { - internalType: 'uint64', - name: 'timestamp', - type: 'uint64', - }, - { - internalType: 'uint64', - name: 'daHeight', - type: 'uint64', - }, - { - internalType: 'uint32', - name: 'outputMessagesCount', - type: 'uint32', - }, - { - internalType: 'uint32', - name: 'consensusParametersVersion', - type: 'uint32', - }, - { - internalType: 'uint32', - name: 'stateTransitionBytecodeVersion', - type: 'uint32', - }, - { - internalType: 'uint32', - name: 'height', - type: 'uint32', - }, - { - internalType: 'bytes32', - name: 'txRoot', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 'outputMessagesRoot', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 'eventInboxRoot', - type: 'bytes32', - }, - { - internalType: 'uint16', - name: 'txCount', - type: 'uint16', - }, - ], - internalType: 'struct FuelBlockHeader', - name: 'blockHeader', - type: 'tuple', - }, - { - components: [ - { - internalType: 'uint256', - name: 'key', - type: 'uint256', - }, - { - internalType: 'bytes32[]', - name: 'proof', - type: 'bytes32[]', - }, - ], - internalType: 'struct MerkleProof', - name: 'blockInHistoryProof', - type: 'tuple', - }, - { - components: [ - { - internalType: 'uint256', - name: 'key', - type: 'uint256', - }, - { - internalType: 'bytes32[]', - name: 'proof', - type: 'bytes32[]', - }, - ], - internalType: 'struct MerkleProof', - name: 'messageInBlockProof', - type: 'tuple', - }, - ], - name: 'relayMessage', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'messageId', - type: 'bytes32', - }, - ], - name: 'removeMessageFromBlacklist', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '_amount', - type: 'uint256', - }, - ], - name: 'resetRateLimitAmount', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'revokeRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'recipient', - type: 'bytes32', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'sendMessage', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newFuelChainState', - type: 'address', - }, - ], - name: 'setFuelChainState', - 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: 'totalDeposited', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'unpause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'unpauseWithdrawals', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bool', - name: 'value', - type: 'bool', - }, - ], - name: 'updateRateLimitStatus', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - ], - name: 'upgradeTo', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'withdrawalsPaused', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - ], - numDeployments: 4, - implementation: '0xF8F2AEdde6AEBB164f804f78Cc95FBCCc3d642A1', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelStreamXAbi.ts b/packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelStreamXAbi.ts deleted file mode 100644 index 91f97854d..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/testnet/fuelStreamXAbi.ts +++ /dev/null @@ -1,1275 +0,0 @@ -export const contract = { - address: '0x130F143e0F6d87371ca510e11340C2F3cD407a2b', - abi: [ - { - inputs: [], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'AccessControlBadConfirmation', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'neededRole', - type: 'bytes32', - }, - ], - name: 'AccessControlUnauthorizedAccount', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'target', - type: 'address', - }, - ], - name: 'AddressEmptyCode', - type: 'error', - }, - { - inputs: [], - name: 'BridgeCommitmentNotFound', - type: 'error', - }, - { - inputs: [], - name: 'CommitmentNotFinalized', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'ERC1967InvalidImplementation', - type: 'error', - }, - { - inputs: [], - name: 'ERC1967NonPayable', - type: 'error', - }, - { - inputs: [], - name: 'EnforcedPause', - type: 'error', - }, - { - inputs: [], - name: 'ExpectedPause', - type: 'error', - }, - { - inputs: [], - name: 'FailedInnerCall', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint8', - name: 'char', - type: 'uint8', - }, - ], - name: 'InvalidCharacter', - type: 'error', - }, - { - inputs: [], - name: 'InvalidCommitmentProof', - type: 'error', - }, - { - inputs: [], - name: 'InvalidExecTxResultCode', - type: 'error', - }, - { - inputs: [], - name: 'InvalidInitialization', - type: 'error', - }, - { - inputs: [ - { - internalType: 'string', - name: 's', - type: 'string', - }, - ], - name: 'InvalidIntString', - type: 'error', - }, - { - inputs: [], - name: 'InvalidProofNonce', - type: 'error', - }, - { - inputs: [], - name: 'InvalidStringLength', - type: 'error', - }, - { - inputs: [], - name: 'InvalidToken', - type: 'error', - }, - { - inputs: [], - name: 'InvalidTxResultProof', - type: 'error', - }, - { - inputs: [ - { - internalType: 'string', - name: 's', - type: 'string', - }, - ], - name: 'InvalidUintString', - type: 'error', - }, - { - inputs: [], - name: 'LatestHeaderNotFound', - type: 'error', - }, - { - inputs: [], - name: 'Missing0xPrefix', - type: 'error', - }, - { - inputs: [], - name: 'NonceAlreadyUsed', - type: 'error', - }, - { - inputs: [], - name: 'NotInitializing', - type: 'error', - }, - { - inputs: [], - name: 'TargetBlockNotInRange', - type: 'error', - }, - { - inputs: [], - name: 'TrustedBlockMismatch', - type: 'error', - }, - { - inputs: [], - name: 'TrustedHeaderMismatch', - type: 'error', - }, - { - inputs: [], - name: 'TrustedHeaderNotFound', - type: 'error', - }, - { - inputs: [], - name: 'UUPSUnauthorizedCallContext', - type: 'error', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'slot', - type: 'bytes32', - }, - ], - name: 'UUPSUnsupportedProxiableUUID', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint256', - name: 'proofNonce', - type: 'uint256', - }, - { - indexed: true, - internalType: 'uint64', - name: 'startBlock', - type: 'uint64', - }, - { - indexed: true, - internalType: 'uint64', - name: 'endBlock', - type: 'uint64', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'bridgeCommitment', - type: 'bytes32', - }, - ], - name: 'BridgeCommitmentStored', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint64', - name: 'blockNumber', - type: 'uint64', - }, - { - indexed: false, - internalType: 'bytes32', - name: 'headerHash', - type: 'bytes32', - }, - ], - name: 'HeadUpdate', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint64', - name: 'version', - type: 'uint64', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Paused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - { - indexed: false, - internalType: 'int256', - name: 'delta', - type: 'int256', - }, - ], - name: 'SupplyDelta', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Unpaused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - { - indexed: true, - internalType: 'address', - name: 'recipient', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'WithdrawalProcessed', - type: 'event', - }, - { - inputs: [], - name: 'BRIDGE_COMMITMENT_MAX', - outputs: [ - { - internalType: 'uint64', - name: '', - type: 'uint64', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'GUARDIAN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'L2_ACCOUNT_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'L2_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'PAUSER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'UPGRADE_INTERFACE_VERSION', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'VERSION', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint64', - name: '', - type: 'uint64', - }, - ], - name: 'blockHeightToHeaderHash', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - name: 'commitmentTimestamp', - outputs: [ - { - internalType: 'uint32', - name: '', - type: 'uint32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'gateway', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'l2Account', - type: 'address', - }, - ], - name: 'grantL2AccountRole', - outputs: [], - stateMutability: 'nonpayable', - 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: [], - name: 'headerRangeFunctionId', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - components: [ - { - internalType: 'address', - name: 'vault', - type: 'address', - }, - { - internalType: 'address', - name: 'verifier', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'vKey', - type: 'bytes32', - }, - { - internalType: 'uint64', - name: 'height', - type: 'uint64', - }, - { - internalType: 'bytes32', - name: 'header', - type: 'bytes32', - }, - { - internalType: 'string', - name: 'tokenCosmosDenomination', - type: 'string', - }, - ], - internalType: 'struct FuelStreamX.InitParameters', - name: '_params', - type: 'tuple', - }, - ], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'header', - type: 'bytes32', - }, - ], - name: 'initializeTrustedHeader', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'latestBlock', - outputs: [ - { - internalType: 'uint64', - name: '', - type: 'uint64', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'nextHeaderFunctionId', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'pause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'paused', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '_proofNonce', - type: 'uint256', - }, - { - components: [ - { - internalType: 'uint256', - name: 'height', - type: 'uint256', - }, - { - internalType: 'bytes32', - name: 'resultsHash', - type: 'bytes32', - }, - ], - internalType: 'struct BridgeCommitmentLeaf', - name: 'bridgeCommitmentLeaf', - type: 'tuple', - }, - { - components: [ - { - internalType: 'bytes32[]', - name: 'sideNodes', - type: 'bytes32[]', - }, - { - internalType: 'uint256', - name: 'key', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'numLeaves', - type: 'uint256', - }, - ], - internalType: 'struct BinaryMerkleProof', - name: 'bridgeCommitmentLeafProof', - type: 'tuple', - }, - { - internalType: 'bytes', - name: 'txResultMarshalled', - type: 'bytes', - }, - { - components: [ - { - internalType: 'bytes32[]', - name: 'sideNodes', - type: 'bytes32[]', - }, - { - internalType: 'uint256', - name: 'key', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'numLeaves', - type: 'uint256', - }, - ], - internalType: 'struct BinaryMerkleProof', - name: 'txResultProof', - type: 'tuple', - }, - ], - name: 'processSequencerSupplyUpdate', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '_proofNonce', - type: 'uint256', - }, - { - components: [ - { - internalType: 'uint256', - name: 'height', - type: 'uint256', - }, - { - internalType: 'bytes32', - name: 'resultsHash', - type: 'bytes32', - }, - ], - internalType: 'struct BridgeCommitmentLeaf', - name: 'bridgeCommitmentLeaf', - type: 'tuple', - }, - { - components: [ - { - internalType: 'bytes32[]', - name: 'sideNodes', - type: 'bytes32[]', - }, - { - internalType: 'uint256', - name: 'key', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'numLeaves', - type: 'uint256', - }, - ], - internalType: 'struct BinaryMerkleProof', - name: 'bridgeCommitmentLeafProof', - type: 'tuple', - }, - { - internalType: 'bytes', - name: 'txResultMarshalled', - type: 'bytes', - }, - { - components: [ - { - internalType: 'bytes32[]', - name: 'sideNodes', - type: 'bytes32[]', - }, - { - internalType: 'uint256', - name: 'key', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'numLeaves', - type: 'uint256', - }, - ], - internalType: 'struct BinaryMerkleProof', - name: 'txResultProof', - type: 'tuple', - }, - ], - name: 'processSequencerWithdrawalMessage', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'recoveryRegistry', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'callerConfirmation', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'revokeRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'string', - name: 'denomination', - type: 'string', - }, - ], - name: 'setCosmosTokenDenomination', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newRecoveryRegistry', - type: 'address', - }, - ], - name: 'setRecoveryRegistry', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 'roleAdmin', - type: 'bytes32', - }, - ], - name: 'setRoleAdmin', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint32', - name: 'newTimeToFinalize', - type: 'uint32', - }, - ], - name: 'setTimeToFinalize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - name: 'state_bridgeCommitments', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'state_proofNonce', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes4', - name: 'interfaceId', - type: 'bytes4', - }, - ], - name: 'supportsInterface', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'timeToFinalize', - outputs: [ - { - internalType: 'uint32', - name: '', - type: 'uint32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'tokenCosmosDenominationHash', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'unpause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes', - name: 'proof', - type: 'bytes', - }, - { - internalType: 'bytes', - name: 'publicValues', - type: 'bytes', - }, - ], - name: 'updateCommitHeaderRange', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint32', - name: '_height', - type: 'uint32', - }, - { - internalType: 'bytes32', - name: '_header', - type: 'bytes32', - }, - ], - name: 'updateGenesisState', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: '_programVKey', - type: 'bytes32', - }, - ], - name: 'updateProgramVKey', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_verifier', - type: 'address', - }, - ], - name: 'updateVerifier', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - name: 'usedNonces', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'vKey', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'vault', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'verifier', - outputs: [ - { - internalType: 'contract ISP1Verifier', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - ], - numDeployments: 2, - implementation: '0x5764aA4872cb753C066ccc174c9d4F824e4ecd4c', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/abi/testnet/rewardsDistributorAbi.ts b/packages/graphql/src/application/uc/IndexL1/abi/testnet/rewardsDistributorAbi.ts deleted file mode 100644 index 07d24bd2b..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/testnet/rewardsDistributorAbi.ts +++ /dev/null @@ -1,721 +0,0 @@ -export const contract = { - address: '0x7c8deB33b992629130CE160f766881A191d874ce', - abi: [ - { - inputs: [ - { - internalType: 'address', - name: '_sequencerInterface', - type: 'address', - }, - { - internalType: 'address', - name: '_fuelToken', - type: 'address', - }, - { - internalType: 'bytes32', - name: '_l2StakingContractId', - type: 'bytes32', - }, - { - internalType: 'address', - name: '_fuelERC20Gateway', - type: 'address', - }, - ], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'AccessControlBadConfirmation', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'neededRole', - type: 'bytes32', - }, - ], - name: 'AccessControlUnauthorizedAccount', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'target', - type: 'address', - }, - ], - name: 'AddressEmptyCode', - type: 'error', - }, - { - inputs: [], - name: 'CollateralLessThanUserDeposits', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'ERC1967InvalidImplementation', - type: 'error', - }, - { - inputs: [], - name: 'ERC1967NonPayable', - type: 'error', - }, - { - inputs: [], - name: 'ExceedsLimit', - type: 'error', - }, - { - inputs: [], - name: 'FailedInnerCall', - type: 'error', - }, - { - inputs: [], - name: 'InsufficientBalance', - type: 'error', - }, - { - inputs: [], - name: 'InvalidAmount', - type: 'error', - }, - { - inputs: [], - name: 'InvalidCaller', - type: 'error', - }, - { - inputs: [], - name: 'InvalidInitialization', - type: 'error', - }, - { - inputs: [], - name: 'InvalidInputs', - type: 'error', - }, - { - inputs: [], - name: 'NoRewardsToDistribute', - type: 'error', - }, - { - inputs: [], - name: 'NotAuthorized', - type: 'error', - }, - { - inputs: [], - name: 'NotInitializing', - type: 'error', - }, - { - inputs: [], - name: 'UUPSUnauthorizedCallContext', - type: 'error', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'slot', - type: 'bytes32', - }, - ], - name: 'UUPSUnsupportedProxiableUUID', - type: 'error', - }, - { - inputs: [], - name: 'UserDepositsHigherThanCollateral', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'CollateralUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: '_foundationAddress', - type: 'address', - }, - ], - name: 'FoundationAddressUpdated', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint64', - name: 'version', - type: 'uint64', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address[]', - name: 'validators', - type: 'address[]', - }, - { - indexed: true, - internalType: 'uint256', - name: 'withdrawAmount', - type: 'uint256', - }, - ], - name: 'RewardsClaimed', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'totalRewards', - type: 'uint256', - }, - { - indexed: true, - internalType: 'uint256', - name: 'userShare', - type: 'uint256', - }, - { - indexed: true, - internalType: 'uint256', - name: 'foundationShare', - type: 'uint256', - }, - ], - name: 'RewardsDistributed', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'UserDepositsUpdated', - type: 'event', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'OPERATOR_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'ORACLE_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'UPGRADE_INTERFACE_VERSION', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address[]', - name: 'validators', - type: 'address[]', - }, - { - internalType: 'uint256', - name: 'withdrawAmount', - type: 'uint256', - }, - ], - name: 'claim', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'collateral', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'distribute', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'foundationAddress', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'fuelERC20Gateway', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'fuelToken', - outputs: [ - { - internalType: 'contract IERC1363', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - 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: [], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'l2StakingContractId', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'callerConfirmation', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'revokeRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'sequencerInterface', - outputs: [ - { - internalType: 'contract ISequencerInterface', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: '_foundationAddress', - type: 'address', - }, - ], - name: 'setFoundationAddress', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: '_l2StakingContractId', - type: 'bytes32', - }, - ], - name: 'setL2StakingContractId', - 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: [ - { - internalType: 'uint256', - name: '_collateral', - type: 'uint256', - }, - ], - name: 'updateCollateral', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: '_userDeposits', - type: 'uint256', - }, - ], - name: 'updateUserDeposits', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [], - name: 'userDeposits', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - ], - args: [ - '0x742C478a1951257E83d3aC8f3DFB3A8e6AB9a2E4', - '0xd7Fc4e8FB2c05567C313f4C9b9e07641a361a550', - '0x1fc685e1c63bbec4784079e60d4124537388f5b96773f16dfad454fae1e4f32e', - '0xa4cA04d02bfdC3A2DF56B9b6994520E69dF43F67', - ], - numDeployments: 1, - implementation: '0x920a73047c8d65db1FfB739E430e60ab6A42fd96', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/abi/testnet/sequencerProxyAbi.ts b/packages/graphql/src/application/uc/IndexL1/abi/testnet/sequencerProxyAbi.ts deleted file mode 100644 index f0cf008c7..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/testnet/sequencerProxyAbi.ts +++ /dev/null @@ -1,1049 +0,0 @@ -export const contract = { - address: '0x0E5CAcD6899a1E2a4B4E6e0c8a1eA7feAD3E25eD', - abi: [ - { - inputs: [], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'AccessControlBadConfirmation', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'neededRole', - type: 'bytes32', - }, - ], - name: 'AccessControlUnauthorizedAccount', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'target', - type: 'address', - }, - ], - name: 'AddressEmptyCode', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'ERC1967InvalidImplementation', - type: 'error', - }, - { - inputs: [], - name: 'ERC1967NonPayable', - type: 'error', - }, - { - inputs: [], - name: 'EnforcedPause', - type: 'error', - }, - { - inputs: [], - name: 'ExpectedPause', - type: 'error', - }, - { - inputs: [], - name: 'FailedInnerCall', - type: 'error', - }, - { - inputs: [], - name: 'InvalidInitialization', - type: 'error', - }, - { - inputs: [], - name: 'NotInitializing', - type: 'error', - }, - { - inputs: [], - name: 'UUPSUnauthorizedCallContext', - type: 'error', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'slot', - type: 'bytes32', - }, - ], - name: 'UUPSUnsupportedProxiableUUID', - type: 'error', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - indexed: false, - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'Authorize', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'validator', - type: 'address', - }, - ], - name: 'ClaimRewards', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'validator', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'Delegate', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'depositor', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'recipient', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'lockup', - type: 'uint256', - }, - ], - name: 'Deposit', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'granter', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'grantee', - type: 'address', - }, - { - indexed: false, - internalType: 'string', - name: 'msgTypeUrl', - type: 'string', - }, - { - indexed: false, - internalType: 'uint32', - name: 'expiration', - type: 'uint32', - }, - ], - name: 'Grant', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint64', - name: 'version', - type: 'uint64', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Paused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'srcValidator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'dstValidator', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'Redelegate', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'granter', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'grantee', - type: 'address', - }, - { - indexed: false, - internalType: 'string', - name: 'msgTypeUrl', - type: 'string', - }, - ], - name: 'Revoke', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'recipient', - type: 'address', - }, - ], - name: 'SetRewardRecipient', - 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: 'amount', - type: 'uint256', - }, - ], - name: 'Transfer', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'validator', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'Unbond', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'Unpaused', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'voter', - type: 'address', - }, - { - indexed: true, - internalType: 'uint64', - name: 'proposalId', - type: 'uint64', - }, - { - indexed: false, - internalType: 'uint32', - name: 'option', - type: 'uint32', - }, - { - indexed: false, - internalType: 'string', - name: 'metadata', - type: 'string', - }, - ], - name: 'Vote', - 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: 'amount', - type: 'uint256', - }, - ], - name: 'Withdraw', - type: 'event', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'INTERFACE_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'PAUSER_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'UPGRADE_INTERFACE_VERSION', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'authorize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - internalType: 'address', - name: 'validator', - type: 'address', - }, - ], - name: 'claimRewards', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - internalType: 'address', - name: 'validator', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'delegate', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'depositor', - type: 'address', - }, - { - internalType: 'address', - name: 'recipient', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'lockup', - type: 'uint256', - }, - ], - name: 'deposit', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'granter', - type: 'address', - }, - { - internalType: 'address', - name: 'grantee', - type: 'address', - }, - { - internalType: 'string', - name: 'msgTypeUrl', - type: 'string', - }, - { - internalType: 'uint32', - name: 'expiration', - type: 'uint32', - }, - ], - name: 'grant', - outputs: [], - stateMutability: 'nonpayable', - 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: [], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'pause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'paused', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - internalType: 'address', - name: 'srcValidator', - type: 'address', - }, - { - internalType: 'address', - name: 'dstValidator', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'redelegate', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'callerConfirmation', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'granter', - type: 'address', - }, - { - internalType: 'address', - name: 'grantee', - type: 'address', - }, - { - internalType: 'string', - name: 'msgTypeUrl', - type: 'string', - }, - ], - name: 'revoke', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'revokeRole', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - internalType: 'address', - name: 'recipient', - type: 'address', - }, - ], - name: 'setRewardRecipient', - 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: [ - { - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - internalType: 'address', - name: 'recipient', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'transfer', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegator', - type: 'address', - }, - { - internalType: 'address', - name: 'validator', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'unbond', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'unpause', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'voter', - type: 'address', - }, - { - internalType: 'uint64', - name: 'proposalId', - type: 'uint64', - }, - { - internalType: 'uint32', - name: 'option', - type: 'uint32', - }, - { - internalType: 'string', - name: 'metadata', - type: 'string', - }, - ], - name: 'vote', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - internalType: 'address', - name: 'recipient', - type: 'address', - }, - { - internalType: 'uint256', - name: 'amount', - type: 'uint256', - }, - ], - name: 'withdraw', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - ], - args: [], - numDeployments: 2, - implementation: '0x929D04D1d1105f11fcFB49012c9AAAdF25909321', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/abi/testnet/tokenAbi.ts b/packages/graphql/src/application/uc/IndexL1/abi/testnet/tokenAbi.ts deleted file mode 100644 index 3a4242bf7..000000000 --- a/packages/graphql/src/application/uc/IndexL1/abi/testnet/tokenAbi.ts +++ /dev/null @@ -1,1538 +0,0 @@ -export const contract = { - address: '0xd7Fc4e8FB2c05567C313f4C9b9e07641a361a550', - abi: [ - { - inputs: [], - stateMutability: 'nonpayable', - type: 'constructor', - }, - { - inputs: [], - name: 'AccessControlBadConfirmation', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'neededRole', - type: 'bytes32', - }, - ], - name: 'AccessControlUnauthorizedAccount', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'target', - type: 'address', - }, - ], - name: 'AddressEmptyCode', - type: 'error', - }, - { - inputs: [], - name: 'CheckpointUnorderedInsertion', - type: 'error', - }, - { - inputs: [], - name: 'ECDSAInvalidSignature', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'length', - type: 'uint256', - }, - ], - name: 'ECDSAInvalidSignatureLength', - type: 'error', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 's', - type: 'bytes32', - }, - ], - name: 'ECDSAInvalidSignatureS', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'ERC1363ApproveFailed', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'receiver', - type: 'address', - }, - ], - name: 'ERC1363EOAReceiver', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - ], - name: 'ERC1363EOASpender', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'receiver', - type: 'address', - }, - ], - name: 'ERC1363InvalidReceiver', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'receiver', - type: 'address', - }, - ], - name: 'ERC1363InvalidReceiverRetVal', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - ], - name: 'ERC1363InvalidSpender', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - ], - name: 'ERC1363InvalidSpenderRetVal', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'ERC1363TransferFailed', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'from', - type: 'address', - }, - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'ERC1363TransferFromFailed', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'ERC1967InvalidImplementation', - type: 'error', - }, - { - inputs: [], - name: 'ERC1967NonPayable', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'increasedSupply', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'cap', - type: 'uint256', - }, - ], - name: 'ERC20ExceededSafeSupply', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - { - internalType: 'uint256', - name: 'allowance', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'needed', - type: 'uint256', - }, - ], - name: 'ERC20InsufficientAllowance', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'sender', - type: 'address', - }, - { - internalType: 'uint256', - name: 'balance', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'needed', - type: 'uint256', - }, - ], - name: 'ERC20InsufficientBalance', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'approver', - type: 'address', - }, - ], - name: 'ERC20InvalidApprover', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'receiver', - type: 'address', - }, - ], - name: 'ERC20InvalidReceiver', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'ERC20InvalidSender', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - ], - name: 'ERC20InvalidSpender', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'deadline', - type: 'uint256', - }, - ], - name: 'ERC2612ExpiredSignature', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'signer', - type: 'address', - }, - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - ], - name: 'ERC2612InvalidSigner', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'timepoint', - type: 'uint256', - }, - { - internalType: 'uint48', - name: 'clock', - type: 'uint48', - }, - ], - name: 'ERC5805FutureLookup', - type: 'error', - }, - { - inputs: [], - name: 'ERC6372InconsistentClock', - type: 'error', - }, - { - inputs: [], - name: 'FailedInnerCall', - type: 'error', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'uint256', - name: 'currentNonce', - type: 'uint256', - }, - ], - name: 'InvalidAccountNonce', - type: 'error', - }, - { - inputs: [], - name: 'InvalidInitialization', - type: 'error', - }, - { - inputs: [], - name: 'NotInitializing', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint8', - name: 'bits', - type: 'uint8', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'SafeCastOverflowedUintDowncast', - type: 'error', - }, - { - inputs: [], - name: 'UUPSUnauthorizedCallContext', - type: 'error', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'slot', - type: 'bytes32', - }, - ], - name: 'UUPSUnsupportedProxiableUUID', - type: 'error', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'expiry', - type: 'uint256', - }, - ], - name: 'VotesExpiredSignature', - 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: 'delegator', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'fromDelegate', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'toDelegate', - type: 'address', - }, - ], - name: 'DelegateChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'delegate', - type: 'address', - }, - { - indexed: false, - internalType: 'uint256', - name: 'previousVotes', - type: 'uint256', - }, - { - indexed: false, - internalType: 'uint256', - name: 'newVotes', - type: 'uint256', - }, - ], - name: 'DelegateVotesChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [], - name: 'EIP712DomainChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: 'uint64', - name: 'version', - type: 'uint64', - }, - ], - name: 'Initialized', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'previousAdminRole', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'bytes32', - name: 'newAdminRole', - type: 'bytes32', - }, - ], - name: 'RoleAdminChanged', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleGranted', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - indexed: true, - internalType: 'address', - name: 'account', - type: 'address', - }, - { - indexed: true, - internalType: 'address', - name: 'sender', - type: 'address', - }, - ], - name: 'RoleRevoked', - 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', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - internalType: 'address', - name: 'implementation', - type: 'address', - }, - ], - name: 'Upgraded', - type: 'event', - }, - { - inputs: [], - name: 'CLOCK_MODE', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'DEFAULT_ADMIN_ROLE', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'DOMAIN_SEPARATOR', - 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: [], - name: 'UPGRADE_INTERFACE_VERSION', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - 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: 'value', - type: 'uint256', - }, - ], - name: 'approve', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'approveAndCall', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'approveAndCall', - 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: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'burn', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'uint32', - name: 'pos', - type: 'uint32', - }, - ], - name: 'checkpoints', - outputs: [ - { - components: [ - { - internalType: 'uint48', - name: '_key', - type: 'uint48', - }, - { - internalType: 'uint208', - name: '_value', - type: 'uint208', - }, - ], - internalType: 'struct Checkpoints.Checkpoint208', - name: '', - type: 'tuple', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'clock', - outputs: [ - { - internalType: 'uint48', - name: '', - type: 'uint48', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'decimals', - outputs: [ - { - internalType: 'uint8', - name: '', - type: 'uint8', - }, - ], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegatee', - type: 'address', - }, - ], - name: 'delegate', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'delegatee', - type: 'address', - }, - { - internalType: 'uint256', - name: 'nonce', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'expiry', - type: 'uint256', - }, - { - internalType: 'uint8', - name: 'v', - type: 'uint8', - }, - { - internalType: 'bytes32', - name: 'r', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 's', - type: 'bytes32', - }, - ], - name: 'delegateBySig', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'delegates', - outputs: [ - { - internalType: 'address', - name: '', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'eip712Domain', - outputs: [ - { - internalType: 'bytes1', - name: 'fields', - type: 'bytes1', - }, - { - internalType: 'string', - name: 'name', - type: 'string', - }, - { - internalType: 'string', - name: 'version', - type: 'string', - }, - { - internalType: 'uint256', - name: 'chainId', - type: 'uint256', - }, - { - internalType: 'address', - name: 'verifyingContract', - type: 'address', - }, - { - internalType: 'bytes32', - name: 'salt', - type: 'bytes32', - }, - { - internalType: 'uint256[]', - name: 'extensions', - type: 'uint256[]', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'uint256', - name: 'timepoint', - type: 'uint256', - }, - ], - name: 'getPastTotalSupply', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - { - internalType: 'uint256', - name: 'timepoint', - type: 'uint256', - }, - ], - name: 'getPastVotes', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - ], - name: 'getRoleAdmin', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'getVotes', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - 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: [], - name: 'initialize', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'mint', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'name', - outputs: [ - { - internalType: 'string', - name: '', - type: 'string', - }, - ], - stateMutability: 'pure', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - ], - name: 'nonces', - outputs: [ - { - internalType: 'uint256', - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'account', - type: 'address', - }, - ], - name: 'numCheckpoints', - outputs: [ - { - internalType: 'uint32', - name: '', - type: 'uint32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'owner', - type: 'address', - }, - { - internalType: 'address', - name: 'spender', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - { - internalType: 'uint256', - name: 'deadline', - type: 'uint256', - }, - { - internalType: 'uint8', - name: 'v', - type: 'uint8', - }, - { - internalType: 'bytes32', - name: 'r', - type: 'bytes32', - }, - { - internalType: 'bytes32', - name: 's', - type: 'bytes32', - }, - ], - name: 'permit', - outputs: [], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'proxiableUUID', - outputs: [ - { - internalType: 'bytes32', - name: '', - type: 'bytes32', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - internalType: 'bytes32', - name: 'role', - type: 'bytes32', - }, - { - internalType: 'address', - name: 'callerConfirmation', - type: 'address', - }, - ], - name: 'renounceRole', - outputs: [], - stateMutability: 'nonpayable', - 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: 'pure', - 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: 'value', - type: 'uint256', - }, - ], - name: 'transfer', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - ], - name: 'transferAndCall', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'to', - type: 'address', - }, - { - internalType: 'uint256', - name: 'value', - type: 'uint256', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'transferAndCall', - 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: 'value', - type: 'uint256', - }, - ], - name: 'transferFrom', - 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: 'value', - type: 'uint256', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'transferFromAndCall', - 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: 'value', - type: 'uint256', - }, - ], - name: 'transferFromAndCall', - outputs: [ - { - internalType: 'bool', - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - internalType: 'address', - name: 'newImplementation', - type: 'address', - }, - { - internalType: 'bytes', - name: 'data', - type: 'bytes', - }, - ], - name: 'upgradeToAndCall', - outputs: [], - stateMutability: 'payable', - type: 'function', - }, - ], - numDeployments: 2, - implementation: '0x3F4B9C3b06DF745c904DA02f93B459b2E9AC536c', -}; diff --git a/packages/graphql/src/application/uc/IndexL1/createL1Provider.ts b/packages/graphql/src/application/uc/IndexL1/createL1Provider.ts deleted file mode 100644 index 941a41572..000000000 --- a/packages/graphql/src/application/uc/IndexL1/createL1Provider.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { ethers } from 'ethers'; -import { env } from '~/config'; - -export function createL1Provider(): ethers.JsonRpcProvider { - const network = env.get('FUEL_CHAIN') || ''; - const base = network === 'mainnet' ? 'mainnet' : 'sepolia'; - return new ethers.JsonRpcProvider( - `https://eth-${base}.g.alchemy.com/v2/${env.get('ALCHEMY_API_KEY')}`, - ); -} diff --git a/packages/graphql/src/application/uc/IndexReceipt.ts b/packages/graphql/src/application/uc/IndexReceipt.ts deleted file mode 100644 index ef333af88..000000000 --- a/packages/graphql/src/application/uc/IndexReceipt.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { logger } from '~/core/Logger'; -import ReceiptsParser from '~/domain/Transaction/ReceiptsParser'; -import type { GQLReceipt } from '~/graphql/generated/sdk'; -import type Transaction from '~/infra/dao/Transaction'; -import { DatabaseConnection } from '~/infra/database/DatabaseConnection'; - -/** Parsed receipt from ReceiptsParser with indent metadata */ -interface ParsedReceipt { - indent: number; - arrow: string; - type: string; - data: GQLReceipt; -} - -// PostgreSQL parameter limits -// Each receipt has 32 params, limit ~65k params → ~2000 receipts per batch -const PARAMS_PER_RECEIPT = 32; -const MAX_PARAMS = 32000; -const MAX_RECEIPTS_PER_BATCH = Math.floor(MAX_PARAMS / PARAMS_PER_RECEIPT); - -export default class IndexReceipts { - async execute(transaction: Transaction) { - const connection = DatabaseConnection.getInstance(); - const parser = new ReceiptsParser(); - const receipts = parser.parse(transaction.data.status.receipts); - - // Only persist MESSAGE_OUT receipts — the only type read by the API (BridgeDAO). - // All other receipt types are stored in transactions.data JSONB and never queried - // from the receipts table, saving ~99.99% of storage. - const messageOutReceipts = receipts.filter( - (r) => r.data.receiptType === 'MESSAGE_OUT', - ); - - if (messageOutReceipts.length === 0) return; - - logger.debug( - 'IndexReceipts', - `Inserting ${messageOutReceipts.length} MESSAGE_OUT receipts for tx ${transaction.transactionHash}`, - ); - - for ( - let i = 0; - i < messageOutReceipts.length; - i += MAX_RECEIPTS_PER_BATCH - ) { - const batch = messageOutReceipts.slice(i, i + MAX_RECEIPTS_PER_BATCH); - await this.insertReceiptsBatch(connection, transaction, batch); - } - } - - private async insertReceiptsBatch( - connection: DatabaseConnection, - transaction: Transaction, - receipts: ParsedReceipt[], - ): Promise { - // Build placeholders using base offset pattern - const placeholders = receipts - .map((_, idx) => { - const base = idx * PARAMS_PER_RECEIPT; - const params = Array.from( - { length: PARAMS_PER_RECEIPT }, - (_, i) => `$${base + i + 1}`, - ); - return `(${params.join(', ')})`; - }) - .join(', '); - - // Flatten all values - const values: (string | number | null | undefined)[] = []; - for (const receipt of receipts) { - values.push( - transaction.blockId, - transaction.id, - transaction.transactionHash, - receipt.indent, - receipt.data.amount, - receipt.data.assetId, - receipt.data.contractId, - receipt.data.data, - receipt.data.digest, - receipt.data.gas, - receipt.data.gasUsed, - receipt.data.id, - receipt.data.is, - receipt.data.len, - receipt.data.nonce, - receipt.data.param1, - receipt.data.param2, - receipt.data.pc, - receipt.data.ptr, - receipt.data.ra, - receipt.data.rb, - receipt.data.rc, - receipt.data.rd, - receipt.data.reason, - receipt.data.receiptType, - receipt.data.recipient, - receipt.data.result, - receipt.data.sender, - receipt.data.subId, - receipt.data.to, - receipt.data.toAddress, - receipt.data.val, - ); - } - - await connection.query( - `INSERT INTO indexer.receipts ( - block_id, transaction_id, tx_hash, indent, - receipt_amount, receipt_asset_id, receipt_contract_id, receipt_data, - receipt_digest, receipt_gas, receipt_gas_used, receipt_id, - receipt_is, receipt_len, receipt_nonce, receipt_param1, - receipt_param2, receipt_pc, receipt_ptr, receipt_ra, - receipt_rb, receipt_rc, receipt_rd, receipt_reason, - receipt_type, receipt_recipient, receipt_result, receipt_sender, - receipt_sub_id, receipt_to, receipt_to_address, receipt_val - ) VALUES ${placeholders} - ON CONFLICT DO NOTHING`, - values, - ); - } -} diff --git a/packages/graphql/src/application/uc/NewAddBlockRange.ts b/packages/graphql/src/application/uc/NewAddBlockRange.ts deleted file mode 100644 index 87fa21da5..000000000 --- a/packages/graphql/src/application/uc/NewAddBlockRange.ts +++ /dev/null @@ -1,470 +0,0 @@ -import { - FUEL_ASSET_ID, - SCRIPT_DATA_CLAIM_REWARDS, - SCRIPT_DATA_DEPOSIT, - SCRIPT_DATA_WITHDRAW, - STAKING_CONTRACT, - TREASURY_ADDRESSES, -} from '~/constants/staking'; -import { logger } from '~/core/Logger'; -import { client } from '~/graphql/GraphQLSDK'; -import type { - GQLBlock, - GQLContractCreated, - GQLInput, - GQLInputCoin, - GQLInputMessage, - GQLOutput, - GQLTransaction, -} from '~/graphql/generated/sdk'; -import Block from '~/infra/dao/Block'; -import Transaction from '~/infra/dao/Transaction'; -import { DatabaseConnection } from '~/infra/database/DatabaseConnection'; -import IndexAsset from './IndexAsset/IndexAsset'; -import IndexReceipts from './IndexReceipt'; - -const MAX_PG_PARAMS = 30000; - -function bulkPlaceholders(rows: number, cols: number): string { - return Array.from( - { length: rows }, - (_, i) => - `(${Array.from({ length: cols }, (_, j) => `$${i * cols + j + 1}`).join(', ')})`, - ).join(', '); -} - -function buildBulkInserts( - statement: string, - rows: any[][], - cols: number, -): { statement: string; params: any }[] { - if (rows.length === 0) return []; - const maxRowsPerBatch = Math.floor(MAX_PG_PARAMS / cols); - const queries: { statement: string; params: any }[] = []; - for (let i = 0; i < rows.length; i += maxRowsPerBatch) { - const batch = rows.slice(i, i + maxRowsPerBatch); - queries.push({ - statement: `${statement} ${bulkPlaceholders(batch.length, cols)} on conflict do nothing`, - params: batch.flat(), - }); - } - return queries; -} - -export default class NewAddBlockRange { - private indexAsset = new IndexAsset(); - private indexReceipts = new IndexReceipts(); - - async execute(input: Input) { - const { from, to } = input; - logger.debug('Consumer', `Syncing blocks: #${from} - #${to}`); - const blocksData = await this.getBlocks(from, to); - await this.processBlocks(blocksData, from, to); - } - - async processBlocks( - blocksData: GQLBlock[], - from: number, - to: number, - ): Promise { - const { indexAsset, indexReceipts } = this; - - if (blocksData.length === 0) { - logger.debug('Consumer', `No blocks to sync: #${from} - #${to}`); - return null; - } - const start = performance.now(); - const connection = DatabaseConnection.getInstance(); - - const allBlockIds = blocksData.map((b) => Number(b.header.height)); - const existingRows = await connection.query( - 'SELECT _id FROM indexer.blocks WHERE _id = ANY($1)', - [allBlockIds], - ); - const existingIds = new Set((existingRows as any[]).map((r) => r._id)); - - let highestSeen: number | null = null; - - for (const blockData of blocksData) { - const block = new Block({ data: blockData }); - highestSeen = block.id; - - if (existingIds.has(block.id)) continue; - - const txRows: any[][] = []; - const accountRows: any[][] = []; - const inputRows: any[][] = []; - const predicateRows: any[][] = []; - const otherQueries: { statement: string; params: any }[] = []; - - for (const [index, transactionData] of blockData.transactions.entries()) { - const transaction = new Transaction( - transactionData, - index, - block.id, - block.timestamp, - ); - txRows.push([ - transaction.id, - transaction.transactionHash, - transaction.timestamp, - transaction.data, - transaction.blockId, - ]); - if (transaction.data?.status) { - try { - await indexReceipts.execute(transaction); - } catch (e: any) { - logger.error('Consumer', 'Error indexing receipts', e); - } - } - const accounts = this.getAccounts(transactionData); - for (const accountHash of accounts) { - accountRows.push([ - transaction.id, - transaction.blockId, - transaction.transactionHash, - accountHash, - ]); - } - if (transaction.data?.status?.receipts) { - try { - await indexAsset.execute(transaction); - } catch (e: any) { - logger.error('Consumer', 'Error fetching assets', e); - } - } - if (transactionData.inputs) { - for (const inputData of transactionData.inputs) { - const nonce = (inputData as any).nonce ?? null; - inputRows.push([transaction.id, nonce]); - const predicate = this.getPredicate(inputData); - if (predicate) { - predicateRows.push([predicate.address, predicate.bytecode]); - } - } - } - if (transactionData.outputs) { - for (const outputData of transactionData.outputs) { - if ( - (outputData.__typename === 'CoinOutput' || - outputData.__typename === 'ChangeOutput' || - outputData.__typename === 'VariableOutput') && - outputData.assetId && - outputData.to && - outputData.amount === '1' - ) { - otherQueries.push({ - statement: `update indexer.assets_contracts set owner = $1 where asset_id = $2 and decimals = 0 and total_supply = '1'`, - params: [outputData.to, outputData.assetId], - }); - } - } - const contractIds = this.getContractIds(transactionData.outputs); - for (const contractId of contractIds) { - try { - logger.debug('Consumer', `Fetching contract: ${contractId}`); - const contract = (await client.sdk.contract({ id: contractId })) - .data.contract; - if (contract) { - logger.debug( - 'Consumer', - `Contract fetched successfully: ${contractId}`, - ); - otherQueries.push({ - statement: - 'insert into indexer.contracts (contract_hash, data) values ($1, $2) on conflict (contract_hash) do update set data = excluded.data', - params: [contract.id, contract], - }); - } else { - logger.error('Consumer', `Contract not found: ${contractId}`); - } - } catch (e: any) { - logger.error( - 'Consumer', - `Error fetching contract ${contractId}: ${e.message}`, - ); - } - } - } - const stakingQueries = this.getStakingAggQueries( - transactionData, - block.timestamp, - ); - otherQueries.push(...stakingQueries); - } - - const queries: { statement: string; params: any }[] = []; - - queries.push({ - statement: - 'insert into indexer.blocks (_id, id, timestamp, data, gas_used, total_fee, producer, transactions_count, da_height) values ($1, $2, $3, $4, $5, $6, $7, $8, $9) on conflict do nothing', - params: [ - block.id, - block.blockHash, - block.timestamp, - block.data, - block.totalGasUsed, - block.totalFee, - block.producer, - block.transactions.length, - block.data.header.daHeight, - ], - }); - - queries.push( - ...buildBulkInserts( - 'insert into indexer.transactions (_id, tx_hash, timestamp, data, block_id) values', - txRows, - 5, - ), - ...buildBulkInserts( - 'insert into indexer.transactions_accounts (_id, block_id, tx_hash, account_hash) values', - accountRows, - 4, - ), - ...buildBulkInserts( - 'insert into indexer.inputs (transaction_id, nonce) values', - inputRows, - 2, - ), - ...buildBulkInserts( - 'insert into indexer.predicates (address, bytecode) values', - predicateRows, - 2, - ), - ); - - queries.push(...otherQueries); - - queries.push({ - statement: ` - INSERT INTO indexer.hourly_statistics_agg (hour, total_fee, total_gas_used) - VALUES (date_trunc('hour', $1::timestamptz), $2, $3) - ON CONFLICT (hour) DO UPDATE - SET total_fee = hourly_statistics_agg.total_fee + excluded.total_fee, - total_gas_used = hourly_statistics_agg.total_gas_used + excluded.total_gas_used - `, - params: [ - block.timestamp, - block.totalFee ?? '0', - block.totalGasUsed ?? 0, - ], - }); - logger.debug('Consumer', `Persisting block: ${block.id}`); - await connection.executeTransaction(queries); - logger.debug('Consumer', `Persisted block: ${block.id}`); - } - const end = performance.now(); - const secs = Number.parseInt(`${(end - start) / 1000}`); - logger.debug('Consumer', `Synced blocks: #${from} - #${to} (${secs}s)`); - return highestSeen; - } - - async getBlocks(from: number, to: number): Promise { - let size = Math.max(to - from, 1); - size = from === 0 ? size + 1 : size; - const after = Math.max(to - size, 0); - const first = size; - const params = { - first: first < 0 ? -first : first, - ...(after ? { after: String(after) } : null), - }; - logger.debug('Consumer', `Fetching blocks: #${from} - #${to}`); - const { data } = await client.sdk.blocks(params); - // checking transactions integrity - for (const block of data.blocks.nodes) { - for (const transaction of block.transactions) { - // Hydrate block on tx so transaction on database keeps blocks in the database - if (!transaction.status) { - logger.warn( - 'Consumer', - `Transaction without status: ${transaction.id} in block #${block.header.height}`, - ); - } else if ( - ['FailureStatus', 'SuccessStatus'].includes( - transaction.status.__typename, - ) - ) { - (transaction.status as any).block = { - ...block, - transactions: [], - transactionIds: [], - }; - } - } - // Hydrate block on transaction so transaction on database keeps blocks in the database - (block as any).transactionIds = block.transactions.map( - (transaction) => transaction.id, - ); - } - logger.debug('Consumer', `Blocks fetched: #${from} - #${to}`); - return data.blocks.nodes as GQLBlock[]; - } - - getContractIds(outputs: GQLOutput[]) { - return ( - outputs.filter( - (output: GQLOutput) => - output.__typename === 'ContractCreated' && output.contract, - ) as GQLContractCreated[] - ).map((i) => i.contract); - } - - getPredicate(input: GQLInput) { - if (!['InputCoin', 'InputMessage'].includes(input.__typename)) return; - const bytecode = (input as GQLInputCoin | GQLInputMessage).predicate; - if (bytecode === '0x') return; - let address = ''; - if (input.__typename === 'InputCoin') address = input.owner; - if (input.__typename === 'InputMessage') address = input.sender; - return { bytecode, address }; - } - - getStakingAggQueries( - transactionData: GQLTransaction, - timestamp: string, - ): { statement: string; params: any }[] { - const queries: { statement: string; params: any }[] = []; - const day = new Date(timestamp).toISOString().split('T')[0]; - const scriptData = (transactionData as any).scriptData as - | string - | undefined; - const receipts = ((transactionData as any).status?.receipts || []) as any[]; - - // Detect L2 staking deposits - if (scriptData?.includes(SCRIPT_DATA_DEPOSIT)) { - for (const r of receipts) { - if ( - r.receiptType === 'CALL' && - r.to === STAKING_CONTRACT && - BigInt(r.amount || '0') > 0n - ) { - const amount = r.amount.toString(); - queries.push({ - statement: - 'INSERT INTO indexer.daily_staked_agg (day, daily_staked) VALUES ($1, $2) ON CONFLICT (day) DO UPDATE SET daily_staked = indexer.daily_staked_agg.daily_staked + $2', - params: [day, amount], - }); - queries.push({ - statement: - 'INSERT INTO indexer.total_staking_agg (day, l1_staked, l2_staked) VALUES ($1, 0, $2) ON CONFLICT (day) DO UPDATE SET l2_staked = indexer.total_staking_agg.l2_staked + $2', - params: [day, amount], - }); - } - } - } - - // Detect L2 unbonding - if (scriptData?.includes(SCRIPT_DATA_WITHDRAW)) { - for (const r of receipts) { - if ( - r.receiptType === 'TRANSFER_OUT' && - r.assetId === FUEL_ASSET_ID && - BigInt(r.amount || '0') > 0n - ) { - const amount = r.amount.toString(); - queries.push({ - statement: - 'INSERT INTO indexer.daily_unbond_agg (day, daily_unbond) VALUES ($1, $2) ON CONFLICT (day) DO UPDATE SET daily_unbond = indexer.daily_unbond_agg.daily_unbond + $2', - params: [day, amount], - }); - } - } - } - - // Detect L2 claim rewards - if (scriptData?.includes(SCRIPT_DATA_CLAIM_REWARDS)) { - for (const r of receipts) { - if ( - r.receiptType === 'TRANSFER_OUT' && - r.assetId === FUEL_ASSET_ID && - BigInt(r.amount || '0') > 0n - ) { - const amount = r.amount.toString(); - queries.push({ - statement: - 'INSERT INTO indexer.daily_claims_agg (day, daily_claims) VALUES ($1, $2) ON CONFLICT (day) DO UPDATE SET daily_claims = indexer.daily_claims_agg.daily_claims + $2', - params: [day, amount], - }); - } - } - } - - // Detect inflows/outflows — match original MV logic which checks - // transactions_accounts (includes both input owners and output recipients) - if (transactionData.outputs) { - const accounts = this.getAccounts(transactionData); - const hasTreasuryAccount = accounts.some((a) => - TREASURY_ADDRESSES.includes(a), - ); - if (hasTreasuryAccount) { - for (const output of transactionData.outputs) { - if ( - output.__typename === 'CoinOutput' && - (output as any).assetId === FUEL_ASSET_ID - ) { - const to = (output as any).to; - const amount = (output as any).amount?.toString(); - if (!amount) continue; - if (!TREASURY_ADDRESSES.includes(to)) { - queries.push({ - statement: - 'INSERT INTO indexer.daily_inflows_agg (day, amount) VALUES ($1, $2) ON CONFLICT (day) DO UPDATE SET amount = indexer.daily_inflows_agg.amount + $2', - params: [day, amount], - }); - } else { - queries.push({ - statement: - 'INSERT INTO indexer.daily_outflows_agg (day, amount) VALUES ($1, $2) ON CONFLICT (day) DO UPDATE SET amount = indexer.daily_outflows_agg.amount + $2', - params: [day, amount], - }); - } - } - } - } - } - - return queries; - } - - getAccounts(transaction: GQLTransaction) { - const accounts = []; - if (transaction.inputs) { - for (const input of transaction.inputs) { - if (input.__typename === 'InputCoin') { - accounts.push(input.owner); - } - if (input.__typename === 'InputMessage') { - accounts.push(input.recipient); - accounts.push(input.sender); - } - if (input.__typename === 'InputContract') { - accounts.push(input.contractId); - } - } - } - if (transaction.outputs) { - for (const output of transaction.outputs) { - if (output.__typename === 'ChangeOutput') { - accounts.push(output.to); - } - if (output.__typename === 'CoinOutput') { - accounts.push(output.to); - } - if (output.__typename === 'ContractCreated') { - accounts.push(output.contract); - } - if (output.__typename === 'VariableOutput') { - accounts.push(output.to); - } - } - } - return accounts; - } -} - -type Input = { - from: number; - to: number; -}; diff --git a/packages/graphql/src/application/uc/RunDatabaseJobs.ts b/packages/graphql/src/application/uc/RunDatabaseJobs.ts deleted file mode 100644 index aac8929e5..000000000 --- a/packages/graphql/src/application/uc/RunDatabaseJobs.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { setTimeout } from 'node:timers/promises'; -import { logger } from '~/core/Logger'; -import { DatabaseConnection } from '~/infra/database/DatabaseConnection'; - -const POLL_INTERVAL_MS = 5000; -const DEFAULT_STATEMENT_TIMEOUT_MS = 30 * 60 * 1000; // 30 minutes -const LOCK_TIMEOUT_MS = 10 * 1000; // 10 seconds — fail fast if lock contention - -export default class RunDatabaseJobs { - async execute() { - const connection = DatabaseConnection.getInstance(); - while (true) { - logger.debug('Database Jobs', 'Fetching jobs'); - await setTimeout(POLL_INTERVAL_MS); - const jobs = await connection.query( - 'select * from indexer.database_jobs where status = $1', - ['pending'], - ); - if (jobs.length === 0) continue; - for (const job of jobs) { - if (job.last_run) { - const now = new Date(); - const diff = (now.getTime() - job.last_run.getTime()) / 1000; - if (diff < job.interval_seconds) continue; - } - logger.debug('Database Jobs', 'Running query', job.query); - const startTime = performance.now(); - let status = 'done'; - let errorMessage = ''; - try { - await connection.queryWithTimeout( - job.query, - [], - DEFAULT_STATEMENT_TIMEOUT_MS, - LOCK_TIMEOUT_MS, - ); - if (job.recurrent) { - status = 'pending'; - } - const elapsed = ((performance.now() - startTime) / 1000).toFixed(1); - logger.debug('Database Jobs', `Completed in ${elapsed}s`, job.query); - } catch (e: any) { - errorMessage = e.message; - status = job.recurrent ? 'pending' : 'error'; - const elapsed = ((performance.now() - startTime) / 1000).toFixed(1); - logger.debug( - 'Database Jobs', - `Failed after ${elapsed}s: ${errorMessage}`, - job.query, - ); - } - await connection.query( - 'update indexer.database_jobs set status = $1, last_run = now(), error_message = $2 where _id = $3', - [status, errorMessage, job._id], - ); - } - } - } -} diff --git a/packages/graphql/src/assets.ts b/packages/graphql/src/assets.ts deleted file mode 100644 index 792c29f24..000000000 --- a/packages/graphql/src/assets.ts +++ /dev/null @@ -1,15 +0,0 @@ -import IndexAssetsRate from './application/uc/IndexAsset/IndexAssetsRate'; -import { logger } from './core/Logger'; -import Timer from './infra/timer/Timer'; - -async function main() { - logger.debug('Timer', 'Starting timer services'); - const indexAssetsRate = new IndexAssetsRate(); - Timer.register(300000, () => indexAssetsRate.execute()); -} - -main().catch(async (error: any) => { - logger.error('Syncer', 'Uncaught error', error); - logger.error('Timer', 'Process exit'); - process.exit(1); -}); diff --git a/packages/graphql/src/balance.ts b/packages/graphql/src/balance.ts deleted file mode 100644 index f1735a85b..000000000 --- a/packages/graphql/src/balance.ts +++ /dev/null @@ -1,15 +0,0 @@ -import IndexBalance from './application/uc/IndexBalance'; -import { logger } from './core/Logger'; -import Timer from './infra/timer/Timer'; - -async function main() { - logger.debug('Balance', 'Starting balance services'); - const indexBalance = new IndexBalance(); - Timer.register(1000, indexBalance.execute); -} - -main().catch(async (error: any) => { - logger.error('Balance', 'Uncaught error', error); - logger.error('Balance', 'Process exit'); - process.exit(1); -}); diff --git a/packages/graphql/src/config.ts b/packages/graphql/src/config.ts index 4af558e41..2304aec07 100644 --- a/packages/graphql/src/config.ts +++ b/packages/graphql/src/config.ts @@ -14,36 +14,11 @@ const falsy = zod.coerce const schema = zod.object({ DEBUG: falsy.optional(), FUEL_PROVIDER: zod.string(), - SERVER_PORT: zod.string(), - SERVER_API_KEY: zod.string().optional().nullable(), - DB_HOST: zod.string().optional(), - DB_PORT: zod.string().optional(), - DB_USER: zod.string().optional(), - DB_PASS: zod.string().optional(), - DB_NAME: zod.string().optional(), - DB_HOST_REPLICA: zod.string().optional(), - DB_PORT_REPLICA: zod.string().optional(), - DB_USER_REPLICA: zod.string().optional(), - DB_PASS_REPLICA: zod.string().optional(), - DB_NAME_REPLICA: zod.string().optional(), - SSL: falsy.optional(), - COINGECKO_API_KEY: zod.string().optional(), - ALCHEMY_API_KEY: zod.string().optional(), FUEL_CHAIN: zod.string().optional(), }); export const env = new Env(schema, { DEBUG: true, FUEL_PROVIDER: 'http://localhost:4000/v1/graphql', - SERVER_PORT: '3002', - SERVER_API_KEY: 'secret', - DB_HOST: 'localhost', - DB_PORT: '5435', - DB_USER: 'postgres', - DB_PASS: 'postgres', - DB_NAME: 'postgres', - SSL: false, - COINGECKO_API_KEY: '', - ALCHEMY_API_KEY: '', FUEL_CHAIN: '', }); diff --git a/packages/graphql/src/constants/staking.ts b/packages/graphql/src/constants/staking.ts deleted file mode 100644 index 43241f5c0..000000000 --- a/packages/graphql/src/constants/staking.ts +++ /dev/null @@ -1,22 +0,0 @@ -// Staking contract and asset constants used for incremental aggregation. -// These match the hardcoded values in migration 019 MV definitions. - -export const STAKING_CONTRACT = - '0x095faac82412324c60fdf6934405b5df9de49982284779536218d16d5ee3dc4c'; - -export const FUEL_ASSET_ID = - '0x1d5d97005e41cae2187a895fd8eab0506111e0e2f3331cd3912c15c24e3c1d82'; - -export const TREASURY_ADDRESSES = [ - '0xdb491b442f68ebaa785f077805158ebfddeede7063f16d5a26e1073ff6987601', - '0xafdda1cd084ed0f56d35f570b2e9d34e7c7380191058e2a2fb16e0c58cbbc7c2', -]; - -// Hex-encoded scriptData substrings that identify staking operations -export const SCRIPT_DATA_DEPOSIT = '76465706f736974'; // "deposit" -export const SCRIPT_DATA_WITHDRAW = '87769746864726177'; // "withdraw" -export const SCRIPT_DATA_CLAIM_REWARDS = 'd636c61696d5f72657761726473'; // "claim_rewards" - -// Cosmos excluded delegator (internal/system delegator) -export const COSMOS_EXCLUDED_DELEGATOR = - '0x85308a35b3ad660213ea91a5d37bbf9620708ecc'; diff --git a/packages/graphql/src/core/Resolver.ts b/packages/graphql/src/core/Resolver.ts deleted file mode 100644 index a4dcd7c6c..000000000 --- a/packages/graphql/src/core/Resolver.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { IResolvers } from '@graphql-tools/utils'; -import type { GraphQLContext } from '~/graphql/GraphQLContext'; - -type Resolvers = IResolvers; - -export class ResolverAdapter { - private resolvers: Resolvers = {}; - - setResolvers(resolvers: Resolvers) { - this.resolvers = resolvers; - } - - getResolvers() { - return this.resolvers; - } -} diff --git a/packages/graphql/src/cosmos.ts b/packages/graphql/src/cosmos.ts deleted file mode 100644 index 59130a63a..000000000 --- a/packages/graphql/src/cosmos.ts +++ /dev/null @@ -1,14 +0,0 @@ -import IndexCosmos from './application/uc/IndexCosmos'; -import { logger } from './core/Logger'; - -async function main() { - logger.debug('Cosmos', 'Starting cosmos services'); - const indexCosmos = new IndexCosmos(); - await indexCosmos.execute(); -} - -main().catch(async (error: any) => { - logger.error('Cosmos', 'Uncaught error', error); - logger.error('Cosmos', 'Process exit'); - process.exit(1); -}); diff --git a/packages/graphql/src/domain/Block/vo/BlockProducer.ts b/packages/graphql/src/domain/Block/vo/BlockProducer.ts index 4f298aa89..f1b888cbf 100644 --- a/packages/graphql/src/domain/Block/vo/BlockProducer.ts +++ b/packages/graphql/src/domain/Block/vo/BlockProducer.ts @@ -1,8 +1,6 @@ import { varchar } from 'drizzle-orm/pg-core'; -import { Signer } from 'fuels'; import { Address } from '~/core/Address'; import { ValueObject } from '~/core/ValueObject'; -import { client } from '~/graphql/GraphQLSDK'; interface Props { value: Address | null; @@ -19,18 +17,6 @@ export class BlockProducer extends ValueObject { return new BlockProducer({ value: address }); } - static async fromSdk() { - // TODO: get from database - const blocks = await client.sdk.blocks({ first: 2 }); - const block = blocks.data.blocks.nodes[0]; - if (block.consensus.__typename === 'Genesis') { - return null; - } - const signature = block.consensus.signature; - const producer = Signer.recoverAddress(block.id, signature).toString(); - return producer; - } - value() { return this.props.value; } diff --git a/packages/graphql/src/execute-contract.ts b/packages/graphql/src/execute-contract.ts deleted file mode 100644 index 1239d4896..000000000 --- a/packages/graphql/src/execute-contract.ts +++ /dev/null @@ -1,2872 +0,0 @@ -import { Contract, Provider } from 'fuels'; -import { DatabaseConnection } from './infra/database/DatabaseConnection'; - -const _connection = DatabaseConnection.getInstance(); - -(async () => { - await execute(); -})(); - -async function execute() { - const contractId = - '0x3f3f87bb15c693784e90521c64bac855ce23d971356a6ccd57aa92e02e696432'; - const assetId = - '0xa134d7fa9bbba3474af4c602a53929767acd23bd36d5e870b40cb6f8aa0f7922'; - const provider = new Provider('https://mainnet.fuel.network/v1/graphql'); - const contract = new Contract(contractId, abi, provider); - const asset: any = {}; - const outputName = await contract.functions.name({ bits: assetId }).dryRun(); - asset.name = outputName.value; - const outputSymbol = await contract.functions - .symbol({ bits: assetId }) - .dryRun(); - asset.symbol = outputSymbol.value; - const outputDecimals = await contract.functions - .decimals({ bits: assetId }) - .dryRun(); - asset.decimals = outputDecimals.value; - const { value } = await contract.functions - .metadata( - { - bits: assetId, - }, - 'uri', - ) - .get(); - console.log(asset); - console.log(value?.String); -} - -const abi = { - programType: 'contract', - specVersion: '1', - encodingVersion: '1', - concreteTypes: [ - { - type: '()', - concreteTypeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - type: 'b256', - concreteTypeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - type: 'bool', - concreteTypeId: - 'b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903', - }, - { - type: 'enum errors::MintError', - concreteTypeId: - 'ee89c439b5472cab716006d7c677d16e15301e6c82cfce12cebfa57919f537de', - metadataTypeId: 0, - }, - { - type: 'enum errors::SetError', - concreteTypeId: - 'bf6597cf3d56a5e47a920520e275ccd481a27e7c988ea6af6f253170d5374c5a', - metadataTypeId: 1, - }, - { - type: 'enum standards::src5::AccessError', - concreteTypeId: - '3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d', - metadataTypeId: 2, - }, - { - type: 'enum standards::src5::State', - concreteTypeId: - '192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c', - metadataTypeId: 3, - }, - { - type: 'enum standards::src7::Metadata', - concreteTypeId: - 'f44b531974c6c04e17e66ab54e9868d230b9a24b3710b184399c363f0190180d', - metadataTypeId: 4, - }, - { - type: 'enum std::identity::Identity', - concreteTypeId: - 'ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335', - metadataTypeId: 5, - }, - { - type: 'enum std::option::Option', - concreteTypeId: - '0c2beb9013490c4f753f2757dfe2d8340b22ce3827d596d81d249b7038033cb6', - metadataTypeId: 6, - typeArguments: [ - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - 'fe93748eeb5d91a422fcea06e1b374216ad4ac0b2db01be0a6316af7f90dfa4f', - metadataTypeId: 6, - typeArguments: [ - 'f44b531974c6c04e17e66ab54e9868d230b9a24b3710b184399c363f0190180d', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - '7c06d929390a9aeeb8ffccf8173ac0d101a9976d99dda01cce74541a81e75ac0', - metadataTypeId: 6, - typeArguments: [ - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - 'd852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d', - metadataTypeId: 6, - typeArguments: [ - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - '2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1', - metadataTypeId: 6, - typeArguments: [ - 'c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b', - ], - }, - { - type: 'enum sway_libs::asset::errors::BurnError', - concreteTypeId: - '3acdc2adac8e0589c5864525e0edc9dc61a9571a4d09c3c57b58ea76d33f4b46', - metadataTypeId: 7, - }, - { - type: 'enum sway_libs::asset::errors::MintError', - concreteTypeId: - 'dff9dfec998a49b40f1c4b09567400f0e712aaf939c08f7d07bc5c63116e1084', - metadataTypeId: 8, - }, - { - type: 'enum sway_libs::asset::errors::SetMetadataError', - concreteTypeId: - 'c6c09c148c1a1341c7ab81697b3545cc695fa67668a169cddc59790a9a0b6b44', - metadataTypeId: 9, - }, - { - type: 'enum sway_libs::ownership::errors::InitializationError', - concreteTypeId: - '1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893', - metadataTypeId: 10, - }, - { - type: 'enum sway_libs::pausable::errors::PauseError', - concreteTypeId: - '8b3afcadf894415a10b09fc3717487e33802c8ffbb030edafe84ca4a71b280bc', - metadataTypeId: 11, - }, - { - type: 'struct standards::src20::SetNameEvent', - concreteTypeId: - '6ce295b0fb4c1c15e8ed1cfa4babda47d8a04940a5266a3229e12243a2e37c2c', - metadataTypeId: 14, - }, - { - type: 'struct standards::src20::SetSymbolEvent', - concreteTypeId: - 'a8a4b78066c51a50da6349bd395fe1c67e774d75c1db2c5c22288a432d7a363d', - metadataTypeId: 15, - }, - { - type: 'struct standards::src20::TotalSupplyEvent', - concreteTypeId: - 'f255d5cc2114d1b6bc34bef4c28d4b60caccffd9a672ed16b79ea217e1c4a8a3', - metadataTypeId: 16, - }, - { - type: 'struct standards::src7::SetMetadataEvent', - concreteTypeId: - 'f1b1cc90b68559aa4bb5cc58201ebb5c5402ed3aa28927140761e8ff7dcd3ab8', - metadataTypeId: 17, - }, - { - type: 'struct std::asset_id::AssetId', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - metadataTypeId: 19, - }, - { - type: 'struct std::string::String', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - metadataTypeId: 23, - }, - { - type: 'struct sway_libs::ownership::events::OwnershipSet', - concreteTypeId: - 'e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5', - metadataTypeId: 24, - }, - { - type: 'u64', - concreteTypeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - type: 'u8', - concreteTypeId: - 'c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b', - }, - ], - metadataTypes: [ - { - type: 'enum errors::MintError', - metadataTypeId: 0, - components: [ - { - name: 'CannotMintMoreThanOneNFTWithSubId', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'MaxNFTsMinted', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'NFTAlreadyMinted', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'SubIdCannotBeNone', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum errors::SetError', - metadataTypeId: 1, - components: [ - { - name: 'ValueAlreadySet', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum standards::src5::AccessError', - metadataTypeId: 2, - components: [ - { - name: 'NotOwner', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum standards::src5::State', - metadataTypeId: 3, - components: [ - { - name: 'Uninitialized', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'Initialized', - typeId: 5, - }, - { - name: 'Revoked', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum standards::src7::Metadata', - metadataTypeId: 4, - components: [ - { - name: 'B256', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - name: 'Bytes', - typeId: 20, - }, - { - name: 'Int', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - name: 'String', - typeId: 23, - }, - ], - }, - { - type: 'enum std::identity::Identity', - metadataTypeId: 5, - components: [ - { - name: 'Address', - typeId: 18, - }, - { - name: 'ContractId', - typeId: 22, - }, - ], - }, - { - type: 'enum std::option::Option', - metadataTypeId: 6, - components: [ - { - name: 'None', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'Some', - typeId: 12, - }, - ], - typeParameters: [12], - }, - { - type: 'enum sway_libs::asset::errors::BurnError', - metadataTypeId: 7, - components: [ - { - name: 'NotEnoughCoins', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'ZeroAmount', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum sway_libs::asset::errors::MintError', - metadataTypeId: 8, - components: [ - { - name: 'ZeroAmount', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum sway_libs::asset::errors::SetMetadataError', - metadataTypeId: 9, - components: [ - { - name: 'EmptyString', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'EmptyBytes', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum sway_libs::ownership::errors::InitializationError', - metadataTypeId: 10, - components: [ - { - name: 'CannotReinitialized', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum sway_libs::pausable::errors::PauseError', - metadataTypeId: 11, - components: [ - { - name: 'Paused', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'NotPaused', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'generic T', - metadataTypeId: 12, - }, - { - type: 'raw untyped ptr', - metadataTypeId: 13, - }, - { - type: 'struct standards::src20::SetNameEvent', - metadataTypeId: 14, - components: [ - { - name: 'asset', - typeId: 19, - }, - { - name: 'name', - typeId: 6, - typeArguments: [ - { - name: '', - typeId: 23, - }, - ], - }, - { - name: 'sender', - typeId: 5, - }, - ], - }, - { - type: 'struct standards::src20::SetSymbolEvent', - metadataTypeId: 15, - components: [ - { - name: 'asset', - typeId: 19, - }, - { - name: 'symbol', - typeId: 6, - typeArguments: [ - { - name: '', - typeId: 23, - }, - ], - }, - { - name: 'sender', - typeId: 5, - }, - ], - }, - { - type: 'struct standards::src20::TotalSupplyEvent', - metadataTypeId: 16, - components: [ - { - name: 'asset', - typeId: 19, - }, - { - name: 'supply', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - name: 'sender', - typeId: 5, - }, - ], - }, - { - type: 'struct standards::src7::SetMetadataEvent', - metadataTypeId: 17, - components: [ - { - name: 'asset', - typeId: 19, - }, - { - name: 'metadata', - typeId: 6, - typeArguments: [ - { - name: '', - typeId: 4, - }, - ], - }, - { - name: 'key', - typeId: 23, - }, - { - name: 'sender', - typeId: 5, - }, - ], - }, - { - type: 'struct std::address::Address', - metadataTypeId: 18, - components: [ - { - name: 'bits', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - }, - { - type: 'struct std::asset_id::AssetId', - metadataTypeId: 19, - components: [ - { - name: 'bits', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - }, - { - type: 'struct std::bytes::Bytes', - metadataTypeId: 20, - components: [ - { - name: 'buf', - typeId: 21, - }, - { - name: 'len', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - }, - { - type: 'struct std::bytes::RawBytes', - metadataTypeId: 21, - components: [ - { - name: 'ptr', - typeId: 13, - }, - { - name: 'cap', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - }, - { - type: 'struct std::contract_id::ContractId', - metadataTypeId: 22, - components: [ - { - name: 'bits', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - }, - { - type: 'struct std::string::String', - metadataTypeId: 23, - components: [ - { - name: 'bytes', - typeId: 20, - }, - ], - }, - { - type: 'struct sway_libs::ownership::events::OwnershipSet', - metadataTypeId: 24, - components: [ - { - name: 'new_owner', - typeId: 5, - }, - ], - }, - ], - functions: [ - { - inputs: [ - { - name: '_asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'decimals', - output: - '2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1', - attributes: [ - { - name: 'doc-comment', - arguments: [' Returns the number of decimals the asset uses.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Additional Information'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' The standardized decimals for NFTs is 0u8.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to query the decimals.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * [Option] - The decimal precision used by `asset`.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId, asset: AssedId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [ - ' let decimals = contract_abi.decimals(asset).unwrap();', - ], - }, - { - name: 'doc-comment', - arguments: [' assert(decimals == 0u8);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'name', - output: - '7c06d929390a9aeeb8ffccf8173ac0d101a9976d99dda01cce74541a81e75ac0', - attributes: [ - { - name: 'doc-comment', - arguments: [' Returns the name of the asset, such as “Ether”.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to query the name.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * [Option] - The name of `asset`.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [' use std::string::String;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_ic: ContractId, asset: AssetId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let name = contract_abi.name(asset).unwrap();'], - }, - { - name: 'doc-comment', - arguments: [' assert(name.len() != 0);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'symbol', - output: - '7c06d929390a9aeeb8ffccf8173ac0d101a9976d99dda01cce74541a81e75ac0', - attributes: [ - { - name: 'doc-comment', - arguments: [' Returns the symbol of the asset, such as “ETH”.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to query the symbol.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * [Option] - The symbol of `asset`.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [' use std::string::String;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId, asset: AssetId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let symbol = contract_abi.symbol(asset).unwrap();'], - }, - { - name: 'doc-comment', - arguments: [' assert(symbol.len() != 0);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [], - name: 'total_assets', - output: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - attributes: [ - { - name: 'doc-comment', - arguments: [ - ' Returns the total number of individual NFTs for this contract.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * [u64] - The number of assets that this contract has minted.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let total_assets = contract_abi.total_assets();'], - }, - { - name: 'doc-comment', - arguments: [' assert(total_assets != 0);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'total_supply', - output: - 'd852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Returns the total supply of coins for an asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Additional Information'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' This must always be at most 1 for NFTs.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to query the total supply.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * [Option] - The total supply of coins for `asset`.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId, asset: AssetId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [ - ' let total_supply = contract_abi.total_supply(asset).unwrap();', - ], - }, - { - name: 'doc-comment', - arguments: [' assert(total_supply == 1);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'sub_id', - concreteTypeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - name: 'amount', - concreteTypeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - name: 'burn', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Burns assets sent with the given `sub_id`.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Additional Information'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' NOTE: The sha-256 hash of `(ContractId, SubId)` must match the `AssetId` where `ContractId` is the id of', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' the implementing contract and `SubId` is the given `sub_id` argument.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `sub_id`: [SubId] - The sub-identifier of the asset to burn.', - ], - }, - { - name: 'doc-comment', - arguments: [' * `amount`: [u64] - The quantity of coins to burn.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the contract is paused.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src3::SRC3;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId, asset_id: AssetId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SR3, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' contract_abi.burn {'], - }, - { - name: 'doc-comment', - arguments: [' gas: 10000,'], - }, - { - name: 'doc-comment', - arguments: [' coins: 1,'], - }, - { - name: 'doc-comment', - arguments: [' asset_id: AssetId,'], - }, - { - name: 'doc-comment', - arguments: [' } (ZERO_B256, 1);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'payable', - arguments: [], - }, - { - name: 'storage', - arguments: ['read', 'write'], - }, - ], - }, - { - inputs: [ - { - name: 'recipient', - concreteTypeId: - 'ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335', - }, - { - name: 'sub_id', - concreteTypeId: - '0c2beb9013490c4f753f2757dfe2d8340b22ce3827d596d81d249b7038033cb6', - }, - { - name: 'amount', - concreteTypeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - name: 'mint', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Mints new assets using the `sub_id` sub-identifier.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Additional Information'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' This conforms to the SRC-20 NFT portion of the standard for a maximum', - ], - }, - { - name: 'doc-comment', - arguments: [' mint amount of 1 coin per asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `recipient`: [Identity] - The user to which the newly minted assets are transferred to.', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' * `sub_id`: [SubId] - The sub-identifier of the newly minted asset.', - ], - }, - { - name: 'doc-comment', - arguments: [' * `amount`: [u64] - The quantity of coins to mint.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the contract is paused.'], - }, - { - name: 'doc-comment', - arguments: [' * When amount is greater than one.'], - }, - { - name: 'doc-comment', - arguments: [' * When the asset has already been minted.'], - }, - { - name: 'doc-comment', - arguments: [ - ' * When more than the MAX_SUPPLY NFTs have been minted.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `3`'], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `2`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src3::SRC3;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SR3, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [ - ' contract_abi.mint(Identity::ContractId(ContractId::this()), ZERO_B256, 1);', - ], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read', 'write'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: 'key', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - }, - ], - name: 'metadata', - output: - 'fe93748eeb5d91a422fcea06e1b374216ad4ac0b2db01be0a6316af7f90dfa4f', - attributes: [ - { - name: 'doc-comment', - arguments: [ - ' Returns metadata for the corresponding `asset` and `key`.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to query the metadata.', - ], - }, - { - name: 'doc-comment', - arguments: [' * `key`: [String] - The key to the specific metadata.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * [Option] - `Some` metadata that corresponds to the `key` or `None`.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src_7::{SRC7, Metadata};'], - }, - { - name: 'doc-comment', - arguments: [' use std::string::String;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId, asset: AssetId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SRC7, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let key = String::from_ascii_str("image");'], - }, - { - name: 'doc-comment', - arguments: [' let data = contract_abi.metadata(asset, key);'], - }, - { - name: 'doc-comment', - arguments: [' assert(data.is_some());'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [], - name: 'owner', - output: - '192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c', - attributes: [ - { - name: 'doc-comment', - arguments: [' Returns the owner.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Return Values'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * [State] - Represents the state of ownership for this contract.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use standards::src5::SRC5;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [' let ownership_abi = abi(contract_id, SRC_5);'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' match ownership_abi.owner() {'], - }, - { - name: 'doc-comment', - arguments: [ - ' State::Uninitalized => log("The ownership is uninitalized"),', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' State::Initialized(owner) => log("The ownership is initalized"),', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' State::Revoked => log("The ownership is revoked"),', - ], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: '_asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: '_decimals', - concreteTypeId: - 'c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b', - }, - ], - name: 'set_decimals', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' This function should never be called.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Additional Information'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' NFT decimals are always `0u8` and thus must not be set.', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' This function is an artifact of the SetAssetAttributes ABI definition,', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' but does not have a use in this contract as the decimal value is hardcoded.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the function is called.'], - }, - { - name: 'storage', - arguments: ['write'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: 'name', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - }, - ], - name: 'set_name', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Sets the name of an asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to set the name.', - ], - }, - { - name: 'doc-comment', - arguments: [' * `name`: [String] - The name of the asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the caller is not the owner of the contract.'], - }, - { - name: 'doc-comment', - arguments: [' * When the name has already been set for an asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `2`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use asset::SetAssetAttributes;'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [' use std::string::String;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(asset: AssetId, contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [ - ' let set_abi = abi(SetAssetAttributes, contract_id);', - ], - }, - { - name: 'doc-comment', - arguments: [' let src_20_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let name = String::from_ascii_str("Ether");'], - }, - { - name: 'doc-comment', - arguments: [' set_abi.set_name(asset, name);'], - }, - { - name: 'doc-comment', - arguments: [' assert(src_20_abi.name(asset) == name);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['write'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: 'symbol', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - }, - ], - name: 'set_symbol', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Sets the symbol of an asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to set the symbol.', - ], - }, - { - name: 'doc-comment', - arguments: [' * `symbol`: [String] - The symbol of the asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the caller is not the owner of the contract.'], - }, - { - name: 'doc-comment', - arguments: [' * When the symbol has already been set for an asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `2`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use asset::SetAssetAttributes;'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [' use std::string::String;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(asset: AssetId, contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [ - ' let set_abi = abi(SetAssetAttributes, contract_id);', - ], - }, - { - name: 'doc-comment', - arguments: [' let src_20_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let symbol = String::from_ascii_str("ETH");'], - }, - { - name: 'doc-comment', - arguments: [' set_abi.set_symbol(asset, symbol);'], - }, - { - name: 'doc-comment', - arguments: [' assert(src_20_abi.symbol(asset) == symbol);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['write'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: 'key', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - }, - { - name: 'metadata', - concreteTypeId: - 'f44b531974c6c04e17e66ab54e9868d230b9a24b3710b184399c363f0190180d', - }, - ], - name: 'set_metadata', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Stores metadata for a specific asset and key pair.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset for the metadata to be stored.', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' * `key`: [String] - The key for the metadata to be stored.', - ], - }, - { - name: 'doc-comment', - arguments: [' * `metadata`: [Metadata] - The metadata to be stored.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * When the metadata has already been set for an asset.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `2`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Example'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use asset::metdata::SetAssetMetadata;'], - }, - { - name: 'doc-comment', - arguments: [' use src_7::{SRC7, Metadata};'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' fn foo(asset: AssetId, key: String, contract_id: ContractId, metadata: Metadata) {', - ], - }, - { - name: 'doc-comment', - arguments: [' let set_abi = abi(SetAssetMetadata, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let src_7_abi = abi(SRC7, contract);'], - }, - { - name: 'doc-comment', - arguments: [ - ' set_abi.set_metadata(storage.metadata, asset, key, metadata);', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' assert(src_7_abi.metadata(asset, key) == metadata);', - ], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read', 'write'], - }, - ], - }, - { - inputs: [], - name: 'is_paused', - output: - 'b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903', - attributes: [ - { - name: 'doc-comment', - arguments: [' Returns whether the contract is paused.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * [bool] - The pause state for the contract.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use sway_libs::pausable::Pausable;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [' let pausable_abi = abi(Pausable, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' assert(!pausable_abi.is_paused());'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [], - name: 'pause', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Pauses the contract.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the caller is not the contract owner.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use sway_libs::pausable::Pausable;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [' let pausable_abi = abi(Pausable, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' pausable_abi.pause();'], - }, - { - name: 'doc-comment', - arguments: [' assert(pausable_abi.is_paused());'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['write'], - }, - ], - }, - { - inputs: [], - name: 'unpause', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Unpauses the contract.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the caller is not the contract owner.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use sway_libs::pausable::Pausable;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [' let pausable_abi = abi(Pausable, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' pausable_abi.unpause();'], - }, - { - name: 'doc-comment', - arguments: [' assert(!pausable_abi.is_paused());'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['write'], - }, - ], - }, - { - inputs: [ - { - name: 'owner', - concreteTypeId: - 'ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335', - }, - ], - name: 'constructor', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Sets the defaults for the contract.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `owner`: [Identity] - The `Identity` that will be the first owner.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When ownership has been set before.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Acesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [' * Write: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use standards::src5::SRC5;'], - }, - { - name: 'doc-comment', - arguments: [' use nft::Constructor;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract: ContractId, owner: Identity) {'], - }, - { - name: 'doc-comment', - arguments: [' let src_5_abi = abi(SRC5, contract.bits());'], - }, - { - name: 'doc-comment', - arguments: [ - ' assert(src_5_abi.owner() == State::Uninitialized);', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' let constructor_abi = abi(Constructor, contract.bits());', - ], - }, - { - name: 'doc-comment', - arguments: [' constructor_abi.constructor(owner);'], - }, - { - name: 'doc-comment', - arguments: [ - ' assert(src_5_abi.owner() == State::Initialized(owner));', - ], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read', 'write'], - }, - ], - }, - ], - loggedTypes: [ - { - logId: '10032608944051208538', - concreteTypeId: - '8b3afcadf894415a10b09fc3717487e33802c8ffbb030edafe84ca4a71b280bc', - }, - { - logId: '4237256875605624201', - concreteTypeId: - '3acdc2adac8e0589c5864525e0edc9dc61a9571a4d09c3c57b58ea76d33f4b46', - }, - { - logId: '17462098202904023478', - concreteTypeId: - 'f255d5cc2114d1b6bc34bef4c28d4b60caccffd9a672ed16b79ea217e1c4a8a3', - }, - { - logId: '17188485204969729195', - concreteTypeId: - 'ee89c439b5472cab716006d7c677d16e15301e6c82cfce12cebfa57919f537de', - }, - { - logId: '16139176946940135860', - concreteTypeId: - 'dff9dfec998a49b40f1c4b09567400f0e712aaf939c08f7d07bc5c63116e1084', - }, - { - logId: '13791596350235125220', - concreteTypeId: - 'bf6597cf3d56a5e47a920520e275ccd481a27e7c988ea6af6f253170d5374c5a', - }, - { - logId: '14321618427101975361', - concreteTypeId: - 'c6c09c148c1a1341c7ab81697b3545cc695fa67668a169cddc59790a9a0b6b44', - }, - { - logId: '7845998088195677205', - concreteTypeId: - '6ce295b0fb4c1c15e8ed1cfa4babda47d8a04940a5266a3229e12243a2e37c2c', - }, - { - logId: '12152039456660331088', - concreteTypeId: - 'a8a4b78066c51a50da6349bd395fe1c67e774d75c1db2c5c22288a432d7a363d', - }, - { - logId: '17415926155927968170', - concreteTypeId: - 'f1b1cc90b68559aa4bb5cc58201ebb5c5402ed3aa28927140761e8ff7dcd3ab8', - }, - { - logId: '4571204900286667806', - concreteTypeId: - '3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d', - }, - { - logId: '2161305517876418151', - concreteTypeId: - '1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893', - }, - { - logId: '16280289466020123285', - concreteTypeId: - 'e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5', - }, - ], - messagesTypes: [], - configurables: [], -}; diff --git a/packages/graphql/src/generated/mocks.ts b/packages/graphql/src/generated/mocks.ts deleted file mode 100644 index 6e6b9aab4..000000000 --- a/packages/graphql/src/generated/mocks.ts +++ /dev/null @@ -1,964 +0,0 @@ -import { Account, Balance, BalanceConnection, BalanceEdge, BalanceFilterInput, Block, BlockConnection, BlockEdge, Breakpoint, ChainInfo, ChangeOutput, Coin, CoinConnection, CoinEdge, CoinFilterInput, CoinOutput, ConsensusParameters, Contract, ContractBalance, ContractBalanceConnection, ContractBalanceEdge, ContractBalanceFilterInput, ContractCreated, ContractOutput, ContractParameters, ExcludeInput, FailureStatus, FeeParameters, GasCosts, Genesis, GroupedInput, GroupedOutput, Header, HeavyOperation, InputCoin, InputContract, InputMessage, LightOperation, MerkleProof, Message, MessageCoin, MessageConnection, MessageEdge, MessageProof, MessageStatus, Mutation, NodeInfo, Operation, OperationReceipt, OutputBreakpoint, PageInfo, ParsedTime, PeerInfo, PoAConsensus, Policies, Predicate, PredicateParameters, ProgramState, Query, Receipt, RunResult, ScriptParameters, SearchAccount, SearchBlock, SearchContract, SearchResult, SearchTransaction, SpendQueryElementInput, SqueezedOutStatus, SubmittedStatus, Subscription, SuccessStatus, Token, Transaction, TransactionAccount, TransactionConnection, TransactionEdge, TxParameters, UtxoItem, VariableOutput, GroupedInputType, GroupedOutputType, MessageState, OperationType, ReceiptType, _ReturnType as ReturnType, RunState, TransactionAccountType, TransactionStatusType } from './types'; - -export const anAccount = (overrides?: Partial): { __typename: 'Account' } & Account => { - return { - __typename: 'Account', - address: overrides && overrides.hasOwnProperty('address') ? overrides.address! : 'autem', - name: overrides && overrides.hasOwnProperty('name') ? overrides.name! : 'nostrum', - url: overrides && overrides.hasOwnProperty('url') ? overrides.url! : 'rerum', - }; -}; - -export const aBalance = (overrides?: Partial): { __typename: 'Balance' } & Balance => { - return { - __typename: 'Balance', - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0x0', - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 'a0f8od7pvhhubad7x3hz9o0zn7xp5j23', - owner: overrides && overrides.hasOwnProperty('owner') ? overrides.owner! : 'tx4go3g6en5w03qjzwnt6ugwv26qrm5q9mwtq5lp', - utxos: overrides && overrides.hasOwnProperty('utxos') ? overrides.utxos! : [anUtxoItem()], - }; -}; - -export const aBalanceConnection = (overrides?: Partial): { __typename: 'BalanceConnection' } & BalanceConnection => { - return { - __typename: 'BalanceConnection', - edges: overrides && overrides.hasOwnProperty('edges') ? overrides.edges! : [aBalanceEdge()], - nodes: overrides && overrides.hasOwnProperty('nodes') ? overrides.nodes! : [aBalance()], - pageInfo: overrides && overrides.hasOwnProperty('pageInfo') ? overrides.pageInfo! : aPageInfo(), - }; -}; - -export const aBalanceEdge = (overrides?: Partial): { __typename: 'BalanceEdge' } & BalanceEdge => { - return { - __typename: 'BalanceEdge', - cursor: overrides && overrides.hasOwnProperty('cursor') ? overrides.cursor! : 'tenetur', - node: overrides && overrides.hasOwnProperty('node') ? overrides.node! : aBalance(), - }; -}; - -export const aBalanceFilterInput = (overrides?: Partial): BalanceFilterInput => { - return { - owner: overrides && overrides.hasOwnProperty('owner') ? overrides.owner! : '9nrgo4xy0vszugxxsuu7t7k4heqvx2it46ns6n49', - }; -}; - -export const aBlock = (overrides?: Partial): { __typename: 'Block' } & Block => { - return { - __typename: 'Block', - consensus: overrides && overrides.hasOwnProperty('consensus') ? overrides.consensus! : aGenesis(), - header: overrides && overrides.hasOwnProperty('header') ? overrides.header! : aHeader(), - id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'fuga', - producer: overrides && overrides.hasOwnProperty('producer') ? overrides.producer! : 'tf26peb03uo1z0i4l6d7yfnvuzumd2fiukebb742', - time: overrides && overrides.hasOwnProperty('time') ? overrides.time! : aParsedTime(), - totalGasUsed: overrides && overrides.hasOwnProperty('totalGasUsed') ? overrides.totalGasUsed! : '0x1', - transactions: overrides && overrides.hasOwnProperty('transactions') ? overrides.transactions! : [aTransaction()], - }; -}; - -export const aBlockConnection = (overrides?: Partial): { __typename: 'BlockConnection' } & BlockConnection => { - return { - __typename: 'BlockConnection', - edges: overrides && overrides.hasOwnProperty('edges') ? overrides.edges! : [aBlockEdge()], - nodes: overrides && overrides.hasOwnProperty('nodes') ? overrides.nodes! : [aBlock()], - pageInfo: overrides && overrides.hasOwnProperty('pageInfo') ? overrides.pageInfo! : aPageInfo(), - }; -}; - -export const aBlockEdge = (overrides?: Partial): { __typename: 'BlockEdge' } & BlockEdge => { - return { - __typename: 'BlockEdge', - cursor: overrides && overrides.hasOwnProperty('cursor') ? overrides.cursor! : 'id', - node: overrides && overrides.hasOwnProperty('node') ? overrides.node! : aBlock(), - }; -}; - -export const aBreakpoint = (overrides?: Partial): Breakpoint => { - return { - contract: overrides && overrides.hasOwnProperty('contract') ? overrides.contract! : 'spxsyh8uujdpzc8kg4t7lkz0r7qmcdsb', - pc: overrides && overrides.hasOwnProperty('pc') ? overrides.pc! : '0xa', - }; -}; - -export const aChainInfo = (overrides?: Partial): { __typename: 'ChainInfo' } & ChainInfo => { - return { - __typename: 'ChainInfo', - consensusParameters: overrides && overrides.hasOwnProperty('consensusParameters') ? overrides.consensusParameters! : aConsensusParameters(), - daHeight: overrides && overrides.hasOwnProperty('daHeight') ? overrides.daHeight! : '0xE', - gasCosts: overrides && overrides.hasOwnProperty('gasCosts') ? overrides.gasCosts! : aGasCosts(), - latestBlock: overrides && overrides.hasOwnProperty('latestBlock') ? overrides.latestBlock! : aBlock(), - name: overrides && overrides.hasOwnProperty('name') ? overrides.name! : 'autem', - }; -}; - -export const aChangeOutput = (overrides?: Partial): { __typename: 'ChangeOutput' } & ChangeOutput => { - return { - __typename: 'ChangeOutput', - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0xD', - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 'e0jf4dwzgypv3lmvt8yed3ebs8sco6xm', - to: overrides && overrides.hasOwnProperty('to') ? overrides.to! : 'dhi4r4fhri7jpmudxj1zxawwhmvmg15ehun33smn', - }; -}; - -export const aCoin = (overrides?: Partial): { __typename: 'Coin' } & Coin => { - return { - __typename: 'Coin', - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0xD', - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 'vl8kx5cac3pojox0cdisfofoyu6smapv', - blockCreated: overrides && overrides.hasOwnProperty('blockCreated') ? overrides.blockCreated! : 'doloremque', - maturity: overrides && overrides.hasOwnProperty('maturity') ? overrides.maturity! : 'architecto', - owner: overrides && overrides.hasOwnProperty('owner') ? overrides.owner! : 'on6sn7qh1ssgeb35sg0so4u4lp3izj4yafvrlk8x', - txCreatedIdx: overrides && overrides.hasOwnProperty('txCreatedIdx') ? overrides.txCreatedIdx! : '0x7', - utxoId: overrides && overrides.hasOwnProperty('utxoId') ? overrides.utxoId! : '78r15xdj851q7w4q6k0tqeof9vlk0gns', - }; -}; - -export const aCoinConnection = (overrides?: Partial): { __typename: 'CoinConnection' } & CoinConnection => { - return { - __typename: 'CoinConnection', - edges: overrides && overrides.hasOwnProperty('edges') ? overrides.edges! : [aCoinEdge()], - nodes: overrides && overrides.hasOwnProperty('nodes') ? overrides.nodes! : [aCoin()], - pageInfo: overrides && overrides.hasOwnProperty('pageInfo') ? overrides.pageInfo! : aPageInfo(), - }; -}; - -export const aCoinEdge = (overrides?: Partial): { __typename: 'CoinEdge' } & CoinEdge => { - return { - __typename: 'CoinEdge', - cursor: overrides && overrides.hasOwnProperty('cursor') ? overrides.cursor! : 'excepturi', - node: overrides && overrides.hasOwnProperty('node') ? overrides.node! : aCoin(), - }; -}; - -export const aCoinFilterInput = (overrides?: Partial): CoinFilterInput => { - return { - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 'kudfhe4l01ysp8358vb8xz1k8veh59hy', - owner: overrides && overrides.hasOwnProperty('owner') ? overrides.owner! : 'baoj8afcxig6c9huma1wloyvmbchd8yi7qa85afh', - }; -}; - -export const aCoinOutput = (overrides?: Partial): { __typename: 'CoinOutput' } & CoinOutput => { - return { - __typename: 'CoinOutput', - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0xD', - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 't153mt7lkdbnhho3wb4ukkb48qhhudy7', - to: overrides && overrides.hasOwnProperty('to') ? overrides.to! : '9olpk2xb6cjl4kyy3he3py3yu0bkm85chtuggo6i', - }; -}; - -export const aConsensusParameters = (overrides?: Partial): { __typename: 'ConsensusParameters' } & ConsensusParameters => { - return { - __typename: 'ConsensusParameters', - baseAssetId: overrides && overrides.hasOwnProperty('baseAssetId') ? overrides.baseAssetId! : 'l2lmmdg42iyd8pb2v79vqcg6fnko5egl', - chainId: overrides && overrides.hasOwnProperty('chainId') ? overrides.chainId! : '0x3', - contractParams: overrides && overrides.hasOwnProperty('contractParams') ? overrides.contractParams! : aContractParameters(), - feeParams: overrides && overrides.hasOwnProperty('feeParams') ? overrides.feeParams! : aFeeParameters(), - gasCosts: overrides && overrides.hasOwnProperty('gasCosts') ? overrides.gasCosts! : aGasCosts(), - predicateParams: overrides && overrides.hasOwnProperty('predicateParams') ? overrides.predicateParams! : aPredicateParameters(), - scriptParams: overrides && overrides.hasOwnProperty('scriptParams') ? overrides.scriptParams! : aScriptParameters(), - txParams: overrides && overrides.hasOwnProperty('txParams') ? overrides.txParams! : aTxParameters(), - }; -}; - -export const aContract = (overrides?: Partial): { __typename: 'Contract' } & Contract => { - return { - __typename: 'Contract', - bytecode: overrides && overrides.hasOwnProperty('bytecode') ? overrides.bytecode! : '0x6092A6C7eb64c9b1A755Df9bE83fC7Bd5bFF2c090Df255Da243CAB4811Fc2016D2a2Ae93CFEDE4FD8d99ab3Dca0DDdAbc7CF1ba3FbAA761e3eC17f8d1609fD5e46BEFFD6886EB1BCA208bB2AE8bEDADF', - id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : '51d28wg0iw33x467k5qd81kn5b9wnrtg', - salt: overrides && overrides.hasOwnProperty('salt') ? overrides.salt! : 'repellendus', - }; -}; - -export const aContractBalance = (overrides?: Partial): { __typename: 'ContractBalance' } & ContractBalance => { - return { - __typename: 'ContractBalance', - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0xc', - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 'm1on4nvj5caxtv0dkued0ncku5ydtsxu', - contract: overrides && overrides.hasOwnProperty('contract') ? overrides.contract! : '7bdxyt98z950w2en4wp4kh5fxekvlzqv', - }; -}; - -export const aContractBalanceConnection = (overrides?: Partial): { __typename: 'ContractBalanceConnection' } & ContractBalanceConnection => { - return { - __typename: 'ContractBalanceConnection', - edges: overrides && overrides.hasOwnProperty('edges') ? overrides.edges! : [aContractBalanceEdge()], - nodes: overrides && overrides.hasOwnProperty('nodes') ? overrides.nodes! : [aContractBalance()], - pageInfo: overrides && overrides.hasOwnProperty('pageInfo') ? overrides.pageInfo! : aPageInfo(), - }; -}; - -export const aContractBalanceEdge = (overrides?: Partial): { __typename: 'ContractBalanceEdge' } & ContractBalanceEdge => { - return { - __typename: 'ContractBalanceEdge', - cursor: overrides && overrides.hasOwnProperty('cursor') ? overrides.cursor! : 'nesciunt', - node: overrides && overrides.hasOwnProperty('node') ? overrides.node! : aContractBalance(), - }; -}; - -export const aContractBalanceFilterInput = (overrides?: Partial): ContractBalanceFilterInput => { - return { - contract: overrides && overrides.hasOwnProperty('contract') ? overrides.contract! : 'lly4yjylzlm1dnmj5lwzlk0tbb9no5sx', - }; -}; - -export const aContractCreated = (overrides?: Partial): { __typename: 'ContractCreated' } & ContractCreated => { - return { - __typename: 'ContractCreated', - contract: overrides && overrides.hasOwnProperty('contract') ? overrides.contract! : aContract(), - stateRoot: overrides && overrides.hasOwnProperty('stateRoot') ? overrides.stateRoot! : 'dolores', - }; -}; - -export const aContractOutput = (overrides?: Partial): { __typename: 'ContractOutput' } & ContractOutput => { - return { - __typename: 'ContractOutput', - balanceRoot: overrides && overrides.hasOwnProperty('balanceRoot') ? overrides.balanceRoot! : 'architecto', - inputIndex: overrides && overrides.hasOwnProperty('inputIndex') ? overrides.inputIndex! : 3397, - stateRoot: overrides && overrides.hasOwnProperty('stateRoot') ? overrides.stateRoot! : 'animi', - }; -}; - -export const aContractParameters = (overrides?: Partial): { __typename: 'ContractParameters' } & ContractParameters => { - return { - __typename: 'ContractParameters', - contractMaxSize: overrides && overrides.hasOwnProperty('contractMaxSize') ? overrides.contractMaxSize! : '0xA', - maxStorageSlots: overrides && overrides.hasOwnProperty('maxStorageSlots') ? overrides.maxStorageSlots! : '0x0', - }; -}; - -export const anExcludeInput = (overrides?: Partial): ExcludeInput => { - return { - messages: overrides && overrides.hasOwnProperty('messages') ? overrides.messages! : ['facilis'], - utxos: overrides && overrides.hasOwnProperty('utxos') ? overrides.utxos! : ['rjjvinnn08hy31jzmpuci05byajz8wme'], - }; -}; - -export const aFailureStatus = (overrides?: Partial): { __typename: 'FailureStatus' } & FailureStatus => { - return { - __typename: 'FailureStatus', - block: overrides && overrides.hasOwnProperty('block') ? overrides.block! : aBlock(), - programState: overrides && overrides.hasOwnProperty('programState') ? overrides.programState! : aProgramState(), - reason: overrides && overrides.hasOwnProperty('reason') ? overrides.reason! : 'corporis', - receipts: overrides && overrides.hasOwnProperty('receipts') ? overrides.receipts! : [aReceipt()], - time: overrides && overrides.hasOwnProperty('time') ? overrides.time! : 'itaque', - transactionId: overrides && overrides.hasOwnProperty('transactionId') ? overrides.transactionId! : 'y3992yk84ltlkuu5f6glx6r5iitmdig8', - }; -}; - -export const aFeeParameters = (overrides?: Partial): { __typename: 'FeeParameters' } & FeeParameters => { - return { - __typename: 'FeeParameters', - gasPerByte: overrides && overrides.hasOwnProperty('gasPerByte') ? overrides.gasPerByte! : '0xA', - gasPriceFactor: overrides && overrides.hasOwnProperty('gasPriceFactor') ? overrides.gasPriceFactor! : '0xb', - }; -}; - -export const aGasCosts = (overrides?: Partial): { __typename: 'GasCosts' } & GasCosts => { - return { - __typename: 'GasCosts', - add: overrides && overrides.hasOwnProperty('add') ? overrides.add! : '0xd', - addi: overrides && overrides.hasOwnProperty('addi') ? overrides.addi! : '0x4', - aloc: overrides && overrides.hasOwnProperty('aloc') ? overrides.aloc! : '0x5', - and: overrides && overrides.hasOwnProperty('and') ? overrides.and! : '0xE', - andi: overrides && overrides.hasOwnProperty('andi') ? overrides.andi! : '0x1', - bal: overrides && overrides.hasOwnProperty('bal') ? overrides.bal! : '0xf', - bhei: overrides && overrides.hasOwnProperty('bhei') ? overrides.bhei! : '0xC', - bhsh: overrides && overrides.hasOwnProperty('bhsh') ? overrides.bhsh! : '0x7', - burn: overrides && overrides.hasOwnProperty('burn') ? overrides.burn! : '0x6', - call: overrides && overrides.hasOwnProperty('call') ? overrides.call! : aHeavyOperation(), - cb: overrides && overrides.hasOwnProperty('cb') ? overrides.cb! : '0x2', - ccp: overrides && overrides.hasOwnProperty('ccp') ? overrides.ccp! : aHeavyOperation(), - cfei: overrides && overrides.hasOwnProperty('cfei') ? overrides.cfei! : '0xc', - cfsi: overrides && overrides.hasOwnProperty('cfsi') ? overrides.cfsi! : '0xB', - contractRoot: overrides && overrides.hasOwnProperty('contractRoot') ? overrides.contractRoot! : aHeavyOperation(), - croo: overrides && overrides.hasOwnProperty('croo') ? overrides.croo! : '0x4', - csiz: overrides && overrides.hasOwnProperty('csiz') ? overrides.csiz! : aHeavyOperation(), - div: overrides && overrides.hasOwnProperty('div') ? overrides.div! : '0x5', - divi: overrides && overrides.hasOwnProperty('divi') ? overrides.divi! : '0xB', - eck1: overrides && overrides.hasOwnProperty('eck1') ? overrides.eck1! : '0x4', - ecr1: overrides && overrides.hasOwnProperty('ecr1') ? overrides.ecr1! : '0x4', - ed19: overrides && overrides.hasOwnProperty('ed19') ? overrides.ed19! : '0xE', - eq: overrides && overrides.hasOwnProperty('eq') ? overrides.eq! : '0xa', - exp: overrides && overrides.hasOwnProperty('exp') ? overrides.exp! : '0x6', - expi: overrides && overrides.hasOwnProperty('expi') ? overrides.expi! : '0x5', - flag: overrides && overrides.hasOwnProperty('flag') ? overrides.flag! : '0xa', - gm: overrides && overrides.hasOwnProperty('gm') ? overrides.gm! : '0x6', - gt: overrides && overrides.hasOwnProperty('gt') ? overrides.gt! : '0x8', - gtf: overrides && overrides.hasOwnProperty('gtf') ? overrides.gtf! : '0xc', - ji: overrides && overrides.hasOwnProperty('ji') ? overrides.ji! : '0xF', - jmp: overrides && overrides.hasOwnProperty('jmp') ? overrides.jmp! : '0xD', - jmpb: overrides && overrides.hasOwnProperty('jmpb') ? overrides.jmpb! : '0xc', - jmpf: overrides && overrides.hasOwnProperty('jmpf') ? overrides.jmpf! : '0x8', - jne: overrides && overrides.hasOwnProperty('jne') ? overrides.jne! : '0x0', - jneb: overrides && overrides.hasOwnProperty('jneb') ? overrides.jneb! : '0x0', - jnef: overrides && overrides.hasOwnProperty('jnef') ? overrides.jnef! : '0x4', - jnei: overrides && overrides.hasOwnProperty('jnei') ? overrides.jnei! : '0xB', - jnzb: overrides && overrides.hasOwnProperty('jnzb') ? overrides.jnzb! : '0x1', - jnzf: overrides && overrides.hasOwnProperty('jnzf') ? overrides.jnzf! : '0xB', - jnzi: overrides && overrides.hasOwnProperty('jnzi') ? overrides.jnzi! : '0x0', - k256: overrides && overrides.hasOwnProperty('k256') ? overrides.k256! : aHeavyOperation(), - lb: overrides && overrides.hasOwnProperty('lb') ? overrides.lb! : '0xA', - ldc: overrides && overrides.hasOwnProperty('ldc') ? overrides.ldc! : aHeavyOperation(), - log: overrides && overrides.hasOwnProperty('log') ? overrides.log! : '0x6', - logd: overrides && overrides.hasOwnProperty('logd') ? overrides.logd! : aHeavyOperation(), - lt: overrides && overrides.hasOwnProperty('lt') ? overrides.lt! : '0xC', - lw: overrides && overrides.hasOwnProperty('lw') ? overrides.lw! : '0xD', - mcl: overrides && overrides.hasOwnProperty('mcl') ? overrides.mcl! : aHeavyOperation(), - mcli: overrides && overrides.hasOwnProperty('mcli') ? overrides.mcli! : aHeavyOperation(), - mcp: overrides && overrides.hasOwnProperty('mcp') ? overrides.mcp! : aHeavyOperation(), - mcpi: overrides && overrides.hasOwnProperty('mcpi') ? overrides.mcpi! : aHeavyOperation(), - meq: overrides && overrides.hasOwnProperty('meq') ? overrides.meq! : aHeavyOperation(), - mint: overrides && overrides.hasOwnProperty('mint') ? overrides.mint! : '0x1', - mldv: overrides && overrides.hasOwnProperty('mldv') ? overrides.mldv! : '0xF', - mlog: overrides && overrides.hasOwnProperty('mlog') ? overrides.mlog! : '0x8', - modOp: overrides && overrides.hasOwnProperty('modOp') ? overrides.modOp! : '0xF', - modi: overrides && overrides.hasOwnProperty('modi') ? overrides.modi! : '0xA', - moveOp: overrides && overrides.hasOwnProperty('moveOp') ? overrides.moveOp! : '0x4', - movi: overrides && overrides.hasOwnProperty('movi') ? overrides.movi! : '0xF', - mroo: overrides && overrides.hasOwnProperty('mroo') ? overrides.mroo! : '0xA', - mul: overrides && overrides.hasOwnProperty('mul') ? overrides.mul! : '0xE', - muli: overrides && overrides.hasOwnProperty('muli') ? overrides.muli! : '0xE', - newStoragePerByte: overrides && overrides.hasOwnProperty('newStoragePerByte') ? overrides.newStoragePerByte! : '0xA', - noop: overrides && overrides.hasOwnProperty('noop') ? overrides.noop! : '0x3', - not: overrides && overrides.hasOwnProperty('not') ? overrides.not! : '0xc', - or: overrides && overrides.hasOwnProperty('or') ? overrides.or! : '0xC', - ori: overrides && overrides.hasOwnProperty('ori') ? overrides.ori! : '0xE', - poph: overrides && overrides.hasOwnProperty('poph') ? overrides.poph! : '0x9', - popl: overrides && overrides.hasOwnProperty('popl') ? overrides.popl! : '0x7', - pshh: overrides && overrides.hasOwnProperty('pshh') ? overrides.pshh! : '0xD', - pshl: overrides && overrides.hasOwnProperty('pshl') ? overrides.pshl! : '0x9', - ret: overrides && overrides.hasOwnProperty('ret') ? overrides.ret! : '0xa', - retd: overrides && overrides.hasOwnProperty('retd') ? overrides.retd! : aHeavyOperation(), - rvrt: overrides && overrides.hasOwnProperty('rvrt') ? overrides.rvrt! : '0xD', - s256: overrides && overrides.hasOwnProperty('s256') ? overrides.s256! : aHeavyOperation(), - sb: overrides && overrides.hasOwnProperty('sb') ? overrides.sb! : '0x8', - scwq: overrides && overrides.hasOwnProperty('scwq') ? overrides.scwq! : aHeavyOperation(), - sll: overrides && overrides.hasOwnProperty('sll') ? overrides.sll! : '0xF', - slli: overrides && overrides.hasOwnProperty('slli') ? overrides.slli! : '0xb', - smo: overrides && overrides.hasOwnProperty('smo') ? overrides.smo! : aHeavyOperation(), - srl: overrides && overrides.hasOwnProperty('srl') ? overrides.srl! : '0xe', - srli: overrides && overrides.hasOwnProperty('srli') ? overrides.srli! : '0xB', - srw: overrides && overrides.hasOwnProperty('srw') ? overrides.srw! : '0x2', - srwq: overrides && overrides.hasOwnProperty('srwq') ? overrides.srwq! : aHeavyOperation(), - stateRoot: overrides && overrides.hasOwnProperty('stateRoot') ? overrides.stateRoot! : aHeavyOperation(), - sub: overrides && overrides.hasOwnProperty('sub') ? overrides.sub! : '0xa', - subi: overrides && overrides.hasOwnProperty('subi') ? overrides.subi! : '0xE', - sw: overrides && overrides.hasOwnProperty('sw') ? overrides.sw! : '0xa', - sww: overrides && overrides.hasOwnProperty('sww') ? overrides.sww! : '0x8', - swwq: overrides && overrides.hasOwnProperty('swwq') ? overrides.swwq! : aHeavyOperation(), - time: overrides && overrides.hasOwnProperty('time') ? overrides.time! : '0x1', - tr: overrides && overrides.hasOwnProperty('tr') ? overrides.tr! : '0x3', - tro: overrides && overrides.hasOwnProperty('tro') ? overrides.tro! : '0x0', - vmInitialization: overrides && overrides.hasOwnProperty('vmInitialization') ? overrides.vmInitialization! : aHeavyOperation(), - wdam: overrides && overrides.hasOwnProperty('wdam') ? overrides.wdam! : '0xf', - wdcm: overrides && overrides.hasOwnProperty('wdcm') ? overrides.wdcm! : '0xD', - wddv: overrides && overrides.hasOwnProperty('wddv') ? overrides.wddv! : '0xe', - wdmd: overrides && overrides.hasOwnProperty('wdmd') ? overrides.wdmd! : '0xB', - wdml: overrides && overrides.hasOwnProperty('wdml') ? overrides.wdml! : '0xe', - wdmm: overrides && overrides.hasOwnProperty('wdmm') ? overrides.wdmm! : '0x6', - wdop: overrides && overrides.hasOwnProperty('wdop') ? overrides.wdop! : '0x0', - wqam: overrides && overrides.hasOwnProperty('wqam') ? overrides.wqam! : '0xF', - wqcm: overrides && overrides.hasOwnProperty('wqcm') ? overrides.wqcm! : '0xA', - wqdv: overrides && overrides.hasOwnProperty('wqdv') ? overrides.wqdv! : '0xD', - wqmd: overrides && overrides.hasOwnProperty('wqmd') ? overrides.wqmd! : '0x3', - wqml: overrides && overrides.hasOwnProperty('wqml') ? overrides.wqml! : '0x5', - wqmm: overrides && overrides.hasOwnProperty('wqmm') ? overrides.wqmm! : '0xE', - wqop: overrides && overrides.hasOwnProperty('wqop') ? overrides.wqop! : '0xA', - xor: overrides && overrides.hasOwnProperty('xor') ? overrides.xor! : '0x1', - xori: overrides && overrides.hasOwnProperty('xori') ? overrides.xori! : '0xb', - }; -}; - -export const aGenesis = (overrides?: Partial): { __typename: 'Genesis' } & Genesis => { - return { - __typename: 'Genesis', - chainConfigHash: overrides && overrides.hasOwnProperty('chainConfigHash') ? overrides.chainConfigHash! : 'aliquam', - coinsRoot: overrides && overrides.hasOwnProperty('coinsRoot') ? overrides.coinsRoot! : 'quae', - contractsRoot: overrides && overrides.hasOwnProperty('contractsRoot') ? overrides.contractsRoot! : 'voluptatum', - messagesRoot: overrides && overrides.hasOwnProperty('messagesRoot') ? overrides.messagesRoot! : 'eligendi', - }; -}; - -export const aGroupedInput = (overrides?: Partial): { __typename: 'GroupedInput' } & GroupedInput => { - return { - __typename: 'GroupedInput', - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 'l599hn1ptb30dgitrqwggvyjwodfl04t', - contractId: overrides && overrides.hasOwnProperty('contractId') ? overrides.contractId! : '49072p4l3rka407xhz10e7gp0yszhwq0', - data: overrides && overrides.hasOwnProperty('data') ? overrides.data! : '0x7f6727C2AF9F0Efa1b908DFBE867BAf01d77D4da3d6Bc0C3cD6b5f496C412d0fAd36cADdE0d8cADbAc6c7Df5CeFe5AAbE5C1ebF6E2E556EBc9EB3E3e1AEb3BBbBCb48FE25eD0eE14b86bAcD7d544Ac25', - inputs: overrides && overrides.hasOwnProperty('inputs') ? overrides.inputs! : [anInputCoin()], - owner: overrides && overrides.hasOwnProperty('owner') ? overrides.owner! : '8fkjv8kwc0jzv1xcunxejkreq92zr4t1vlxzrtta', - recipient: overrides && overrides.hasOwnProperty('recipient') ? overrides.recipient! : 'kvplkj85usmst9e0xjn49sgbuh9wxa35lpfkgbra', - sender: overrides && overrides.hasOwnProperty('sender') ? overrides.sender! : '6e6zaxag3v02nvh7jj6xi3gcbuv7y8zb4rr18s0n', - totalAmount: overrides && overrides.hasOwnProperty('totalAmount') ? overrides.totalAmount! : '0xF', - type: overrides && overrides.hasOwnProperty('type') ? overrides.type! : GroupedInputType.InputCoin, - }; -}; - -export const aGroupedOutput = (overrides?: Partial): { __typename: 'GroupedOutput' } & GroupedOutput => { - return { - __typename: 'GroupedOutput', - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 'p8osmyjj0rnsi6vo519osau4bdzyw6l6', - contract: overrides && overrides.hasOwnProperty('contract') ? overrides.contract! : aContract(), - inputIndex: overrides && overrides.hasOwnProperty('inputIndex') ? overrides.inputIndex! : 8778, - outputs: overrides && overrides.hasOwnProperty('outputs') ? overrides.outputs! : [aChangeOutput()], - recipient: overrides && overrides.hasOwnProperty('recipient') ? overrides.recipient! : '6ybk3rig2whm9etumk6wzngk9tnu48powxck8bi9', - to: overrides && overrides.hasOwnProperty('to') ? overrides.to! : '3iyq0oy3da8pvdzjktq1pkua8w8a3rx4gr4k2zzp', - totalAmount: overrides && overrides.hasOwnProperty('totalAmount') ? overrides.totalAmount! : '0xb', - type: overrides && overrides.hasOwnProperty('type') ? overrides.type! : GroupedOutputType.ChangeOutput, - }; -}; - -export const aHeader = (overrides?: Partial

): { __typename: 'Header' } & Header => { - return { - __typename: 'Header', - applicationHash: overrides && overrides.hasOwnProperty('applicationHash') ? overrides.applicationHash! : 'sint', - daHeight: overrides && overrides.hasOwnProperty('daHeight') ? overrides.daHeight! : '0xb', - height: overrides && overrides.hasOwnProperty('height') ? overrides.height! : 'saepe', - id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'pariatur', - messageReceiptCount: overrides && overrides.hasOwnProperty('messageReceiptCount') ? overrides.messageReceiptCount! : '0x1', - messageReceiptRoot: overrides && overrides.hasOwnProperty('messageReceiptRoot') ? overrides.messageReceiptRoot! : 'quas', - prevRoot: overrides && overrides.hasOwnProperty('prevRoot') ? overrides.prevRoot! : 'reprehenderit', - time: overrides && overrides.hasOwnProperty('time') ? overrides.time! : 'perspiciatis', - transactionsCount: overrides && overrides.hasOwnProperty('transactionsCount') ? overrides.transactionsCount! : '0x0', - transactionsRoot: overrides && overrides.hasOwnProperty('transactionsRoot') ? overrides.transactionsRoot! : 'animi', - }; -}; - -export const aHeavyOperation = (overrides?: Partial): { __typename: 'HeavyOperation' } & HeavyOperation => { - return { - __typename: 'HeavyOperation', - base: overrides && overrides.hasOwnProperty('base') ? overrides.base! : '0xE', - gasPerUnit: overrides && overrides.hasOwnProperty('gasPerUnit') ? overrides.gasPerUnit! : '0xF', - }; -}; - -export const anInputCoin = (overrides?: Partial): { __typename: 'InputCoin' } & InputCoin => { - return { - __typename: 'InputCoin', - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0xA', - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 'y27xk4sns2byxqyzgpcy513i3crqms8m', - maturity: overrides && overrides.hasOwnProperty('maturity') ? overrides.maturity! : 'incidunt', - owner: overrides && overrides.hasOwnProperty('owner') ? overrides.owner! : 'vamcamah4e8u1v6tw4ldf49gn6i4nhcxuhztvd8f', - predicate: overrides && overrides.hasOwnProperty('predicate') ? overrides.predicate! : '0xa67Faa70dBB8BFe84AeA310BFCb62991Ad08F6635BBeFeafAe7abac62E8BdeeB4cefB8E74f0dB67569E5f42cCdc9EBfA64c4326ED6Df8B3583E50A790F441b29BDD613D18e7D9eF2d42fE1F8C7dd4ee3', - predicateData: overrides && overrides.hasOwnProperty('predicateData') ? overrides.predicateData! : '0x63CCab6C200Cade6C4B7d1689bB2964b3BD8CaAb96C1AcBba1CED702F09b342f40d10F36824275eDba5BD55B657b71CF409Aeee963C126Bb2dEb80bDEeB57DF6c1dEdDC65389f3FAc6c72910319aBF2B', - predicateGasUsed: overrides && overrides.hasOwnProperty('predicateGasUsed') ? overrides.predicateGasUsed! : '0xd', - txPointer: overrides && overrides.hasOwnProperty('txPointer') ? overrides.txPointer! : 'officia', - utxoId: overrides && overrides.hasOwnProperty('utxoId') ? overrides.utxoId! : '37d3ah19hr1fh00b5j2qsz0tjfhyjk5f', - witnessIndex: overrides && overrides.hasOwnProperty('witnessIndex') ? overrides.witnessIndex! : 8296, - }; -}; - -export const anInputContract = (overrides?: Partial): { __typename: 'InputContract' } & InputContract => { - return { - __typename: 'InputContract', - balanceRoot: overrides && overrides.hasOwnProperty('balanceRoot') ? overrides.balanceRoot! : 'laboriosam', - contract: overrides && overrides.hasOwnProperty('contract') ? overrides.contract! : aContract(), - stateRoot: overrides && overrides.hasOwnProperty('stateRoot') ? overrides.stateRoot! : 'voluptatem', - txPointer: overrides && overrides.hasOwnProperty('txPointer') ? overrides.txPointer! : 'natus', - utxoId: overrides && overrides.hasOwnProperty('utxoId') ? overrides.utxoId! : 'bdooy2lb4df6d1qrjvhul62w3u6t7zu9', - }; -}; - -export const anInputMessage = (overrides?: Partial): { __typename: 'InputMessage' } & InputMessage => { - return { - __typename: 'InputMessage', - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0x5', - data: overrides && overrides.hasOwnProperty('data') ? overrides.data! : '0xffd6Fc68D8c1a4DffacF63db8CEb7FFfA2db2593cDEbFb1De88bF3ebDabFb9813db7bd45DE53dd24d4FCCfD7005D63fb806A0574dcba040c4bdFAdB5d8b66BffeAC2D282A0D6305AbDcaAaBB1479AF9f', - nonce: overrides && overrides.hasOwnProperty('nonce') ? overrides.nonce! : 'labore', - predicate: overrides && overrides.hasOwnProperty('predicate') ? overrides.predicate! : '0x44db0eAA0a6aBD6a0b2e1bAee42Bb2aD2dcDA8eAE1A3aF9A13EBfBE852d8E4D5450A3712bDe127A27Bd8dC149965Bde13Abee6Ddbb6aDcfE4420c53eCbe01B6d268A85eC2fffA1d9264CEDbD3d8ADCfF', - predicateData: overrides && overrides.hasOwnProperty('predicateData') ? overrides.predicateData! : '0x33CfF8399c2AE8debdB30dE8bBeCD90C9dEbdcA005444F492CcF5DF0B8E9d5a1EBDBf405Af0Beabe45aF6C05C888BFEd8789e0ed3aEadBAafaF83D60fDF6E48A9ceBc1aebc5EcDacf3cD297c7ab02D1D', - predicateGasUsed: overrides && overrides.hasOwnProperty('predicateGasUsed') ? overrides.predicateGasUsed! : '0x5', - recipient: overrides && overrides.hasOwnProperty('recipient') ? overrides.recipient! : '9zwmg9jnt78zbvx3yxpdmav9do29us3xpjekgh1w', - sender: overrides && overrides.hasOwnProperty('sender') ? overrides.sender! : 'zhhyn3xw7xjv92a6r70t4cxh0hrjaj1r2jqekoag', - witnessIndex: overrides && overrides.hasOwnProperty('witnessIndex') ? overrides.witnessIndex! : 4160, - }; -}; - -export const aLightOperation = (overrides?: Partial): { __typename: 'LightOperation' } & LightOperation => { - return { - __typename: 'LightOperation', - base: overrides && overrides.hasOwnProperty('base') ? overrides.base! : '0x2', - unitsPerGas: overrides && overrides.hasOwnProperty('unitsPerGas') ? overrides.unitsPerGas! : '0xC', - }; -}; - -export const aMerkleProof = (overrides?: Partial): { __typename: 'MerkleProof' } & MerkleProof => { - return { - __typename: 'MerkleProof', - proofIndex: overrides && overrides.hasOwnProperty('proofIndex') ? overrides.proofIndex! : '0x8', - proofSet: overrides && overrides.hasOwnProperty('proofSet') ? overrides.proofSet! : ['voluptatem'], - }; -}; - -export const aMessage = (overrides?: Partial): { __typename: 'Message' } & Message => { - return { - __typename: 'Message', - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0xf', - daHeight: overrides && overrides.hasOwnProperty('daHeight') ? overrides.daHeight! : '0xD', - data: overrides && overrides.hasOwnProperty('data') ? overrides.data! : '0xec2db5aad31B91F403b8bcFA5dD8F6845C6514DaDeea2436cCE1E06CE58B5296Daab472Bb836847ecf6847729Afd2DefC48F9d07b8cb8DfFC165aF23df8c9BcaB436a215F43a7fab959115dDb0dB4e1a', - nonce: overrides && overrides.hasOwnProperty('nonce') ? overrides.nonce! : 'sapiente', - recipient: overrides && overrides.hasOwnProperty('recipient') ? overrides.recipient! : 'wcevmsvhv80welag1jy7xwl2tpov1t6j49u8cpu8', - sender: overrides && overrides.hasOwnProperty('sender') ? overrides.sender! : 'o6quj8u98g4443vfmjfvuul2fxj1vjjhpubzjg0d', - }; -}; - -export const aMessageCoin = (overrides?: Partial): { __typename: 'MessageCoin' } & MessageCoin => { - return { - __typename: 'MessageCoin', - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0xE', - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 'jpsgc82trduth738qdx4lhs5i49bkjtd', - daHeight: overrides && overrides.hasOwnProperty('daHeight') ? overrides.daHeight! : '0xD', - nonce: overrides && overrides.hasOwnProperty('nonce') ? overrides.nonce! : 'modi', - recipient: overrides && overrides.hasOwnProperty('recipient') ? overrides.recipient! : '9ihbzqa03yfdgtw7q44azh77epkfzyjvoq58ldsc', - sender: overrides && overrides.hasOwnProperty('sender') ? overrides.sender! : '285w90pyy72x8y114624t9i328lyqmeno2nbs7qk', - }; -}; - -export const aMessageConnection = (overrides?: Partial): { __typename: 'MessageConnection' } & MessageConnection => { - return { - __typename: 'MessageConnection', - edges: overrides && overrides.hasOwnProperty('edges') ? overrides.edges! : [aMessageEdge()], - nodes: overrides && overrides.hasOwnProperty('nodes') ? overrides.nodes! : [aMessage()], - pageInfo: overrides && overrides.hasOwnProperty('pageInfo') ? overrides.pageInfo! : aPageInfo(), - }; -}; - -export const aMessageEdge = (overrides?: Partial): { __typename: 'MessageEdge' } & MessageEdge => { - return { - __typename: 'MessageEdge', - cursor: overrides && overrides.hasOwnProperty('cursor') ? overrides.cursor! : 'quas', - node: overrides && overrides.hasOwnProperty('node') ? overrides.node! : aMessage(), - }; -}; - -export const aMessageProof = (overrides?: Partial): { __typename: 'MessageProof' } & MessageProof => { - return { - __typename: 'MessageProof', - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0xa', - blockProof: overrides && overrides.hasOwnProperty('blockProof') ? overrides.blockProof! : aMerkleProof(), - commitBlockHeader: overrides && overrides.hasOwnProperty('commitBlockHeader') ? overrides.commitBlockHeader! : aHeader(), - data: overrides && overrides.hasOwnProperty('data') ? overrides.data! : '0x7d92f23a7d82BaAC7beA88Ba6DD85fFB85c368D7984bf87D32b5DcBb79B877d0b20acE4c41F7f3e601BBBeEAA34BbeeA9AAF4F58E3cc2997e42fDA2d9cb6AFBaec43fa33adDe7F458Eda8c9d318f86aA', - messageBlockHeader: overrides && overrides.hasOwnProperty('messageBlockHeader') ? overrides.messageBlockHeader! : aHeader(), - messageProof: overrides && overrides.hasOwnProperty('messageProof') ? overrides.messageProof! : aMerkleProof(), - nonce: overrides && overrides.hasOwnProperty('nonce') ? overrides.nonce! : 'enim', - recipient: overrides && overrides.hasOwnProperty('recipient') ? overrides.recipient! : 'dgpdudd1bdvc6wt4rkqjkvi4ycbkxoo9bcn17xof', - sender: overrides && overrides.hasOwnProperty('sender') ? overrides.sender! : 'yp1myonssz56zhe7fe1iakhvo22x2n8nek77r1lo', - }; -}; - -export const aMessageStatus = (overrides?: Partial): { __typename: 'MessageStatus' } & MessageStatus => { - return { - __typename: 'MessageStatus', - state: overrides && overrides.hasOwnProperty('state') ? overrides.state! : MessageState.NotFound, - }; -}; - -export const aMutation = (overrides?: Partial): { __typename: 'Mutation' } & Mutation => { - return { - __typename: 'Mutation', - continueTx: overrides && overrides.hasOwnProperty('continueTx') ? overrides.continueTx! : aRunResult(), - dryRun: overrides && overrides.hasOwnProperty('dryRun') ? overrides.dryRun! : [aReceipt()], - endSession: overrides && overrides.hasOwnProperty('endSession') ? overrides.endSession! : false, - execute: overrides && overrides.hasOwnProperty('execute') ? overrides.execute! : true, - produceBlocks: overrides && overrides.hasOwnProperty('produceBlocks') ? overrides.produceBlocks! : 'voluptatum', - reset: overrides && overrides.hasOwnProperty('reset') ? overrides.reset! : false, - setBreakpoint: overrides && overrides.hasOwnProperty('setBreakpoint') ? overrides.setBreakpoint! : true, - setSingleStepping: overrides && overrides.hasOwnProperty('setSingleStepping') ? overrides.setSingleStepping! : false, - startSession: overrides && overrides.hasOwnProperty('startSession') ? overrides.startSession! : '41a96a12-468a-4440-92ca-9eb4da4141a5', - startTx: overrides && overrides.hasOwnProperty('startTx') ? overrides.startTx! : aRunResult(), - submit: overrides && overrides.hasOwnProperty('submit') ? overrides.submit! : aTransaction(), - }; -}; - -export const aNodeInfo = (overrides?: Partial): { __typename: 'NodeInfo' } & NodeInfo => { - return { - __typename: 'NodeInfo', - maxDepth: overrides && overrides.hasOwnProperty('maxDepth') ? overrides.maxDepth! : '0xf', - maxTx: overrides && overrides.hasOwnProperty('maxTx') ? overrides.maxTx! : '0x2', - minGasPrice: overrides && overrides.hasOwnProperty('minGasPrice') ? overrides.minGasPrice! : '0x3', - nodeVersion: overrides && overrides.hasOwnProperty('nodeVersion') ? overrides.nodeVersion! : 'nobis', - peers: overrides && overrides.hasOwnProperty('peers') ? overrides.peers! : [aPeerInfo()], - utxoValidation: overrides && overrides.hasOwnProperty('utxoValidation') ? overrides.utxoValidation! : true, - vmBacktrace: overrides && overrides.hasOwnProperty('vmBacktrace') ? overrides.vmBacktrace! : true, - }; -}; - -export const anOperation = (overrides?: Partial): { __typename: 'Operation' } & Operation => { - return { - __typename: 'Operation', - receipts: overrides && overrides.hasOwnProperty('receipts') ? overrides.receipts! : [anOperationReceipt()], - type: overrides && overrides.hasOwnProperty('type') ? overrides.type! : OperationType.FinalResult, - }; -}; - -export const anOperationReceipt = (overrides?: Partial): { __typename: 'OperationReceipt' } & OperationReceipt => { - return { - __typename: 'OperationReceipt', - item: overrides && overrides.hasOwnProperty('item') ? overrides.item! : aReceipt(), - receipts: overrides && overrides.hasOwnProperty('receipts') ? overrides.receipts! : [anOperationReceipt()], - }; -}; - -export const anOutputBreakpoint = (overrides?: Partial): { __typename: 'OutputBreakpoint' } & OutputBreakpoint => { - return { - __typename: 'OutputBreakpoint', - contract: overrides && overrides.hasOwnProperty('contract') ? overrides.contract! : '6ghwqlax5rq8vz7bbvxhn3nex1uoqjwo', - pc: overrides && overrides.hasOwnProperty('pc') ? overrides.pc! : '0xf', - }; -}; - -export const aPageInfo = (overrides?: Partial): { __typename: 'PageInfo' } & PageInfo => { - return { - __typename: 'PageInfo', - endCursor: overrides && overrides.hasOwnProperty('endCursor') ? overrides.endCursor! : 'cum', - hasNextPage: overrides && overrides.hasOwnProperty('hasNextPage') ? overrides.hasNextPage! : false, - hasPreviousPage: overrides && overrides.hasOwnProperty('hasPreviousPage') ? overrides.hasPreviousPage! : true, - startCursor: overrides && overrides.hasOwnProperty('startCursor') ? overrides.startCursor! : 'repellendus', - }; -}; - -export const aParsedTime = (overrides?: Partial): { __typename: 'ParsedTime' } & ParsedTime => { - return { - __typename: 'ParsedTime', - fromNow: overrides && overrides.hasOwnProperty('fromNow') ? overrides.fromNow! : 'amet', - full: overrides && overrides.hasOwnProperty('full') ? overrides.full! : 'beatae', - rawTai64: overrides && overrides.hasOwnProperty('rawTai64') ? overrides.rawTai64! : 'esse', - rawUnix: overrides && overrides.hasOwnProperty('rawUnix') ? overrides.rawUnix! : 'quis', - }; -}; - -export const aPeerInfo = (overrides?: Partial): { __typename: 'PeerInfo' } & PeerInfo => { - return { - __typename: 'PeerInfo', - addresses: overrides && overrides.hasOwnProperty('addresses') ? overrides.addresses! : ['iusto'], - appScore: overrides && overrides.hasOwnProperty('appScore') ? overrides.appScore! : 0.8, - blockHeight: overrides && overrides.hasOwnProperty('blockHeight') ? overrides.blockHeight! : 'magni', - clientVersion: overrides && overrides.hasOwnProperty('clientVersion') ? overrides.clientVersion! : 'vero', - id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'nesciunt', - lastHeartbeatMs: overrides && overrides.hasOwnProperty('lastHeartbeatMs') ? overrides.lastHeartbeatMs! : '0x9', - }; -}; - -export const aPoAConsensus = (overrides?: Partial): { __typename: 'PoAConsensus' } & PoAConsensus => { - return { - __typename: 'PoAConsensus', - signature: overrides && overrides.hasOwnProperty('signature') ? overrides.signature! : 'consectetur', - }; -}; - -export const aPolicies = (overrides?: Partial): { __typename: 'Policies' } & Policies => { - return { - __typename: 'Policies', - gasPrice: overrides && overrides.hasOwnProperty('gasPrice') ? overrides.gasPrice! : '0xc', - maturity: overrides && overrides.hasOwnProperty('maturity') ? overrides.maturity! : 'ex', - maxFee: overrides && overrides.hasOwnProperty('maxFee') ? overrides.maxFee! : '0x8', - witnessLimit: overrides && overrides.hasOwnProperty('witnessLimit') ? overrides.witnessLimit! : '0xb', - }; -}; - -export const aPredicate = (overrides?: Partial): { __typename: 'Predicate' } & Predicate => { - return { - __typename: 'Predicate', - bytecode: overrides && overrides.hasOwnProperty('bytecode') ? overrides.bytecode! : '0xfffe55e470BDC8afCf78D3F2Fc7A78Db29ed2a983a8487e5c920C9cAF84BAC09391A115a6E8dC6FdaEDB8ccddD9C2aAFFA88B8bBa1b24A79cE1eF1FfEb54C59Cc3dEF3abEcCFFb127D952e79fcC2aE5C', - id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'h8av7w6p17to88fx0fsavbp5jsx5zhikml24gqju', - }; -}; - -export const aPredicateParameters = (overrides?: Partial): { __typename: 'PredicateParameters' } & PredicateParameters => { - return { - __typename: 'PredicateParameters', - maxGasPerPredicate: overrides && overrides.hasOwnProperty('maxGasPerPredicate') ? overrides.maxGasPerPredicate! : '0x0', - maxMessageDataLength: overrides && overrides.hasOwnProperty('maxMessageDataLength') ? overrides.maxMessageDataLength! : '0xe', - maxPredicateDataLength: overrides && overrides.hasOwnProperty('maxPredicateDataLength') ? overrides.maxPredicateDataLength! : '0xE', - maxPredicateLength: overrides && overrides.hasOwnProperty('maxPredicateLength') ? overrides.maxPredicateLength! : '0x8', - }; -}; - -export const aProgramState = (overrides?: Partial): { __typename: 'ProgramState' } & ProgramState => { - return { - __typename: 'ProgramState', - data: overrides && overrides.hasOwnProperty('data') ? overrides.data! : '0xE8f2fDf6aF89644c89Ca7eC89Bd1Aab8B95c114F2eE3fBF8b1C10AC6ccCe9EafA5dCeFaC56832ED898dC230295bc996bBCa7b21Fb0F614b0B2C28e964C2aA9f0F1C1808c9B9cB0ab60EAD68F8E07Baa2', - returnType: overrides && overrides.hasOwnProperty('returnType') ? overrides.returnType! : ReturnType.Return, - }; -}; - -export const aQuery = (overrides?: Partial): { __typename: 'Query' } & Query => { - return { - __typename: 'Query', - accounts: overrides && overrides.hasOwnProperty('accounts') ? overrides.accounts! : [anAccount()], - balance: overrides && overrides.hasOwnProperty('balance') ? overrides.balance! : aBalance(), - balances: overrides && overrides.hasOwnProperty('balances') ? overrides.balances! : aBalanceConnection(), - block: overrides && overrides.hasOwnProperty('block') ? overrides.block! : aBlock(), - blocks: overrides && overrides.hasOwnProperty('blocks') ? overrides.blocks! : aBlockConnection(), - chain: overrides && overrides.hasOwnProperty('chain') ? overrides.chain! : aChainInfo(), - coin: overrides && overrides.hasOwnProperty('coin') ? overrides.coin! : aCoin(), - coins: overrides && overrides.hasOwnProperty('coins') ? overrides.coins! : aCoinConnection(), - coinsToSpend: overrides && overrides.hasOwnProperty('coinsToSpend') ? overrides.coinsToSpend! : [[aCoin()]], - contract: overrides && overrides.hasOwnProperty('contract') ? overrides.contract! : aContract(), - contractBalance: overrides && overrides.hasOwnProperty('contractBalance') ? overrides.contractBalance! : aContractBalance(), - contractBalances: overrides && overrides.hasOwnProperty('contractBalances') ? overrides.contractBalances! : aContractBalanceConnection(), - estimatePredicates: overrides && overrides.hasOwnProperty('estimatePredicates') ? overrides.estimatePredicates! : aTransaction(), - health: overrides && overrides.hasOwnProperty('health') ? overrides.health! : true, - memory: overrides && overrides.hasOwnProperty('memory') ? overrides.memory! : 'id', - messageProof: overrides && overrides.hasOwnProperty('messageProof') ? overrides.messageProof! : aMessageProof(), - messageStatus: overrides && overrides.hasOwnProperty('messageStatus') ? overrides.messageStatus! : aMessageStatus(), - messages: overrides && overrides.hasOwnProperty('messages') ? overrides.messages! : aMessageConnection(), - nodeInfo: overrides && overrides.hasOwnProperty('nodeInfo') ? overrides.nodeInfo! : aNodeInfo(), - predicate: overrides && overrides.hasOwnProperty('predicate') ? overrides.predicate! : aPredicate(), - register: overrides && overrides.hasOwnProperty('register') ? overrides.register! : '0x3', - search: overrides && overrides.hasOwnProperty('search') ? overrides.search! : aSearchResult(), - tokens: overrides && overrides.hasOwnProperty('tokens') ? overrides.tokens! : [aToken()], - transaction: overrides && overrides.hasOwnProperty('transaction') ? overrides.transaction! : aTransaction(), - transactions: overrides && overrides.hasOwnProperty('transactions') ? overrides.transactions! : aTransactionConnection(), - transactionsByOwner: overrides && overrides.hasOwnProperty('transactionsByOwner') ? overrides.transactionsByOwner! : aTransactionConnection(), - }; -}; - -export const aReceipt = (overrides?: Partial): { __typename: 'Receipt' } & Receipt => { - return { - __typename: 'Receipt', - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0xB', - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 'z58vuwpyp5fwi1yhwzlqj9ka232t9a8r', - contract: overrides && overrides.hasOwnProperty('contract') ? overrides.contract! : aContract(), - contractId: overrides && overrides.hasOwnProperty('contractId') ? overrides.contractId! : '9d382ivp4mteisohn79svut91p9msibm', - data: overrides && overrides.hasOwnProperty('data') ? overrides.data! : '0xe2b353aAEa5e7E1Ff6fc4Da5bf9c0af8c0DcEe5ECD206ba852cDf1C7285F1fbd9eCbE4ba1AFCb6f9f4ef2Ce96c1a8f1DFE4AcD2FaD74D82eB1DFBFeFE3fc2F8EADBeeCDEE0ebF41E3ba0682aaa8Fa59A', - digest: overrides && overrides.hasOwnProperty('digest') ? overrides.digest! : 'architecto', - gas: overrides && overrides.hasOwnProperty('gas') ? overrides.gas! : '0x4', - gasUsed: overrides && overrides.hasOwnProperty('gasUsed') ? overrides.gasUsed! : '0x2', - is: overrides && overrides.hasOwnProperty('is') ? overrides.is! : '0xb', - len: overrides && overrides.hasOwnProperty('len') ? overrides.len! : '0xf', - nonce: overrides && overrides.hasOwnProperty('nonce') ? overrides.nonce! : 'mollitia', - param1: overrides && overrides.hasOwnProperty('param1') ? overrides.param1! : '0xf', - param2: overrides && overrides.hasOwnProperty('param2') ? overrides.param2! : '0xe', - pc: overrides && overrides.hasOwnProperty('pc') ? overrides.pc! : '0xd', - ptr: overrides && overrides.hasOwnProperty('ptr') ? overrides.ptr! : '0x8', - ra: overrides && overrides.hasOwnProperty('ra') ? overrides.ra! : '0xA', - rb: overrides && overrides.hasOwnProperty('rb') ? overrides.rb! : '0xd', - rc: overrides && overrides.hasOwnProperty('rc') ? overrides.rc! : '0x2', - rd: overrides && overrides.hasOwnProperty('rd') ? overrides.rd! : '0xF', - reason: overrides && overrides.hasOwnProperty('reason') ? overrides.reason! : '0xF', - receiptType: overrides && overrides.hasOwnProperty('receiptType') ? overrides.receiptType! : ReceiptType.Burn, - recipient: overrides && overrides.hasOwnProperty('recipient') ? overrides.recipient! : 'q7mhlsz9na9drlzwtj38y91r243dzrsfdkzsyxiq', - result: overrides && overrides.hasOwnProperty('result') ? overrides.result! : '0x0', - sender: overrides && overrides.hasOwnProperty('sender') ? overrides.sender! : 'ysjl9jycalt7pupoecumgfg3l76d5g22g2yy181x', - subId: overrides && overrides.hasOwnProperty('subId') ? overrides.subId! : 'quam', - to: overrides && overrides.hasOwnProperty('to') ? overrides.to! : aContract(), - toAddress: overrides && overrides.hasOwnProperty('toAddress') ? overrides.toAddress! : '40v7wkyreg1nryfbtnbhw09swv0ciohkdcfloi6w', - val: overrides && overrides.hasOwnProperty('val') ? overrides.val! : '0xf', - }; -}; - -export const aRunResult = (overrides?: Partial): { __typename: 'RunResult' } & RunResult => { - return { - __typename: 'RunResult', - breakpoint: overrides && overrides.hasOwnProperty('breakpoint') ? overrides.breakpoint! : anOutputBreakpoint(), - jsonReceipts: overrides && overrides.hasOwnProperty('jsonReceipts') ? overrides.jsonReceipts! : ['esse'], - state: overrides && overrides.hasOwnProperty('state') ? overrides.state! : RunState.Breakpoint, - }; -}; - -export const aScriptParameters = (overrides?: Partial): { __typename: 'ScriptParameters' } & ScriptParameters => { - return { - __typename: 'ScriptParameters', - maxScriptDataLength: overrides && overrides.hasOwnProperty('maxScriptDataLength') ? overrides.maxScriptDataLength! : '0x9', - maxScriptLength: overrides && overrides.hasOwnProperty('maxScriptLength') ? overrides.maxScriptLength! : '0x8', - }; -}; - -export const aSearchAccount = (overrides?: Partial): { __typename: 'SearchAccount' } & SearchAccount => { - return { - __typename: 'SearchAccount', - address: overrides && overrides.hasOwnProperty('address') ? overrides.address! : 'fxjjhq8rar88egu9vnil1ab5e9xsldm8tl3aii4l', - transactions: overrides && overrides.hasOwnProperty('transactions') ? overrides.transactions! : [aSearchTransaction()], - }; -}; - -export const aSearchBlock = (overrides?: Partial): { __typename: 'SearchBlock' } & SearchBlock => { - return { - __typename: 'SearchBlock', - height: overrides && overrides.hasOwnProperty('height') ? overrides.height! : 'ea', - id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'necessitatibus', - }; -}; - -export const aSearchContract = (overrides?: Partial): { __typename: 'SearchContract' } & SearchContract => { - return { - __typename: 'SearchContract', - id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'cal06fr6xavgycxm6euv9zube4yuy9v6', - }; -}; - -export const aSearchResult = (overrides?: Partial): { __typename: 'SearchResult' } & SearchResult => { - return { - __typename: 'SearchResult', - account: overrides && overrides.hasOwnProperty('account') ? overrides.account! : aSearchAccount(), - block: overrides && overrides.hasOwnProperty('block') ? overrides.block! : aSearchBlock(), - contract: overrides && overrides.hasOwnProperty('contract') ? overrides.contract! : aSearchContract(), - transaction: overrides && overrides.hasOwnProperty('transaction') ? overrides.transaction! : aSearchTransaction(), - }; -}; - -export const aSearchTransaction = (overrides?: Partial): { __typename: 'SearchTransaction' } & SearchTransaction => { - return { - __typename: 'SearchTransaction', - id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'ikjck0dx2w0q8gftmk41pxgde8kadbzf', - }; -}; - -export const aSpendQueryElementInput = (overrides?: Partial): SpendQueryElementInput => { - return { - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0xd', - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 'uf0lsb3kvot747ow9j0nv0mh9tf7zsgw', - max: overrides && overrides.hasOwnProperty('max') ? overrides.max! : 'odit', - }; -}; - -export const aSqueezedOutStatus = (overrides?: Partial): { __typename: 'SqueezedOutStatus' } & SqueezedOutStatus => { - return { - __typename: 'SqueezedOutStatus', - reason: overrides && overrides.hasOwnProperty('reason') ? overrides.reason! : 'voluptatibus', - }; -}; - -export const aSubmittedStatus = (overrides?: Partial): { __typename: 'SubmittedStatus' } & SubmittedStatus => { - return { - __typename: 'SubmittedStatus', - time: overrides && overrides.hasOwnProperty('time') ? overrides.time! : 'natus', - }; -}; - -export const aSubscription = (overrides?: Partial): { __typename: 'Subscription' } & Subscription => { - return { - __typename: 'Subscription', - statusChange: overrides && overrides.hasOwnProperty('statusChange') ? overrides.statusChange! : aFailureStatus(), - submitAndAwait: overrides && overrides.hasOwnProperty('submitAndAwait') ? overrides.submitAndAwait! : aFailureStatus(), - }; -}; - -export const aSuccessStatus = (overrides?: Partial): { __typename: 'SuccessStatus' } & SuccessStatus => { - return { - __typename: 'SuccessStatus', - block: overrides && overrides.hasOwnProperty('block') ? overrides.block! : aBlock(), - programState: overrides && overrides.hasOwnProperty('programState') ? overrides.programState! : aProgramState(), - receipts: overrides && overrides.hasOwnProperty('receipts') ? overrides.receipts! : [aReceipt()], - time: overrides && overrides.hasOwnProperty('time') ? overrides.time! : 'modi', - transactionId: overrides && overrides.hasOwnProperty('transactionId') ? overrides.transactionId! : '7yxyr87uqpfquupe4qq7bmmlpvtejjdv', - }; -}; - -export const aToken = (overrides?: Partial): { __typename: 'Token' } & Token => { - return { - __typename: 'Token', - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 'occaecati', - decimals: overrides && overrides.hasOwnProperty('decimals') ? overrides.decimals! : '0x6', - name: overrides && overrides.hasOwnProperty('name') ? overrides.name! : 'voluptates', - symbol: overrides && overrides.hasOwnProperty('symbol') ? overrides.symbol! : 'iusto', - totalAssets: overrides && overrides.hasOwnProperty('totalAssets') ? overrides.totalAssets! : '0x8', - totalSupply: overrides && overrides.hasOwnProperty('totalSupply') ? overrides.totalSupply! : '0x5', - url: overrides && overrides.hasOwnProperty('url') ? overrides.url! : 'itaque', - }; -}; - -export const aTransaction = (overrides?: Partial): { __typename: 'Transaction' } & Transaction => { - return { - __typename: 'Transaction', - accountsInvolved: overrides && overrides.hasOwnProperty('accountsInvolved') ? overrides.accountsInvolved! : [aTransactionAccount()], - blockHeight: overrides && overrides.hasOwnProperty('blockHeight') ? overrides.blockHeight! : 'non', - bytecodeLength: overrides && overrides.hasOwnProperty('bytecodeLength') ? overrides.bytecodeLength! : '0x6', - bytecodeWitnessIndex: overrides && overrides.hasOwnProperty('bytecodeWitnessIndex') ? overrides.bytecodeWitnessIndex! : 9380, - fee: overrides && overrides.hasOwnProperty('fee') ? overrides.fee! : '0x0', - gasPrice: overrides && overrides.hasOwnProperty('gasPrice') ? overrides.gasPrice! : '0xD', - gasUsed: overrides && overrides.hasOwnProperty('gasUsed') ? overrides.gasUsed! : '0xb', - groupedInputs: overrides && overrides.hasOwnProperty('groupedInputs') ? overrides.groupedInputs! : [aGroupedInput()], - groupedOutputs: overrides && overrides.hasOwnProperty('groupedOutputs') ? overrides.groupedOutputs! : [aGroupedOutput()], - id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'm5skeiw541vcdt1lceitryfralzuwdw9', - inputAssetIds: overrides && overrides.hasOwnProperty('inputAssetIds') ? overrides.inputAssetIds! : ['ivh1nwdxbmv9t9y30qbwmnpsdwxc5pao'], - inputContract: overrides && overrides.hasOwnProperty('inputContract') ? overrides.inputContract! : anInputContract(), - inputContracts: overrides && overrides.hasOwnProperty('inputContracts') ? overrides.inputContracts! : [aContract()], - inputs: overrides && overrides.hasOwnProperty('inputs') ? overrides.inputs! : [anInputCoin()], - isCreate: overrides && overrides.hasOwnProperty('isCreate') ? overrides.isCreate! : true, - isMint: overrides && overrides.hasOwnProperty('isMint') ? overrides.isMint! : false, - isPredicate: overrides && overrides.hasOwnProperty('isPredicate') ? overrides.isPredicate! : false, - isScript: overrides && overrides.hasOwnProperty('isScript') ? overrides.isScript! : true, - maturity: overrides && overrides.hasOwnProperty('maturity') ? overrides.maturity! : 'distinctio', - mintAmount: overrides && overrides.hasOwnProperty('mintAmount') ? overrides.mintAmount! : '0x4', - mintAssetId: overrides && overrides.hasOwnProperty('mintAssetId') ? overrides.mintAssetId! : 'ear74yjd6jnrhxyo9jp8jbbywtajy2y7', - operations: overrides && overrides.hasOwnProperty('operations') ? overrides.operations! : [anOperation()], - outputContract: overrides && overrides.hasOwnProperty('outputContract') ? overrides.outputContract! : aContractOutput(), - outputs: overrides && overrides.hasOwnProperty('outputs') ? overrides.outputs! : [aChangeOutput()], - policies: overrides && overrides.hasOwnProperty('policies') ? overrides.policies! : aPolicies(), - rawPayload: overrides && overrides.hasOwnProperty('rawPayload') ? overrides.rawPayload! : '0xCafBd5Ce4b560Aca24ffa36ce3BdFbAdbeDef78a2f072846FBE99a5FC46eFaAb7CBdFCdd25acC24Ead593EBAE0eA8Ce6CDE3fAa6FD794c53eBb332A25EdD6F86e1BD0CF857DA0DdD7bC49E162cFdE61C', - receipts: overrides && overrides.hasOwnProperty('receipts') ? overrides.receipts! : [aReceipt()], - receiptsRoot: overrides && overrides.hasOwnProperty('receiptsRoot') ? overrides.receiptsRoot! : 'debitis', - salt: overrides && overrides.hasOwnProperty('salt') ? overrides.salt! : 'fuga', - script: overrides && overrides.hasOwnProperty('script') ? overrides.script! : '0xb57ff0B5B7b8fddBE6BC4CF94dFccd4BA278C9b9eCddf46Ad73baBcE85d1ABEaECe392fbeB37116cFcc8E5a15C3E4Ea7356B35c70a1d4DBFe8ab0EDf83bFf6f54FCFF0e90b42b363CD4bEca9d5AB38D5', - scriptData: overrides && overrides.hasOwnProperty('scriptData') ? overrides.scriptData! : '0xa8B9bEba75644Ef15fc7FE0ebEdc7376E6D83DF543E4218a00556f33B1cfa47D935B2cbD0CCD36D1D5074D1bbFAC059E4fCcd3d8FADbca1CcCa85DFb15cdcA817a6aD1d52dd4bbee8ae8c3A08e0dC56A', - scriptGasLimit: overrides && overrides.hasOwnProperty('scriptGasLimit') ? overrides.scriptGasLimit! : '0xA', - status: overrides && overrides.hasOwnProperty('status') ? overrides.status! : aFailureStatus(), - statusType: overrides && overrides.hasOwnProperty('statusType') ? overrides.statusType! : TransactionStatusType.Failure, - storageSlots: overrides && overrides.hasOwnProperty('storageSlots') ? overrides.storageSlots! : ['0x93F3d4f06033Babda85ce01DC9cbfc37cEddcBFf9bEd8DE4c4E83B5305a1DfFb3C4ef9d6E51AEAb68bf0D70eD039DCffF924C2359c5d1c0c0C41C4B2fafF6F692aD54de3a4CAace3bfef27eefe672530'], - time: overrides && overrides.hasOwnProperty('time') ? overrides.time! : aParsedTime(), - title: overrides && overrides.hasOwnProperty('title') ? overrides.title! : 'qui', - totalAccounts: overrides && overrides.hasOwnProperty('totalAccounts') ? overrides.totalAccounts! : 205, - totalAssets: overrides && overrides.hasOwnProperty('totalAssets') ? overrides.totalAssets! : 4943, - totalOperations: overrides && overrides.hasOwnProperty('totalOperations') ? overrides.totalOperations! : 1610, - txPointer: overrides && overrides.hasOwnProperty('txPointer') ? overrides.txPointer! : 'expedita', - witnesses: overrides && overrides.hasOwnProperty('witnesses') ? overrides.witnesses! : ['0x8b5Da64f37447BECBc9A170Ab9C36D48b0D4D0FBEdc79240BE46b52AbfFc1DB1BC9deAEe64E474Ed67bf8641137b857CBCA06ea6362937913F3EDEaca7ffC1Abf45ab6a7941D8bF61Bec1B5fAB8fbb1b'], - }; -}; - -export const aTransactionAccount = (overrides?: Partial): { __typename: 'TransactionAccount' } & TransactionAccount => { - return { - __typename: 'TransactionAccount', - id: overrides && overrides.hasOwnProperty('id') ? overrides.id! : 'aut', - type: overrides && overrides.hasOwnProperty('type') ? overrides.type! : TransactionAccountType.Contract, - }; -}; - -export const aTransactionConnection = (overrides?: Partial): { __typename: 'TransactionConnection' } & TransactionConnection => { - return { - __typename: 'TransactionConnection', - accounts: overrides && overrides.hasOwnProperty('accounts') ? overrides.accounts! : [anAccount()], - edges: overrides && overrides.hasOwnProperty('edges') ? overrides.edges! : [aTransactionEdge()], - nodes: overrides && overrides.hasOwnProperty('nodes') ? overrides.nodes! : [aTransaction()], - pageInfo: overrides && overrides.hasOwnProperty('pageInfo') ? overrides.pageInfo! : aPageInfo(), - tokens: overrides && overrides.hasOwnProperty('tokens') ? overrides.tokens! : [aToken()], - }; -}; - -export const aTransactionEdge = (overrides?: Partial): { __typename: 'TransactionEdge' } & TransactionEdge => { - return { - __typename: 'TransactionEdge', - cursor: overrides && overrides.hasOwnProperty('cursor') ? overrides.cursor! : 'eos', - node: overrides && overrides.hasOwnProperty('node') ? overrides.node! : aTransaction(), - }; -}; - -export const aTxParameters = (overrides?: Partial): { __typename: 'TxParameters' } & TxParameters => { - return { - __typename: 'TxParameters', - maxGasPerTx: overrides && overrides.hasOwnProperty('maxGasPerTx') ? overrides.maxGasPerTx! : '0xf', - maxInputs: overrides && overrides.hasOwnProperty('maxInputs') ? overrides.maxInputs! : 'soluta', - maxOutputs: overrides && overrides.hasOwnProperty('maxOutputs') ? overrides.maxOutputs! : 'iure', - maxSize: overrides && overrides.hasOwnProperty('maxSize') ? overrides.maxSize! : '0x4', - maxWitnesses: overrides && overrides.hasOwnProperty('maxWitnesses') ? overrides.maxWitnesses! : 'modi', - }; -}; - -export const anUtxoItem = (overrides?: Partial): { __typename: 'UtxoItem' } & UtxoItem => { - return { - __typename: 'UtxoItem', - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0xB', - blockCreated: overrides && overrides.hasOwnProperty('blockCreated') ? overrides.blockCreated! : 'quasi', - txCreatedIdx: overrides && overrides.hasOwnProperty('txCreatedIdx') ? overrides.txCreatedIdx! : '0xD', - utxoId: overrides && overrides.hasOwnProperty('utxoId') ? overrides.utxoId! : 'yk6ff55bv2kpr4nl0rf5mxxuz7pelbo0', - }; -}; - -export const aVariableOutput = (overrides?: Partial): { __typename: 'VariableOutput' } & VariableOutput => { - return { - __typename: 'VariableOutput', - amount: overrides && overrides.hasOwnProperty('amount') ? overrides.amount! : '0xc', - assetId: overrides && overrides.hasOwnProperty('assetId') ? overrides.assetId! : 'hq38k3ap8ok8krpquh789zkbfdd74ab6', - to: overrides && overrides.hasOwnProperty('to') ? overrides.to! : '4gs9ppn7jqumdt8t0gd7u4mra5dblqlbgjy1w5bv', - }; -}; diff --git a/packages/graphql/src/generated/types.ts b/packages/graphql/src/generated/types.ts deleted file mode 100644 index a911fbed8..000000000 --- a/packages/graphql/src/generated/types.ts +++ /dev/null @@ -1,1890 +0,0 @@ -import type { GraphQLClient, RequestOptions } from 'graphql-request'; -import { GraphQLError, print } from 'graphql' -import gql from 'graphql-tag'; -export type Maybe = T | null; -export type InputMaybe = Maybe; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { [_ in K]?: never }; -export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -type GraphQLClientRequestHeaders = RequestOptions['requestHeaders']; -/** All built-in and custom scalars, mapped to their actual values */ -export type Scalars = { - ID: { input: string; output: string; } - String: { input: string; output: string; } - Boolean: { input: boolean; output: boolean; } - Int: { input: number; output: number; } - Float: { input: number; output: number; } - Address: { input: string; output: string; } - AssetId: { input: string; output: string; } - BlockId: { input: string; output: string; } - Bytes32: { input: string; output: string; } - ContractId: { input: string; output: string; } - HexString: { input: string; output: string; } - Nonce: { input: string; output: string; } - Salt: { input: string; output: string; } - Signature: { input: string; output: string; } - Tai64Timestamp: { input: string; output: string; } - TransactionId: { input: string; output: string; } - TxPointer: { input: string; output: string; } - U8: { input: string; output: string; } - U32: { input: string; output: string; } - U64: { input: string; output: string; } - UtxoId: { input: string; output: string; } -}; - -export type Account = { - __typename: 'Account'; - address: Scalars['String']['output']; - name: Scalars['String']['output']; - url?: Maybe; -}; - -export type Balance = { - __typename: 'Balance'; - amount: Scalars['U64']['output']; - assetId: Scalars['AssetId']['output']; - owner: Scalars['Address']['output']; - utxos?: Maybe>>; -}; - -export type BalanceConnection = { - __typename: 'BalanceConnection'; - /** A list of edges. */ - edges: Array; - /** A list of nodes. */ - nodes: Array; - /** Information to aid in pagination. */ - pageInfo: PageInfo; -}; - -/** An edge in a connection. */ -export type BalanceEdge = { - __typename: 'BalanceEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node: Balance; -}; - -export type BalanceFilterInput = { - /** Filter coins based on the `owner` field */ - owner: Scalars['Address']['input']; -}; - -export type Block = { - __typename: 'Block'; - consensus: Consensus; - header: Header; - id: Scalars['BlockId']['output']; - producer?: Maybe; - time?: Maybe; - totalGasUsed?: Maybe; - transactions: Array; -}; - -export type BlockConnection = { - __typename: 'BlockConnection'; - /** A list of edges. */ - edges: Array; - /** A list of nodes. */ - nodes: Array; - /** Information to aid in pagination. */ - pageInfo: PageInfo; -}; - -/** An edge in a connection. */ -export type BlockEdge = { - __typename: 'BlockEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node: Block; -}; - -export type Breakpoint = { - contract: Scalars['ContractId']['input']; - pc: Scalars['U64']['input']; -}; - -export type ChainInfo = { - __typename: 'ChainInfo'; - consensusParameters: ConsensusParameters; - daHeight: Scalars['U64']['output']; - gasCosts: GasCosts; - latestBlock: Block; - name: Scalars['String']['output']; -}; - -export type ChangeOutput = { - __typename: 'ChangeOutput'; - amount: Scalars['U64']['output']; - assetId: Scalars['AssetId']['output']; - to: Scalars['Address']['output']; -}; - -export type Coin = { - __typename: 'Coin'; - amount: Scalars['U64']['output']; - assetId: Scalars['AssetId']['output']; - /** TxPointer - the height of the block this coin was created in */ - blockCreated: Scalars['U32']['output']; - maturity: Scalars['U32']['output']; - owner: Scalars['Address']['output']; - /** TxPointer - the index of the transaction that created this coin */ - txCreatedIdx: Scalars['U64']['output']; - utxoId: Scalars['UtxoId']['output']; -}; - -export type CoinConnection = { - __typename: 'CoinConnection'; - /** A list of edges. */ - edges: Array; - /** A list of nodes. */ - nodes: Array; - /** Information to aid in pagination. */ - pageInfo: PageInfo; -}; - -/** An edge in a connection. */ -export type CoinEdge = { - __typename: 'CoinEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node: Coin; -}; - -export type CoinFilterInput = { - /** Returns coins only with `asset_id`. */ - assetId?: InputMaybe; - /** Returns coins owned by the `owner`. */ - owner: Scalars['Address']['input']; -}; - -export type CoinOutput = { - __typename: 'CoinOutput'; - amount: Scalars['U64']['output']; - assetId: Scalars['AssetId']['output']; - to: Scalars['Address']['output']; -}; - -/** The schema analog of the [`coins::CoinType`]. */ -export type CoinType = Coin | MessageCoin; - -export type Consensus = Genesis | PoAConsensus; - -export type ConsensusParameters = { - __typename: 'ConsensusParameters'; - baseAssetId: Scalars['AssetId']['output']; - chainId: Scalars['U64']['output']; - contractParams: ContractParameters; - feeParams: FeeParameters; - gasCosts: GasCosts; - predicateParams: PredicateParameters; - scriptParams: ScriptParameters; - txParams: TxParameters; -}; - -export type Contract = { - __typename: 'Contract'; - bytecode: Scalars['HexString']['output']; - id: Scalars['ContractId']['output']; - salt: Scalars['Salt']['output']; -}; - -export type ContractBalance = { - __typename: 'ContractBalance'; - amount: Scalars['U64']['output']; - assetId: Scalars['AssetId']['output']; - contract: Scalars['ContractId']['output']; -}; - -export type ContractBalanceConnection = { - __typename: 'ContractBalanceConnection'; - /** A list of edges. */ - edges: Array; - /** A list of nodes. */ - nodes: Array; - /** Information to aid in pagination. */ - pageInfo: PageInfo; -}; - -/** An edge in a connection. */ -export type ContractBalanceEdge = { - __typename: 'ContractBalanceEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node: ContractBalance; -}; - -export type ContractBalanceFilterInput = { - /** Filter assets based on the `contractId` field */ - contract: Scalars['ContractId']['input']; -}; - -export type ContractCreated = { - __typename: 'ContractCreated'; - contract: Contract; - stateRoot: Scalars['Bytes32']['output']; -}; - -export type ContractOutput = { - __typename: 'ContractOutput'; - balanceRoot: Scalars['Bytes32']['output']; - inputIndex: Scalars['Int']['output']; - stateRoot: Scalars['Bytes32']['output']; -}; - -export type ContractParameters = { - __typename: 'ContractParameters'; - contractMaxSize: Scalars['U64']['output']; - maxStorageSlots: Scalars['U64']['output']; -}; - -export type DependentCost = HeavyOperation | LightOperation; - -export type ExcludeInput = { - /** Messages to exclude from the selection. */ - messages: Array; - /** Utxos to exclude from the selection. */ - utxos: Array; -}; - -export type FailureStatus = { - __typename: 'FailureStatus'; - block: Block; - programState?: Maybe; - reason: Scalars['String']['output']; - receipts: Array; - time: Scalars['Tai64Timestamp']['output']; - transactionId: Scalars['TransactionId']['output']; -}; - -export type FeeParameters = { - __typename: 'FeeParameters'; - gasPerByte: Scalars['U64']['output']; - gasPriceFactor: Scalars['U64']['output']; -}; - -export type GasCosts = { - __typename: 'GasCosts'; - add: Scalars['U64']['output']; - addi: Scalars['U64']['output']; - aloc: Scalars['U64']['output']; - and: Scalars['U64']['output']; - andi: Scalars['U64']['output']; - bal: Scalars['U64']['output']; - bhei: Scalars['U64']['output']; - bhsh: Scalars['U64']['output']; - burn: Scalars['U64']['output']; - call: DependentCost; - cb: Scalars['U64']['output']; - ccp: DependentCost; - cfei: Scalars['U64']['output']; - cfsi: Scalars['U64']['output']; - contractRoot: DependentCost; - croo: Scalars['U64']['output']; - csiz: DependentCost; - div: Scalars['U64']['output']; - divi: Scalars['U64']['output']; - eck1: Scalars['U64']['output']; - ecr1: Scalars['U64']['output']; - ed19: Scalars['U64']['output']; - eq: Scalars['U64']['output']; - exp: Scalars['U64']['output']; - expi: Scalars['U64']['output']; - flag: Scalars['U64']['output']; - gm: Scalars['U64']['output']; - gt: Scalars['U64']['output']; - gtf: Scalars['U64']['output']; - ji: Scalars['U64']['output']; - jmp: Scalars['U64']['output']; - jmpb: Scalars['U64']['output']; - jmpf: Scalars['U64']['output']; - jne: Scalars['U64']['output']; - jneb: Scalars['U64']['output']; - jnef: Scalars['U64']['output']; - jnei: Scalars['U64']['output']; - jnzb: Scalars['U64']['output']; - jnzf: Scalars['U64']['output']; - jnzi: Scalars['U64']['output']; - k256: DependentCost; - lb: Scalars['U64']['output']; - ldc: DependentCost; - log: Scalars['U64']['output']; - logd: DependentCost; - lt: Scalars['U64']['output']; - lw: Scalars['U64']['output']; - mcl: DependentCost; - mcli: DependentCost; - mcp: DependentCost; - mcpi: DependentCost; - meq: DependentCost; - mint: Scalars['U64']['output']; - mldv: Scalars['U64']['output']; - mlog: Scalars['U64']['output']; - modOp: Scalars['U64']['output']; - modi: Scalars['U64']['output']; - moveOp: Scalars['U64']['output']; - movi: Scalars['U64']['output']; - mroo: Scalars['U64']['output']; - mul: Scalars['U64']['output']; - muli: Scalars['U64']['output']; - newStoragePerByte: Scalars['U64']['output']; - noop: Scalars['U64']['output']; - not: Scalars['U64']['output']; - or: Scalars['U64']['output']; - ori: Scalars['U64']['output']; - poph: Scalars['U64']['output']; - popl: Scalars['U64']['output']; - pshh: Scalars['U64']['output']; - pshl: Scalars['U64']['output']; - ret: Scalars['U64']['output']; - retd: DependentCost; - rvrt: Scalars['U64']['output']; - s256: DependentCost; - sb: Scalars['U64']['output']; - scwq: DependentCost; - sll: Scalars['U64']['output']; - slli: Scalars['U64']['output']; - smo: DependentCost; - srl: Scalars['U64']['output']; - srli: Scalars['U64']['output']; - srw: Scalars['U64']['output']; - srwq: DependentCost; - stateRoot: DependentCost; - sub: Scalars['U64']['output']; - subi: Scalars['U64']['output']; - sw: Scalars['U64']['output']; - sww: Scalars['U64']['output']; - swwq: DependentCost; - time: Scalars['U64']['output']; - tr: Scalars['U64']['output']; - tro: Scalars['U64']['output']; - vmInitialization: DependentCost; - wdam: Scalars['U64']['output']; - wdcm: Scalars['U64']['output']; - wddv: Scalars['U64']['output']; - wdmd: Scalars['U64']['output']; - wdml: Scalars['U64']['output']; - wdmm: Scalars['U64']['output']; - wdop: Scalars['U64']['output']; - wqam: Scalars['U64']['output']; - wqcm: Scalars['U64']['output']; - wqdv: Scalars['U64']['output']; - wqmd: Scalars['U64']['output']; - wqml: Scalars['U64']['output']; - wqmm: Scalars['U64']['output']; - wqop: Scalars['U64']['output']; - xor: Scalars['U64']['output']; - xori: Scalars['U64']['output']; -}; - -export type Genesis = { - __typename: 'Genesis'; - /** - * The chain configs define what consensus type to use, what settlement layer to use, - * rules of block validity, etc. - */ - chainConfigHash: Scalars['Bytes32']['output']; - /** The Binary Merkle Tree root of all genesis coins. */ - coinsRoot: Scalars['Bytes32']['output']; - /** The Binary Merkle Tree root of state, balances, contracts code hash of each contract. */ - contractsRoot: Scalars['Bytes32']['output']; - /** The Binary Merkle Tree root of all genesis messages. */ - messagesRoot: Scalars['Bytes32']['output']; -}; - -export type GroupedInput = { - __typename: 'GroupedInput'; - assetId?: Maybe; - contractId?: Maybe; - data?: Maybe; - inputs?: Maybe>>; - owner?: Maybe; - recipient?: Maybe; - sender?: Maybe; - totalAmount?: Maybe; - type?: Maybe; -}; - -export enum GroupedInputType { - InputCoin = 'InputCoin', - InputContract = 'InputContract', - InputMessage = 'InputMessage' -} - -export type GroupedOutput = { - __typename: 'GroupedOutput'; - assetId?: Maybe; - contract?: Maybe; - inputIndex?: Maybe; - outputs?: Maybe>>; - recipient?: Maybe; - to?: Maybe; - totalAmount?: Maybe; - type?: Maybe; -}; - -export enum GroupedOutputType { - ChangeOutput = 'ChangeOutput', - CoinOutput = 'CoinOutput', - ContractCreated = 'ContractCreated', - ContractOutput = 'ContractOutput', - MessageOutput = 'MessageOutput', - VariableOutput = 'VariableOutput' -} - -export type Header = { - __typename: 'Header'; - /** Hash of the application header. */ - applicationHash: Scalars['Bytes32']['output']; - /** The layer 1 height of messages and events to include since the last layer 1 block number. */ - daHeight: Scalars['U64']['output']; - /** Fuel block height. */ - height: Scalars['U32']['output']; - /** Hash of the header */ - id: Scalars['BlockId']['output']; - /** Number of message receipts in this block. */ - messageReceiptCount: Scalars['U64']['output']; - /** Merkle root of message receipts in this block. */ - messageReceiptRoot: Scalars['Bytes32']['output']; - /** Merkle root of all previous block header hashes. */ - prevRoot: Scalars['Bytes32']['output']; - /** The block producer time. */ - time: Scalars['Tai64Timestamp']['output']; - /** Number of transactions in this block. */ - transactionsCount: Scalars['U64']['output']; - /** Merkle root of transactions. */ - transactionsRoot: Scalars['Bytes32']['output']; -}; - -export type HeavyOperation = { - __typename: 'HeavyOperation'; - base: Scalars['U64']['output']; - gasPerUnit: Scalars['U64']['output']; -}; - -export type Input = InputCoin | InputContract | InputMessage; - -export type InputCoin = { - __typename: 'InputCoin'; - amount: Scalars['U64']['output']; - assetId: Scalars['AssetId']['output']; - maturity: Scalars['U32']['output']; - owner: Scalars['Address']['output']; - predicate: Scalars['HexString']['output']; - predicateData: Scalars['HexString']['output']; - predicateGasUsed: Scalars['U64']['output']; - txPointer: Scalars['TxPointer']['output']; - utxoId: Scalars['UtxoId']['output']; - witnessIndex: Scalars['Int']['output']; -}; - -export type InputContract = { - __typename: 'InputContract'; - balanceRoot: Scalars['Bytes32']['output']; - contract: Contract; - stateRoot: Scalars['Bytes32']['output']; - txPointer: Scalars['TxPointer']['output']; - utxoId: Scalars['UtxoId']['output']; -}; - -export type InputMessage = { - __typename: 'InputMessage'; - amount: Scalars['U64']['output']; - data: Scalars['HexString']['output']; - nonce: Scalars['Nonce']['output']; - predicate: Scalars['HexString']['output']; - predicateData: Scalars['HexString']['output']; - predicateGasUsed: Scalars['U64']['output']; - recipient: Scalars['Address']['output']; - sender: Scalars['Address']['output']; - witnessIndex: Scalars['Int']['output']; -}; - -export type LightOperation = { - __typename: 'LightOperation'; - base: Scalars['U64']['output']; - unitsPerGas: Scalars['U64']['output']; -}; - -export type MerkleProof = { - __typename: 'MerkleProof'; - proofIndex: Scalars['U64']['output']; - proofSet: Array; -}; - -export type Message = { - __typename: 'Message'; - amount: Scalars['U64']['output']; - daHeight: Scalars['U64']['output']; - data: Scalars['HexString']['output']; - nonce: Scalars['Nonce']['output']; - recipient: Scalars['Address']['output']; - sender: Scalars['Address']['output']; -}; - -export type MessageCoin = { - __typename: 'MessageCoin'; - amount: Scalars['U64']['output']; - assetId: Scalars['AssetId']['output']; - daHeight: Scalars['U64']['output']; - nonce: Scalars['Nonce']['output']; - recipient: Scalars['Address']['output']; - sender: Scalars['Address']['output']; -}; - -export type MessageConnection = { - __typename: 'MessageConnection'; - /** A list of edges. */ - edges: Array; - /** A list of nodes. */ - nodes: Array; - /** Information to aid in pagination. */ - pageInfo: PageInfo; -}; - -/** An edge in a connection. */ -export type MessageEdge = { - __typename: 'MessageEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node: Message; -}; - -export type MessageProof = { - __typename: 'MessageProof'; - amount: Scalars['U64']['output']; - blockProof: MerkleProof; - commitBlockHeader: Header; - data: Scalars['HexString']['output']; - messageBlockHeader: Header; - messageProof: MerkleProof; - nonce: Scalars['Nonce']['output']; - recipient: Scalars['Address']['output']; - sender: Scalars['Address']['output']; -}; - -export enum MessageState { - NotFound = 'NOT_FOUND', - Spent = 'SPENT', - Unspent = 'UNSPENT' -} - -export type MessageStatus = { - __typename: 'MessageStatus'; - state: MessageState; -}; - -export type Mutation = { - __typename: 'Mutation'; - continueTx: RunResult; - /** Execute a dry-run of the transaction using a fork of current state, no changes are committed. */ - dryRun: Array; - endSession: Scalars['Boolean']['output']; - execute: Scalars['Boolean']['output']; - /** - * Sequentially produces `blocks_to_produce` blocks. The first block starts with - * `start_timestamp`. If the block production in the [`crate::service::Config`] is - * `Trigger::Interval { block_time }`, produces blocks with `block_time ` intervals between - * them. The `start_timestamp` is the timestamp in seconds. - */ - produceBlocks: Scalars['U32']['output']; - reset: Scalars['Boolean']['output']; - setBreakpoint: Scalars['Boolean']['output']; - setSingleStepping: Scalars['Boolean']['output']; - startSession: Scalars['ID']['output']; - startTx: RunResult; - /** - * Submits transaction to the `TxPool`. - * - * Returns submitted transaction if the transaction is included in the `TxPool` without problems. - */ - submit: Transaction; -}; - - -export type MutationContinueTxArgs = { - id: Scalars['ID']['input']; -}; - - -export type MutationDryRunArgs = { - tx: Scalars['HexString']['input']; - utxoValidation?: InputMaybe; -}; - - -export type MutationEndSessionArgs = { - id: Scalars['ID']['input']; -}; - - -export type MutationExecuteArgs = { - id: Scalars['ID']['input']; - op: Scalars['String']['input']; -}; - - -export type MutationProduceBlocksArgs = { - blocksToProduce: Scalars['U32']['input']; - startTimestamp?: InputMaybe; -}; - - -export type MutationResetArgs = { - id: Scalars['ID']['input']; -}; - - -export type MutationSetBreakpointArgs = { - breakpoint: Breakpoint; - id: Scalars['ID']['input']; -}; - - -export type MutationSetSingleSteppingArgs = { - enable: Scalars['Boolean']['input']; - id: Scalars['ID']['input']; -}; - - -export type MutationStartTxArgs = { - id: Scalars['ID']['input']; - txJson: Scalars['String']['input']; -}; - - -export type MutationSubmitArgs = { - tx: Scalars['HexString']['input']; -}; - -export type NodeInfo = { - __typename: 'NodeInfo'; - maxDepth: Scalars['U64']['output']; - maxTx: Scalars['U64']['output']; - minGasPrice: Scalars['U64']['output']; - nodeVersion: Scalars['String']['output']; - peers: Array; - utxoValidation: Scalars['Boolean']['output']; - vmBacktrace: Scalars['Boolean']['output']; -}; - -export type Operation = { - __typename: 'Operation'; - receipts?: Maybe>>; - type?: Maybe; -}; - -export type OperationReceipt = { - __typename: 'OperationReceipt'; - item?: Maybe; - receipts?: Maybe>>; -}; - -export enum OperationType { - FinalResult = 'FINAL_RESULT', - FromAccount = 'FROM_ACCOUNT', - FromContract = 'FROM_CONTRACT' -} - -export type Output = ChangeOutput | CoinOutput | ContractCreated | ContractOutput | VariableOutput; - -/** - * A separate `Breakpoint` type to be used as an output, as a single - * type cannot act as both input and output type in async-graphql - */ -export type OutputBreakpoint = { - __typename: 'OutputBreakpoint'; - contract: Scalars['ContractId']['output']; - pc: Scalars['U64']['output']; -}; - -/** Information about pagination in a connection */ -export type PageInfo = { - __typename: 'PageInfo'; - /** When paginating forwards, the cursor to continue. */ - endCursor?: Maybe; - /** When paginating forwards, are there more items? */ - hasNextPage: Scalars['Boolean']['output']; - /** When paginating backwards, are there more items? */ - hasPreviousPage: Scalars['Boolean']['output']; - /** When paginating backwards, the cursor to continue. */ - startCursor?: Maybe; -}; - -export type ParsedTime = { - __typename: 'ParsedTime'; - fromNow?: Maybe; - full?: Maybe; - rawTai64?: Maybe; - rawUnix?: Maybe; -}; - -export type PeerInfo = { - __typename: 'PeerInfo'; - /** The advertised multi-addrs that can be used to connect to this peer */ - addresses: Array; - /** The internal fuel p2p reputation of this peer */ - appScore: Scalars['Float']['output']; - /** The last reported height of the peer */ - blockHeight?: Maybe; - /** The self-reported version of the client the peer is using */ - clientVersion?: Maybe; - /** The libp2p peer id */ - id: Scalars['String']['output']; - /** The last heartbeat from this peer in unix epoch time ms */ - lastHeartbeatMs: Scalars['U64']['output']; -}; - -export type PoAConsensus = { - __typename: 'PoAConsensus'; - /** Gets the signature of the block produced by `PoA` consensus. */ - signature: Scalars['Signature']['output']; -}; - -export type Policies = { - __typename: 'Policies'; - gasPrice?: Maybe; - maturity?: Maybe; - maxFee?: Maybe; - witnessLimit?: Maybe; -}; - -export type Predicate = { - __typename: 'Predicate'; - bytecode: Scalars['HexString']['output']; - id: Scalars['Address']['output']; -}; - -export type PredicateParameters = { - __typename: 'PredicateParameters'; - maxGasPerPredicate: Scalars['U64']['output']; - maxMessageDataLength: Scalars['U64']['output']; - maxPredicateDataLength: Scalars['U64']['output']; - maxPredicateLength: Scalars['U64']['output']; -}; - -export type ProgramState = { - __typename: 'ProgramState'; - data: Scalars['HexString']['output']; - returnType: _ReturnType; -}; - -export type Query = { - __typename: 'Query'; - accounts: Array; - balance: Balance; - balances: BalanceConnection; - block?: Maybe; - blocks: BlockConnection; - chain: ChainInfo; - /** Gets the coin by `utxo_id`. */ - coin?: Maybe; - /** Gets all unspent coins of some `owner` maybe filtered with by `asset_id` per page. */ - coins: CoinConnection; - /** - * For each `query_per_asset`, get some spendable coins(of asset specified by the query) owned by - * `owner` that add up at least the query amount. The returned coins can be spent. - * The number of coins is optimized to prevent dust accumulation. - * - * The query supports excluding and maximum the number of coins. - * - * Returns: - * The list of spendable coins per asset from the query. The length of the result is - * the same as the length of `query_per_asset`. The ordering of assets and `query_per_asset` - * is the same. - */ - coinsToSpend: Array>; - contract?: Maybe; - contractBalance: ContractBalance; - contractBalances: ContractBalanceConnection; - /** Estimate the predicate gas for the provided transaction */ - estimatePredicates: Transaction; - /** Returns true when the GraphQL API is serving requests. */ - health: Scalars['Boolean']['output']; - memory: Scalars['String']['output']; - messageProof?: Maybe; - messageStatus: MessageStatus; - messages: MessageConnection; - nodeInfo: NodeInfo; - predicate?: Maybe; - register: Scalars['U64']['output']; - search?: Maybe; - tokens: Array; - transaction?: Maybe; - transactions: TransactionConnection; - transactionsByOwner: TransactionConnection; -}; - - -export type QueryAccountsArgs = { - addresses: Array>; -}; - - -export type QueryBalanceArgs = { - assetId: Scalars['AssetId']['input']; - owner: Scalars['Address']['input']; -}; - - -export type QueryBalancesArgs = { - after?: InputMaybe; - before?: InputMaybe; - filter: BalanceFilterInput; - first?: InputMaybe; - last?: InputMaybe; -}; - - -export type QueryBlockArgs = { - height?: InputMaybe; - id?: InputMaybe; -}; - - -export type QueryBlocksArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - - -export type QueryCoinArgs = { - utxoId: Scalars['UtxoId']['input']; -}; - - -export type QueryCoinsArgs = { - after?: InputMaybe; - before?: InputMaybe; - filter: CoinFilterInput; - first?: InputMaybe; - last?: InputMaybe; -}; - - -export type QueryCoinsToSpendArgs = { - excludedIds?: InputMaybe; - owner: Scalars['Address']['input']; - queryPerAsset: Array; -}; - - -export type QueryContractArgs = { - id: Scalars['ContractId']['input']; -}; - - -export type QueryContractBalanceArgs = { - asset: Scalars['AssetId']['input']; - contract: Scalars['ContractId']['input']; -}; - - -export type QueryContractBalancesArgs = { - after?: InputMaybe; - before?: InputMaybe; - filter: ContractBalanceFilterInput; - first?: InputMaybe; - last?: InputMaybe; -}; - - -export type QueryEstimatePredicatesArgs = { - tx: Scalars['HexString']['input']; -}; - - -export type QueryMemoryArgs = { - id: Scalars['ID']['input']; - size: Scalars['U32']['input']; - start: Scalars['U32']['input']; -}; - - -export type QueryMessageProofArgs = { - commitBlockHeight?: InputMaybe; - commitBlockId?: InputMaybe; - nonce: Scalars['Nonce']['input']; - transactionId: Scalars['TransactionId']['input']; -}; - - -export type QueryMessageStatusArgs = { - nonce: Scalars['Nonce']['input']; -}; - - -export type QueryMessagesArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; - owner?: InputMaybe; -}; - - -export type QueryPredicateArgs = { - address: Scalars['Address']['input']; -}; - - -export type QueryRegisterArgs = { - id: Scalars['ID']['input']; - register: Scalars['U32']['input']; -}; - - -export type QuerySearchArgs = { - query: Scalars['String']['input']; -}; - - -export type QueryTokensArgs = { - assetsId: Array>; -}; - - -export type QueryTransactionArgs = { - id: Scalars['TransactionId']['input']; -}; - - -export type QueryTransactionsArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; -}; - - -export type QueryTransactionsByOwnerArgs = { - after?: InputMaybe; - before?: InputMaybe; - first?: InputMaybe; - last?: InputMaybe; - owner: Scalars['Address']['input']; -}; - -export type Receipt = { - __typename: 'Receipt'; - amount?: Maybe; - assetId?: Maybe; - contract?: Maybe; - contractId?: Maybe; - data?: Maybe; - digest?: Maybe; - gas?: Maybe; - gasUsed?: Maybe; - is?: Maybe; - len?: Maybe; - nonce?: Maybe; - param1?: Maybe; - param2?: Maybe; - pc?: Maybe; - ptr?: Maybe; - ra?: Maybe; - rb?: Maybe; - rc?: Maybe; - rd?: Maybe; - reason?: Maybe; - receiptType: ReceiptType; - recipient?: Maybe; - result?: Maybe; - sender?: Maybe; - subId?: Maybe; - to?: Maybe; - toAddress?: Maybe; - val?: Maybe; -}; - -export enum ReceiptType { - Burn = 'BURN', - Call = 'CALL', - Log = 'LOG', - LogData = 'LOG_DATA', - MessageOut = 'MESSAGE_OUT', - Mint = 'MINT', - Panic = 'PANIC', - Return = 'RETURN', - ReturnData = 'RETURN_DATA', - Revert = 'REVERT', - ScriptResult = 'SCRIPT_RESULT', - Transfer = 'TRANSFER', - TransferOut = 'TRANSFER_OUT' -} - -export enum _ReturnType { - Return = 'RETURN', - ReturnData = 'RETURN_DATA', - Revert = 'REVERT' -} - -export type RunResult = { - __typename: 'RunResult'; - breakpoint?: Maybe; - jsonReceipts: Array; - state: RunState; -}; - -export enum RunState { - /** Stopped on a breakpoint */ - Breakpoint = 'BREAKPOINT', - /** All breakpoints have been processed, and the program has terminated */ - Completed = 'COMPLETED' -} - -export type ScriptParameters = { - __typename: 'ScriptParameters'; - maxScriptDataLength: Scalars['U64']['output']; - maxScriptLength: Scalars['U64']['output']; -}; - -export type SearchAccount = { - __typename: 'SearchAccount'; - address?: Maybe; - transactions?: Maybe>>; -}; - -export type SearchBlock = { - __typename: 'SearchBlock'; - height?: Maybe; - id?: Maybe; -}; - -export type SearchContract = { - __typename: 'SearchContract'; - id?: Maybe; -}; - -export type SearchResult = { - __typename: 'SearchResult'; - account?: Maybe; - block?: Maybe; - contract?: Maybe; - transaction?: Maybe; -}; - -export type SearchTransaction = { - __typename: 'SearchTransaction'; - id?: Maybe; -}; - -export type SpendQueryElementInput = { - /** Target amount for the query. */ - amount: Scalars['U64']['input']; - /** Identifier of the asset to spend. */ - assetId: Scalars['AssetId']['input']; - /** The maximum number of currencies for selection. */ - max?: InputMaybe; -}; - -export type SqueezedOutStatus = { - __typename: 'SqueezedOutStatus'; - reason: Scalars['String']['output']; -}; - -export type SubmittedStatus = { - __typename: 'SubmittedStatus'; - time: Scalars['Tai64Timestamp']['output']; -}; - -export type Subscription = { - __typename: 'Subscription'; - /** - * Returns a stream of status updates for the given transaction id. - * If the current status is [`TransactionStatus::Success`], [`TransactionStatus::SqueezedOut`] - * or [`TransactionStatus::Failed`] the stream will return that and end immediately. - * If the current status is [`TransactionStatus::Submitted`] this will be returned - * and the stream will wait for a future update. - * - * This stream will wait forever so it's advised to use within a timeout. - * - * It is possible for the stream to miss an update if it is polled slower - * then the updates arrive. In such a case the stream will close without - * a status. If this occurs the stream can simply be restarted to return - * the latest status. - */ - statusChange: TransactionStatus; - /** Submits transaction to the `TxPool` and await either confirmation or failure. */ - submitAndAwait: TransactionStatus; -}; - - -export type SubscriptionStatusChangeArgs = { - id: Scalars['TransactionId']['input']; -}; - - -export type SubscriptionSubmitAndAwaitArgs = { - tx: Scalars['HexString']['input']; -}; - -export type SuccessStatus = { - __typename: 'SuccessStatus'; - block: Block; - programState?: Maybe; - receipts: Array; - time: Scalars['Tai64Timestamp']['output']; - transactionId: Scalars['TransactionId']['output']; -}; - -export type Token = { - __typename: 'Token'; - assetId: Scalars['String']['output']; - decimals: Scalars['U64']['output']; - name: Scalars['String']['output']; - symbol: Scalars['String']['output']; - totalAssets?: Maybe; - totalSupply?: Maybe; - url?: Maybe; -}; - -export type Transaction = { - __typename: 'Transaction'; - accountsInvolved?: Maybe>>; - blockHeight?: Maybe; - bytecodeLength?: Maybe; - bytecodeWitnessIndex?: Maybe; - fee?: Maybe; - gasPrice?: Maybe; - gasUsed?: Maybe; - groupedInputs?: Maybe>>; - groupedOutputs?: Maybe>>; - id: Scalars['TransactionId']['output']; - inputAssetIds?: Maybe>; - inputContract?: Maybe; - inputContracts?: Maybe>; - inputs?: Maybe>; - isCreate: Scalars['Boolean']['output']; - isMint: Scalars['Boolean']['output']; - isPredicate?: Maybe; - isScript: Scalars['Boolean']['output']; - maturity?: Maybe; - mintAmount?: Maybe; - mintAssetId?: Maybe; - operations?: Maybe>>; - outputContract?: Maybe; - outputs: Array; - policies?: Maybe; - /** Return the transaction bytes using canonical encoding */ - rawPayload: Scalars['HexString']['output']; - receipts?: Maybe>; - receiptsRoot?: Maybe; - salt?: Maybe; - script?: Maybe; - scriptData?: Maybe; - scriptGasLimit?: Maybe; - status?: Maybe; - statusType?: Maybe; - storageSlots?: Maybe>; - time?: Maybe; - title?: Maybe; - totalAccounts?: Maybe; - totalAssets?: Maybe; - totalOperations?: Maybe; - txPointer?: Maybe; - witnesses?: Maybe>; -}; - -export type TransactionAccount = { - __typename: 'TransactionAccount'; - id?: Maybe; - type?: Maybe; -}; - -export enum TransactionAccountType { - Contract = 'Contract', - Predicate = 'Predicate', - Wallet = 'Wallet' -} - -export type TransactionConnection = { - __typename: 'TransactionConnection'; - accounts?: Maybe>>; - /** A list of edges. */ - edges: Array; - /** A list of nodes. */ - nodes: Array; - /** Information to aid in pagination. */ - pageInfo: PageInfo; - tokens?: Maybe>>; -}; - -/** An edge in a connection. */ -export type TransactionEdge = { - __typename: 'TransactionEdge'; - /** A cursor for use in pagination */ - cursor: Scalars['String']['output']; - /** The item at the end of the edge */ - node: Transaction; -}; - -export type TransactionStatus = FailureStatus | SqueezedOutStatus | SubmittedStatus | SuccessStatus; - -export enum TransactionStatusType { - Failure = 'Failure', - Submitted = 'Submitted', - Success = 'Success' -} - -export type TxParameters = { - __typename: 'TxParameters'; - maxGasPerTx: Scalars['U64']['output']; - maxInputs: Scalars['U8']['output']; - maxOutputs: Scalars['U8']['output']; - maxSize: Scalars['U64']['output']; - maxWitnesses: Scalars['U32']['output']; -}; - -export type UtxoItem = { - __typename: 'UtxoItem'; - amount: Scalars['U64']['output']; - blockCreated?: Maybe; - txCreatedIdx?: Maybe; - utxoId: Scalars['UtxoId']['output']; -}; - -export type VariableOutput = { - __typename: 'VariableOutput'; - amount: Scalars['U64']['output']; - assetId: Scalars['AssetId']['output']; - to: Scalars['Address']['output']; -}; - -export type ContractItemFragment = { __typename: 'Contract', id: string, bytecode: string, salt: string }; - -export type ContractBalanceItemFragment = { __typename: 'ContractBalance', contract: string, amount: string, assetId: string }; - -export type ContractBalanceConnectionItemFragment = { __typename: 'ContractBalanceConnection', pageInfo: { __typename: 'PageInfo', hasNextPage: boolean, hasPreviousPage: boolean, endCursor?: string | null, startCursor?: string | null }, edges: Array<{ __typename: 'ContractBalanceEdge', cursor: string, node: { __typename: 'ContractBalance', contract: string, amount: string, assetId: string } }> }; - -export type GetAccountTransactionsQueryVariables = Exact<{ - owner: Scalars['Address']['input']; -}>; - - -export type GetAccountTransactionsQuery = { __typename: 'Query', transactions: { __typename: 'TransactionConnection', pageInfo: { __typename: 'PageInfo', hasNextPage: boolean, hasPreviousPage: boolean, endCursor?: string | null, startCursor?: string | null }, edges: Array<{ __typename: 'TransactionEdge', cursor: string, node: { __typename: 'Transaction', id: string, title?: string | null, isPredicate?: boolean | null, blockHeight?: string | null, statusType?: TransactionStatusType | null, totalAccounts?: number | null, totalAssets?: number | null, totalOperations?: number | null, gasUsed?: string | null, fee?: string | null, gasPrice?: string | null, maturity?: string | null, txPointer?: string | null, isScript: boolean, isCreate: boolean, isMint: boolean, witnesses?: Array | null, receiptsRoot?: string | null, script?: string | null, scriptData?: string | null, bytecodeWitnessIndex?: number | null, bytecodeLength?: string | null, salt?: string | null, storageSlots?: Array | null, rawPayload: string, mintAmount?: string | null, mintAssetId?: string | null, inputAssetIds?: Array | null, time?: { __typename: 'ParsedTime', fromNow?: string | null, full?: string | null, rawTai64?: string | null, rawUnix?: string | null } | null, groupedInputs?: Array<{ __typename: 'GroupedInput', type?: GroupedInputType | null, totalAmount?: string | null, contractId?: string | null, assetId?: string | null, sender?: string | null, recipient?: string | null, data?: string | null, owner?: string | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string } | null> | null } | null> | null, groupedOutputs?: Array<{ __typename: 'GroupedOutput', to?: string | null, type?: GroupedOutputType | null, totalAmount?: string | null, assetId?: string | null, inputIndex?: number | null, recipient?: string | null, outputs?: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string } | null> | null, contract?: { __typename: 'Contract', id: string } | null } | null> | null, accountsInvolved?: Array<{ __typename: 'TransactionAccount', id?: string | null, type?: TransactionAccountType | null } | null> | null, operations?: Array<{ __typename: 'Operation', type?: OperationType | null, receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null } | null> | null, inputContract?: { __typename: 'InputContract', contract: { __typename: 'Contract', id: string } } | null, outputContract?: { __typename: 'ContractOutput', inputIndex: number } | null, status?: { __typename: 'FailureStatus', time: string, programState?: { __typename: 'ProgramState', data: string } | null } | { __typename: 'SqueezedOutStatus', reason: string } | { __typename: 'SubmittedStatus', time: string } | { __typename: 'SuccessStatus', time: string, block: { __typename: 'Block', id: string, header: { __typename: 'Header', id: string, height: string, daHeight: string, applicationHash: string, messageReceiptRoot: string, messageReceiptCount: string, time: string } }, programState?: { __typename: 'ProgramState', data: string } | null } | null, inputContracts?: Array<{ __typename: 'Contract', id: string }> | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string }> | null, outputs: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string }>, receipts?: Array<{ __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null }> | null } }> } }; - -export type AccountBalanceFragment = { __typename: 'Balance', assetId: string, amount: string, owner: string, utxos?: Array<{ __typename: 'UtxoItem', utxoId: string, amount: string, txCreatedIdx?: string | null, blockCreated?: string | null } | null> | null }; - -export type GetBalancesQueryVariables = Exact<{ - owner: Scalars['Address']['input']; -}>; - - -export type GetBalancesQuery = { __typename: 'Query', balances: { __typename: 'BalanceConnection', nodes: Array<{ __typename: 'Balance', assetId: string, amount: string, owner: string, utxos?: Array<{ __typename: 'UtxoItem', utxoId: string, amount: string, txCreatedIdx?: string | null, blockCreated?: string | null } | null> | null }> } }; - -export type BlockItemFragment = { __typename: 'Block', totalGasUsed?: string | null, id: string, time?: { __typename: 'ParsedTime', fromNow?: string | null, full?: string | null, rawTai64?: string | null, rawUnix?: string | null } | null, consensus: { __typename: 'Genesis' } | { __typename: 'PoAConsensus', signature: string }, header: { __typename: 'Header', transactionsCount: string, time: string }, transactions: Array<{ __typename: 'Transaction', id: string, title?: string | null, isPredicate?: boolean | null, blockHeight?: string | null, statusType?: TransactionStatusType | null, totalAccounts?: number | null, totalAssets?: number | null, totalOperations?: number | null, gasUsed?: string | null, fee?: string | null, gasPrice?: string | null, maturity?: string | null, txPointer?: string | null, isScript: boolean, isCreate: boolean, isMint: boolean, witnesses?: Array | null, receiptsRoot?: string | null, script?: string | null, scriptData?: string | null, bytecodeWitnessIndex?: number | null, bytecodeLength?: string | null, salt?: string | null, storageSlots?: Array | null, rawPayload: string, mintAmount?: string | null, mintAssetId?: string | null, inputAssetIds?: Array | null, time?: { __typename: 'ParsedTime', fromNow?: string | null, full?: string | null, rawTai64?: string | null, rawUnix?: string | null } | null, groupedInputs?: Array<{ __typename: 'GroupedInput', type?: GroupedInputType | null, totalAmount?: string | null, contractId?: string | null, assetId?: string | null, sender?: string | null, recipient?: string | null, data?: string | null, owner?: string | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string } | null> | null } | null> | null, groupedOutputs?: Array<{ __typename: 'GroupedOutput', to?: string | null, type?: GroupedOutputType | null, totalAmount?: string | null, assetId?: string | null, inputIndex?: number | null, recipient?: string | null, outputs?: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string } | null> | null, contract?: { __typename: 'Contract', id: string } | null } | null> | null, accountsInvolved?: Array<{ __typename: 'TransactionAccount', id?: string | null, type?: TransactionAccountType | null } | null> | null, operations?: Array<{ __typename: 'Operation', type?: OperationType | null, receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null } | null> | null, inputContract?: { __typename: 'InputContract', contract: { __typename: 'Contract', id: string } } | null, outputContract?: { __typename: 'ContractOutput', inputIndex: number } | null, status?: { __typename: 'FailureStatus', time: string, programState?: { __typename: 'ProgramState', data: string } | null } | { __typename: 'SqueezedOutStatus', reason: string } | { __typename: 'SubmittedStatus', time: string } | { __typename: 'SuccessStatus', time: string, block: { __typename: 'Block', id: string, header: { __typename: 'Header', id: string, height: string, daHeight: string, applicationHash: string, messageReceiptRoot: string, messageReceiptCount: string, time: string } }, programState?: { __typename: 'ProgramState', data: string } | null } | null, inputContracts?: Array<{ __typename: 'Contract', id: string }> | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string }> | null, outputs: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string }>, receipts?: Array<{ __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null }> | null }> }; - -export type GetBlockByHeightQueryVariables = Exact<{ - height?: InputMaybe; -}>; - - -export type GetBlockByHeightQuery = { __typename: 'Query', block?: { __typename: 'Block', totalGasUsed?: string | null, id: string, time?: { __typename: 'ParsedTime', fromNow?: string | null, full?: string | null, rawTai64?: string | null, rawUnix?: string | null } | null, consensus: { __typename: 'Genesis' } | { __typename: 'PoAConsensus', signature: string }, header: { __typename: 'Header', transactionsCount: string, time: string }, transactions: Array<{ __typename: 'Transaction', id: string, title?: string | null, isPredicate?: boolean | null, blockHeight?: string | null, statusType?: TransactionStatusType | null, totalAccounts?: number | null, totalAssets?: number | null, totalOperations?: number | null, gasUsed?: string | null, fee?: string | null, gasPrice?: string | null, maturity?: string | null, txPointer?: string | null, isScript: boolean, isCreate: boolean, isMint: boolean, witnesses?: Array | null, receiptsRoot?: string | null, script?: string | null, scriptData?: string | null, bytecodeWitnessIndex?: number | null, bytecodeLength?: string | null, salt?: string | null, storageSlots?: Array | null, rawPayload: string, mintAmount?: string | null, mintAssetId?: string | null, inputAssetIds?: Array | null, time?: { __typename: 'ParsedTime', fromNow?: string | null, full?: string | null, rawTai64?: string | null, rawUnix?: string | null } | null, groupedInputs?: Array<{ __typename: 'GroupedInput', type?: GroupedInputType | null, totalAmount?: string | null, contractId?: string | null, assetId?: string | null, sender?: string | null, recipient?: string | null, data?: string | null, owner?: string | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string } | null> | null } | null> | null, groupedOutputs?: Array<{ __typename: 'GroupedOutput', to?: string | null, type?: GroupedOutputType | null, totalAmount?: string | null, assetId?: string | null, inputIndex?: number | null, recipient?: string | null, outputs?: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string } | null> | null, contract?: { __typename: 'Contract', id: string } | null } | null> | null, accountsInvolved?: Array<{ __typename: 'TransactionAccount', id?: string | null, type?: TransactionAccountType | null } | null> | null, operations?: Array<{ __typename: 'Operation', type?: OperationType | null, receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null } | null> | null, inputContract?: { __typename: 'InputContract', contract: { __typename: 'Contract', id: string } } | null, outputContract?: { __typename: 'ContractOutput', inputIndex: number } | null, status?: { __typename: 'FailureStatus', time: string, programState?: { __typename: 'ProgramState', data: string } | null } | { __typename: 'SqueezedOutStatus', reason: string } | { __typename: 'SubmittedStatus', time: string } | { __typename: 'SuccessStatus', time: string, block: { __typename: 'Block', id: string, header: { __typename: 'Header', id: string, height: string, daHeight: string, applicationHash: string, messageReceiptRoot: string, messageReceiptCount: string, time: string } }, programState?: { __typename: 'ProgramState', data: string } | null } | null, inputContracts?: Array<{ __typename: 'Contract', id: string }> | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string }> | null, outputs: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string }>, receipts?: Array<{ __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null }> | null }> } | null }; - -export type GetBlockByIdQueryVariables = Exact<{ - id?: InputMaybe; -}>; - - -export type GetBlockByIdQuery = { __typename: 'Query', block?: { __typename: 'Block', totalGasUsed?: string | null, id: string, time?: { __typename: 'ParsedTime', fromNow?: string | null, full?: string | null, rawTai64?: string | null, rawUnix?: string | null } | null, consensus: { __typename: 'Genesis' } | { __typename: 'PoAConsensus', signature: string }, header: { __typename: 'Header', transactionsCount: string, time: string }, transactions: Array<{ __typename: 'Transaction', id: string, title?: string | null, isPredicate?: boolean | null, blockHeight?: string | null, statusType?: TransactionStatusType | null, totalAccounts?: number | null, totalAssets?: number | null, totalOperations?: number | null, gasUsed?: string | null, fee?: string | null, gasPrice?: string | null, maturity?: string | null, txPointer?: string | null, isScript: boolean, isCreate: boolean, isMint: boolean, witnesses?: Array | null, receiptsRoot?: string | null, script?: string | null, scriptData?: string | null, bytecodeWitnessIndex?: number | null, bytecodeLength?: string | null, salt?: string | null, storageSlots?: Array | null, rawPayload: string, mintAmount?: string | null, mintAssetId?: string | null, inputAssetIds?: Array | null, time?: { __typename: 'ParsedTime', fromNow?: string | null, full?: string | null, rawTai64?: string | null, rawUnix?: string | null } | null, groupedInputs?: Array<{ __typename: 'GroupedInput', type?: GroupedInputType | null, totalAmount?: string | null, contractId?: string | null, assetId?: string | null, sender?: string | null, recipient?: string | null, data?: string | null, owner?: string | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string } | null> | null } | null> | null, groupedOutputs?: Array<{ __typename: 'GroupedOutput', to?: string | null, type?: GroupedOutputType | null, totalAmount?: string | null, assetId?: string | null, inputIndex?: number | null, recipient?: string | null, outputs?: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string } | null> | null, contract?: { __typename: 'Contract', id: string } | null } | null> | null, accountsInvolved?: Array<{ __typename: 'TransactionAccount', id?: string | null, type?: TransactionAccountType | null } | null> | null, operations?: Array<{ __typename: 'Operation', type?: OperationType | null, receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null } | null> | null, inputContract?: { __typename: 'InputContract', contract: { __typename: 'Contract', id: string } } | null, outputContract?: { __typename: 'ContractOutput', inputIndex: number } | null, status?: { __typename: 'FailureStatus', time: string, programState?: { __typename: 'ProgramState', data: string } | null } | { __typename: 'SqueezedOutStatus', reason: string } | { __typename: 'SubmittedStatus', time: string } | { __typename: 'SuccessStatus', time: string, block: { __typename: 'Block', id: string, header: { __typename: 'Header', id: string, height: string, daHeight: string, applicationHash: string, messageReceiptRoot: string, messageReceiptCount: string, time: string } }, programState?: { __typename: 'ProgramState', data: string } | null } | null, inputContracts?: Array<{ __typename: 'Contract', id: string }> | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string }> | null, outputs: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string }>, receipts?: Array<{ __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null }> | null }> } | null }; - -export type GetContractQueryVariables = Exact<{ - id: Scalars['ContractId']['input']; -}>; - - -export type GetContractQuery = { __typename: 'Query', contract?: { __typename: 'Contract', id: string, bytecode: string, salt: string } | null }; - -export type GetContractBalancesQueryVariables = Exact<{ - id: Scalars['ContractId']['input']; -}>; - - -export type GetContractBalancesQuery = { __typename: 'Query', contractBalances: { __typename: 'ContractBalanceConnection', pageInfo: { __typename: 'PageInfo', hasNextPage: boolean, hasPreviousPage: boolean, endCursor?: string | null, startCursor?: string | null }, edges: Array<{ __typename: 'ContractBalanceEdge', cursor: string, node: { __typename: 'ContractBalance', contract: string, amount: string, assetId: string } }> } }; - -export type GetLastTransactionsQueryVariables = Exact<{ - last?: InputMaybe; - first?: InputMaybe; - after?: InputMaybe; - before?: InputMaybe; -}>; - - -export type GetLastTransactionsQuery = { __typename: 'Query', transactions: { __typename: 'TransactionConnection', pageInfo: { __typename: 'PageInfo', hasNextPage: boolean, hasPreviousPage: boolean, endCursor?: string | null, startCursor?: string | null }, edges: Array<{ __typename: 'TransactionEdge', cursor: string, node: { __typename: 'Transaction', id: string, title?: string | null, isPredicate?: boolean | null, blockHeight?: string | null, statusType?: TransactionStatusType | null, totalAccounts?: number | null, totalAssets?: number | null, totalOperations?: number | null, gasUsed?: string | null, fee?: string | null, gasPrice?: string | null, maturity?: string | null, txPointer?: string | null, isScript: boolean, isCreate: boolean, isMint: boolean, witnesses?: Array | null, receiptsRoot?: string | null, script?: string | null, scriptData?: string | null, bytecodeWitnessIndex?: number | null, bytecodeLength?: string | null, salt?: string | null, storageSlots?: Array | null, rawPayload: string, mintAmount?: string | null, mintAssetId?: string | null, inputAssetIds?: Array | null, time?: { __typename: 'ParsedTime', fromNow?: string | null, full?: string | null, rawTai64?: string | null, rawUnix?: string | null } | null, groupedInputs?: Array<{ __typename: 'GroupedInput', type?: GroupedInputType | null, totalAmount?: string | null, contractId?: string | null, assetId?: string | null, sender?: string | null, recipient?: string | null, data?: string | null, owner?: string | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string } | null> | null } | null> | null, groupedOutputs?: Array<{ __typename: 'GroupedOutput', to?: string | null, type?: GroupedOutputType | null, totalAmount?: string | null, assetId?: string | null, inputIndex?: number | null, recipient?: string | null, outputs?: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string } | null> | null, contract?: { __typename: 'Contract', id: string } | null } | null> | null, accountsInvolved?: Array<{ __typename: 'TransactionAccount', id?: string | null, type?: TransactionAccountType | null } | null> | null, operations?: Array<{ __typename: 'Operation', type?: OperationType | null, receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null } | null> | null, inputContract?: { __typename: 'InputContract', contract: { __typename: 'Contract', id: string } } | null, outputContract?: { __typename: 'ContractOutput', inputIndex: number } | null, status?: { __typename: 'FailureStatus', time: string, programState?: { __typename: 'ProgramState', data: string } | null } | { __typename: 'SqueezedOutStatus', reason: string } | { __typename: 'SubmittedStatus', time: string } | { __typename: 'SuccessStatus', time: string, block: { __typename: 'Block', id: string, header: { __typename: 'Header', id: string, height: string, daHeight: string, applicationHash: string, messageReceiptRoot: string, messageReceiptCount: string, time: string } }, programState?: { __typename: 'ProgramState', data: string } | null } | null, inputContracts?: Array<{ __typename: 'Contract', id: string }> | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string }> | null, outputs: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string }>, receipts?: Array<{ __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null }> | null } }> } }; - -export type GetPredicateQueryVariables = Exact<{ - address: Scalars['Address']['input']; -}>; - - -export type GetPredicateQuery = { __typename: 'Query', predicate?: { __typename: 'Predicate', id: string, bytecode: string } | null }; - -export type GetTransactionQueryVariables = Exact<{ - id: Scalars['TransactionId']['input']; -}>; - - -export type GetTransactionQuery = { __typename: 'Query', transaction?: { __typename: 'Transaction', id: string, title?: string | null, isPredicate?: boolean | null, blockHeight?: string | null, statusType?: TransactionStatusType | null, totalAccounts?: number | null, totalAssets?: number | null, totalOperations?: number | null, gasUsed?: string | null, fee?: string | null, gasPrice?: string | null, maturity?: string | null, txPointer?: string | null, isScript: boolean, isCreate: boolean, isMint: boolean, witnesses?: Array | null, receiptsRoot?: string | null, script?: string | null, scriptData?: string | null, bytecodeWitnessIndex?: number | null, bytecodeLength?: string | null, salt?: string | null, storageSlots?: Array | null, rawPayload: string, mintAmount?: string | null, mintAssetId?: string | null, inputAssetIds?: Array | null, time?: { __typename: 'ParsedTime', fromNow?: string | null, full?: string | null, rawTai64?: string | null, rawUnix?: string | null } | null, groupedInputs?: Array<{ __typename: 'GroupedInput', type?: GroupedInputType | null, totalAmount?: string | null, contractId?: string | null, assetId?: string | null, sender?: string | null, recipient?: string | null, data?: string | null, owner?: string | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string } | null> | null } | null> | null, groupedOutputs?: Array<{ __typename: 'GroupedOutput', to?: string | null, type?: GroupedOutputType | null, totalAmount?: string | null, assetId?: string | null, inputIndex?: number | null, recipient?: string | null, outputs?: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string } | null> | null, contract?: { __typename: 'Contract', id: string } | null } | null> | null, accountsInvolved?: Array<{ __typename: 'TransactionAccount', id?: string | null, type?: TransactionAccountType | null } | null> | null, operations?: Array<{ __typename: 'Operation', type?: OperationType | null, receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null } | null> | null, inputContract?: { __typename: 'InputContract', contract: { __typename: 'Contract', id: string } } | null, outputContract?: { __typename: 'ContractOutput', inputIndex: number } | null, status?: { __typename: 'FailureStatus', time: string, programState?: { __typename: 'ProgramState', data: string } | null } | { __typename: 'SqueezedOutStatus', reason: string } | { __typename: 'SubmittedStatus', time: string } | { __typename: 'SuccessStatus', time: string, block: { __typename: 'Block', id: string, header: { __typename: 'Header', id: string, height: string, daHeight: string, applicationHash: string, messageReceiptRoot: string, messageReceiptCount: string, time: string } }, programState?: { __typename: 'ProgramState', data: string } | null } | null, inputContracts?: Array<{ __typename: 'Contract', id: string }> | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string }> | null, outputs: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string }>, receipts?: Array<{ __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null }> | null } | null }; - -export type SearchQueryQueryVariables = Exact<{ - search: Scalars['String']['input']; -}>; - - -export type SearchQueryQuery = { __typename: 'Query', search?: { __typename: 'SearchResult', account?: { __typename: 'SearchAccount', address?: string | null, transactions?: Array<{ __typename: 'SearchTransaction', id?: string | null } | null> | null } | null, contract?: { __typename: 'SearchContract', id?: string | null } | null, block?: { __typename: 'SearchBlock', id?: string | null, height?: string | null } | null, transaction?: { __typename: 'SearchTransaction', id?: string | null } | null } | null }; - -export type TransactionContractItemFragment = { __typename: 'Contract', id: string }; - -type TransactionStatus_FailureStatus_Fragment = { __typename: 'FailureStatus', time: string, programState?: { __typename: 'ProgramState', data: string } | null }; - -type TransactionStatus_SqueezedOutStatus_Fragment = { __typename: 'SqueezedOutStatus', reason: string }; - -type TransactionStatus_SubmittedStatus_Fragment = { __typename: 'SubmittedStatus', time: string }; - -type TransactionStatus_SuccessStatus_Fragment = { __typename: 'SuccessStatus', time: string, block: { __typename: 'Block', id: string, header: { __typename: 'Header', id: string, height: string, daHeight: string, applicationHash: string, messageReceiptRoot: string, messageReceiptCount: string, time: string } }, programState?: { __typename: 'ProgramState', data: string } | null }; - -export type TransactionStatusFragment = TransactionStatus_FailureStatus_Fragment | TransactionStatus_SqueezedOutStatus_Fragment | TransactionStatus_SubmittedStatus_Fragment | TransactionStatus_SuccessStatus_Fragment; - -type TransactionInput_InputCoin_Fragment = { __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number }; - -type TransactionInput_InputContract_Fragment = { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } }; - -type TransactionInput_InputMessage_Fragment = { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string }; - -export type TransactionInputFragment = TransactionInput_InputCoin_Fragment | TransactionInput_InputContract_Fragment | TransactionInput_InputMessage_Fragment; - -type TransactionOutput_ChangeOutput_Fragment = { __typename: 'ChangeOutput', to: string, amount: string, assetId: string }; - -type TransactionOutput_CoinOutput_Fragment = { __typename: 'CoinOutput', to: string, amount: string, assetId: string }; - -type TransactionOutput_ContractCreated_Fragment = { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } }; - -type TransactionOutput_ContractOutput_Fragment = { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string }; - -type TransactionOutput_VariableOutput_Fragment = { __typename: 'VariableOutput', to: string, amount: string, assetId: string }; - -export type TransactionOutputFragment = TransactionOutput_ChangeOutput_Fragment | TransactionOutput_CoinOutput_Fragment | TransactionOutput_ContractCreated_Fragment | TransactionOutput_ContractOutput_Fragment | TransactionOutput_VariableOutput_Fragment; - -export type TransactionReceiptFragment = { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null }; - -export type InnerReceiptItemFragment = { __typename: 'OperationReceipt', item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null }; - -export type OperationReceiptItemFragment = { __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null }; - -export type OperationItemFragment = { __typename: 'Operation', type?: OperationType | null, receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null }; - -export type TransactionItemFragment = { __typename: 'Transaction', id: string, title?: string | null, isPredicate?: boolean | null, blockHeight?: string | null, statusType?: TransactionStatusType | null, totalAccounts?: number | null, totalAssets?: number | null, totalOperations?: number | null, gasUsed?: string | null, fee?: string | null, gasPrice?: string | null, maturity?: string | null, txPointer?: string | null, isScript: boolean, isCreate: boolean, isMint: boolean, witnesses?: Array | null, receiptsRoot?: string | null, script?: string | null, scriptData?: string | null, bytecodeWitnessIndex?: number | null, bytecodeLength?: string | null, salt?: string | null, storageSlots?: Array | null, rawPayload: string, mintAmount?: string | null, mintAssetId?: string | null, inputAssetIds?: Array | null, time?: { __typename: 'ParsedTime', fromNow?: string | null, full?: string | null, rawTai64?: string | null, rawUnix?: string | null } | null, groupedInputs?: Array<{ __typename: 'GroupedInput', type?: GroupedInputType | null, totalAmount?: string | null, contractId?: string | null, assetId?: string | null, sender?: string | null, recipient?: string | null, data?: string | null, owner?: string | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string } | null> | null } | null> | null, groupedOutputs?: Array<{ __typename: 'GroupedOutput', to?: string | null, type?: GroupedOutputType | null, totalAmount?: string | null, assetId?: string | null, inputIndex?: number | null, recipient?: string | null, outputs?: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string } | null> | null, contract?: { __typename: 'Contract', id: string } | null } | null> | null, accountsInvolved?: Array<{ __typename: 'TransactionAccount', id?: string | null, type?: TransactionAccountType | null } | null> | null, operations?: Array<{ __typename: 'Operation', type?: OperationType | null, receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', receipts?: Array<{ __typename: 'OperationReceipt', item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null, item?: { __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null } | null } | null> | null } | null> | null, inputContract?: { __typename: 'InputContract', contract: { __typename: 'Contract', id: string } } | null, outputContract?: { __typename: 'ContractOutput', inputIndex: number } | null, status?: { __typename: 'FailureStatus', time: string, programState?: { __typename: 'ProgramState', data: string } | null } | { __typename: 'SqueezedOutStatus', reason: string } | { __typename: 'SubmittedStatus', time: string } | { __typename: 'SuccessStatus', time: string, block: { __typename: 'Block', id: string, header: { __typename: 'Header', id: string, height: string, daHeight: string, applicationHash: string, messageReceiptRoot: string, messageReceiptCount: string, time: string } }, programState?: { __typename: 'ProgramState', data: string } | null } | null, inputContracts?: Array<{ __typename: 'Contract', id: string }> | null, inputs?: Array<{ __typename: 'InputCoin', amount: string, assetId: string, owner: string, predicate: string, predicateData: string, txPointer: string, utxoId: string, witnessIndex: number } | { __typename: 'InputContract', utxoId: string, balanceRoot: string, txPointer: string, contract: { __typename: 'Contract', id: string } } | { __typename: 'InputMessage', sender: string, recipient: string, amount: string, nonce: string, data: string, predicate: string, predicateData: string }> | null, outputs: Array<{ __typename: 'ChangeOutput', to: string, amount: string, assetId: string } | { __typename: 'CoinOutput', to: string, amount: string, assetId: string } | { __typename: 'ContractCreated', contract: { __typename: 'Contract', id: string } } | { __typename: 'ContractOutput', inputIndex: number, balanceRoot: string } | { __typename: 'VariableOutput', to: string, amount: string, assetId: string }>, receipts?: Array<{ __typename: 'Receipt', pc?: string | null, is?: string | null, toAddress?: string | null, amount?: string | null, assetId?: string | null, gas?: string | null, param1?: string | null, param2?: string | null, val?: string | null, ptr?: string | null, digest?: string | null, reason?: string | null, ra?: string | null, rb?: string | null, rc?: string | null, rd?: string | null, len?: string | null, receiptType: ReceiptType, result?: string | null, gasUsed?: string | null, data?: string | null, sender?: string | null, recipient?: string | null, nonce?: string | null, contractId?: string | null, subId?: string | null, contract?: { __typename: 'Contract', id: string } | null, to?: { __typename: 'Contract', id: string } | null }> | null }; - -export const ContractItemFragmentDoc = gql` - fragment ContractItem on Contract { - id - bytecode - salt -} - `; -export const ContractBalanceItemFragmentDoc = gql` - fragment ContractBalanceItem on ContractBalance { - contract - amount - assetId -} - `; -export const ContractBalanceConnectionItemFragmentDoc = gql` - fragment ContractBalanceConnectionItem on ContractBalanceConnection { - pageInfo { - hasNextPage - hasPreviousPage - endCursor - startCursor - } - edges { - cursor - node { - ...ContractBalanceItem - } - } -} - ${ContractBalanceItemFragmentDoc}`; -export const AccountBalanceFragmentDoc = gql` - fragment AccountBalance on Balance { - __typename - assetId - amount - owner - utxos { - __typename - utxoId - amount - txCreatedIdx - blockCreated - } -} - `; -export const TransactionContractItemFragmentDoc = gql` - fragment TransactionContractItem on Contract { - __typename - id -} - `; -export const TransactionInputFragmentDoc = gql` - fragment TransactionInput on Input { - __typename - ... on InputCoin { - amount - assetId - owner - predicate - predicateData - txPointer - utxoId - witnessIndex - } - ... on InputContract { - utxoId - balanceRoot - txPointer - contract { - ...TransactionContractItem - } - } - ... on InputMessage { - sender - recipient - amount - nonce - data - predicate - predicateData - } -} - ${TransactionContractItemFragmentDoc}`; -export const TransactionOutputFragmentDoc = gql` - fragment TransactionOutput on Output { - __typename - ... on CoinOutput { - to - amount - assetId - } - ... on ContractOutput { - inputIndex - balanceRoot - } - ... on ChangeOutput { - to - amount - assetId - } - ... on VariableOutput { - to - amount - assetId - } - ... on ContractCreated { - contract { - ...TransactionContractItem - } - } -} - ${TransactionContractItemFragmentDoc}`; -export const TransactionReceiptFragmentDoc = gql` - fragment TransactionReceipt on Receipt { - __typename - contract { - ...TransactionContractItem - } - to { - ...TransactionContractItem - } - pc - is - toAddress - amount - assetId - gas - param1 - param2 - val - ptr - digest - reason - ra - rb - rc - rd - len - receiptType - result - gasUsed - data - sender - recipient - nonce - contractId - subId -} - ${TransactionContractItemFragmentDoc}`; -export const InnerReceiptItemFragmentDoc = gql` - fragment InnerReceiptItem on OperationReceipt { - item { - ...TransactionReceipt - } -} - ${TransactionReceiptFragmentDoc}`; -export const OperationReceiptItemFragmentDoc = gql` - fragment OperationReceiptItem on OperationReceipt { - ...InnerReceiptItem - receipts { - ...InnerReceiptItem - receipts { - ...InnerReceiptItem - receipts { - ...InnerReceiptItem - } - } - } -} - ${InnerReceiptItemFragmentDoc}`; -export const OperationItemFragmentDoc = gql` - fragment OperationItem on Operation { - __typename - type - receipts { - ...OperationReceiptItem - receipts { - ...OperationReceiptItem - } - } -} - ${OperationReceiptItemFragmentDoc}`; -export const TransactionStatusFragmentDoc = gql` - fragment TransactionStatus on TransactionStatus { - __typename - ... on SqueezedOutStatus { - reason - } - ... on SuccessStatus { - time - block { - id - header { - id - height - daHeight - applicationHash - messageReceiptRoot - messageReceiptCount - time - } - } - programState { - data - } - } - ... on FailureStatus { - time - programState { - data - } - } - ... on SubmittedStatus { - time - } -} - `; -export const TransactionItemFragmentDoc = gql` - fragment TransactionItem on Transaction { - id - title - time { - fromNow - full - rawTai64 - rawUnix - } - groupedInputs { - type - totalAmount - inputs { - ...TransactionInput - } - contractId - assetId - sender - recipient - data - owner - } - groupedOutputs { - to - type - totalAmount - outputs { - ...TransactionOutput - } - contract { - id - } - assetId - inputIndex - recipient - } - accountsInvolved { - id - type - } - operations { - ...OperationItem - } - isPredicate - blockHeight - statusType - totalAccounts - totalAssets - totalOperations - gasUsed - fee - __typename - gasPrice - maturity - txPointer - isScript - isCreate - isMint - witnesses - receiptsRoot - script - scriptData - bytecodeWitnessIndex - bytecodeLength - salt - storageSlots - rawPayload - mintAmount - mintAssetId - inputContract { - contract { - id - } - } - outputContract { - inputIndex - } - status { - ...TransactionStatus - } - inputAssetIds - inputContracts { - ...TransactionContractItem - } - inputs { - ...TransactionInput - } - outputs { - ...TransactionOutput - } - receipts { - ...TransactionReceipt - } -} - ${TransactionInputFragmentDoc} -${TransactionOutputFragmentDoc} -${OperationItemFragmentDoc} -${TransactionStatusFragmentDoc} -${TransactionContractItemFragmentDoc} -${TransactionReceiptFragmentDoc}`; -export const BlockItemFragmentDoc = gql` - fragment BlockItem on Block { - time { - fromNow - full - rawTai64 - rawUnix - } - totalGasUsed - id - consensus { - __typename - ... on PoAConsensus { - signature - } - } - header { - transactionsCount - time - } - transactions { - ...TransactionItem - } -} - ${TransactionItemFragmentDoc}`; -export const GetAccountTransactionsDocument = gql` - query getAccountTransactions($owner: Address!) { - transactions: transactionsByOwner(first: 30, owner: $owner) { - pageInfo { - hasNextPage - hasPreviousPage - endCursor - startCursor - } - edges { - cursor - node { - ...TransactionItem - } - } - } -} - ${TransactionItemFragmentDoc}`; -export const GetBalancesDocument = gql` - query getBalances($owner: Address!) { - balances(first: 100, filter: {owner: $owner}) { - nodes { - ...AccountBalance - } - } -} - ${AccountBalanceFragmentDoc}`; -export const GetBlockByHeightDocument = gql` - query getBlockByHeight($height: U32) { - block(height: $height) { - ...BlockItem - } -} - ${BlockItemFragmentDoc}`; -export const GetBlockByIdDocument = gql` - query getBlockById($id: BlockId) { - block(id: $id) { - ...BlockItem - } -} - ${BlockItemFragmentDoc}`; -export const GetContractDocument = gql` - query getContract($id: ContractId!) { - contract(id: $id) { - ...ContractItem - } -} - ${ContractItemFragmentDoc}`; -export const GetContractBalancesDocument = gql` - query getContractBalances($id: ContractId!) { - contractBalances(filter: {contract: $id}, first: 1000) { - ...ContractBalanceConnectionItem - } -} - ${ContractBalanceConnectionItemFragmentDoc}`; -export const GetLastTransactionsDocument = gql` - query getLastTransactions($last: Int, $first: Int, $after: String, $before: String) { - transactions(last: $last, first: $first, after: $after, before: $before) { - pageInfo { - hasNextPage - hasPreviousPage - endCursor - startCursor - } - edges { - cursor - node { - ...TransactionItem - } - } - } -} - ${TransactionItemFragmentDoc}`; -export const GetPredicateDocument = gql` - query getPredicate($address: Address!) { - predicate(address: $address) { - id - bytecode - } -} - `; -export const GetTransactionDocument = gql` - query getTransaction($id: TransactionId!) { - transaction(id: $id) { - ...TransactionItem - } -} - ${TransactionItemFragmentDoc}`; -export const SearchQueryDocument = gql` - query searchQuery($search: String!) { - search(query: $search) { - account { - address - transactions { - id - } - } - contract { - id - } - block { - id - height - } - transaction { - id - } - } -} - `; - -export type SdkFunctionWrapper = (action: (requestHeaders?:Record) => Promise, operationName: string, operationType?: string, variables?: any) => Promise; - - -const defaultWrapper: SdkFunctionWrapper = (action, _operationName, _operationType, _variables) => action(); -const GetAccountTransactionsDocumentString = print(GetAccountTransactionsDocument); -const GetBalancesDocumentString = print(GetBalancesDocument); -const GetBlockByHeightDocumentString = print(GetBlockByHeightDocument); -const GetBlockByIdDocumentString = print(GetBlockByIdDocument); -const GetContractDocumentString = print(GetContractDocument); -const GetContractBalancesDocumentString = print(GetContractBalancesDocument); -const GetLastTransactionsDocumentString = print(GetLastTransactionsDocument); -const GetPredicateDocumentString = print(GetPredicateDocument); -const GetTransactionDocumentString = print(GetTransactionDocument); -const SearchQueryDocumentString = print(SearchQueryDocument); -export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = defaultWrapper) { - return { - getAccountTransactions(variables: GetAccountTransactionsQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<{ data: GetAccountTransactionsQuery; errors?: GraphQLError[]; extensions?: any; headers: Headers; status: number; }> { - return withWrapper((wrappedRequestHeaders) => client.rawRequest(GetAccountTransactionsDocumentString, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getAccountTransactions', 'query', variables); - }, - getBalances(variables: GetBalancesQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<{ data: GetBalancesQuery; errors?: GraphQLError[]; extensions?: any; headers: Headers; status: number; }> { - return withWrapper((wrappedRequestHeaders) => client.rawRequest(GetBalancesDocumentString, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getBalances', 'query', variables); - }, - getBlockByHeight(variables?: GetBlockByHeightQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<{ data: GetBlockByHeightQuery; errors?: GraphQLError[]; extensions?: any; headers: Headers; status: number; }> { - return withWrapper((wrappedRequestHeaders) => client.rawRequest(GetBlockByHeightDocumentString, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getBlockByHeight', 'query', variables); - }, - getBlockById(variables?: GetBlockByIdQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<{ data: GetBlockByIdQuery; errors?: GraphQLError[]; extensions?: any; headers: Headers; status: number; }> { - return withWrapper((wrappedRequestHeaders) => client.rawRequest(GetBlockByIdDocumentString, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getBlockById', 'query', variables); - }, - getContract(variables: GetContractQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<{ data: GetContractQuery; errors?: GraphQLError[]; extensions?: any; headers: Headers; status: number; }> { - return withWrapper((wrappedRequestHeaders) => client.rawRequest(GetContractDocumentString, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getContract', 'query', variables); - }, - getContractBalances(variables: GetContractBalancesQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<{ data: GetContractBalancesQuery; errors?: GraphQLError[]; extensions?: any; headers: Headers; status: number; }> { - return withWrapper((wrappedRequestHeaders) => client.rawRequest(GetContractBalancesDocumentString, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getContractBalances', 'query', variables); - }, - getLastTransactions(variables?: GetLastTransactionsQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<{ data: GetLastTransactionsQuery; errors?: GraphQLError[]; extensions?: any; headers: Headers; status: number; }> { - return withWrapper((wrappedRequestHeaders) => client.rawRequest(GetLastTransactionsDocumentString, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getLastTransactions', 'query', variables); - }, - getPredicate(variables: GetPredicateQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<{ data: GetPredicateQuery; errors?: GraphQLError[]; extensions?: any; headers: Headers; status: number; }> { - return withWrapper((wrappedRequestHeaders) => client.rawRequest(GetPredicateDocumentString, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getPredicate', 'query', variables); - }, - getTransaction(variables: GetTransactionQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<{ data: GetTransactionQuery; errors?: GraphQLError[]; extensions?: any; headers: Headers; status: number; }> { - return withWrapper((wrappedRequestHeaders) => client.rawRequest(GetTransactionDocumentString, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'getTransaction', 'query', variables); - }, - searchQuery(variables: SearchQueryQueryVariables, requestHeaders?: GraphQLClientRequestHeaders): Promise<{ data: SearchQueryQuery; errors?: GraphQLError[]; extensions?: any; headers: Headers; status: number; }> { - return withWrapper((wrappedRequestHeaders) => client.rawRequest(SearchQueryDocumentString, variables, {...requestHeaders, ...wrappedRequestHeaders}), 'searchQuery', 'query', variables); - } - }; -} -export type Sdk = ReturnType; \ No newline at end of file diff --git a/packages/graphql/src/graphql/GraphQLContext.ts b/packages/graphql/src/graphql/GraphQLContext.ts deleted file mode 100644 index 68e3f93b1..000000000 --- a/packages/graphql/src/graphql/GraphQLContext.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { env } from '~/config'; -import { ChainEntity } from '~/domain/Chain/ChainEntity'; -import DataCache from '~/infra/cache/DataCache'; -import { type GraphQLSDK, client } from './GraphQLSDK'; -import type { GQLChainInfo } from './generated/sdk-provider'; - -export type GraphQLContext = { - chain: ChainEntity | null; - client: GraphQLSDK; - isAuthenticated: boolean; -}; - -export class GraphQLContextFactory { - static async create(req: Request): Promise { - let isAuthenticated = true; - const secret = env.get('SERVER_API_KEY'); - const bearer = `Bearer ${secret}`; - const token = - req.headers.get('x-api-key') || req.headers.get('Authorization'); - if (!token || token !== bearer) { - isAuthenticated = false; - } - - // Cache chain info to avoid fetching on every request - let chainEntity = DataCache.getInstance().get('chainInfo'); - if (!chainEntity) { - const res = await client.sdk.chain(); - const chainItem = res.data?.chain; - if (!chainItem) { - return { client, chain: null, isAuthenticated }; - } - chainEntity = ChainEntity.create(chainItem as GQLChainInfo); - DataCache.getInstance().save('chainInfo', 10 * 60 * 1000, chainEntity); - } - - return { client, chain: chainEntity, isAuthenticated }; - } -} diff --git a/packages/graphql/src/graphql/GraphQLSDK.ts b/packages/graphql/src/graphql/GraphQLSDK.ts deleted file mode 100644 index 77f1a3876..000000000 --- a/packages/graphql/src/graphql/GraphQLSDK.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { GraphQLClient } from 'graphql-request'; -import { env } from '~/config'; -import { getSdk } from '~/graphql/generated/sdk-provider'; - -export type GQLClient = ReturnType; - -export class GraphQLSDK { - client: GraphQLClient; - sdk: ReturnType; - - constructor() { - const provider = env.get('FUEL_PROVIDER'); - if (!provider) { - throw new Error('Missing FUEL_PROVIDER'); - } - this.client = new GraphQLClient(provider); - this.sdk = getSdk(this.client); - } -} - -export const client = new GraphQLSDK(); diff --git a/packages/graphql/src/graphql/GraphQLServer.ts b/packages/graphql/src/graphql/GraphQLServer.ts deleted file mode 100644 index 8b42461b1..000000000 --- a/packages/graphql/src/graphql/GraphQLServer.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { join } from 'node:path'; -import { loadFilesSync } from '@graphql-tools/load-files'; -import { mergeTypeDefs } from '@graphql-tools/merge'; -import { makeExecutableSchema } from '@graphql-tools/schema'; -import type { GraphQLSchema } from 'graphql'; -import { createYoga } from 'graphql-yoga'; -import { env } from '~/config'; -import { GraphQLContextFactory } from './GraphQLContext'; -import { resolvers } from './resolvers'; - -const DEBUG = env.get('DEBUG'); -const typesArray = loadFilesSync(join(__dirname, './schemas')); -const typeDefs = mergeTypeDefs(typesArray); - -export class GraphQLServer { - schema() { - return makeExecutableSchema({ - typeDefs, - resolvers, - }); - } - - setup(schema: GraphQLSchema) { - return createYoga({ - schema, - batching: true, - logging: !!DEBUG, - maskedErrors: !!DEBUG, - context: async ({ request }) => { - return GraphQLContextFactory.create(request); - }, - }); - } -} diff --git a/packages/graphql/src/graphql/resolvers/APYResolver.ts b/packages/graphql/src/graphql/resolvers/APYResolver.ts deleted file mode 100644 index 47e69cfd3..000000000 --- a/packages/graphql/src/graphql/resolvers/APYResolver.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { env } from '~/config'; -import { logger } from '~/core/Logger'; -import DataCache from '~/infra/cache/DataCache'; - -const ONE_UNIT = 10n ** 9n; -const INITIAL_SUPPLY = 10_000_000_000n * ONE_UNIT; -// 30 minutes -const CACHE_EXPIRATION = 1000 * 60 * 30; - -export class APYResolver { - static create() { - const resolvers = new APYResolver(); - return { - Query: { - stakingAPY: resolvers.stakingAPY, - }, - }; - } - - async stakingAPY() { - logger.debug('GraphQL', 'APYResolver.stakingAPY'); - const cachedAPY = DataCache.getInstance().get('staking-apy'); - - if (cachedAPY) - return { - amount: cachedAPY, - }; - - const network = env.get('FUEL_CHAIN'); - const envPrefix = network === 'mainnet' ? 'mainnet' : 'testnet'; - const baseUrl = `https://rest.seq.${envPrefix}.fuel.network`; - const poolResp = await fetch( - new URL('/cosmos/staking/v1beta1/pool', baseUrl), - ).then((resp) => resp.json()); - const inflationResp = await fetch( - new URL('/cosmos/mint/v1beta1/inflation', baseUrl), - ).then((resp) => resp.json()); - const inflation = BigInt(Number(inflationResp.inflation) * 100); - const totalDelegation = BigInt(poolResp.pool.bonded_tokens); - const totalInflation = (INITIAL_SUPPLY / 100n) * inflation; - const APY = (totalInflation * 100n) / totalDelegation; - - DataCache.getInstance().save( - 'staking-apy', - CACHE_EXPIRATION, - APY.toString(), - ); - - return { - amount: APY.toString(), - }; - } -} diff --git a/packages/graphql/src/graphql/resolvers/AssetResolver.ts b/packages/graphql/src/graphql/resolvers/AssetResolver.ts deleted file mode 100644 index 23d6005a8..000000000 --- a/packages/graphql/src/graphql/resolvers/AssetResolver.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { logger } from '~/core/Logger'; -import type { GQLQueryTransactionsArgs } from '~/graphql/generated/sdk-provider'; -import AssetDAO from '~/infra/dao/AssetDAO'; -import AssetGateway from '~/infra/gateway/AssetGateway'; -import PaginatedParams from '~/infra/paginator/PaginatedParams'; -import type { GraphQLContext } from '../GraphQLContext'; - -type Params = { - asset: { contractId: string } & GQLQueryTransactionsArgs; -}; - -export class AssetResolver { - static create() { - const resolvers = new AssetResolver(); - return { - Query: { - assetsByContract: resolvers.assetsByContract, - }, - }; - } - - // TODO: index data to Postgres instead of fetch from SDK - async assetsByContract( - _: any, - params: Params['asset'], - { chain }: GraphQLContext, - ) { - logger.debug('GraphQL', 'AssetResolver.assetsByContract'); - const assetGateway = new AssetGateway(); - const assetDAO = new AssetDAO(); - const chainId = chain ? Number.parseInt(chain.chainId) : undefined; - const assets = await assetDAO.getPaginatedByContractId( - params.contractId, - new PaginatedParams(params), - ); - for (const asset of assets.nodes) { - const resolvedAsset = await assetGateway.getAsset(asset.assetId, chainId); - asset.assetId = resolvedAsset.assetId; - asset.contractId = resolvedAsset.contractId; - asset.name = resolvedAsset.name; - asset.symbol = resolvedAsset.symbol; - asset.decimals = resolvedAsset.decimals; - asset.icon = resolvedAsset.icon; - asset.networks = resolvedAsset.networks; - asset.suspicious = resolvedAsset.suspicious; - asset.rate = resolvedAsset.rate; - } - return assets; - } -} diff --git a/packages/graphql/src/graphql/resolvers/BalanceResolver.ts b/packages/graphql/src/graphql/resolvers/BalanceResolver.ts deleted file mode 100644 index 79dc0eac5..000000000 --- a/packages/graphql/src/graphql/resolvers/BalanceResolver.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { logger } from '~/core/Logger'; -import type { - GQLBalance, - GQLQueryBalanceArgs, - GQLQueryBalanceByBlockHeightArgs, - GQLQueryBalancesArgs, - GQLQueryCoinsArgs, -} from '~/graphql/generated/sdk-provider'; -import BalanceDAO from '~/infra/dao/BalanceDAO'; -import { convertToUsd } from '~/infra/dao/utils'; -import AssetGateway from '~/infra/gateway/AssetGateway'; -import type { GraphQLContext } from '../GraphQLContext'; - -type Source = GQLBalance; -type Params = { - balance: GQLQueryBalanceArgs; - balances: GQLQueryBalancesArgs; - balanceByBlockHeight: GQLQueryBalanceByBlockHeightArgs; - utxos: GQLQueryCoinsArgs['filter']; -}; - -export class BalanceResolver { - static create() { - const resolvers = new BalanceResolver(); - return { - Query: { - balance: resolvers.balance, - balances: resolvers.balances, - balanceByBlockHeight: resolvers.balanceByBlockHeight, - }, - Balance: { - utxos: resolvers.utxos, - }, - }; - } - - async balance( - _: Source, - params: Params['balance'], - { client, chain }: GraphQLContext, - ) { - logger.debug('GraphQL', 'BalanceResolver.balance'); - const assetGateway = new AssetGateway(); - const res = await client.sdk.balance(params); - const balance = res.data.balance as any; - const chainId = chain ? Number.parseInt(chain.chainId) : undefined; - const asset = await assetGateway.getAsset(balance.assetId, chainId); - if (asset) { - balance.assetId = asset.assetId; - balance.contractId = asset.contractId; - balance.name = asset.name; - balance.symbol = asset.symbol; - balance.icon = asset.icon; - balance.decimals = asset.decimals; - balance.totalSupply = asset.totalSupply; - balance.suspicious = asset.suspicious; - balance.collection = asset.collection; - balance.rate = asset.rate; - balance.amountInUsd = asset.rate - ? convertToUsd(balance.amount, balance.decimals, asset.rate).formatted - : null; - } - return balance; - } - - async balances( - _: Source, - params: Params['balances'], - { client, chain }: GraphQLContext, - ) { - logger.debug('GraphQL', 'BalanceResolver.balances'); - const assetGateway = new AssetGateway(); - const res = (await client.sdk.balances(params)) as any; - const balances = res.data.balances; - for (const balance of balances.nodes) { - const chainId = chain ? Number.parseInt(chain.chainId) : undefined; - const asset = await assetGateway.getAsset(balance.assetId, chainId); - if (asset) { - balance.assetId = asset.assetId; - balance.contractId = asset.contractId; - balance.name = asset.name; - balance.symbol = asset.symbol; - balance.icon = asset.icon; - balance.decimals = asset.decimals; - balance.totalSupply = asset.totalSupply; - balance.suspicious = asset.suspicious; - if (asset.metadata?.image) { - asset.metadata.image = asset.metadata.image.replace( - 'ipfs://', - 'https://ipfs.io/ipfs/', - ); - } - balance.metadata = JSON.stringify(asset.metadata); - balance.collection = asset.collection; - balance.rate = asset.rate; - balance.amountInUsd = asset.rate - ? convertToUsd(balance.amount, balance.decimals, asset.rate).formatted - : null; - } - } - return balances; - } - - async balanceByBlockHeight( - _: Source, - params: Params['balanceByBlockHeight'], - { chain }: GraphQLContext, - ) { - logger.debug('GraphQL', 'BalanceResolver.balanceByBlockHeight'); - const chainId = chain ? Number.parseInt(chain.chainId) : undefined; - const balanceDAO = new BalanceDAO(); - const output = await balanceDAO.getBalance( - params.accountHash, - params.assetId, - params.blockHeight || null, - ); - if (!output) { - return {}; - } - const assetGateway = new AssetGateway(); - const asset = await assetGateway.getAsset(params.assetId, chainId); - return { - accountHash: output.account_hash, - assetId: output.asset_id, - blockHeight: output.block_height, - balance: output.balance, - balanceInUsd: asset.rate - ? convertToUsd(output.balance, asset.decimals, asset.rate).formatted - : null, - }; - } - - async utxos( - parent: Source, - params: Params['utxos'], - { client }: GraphQLContext, - ) { - logger.debug('GraphQL', 'BalanceResolver.utxos'); - const filter = !params?.owner - ? { - assetId: parent.assetId, - owner: parent.owner, - } - : params; - - const res = await client.sdk.coins({ first: 2500, filter }); - return res.data.coins.nodes; - } -} diff --git a/packages/graphql/src/graphql/resolvers/BlockResolver.ts b/packages/graphql/src/graphql/resolvers/BlockResolver.ts deleted file mode 100644 index f754ba50a..000000000 --- a/packages/graphql/src/graphql/resolvers/BlockResolver.ts +++ /dev/null @@ -1,257 +0,0 @@ -import { sleep } from 'fuels'; -import { GraphQLError } from 'graphql'; -import { logger } from '~/core/Logger'; -import type { - GQLBlock, - GQLQueryBlockArgs, - GQLQueryBlocksArgs, -} from '~/graphql/generated/sdk-provider'; -import DataCache from '~/infra/cache/DataCache'; -import BlockDAO from '~/infra/dao/BlockDAO'; -import { convertToUsd } from '~/infra/dao/utils'; -import AssetGateway from '~/infra/gateway/AssetGateway'; -import PaginatedParams from '~/infra/paginator/PaginatedParams'; -import type { GraphQLContext } from '../GraphQLContext'; - -type Source = GQLBlock; -type Params = { - blocks: GQLQueryBlocksArgs; - block: GQLQueryBlockArgs; - tps: null; - getBlocksDashboard: null; -}; - -export class BlockResolver { - getBlocksDashboardData: Awaited< - ReturnType> - > | null = null; - statisticsData: Awaited< - ReturnType> - > | null = null; - tpsData: Awaited< - ReturnType> - > | null = null; - - static create() { - const resolvers = new BlockResolver(); - return { - startPoolingAnalytics: resolvers.startPoolingAnalytics, - Query: { - block: resolvers.block.bind(resolvers), - blocks: resolvers.blocks.bind(resolvers), - tps: resolvers.tps.bind(resolvers), - statistics: resolvers.statistics.bind(resolvers), - getBlocksDashboard: resolvers.getBlocksDashboard.bind(resolvers), - }, - }; - } - - startPoolingAnalytics = async ({ - chainId, - baseAssetId, - }: { chainId: number; baseAssetId: string }) => { - try { - logger.debug('GraphQL', 'BlockResolver.startPoolingAnalytics START'); - this.getBlocksDashboardData = await this._getBlocksDashboard( - {} as any, - null, - { chainId, baseAssetId }, - ); - this.statisticsData = await this._statistics({} as any, null, { - chainId, - baseAssetId, - }); - this.tpsData = await this._tps({} as any, null); - logger.debug('GraphQL', 'BlockResolver.startPoolingAnalytics END'); - } catch (e) { - logger.error('GraphQL', 'BlockResolver.startPoolingAnalytics', e); - } finally { - await sleep(7_000); - this.startPoolingAnalytics({ chainId, baseAssetId }); - } - }; - - async block(_: Source, { id, height }: Params['block']) { - logger.debug('GraphQL', 'BlockResolver.block'); - if (!id && !height) { - throw new Error('Either id or height must be provided'); - } - - if (id) { - const blockDAO = new BlockDAO(); - const block = await blockDAO.getByHash(id); - return block?.toGQLNode(); - } - - if (!height) throw new Error(); - const blockDAO = new BlockDAO(); - const block = await blockDAO.getByHeight(Number.parseInt(height)); - return block?.toGQLNode(); - } - - async blocks(_: Source, params: Params['blocks']) { - logger.debug('GraphQL', 'BlockResolver.blocks'); - if (!params.first && !params.last) { - throw new GraphQLError('Either first or last must be provided'); - } - const blockDAO = new BlockDAO(); - const blocks = await blockDAO.getPaginatedBlocks( - new PaginatedParams(params), - ); - return blocks; - } - - async getBlocksDashboard( - _: Source, - _params: Params['getBlocksDashboard'], - context: GraphQLContext, - ) { - // If background data is available, return it (fast path) - if (this.getBlocksDashboardData) { - return this.getBlocksDashboardData; - } - - const chainId = context.chain?.chainId; - const baseAssetId = context.chain?.data.consensusParameters.baseAssetId; - - // Fallback: compute on-demand if background process hasn't run yet - logger.debug('GraphQL', 'BlockResolver.getBlocksDashboard - FALLBACK'); - return this._getBlocksDashboard(_, _params, { - chainId: Number.parseInt(chainId || '0'), - baseAssetId, - }); - } - - async _getBlocksDashboard( - _: Source, - _params: Params['getBlocksDashboard'], - { chainId, baseAssetId }: { chainId?: number; baseAssetId?: string }, - ) { - logger.debug('GraphQL', 'BlockResolver.getBlocksDashboard'); - const assetGateway = new AssetGateway(); - const baseAsset = await assetGateway.getAsset( - baseAssetId || '', - chainId || 0, - ); - const blockDAO = new BlockDAO(); - const blocks = await blockDAO.getBlocksDashboard(); - for (const block of blocks.nodes) { - block.totalFeeInUsd = baseAsset?.rate - ? convertToUsd( - String(block.totalFee), - baseAsset.decimals, - baseAsset.rate, - )?.formatted - : ''; - block.gasUsedInUsd = baseAsset?.rate - ? convertToUsd( - String(block.gasUsed), - baseAsset.decimals, - baseAsset.rate, - )?.formatted - : ''; - } - return blocks; - } - - async tps(_: Source, _params: Params['tps']) { - // If background data is available, return it (fast path) - if (this.tpsData) { - return this.tpsData; - } - - // Fallback: compute on-demand if background process hasn't run yet - logger.debug('GraphQL', 'BlockResolver.tps - FALLBACK'); - return this._tps(_, _params); - } - - async _tps(_: Source, _params: Params['tps']) { - logger.debug('GraphQL', 'BlockResolver.tps'); - const cachedTps = DataCache.getInstance().get('tps'); - if (cachedTps) return cachedTps; - const blockDAO = new BlockDAO(); - const maxTs = await blockDAO.getMaxTimestamp(); - const tps = await blockDAO.tps(maxTs); - DataCache.getInstance().save('tps', 60000, tps); - return tps; - } - - async statistics(_: Source, __: any, context: GraphQLContext) { - // If background data is available, return it (fast path) - if (this.statisticsData) { - return this.statisticsData; - } - - const chainId = context.chain?.chainId; - const baseAssetId = context.chain?.data.consensusParameters.baseAssetId; - - // Fallback: compute on-demand if background process hasn't run yet - logger.debug('GraphQL', 'BlockResolver.statistics - FALLBACK'); - return this._statistics(_, __, { - chainId: Number.parseInt(chainId || '0'), - baseAssetId, - }); - } - - async _statistics( - _: Source, - __: any, - { chainId, baseAssetId }: { chainId?: number; baseAssetId?: string }, - ) { - logger.debug('GraphQL', 'BlockResolver.statistics'); - const assetGateway = new AssetGateway(); - const baseAsset = await assetGateway.getAsset( - baseAssetId || '', - chainId || 0, - ); - const cachedTps = DataCache.getInstance().get('statistics'); - if (cachedTps) return cachedTps; - const blockDAO = new BlockDAO(); - - // Pin the analytics window to a single MAX(timestamp) lookup so all - // downstream queries share the same anchor (consistent snapshot) AND so - // the value can be passed as a bound parameter — that's what lets the - // planner pick an Index Scan on blocks_timestamp_idx instead of a - // Parallel Seq Scan over the whole blocks table. - const maxTs = await blockDAO.getMaxTimestamp(); - - const [hourly, averageTpsPerMinute, rollingStats60s, totalFee] = - await Promise.all([ - blockDAO.getHourlyStatistics(maxTs), - blockDAO.getAverageTpsPerMinute(maxTs), - blockDAO.getRollingStats60s(maxTs), - blockDAO.getTotalFee() as any, - ]); - - let totalFee24hrs = 0; - for (const fee of totalFee) { - totalFee24hrs += Number(fee.value); - fee.valueInUsd = baseAsset?.rate - ? convertToUsd(String(fee.value), baseAsset.decimals, baseAsset.rate) - ?.formatted - : null; - } - - const totalFee24hrsInUsd = baseAsset?.rate - ? convertToUsd(String(totalFee24hrs), baseAsset.decimals, baseAsset.rate) - ?.formatted - : null; - - const statistics = { - nodes: { - totalTps: hourly.totalTps, - averageTps: hourly.averageTps, - maxTps: hourly.maxTps, - averageTpsPerMinute, - rollingStats60s, - totalGasUsed: hourly.totalGasUsed, - averageGasUsed: hourly.averageGasUsed, - maxGasUsed: hourly.maxGasUsed, - totalFee, - totalFee24hrs: totalFee24hrsInUsd, - }, - }; - DataCache.getInstance().save('statistics', 60000, statistics); - return statistics; - } -} diff --git a/packages/graphql/src/graphql/resolvers/BridgeResolver.ts b/packages/graphql/src/graphql/resolvers/BridgeResolver.ts deleted file mode 100644 index f37bc441f..000000000 --- a/packages/graphql/src/graphql/resolvers/BridgeResolver.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { logger } from '~/core/Logger'; -import BridgeDAO from '~/infra/dao/BridgeDAO'; -import type { - GQLBridgeResponse, - GQLQueryBridgeEventArgs, - GQLQueryBridgeEventsArgs, -} from '../generated/sdk-provider'; - -export class BridgeResolver { - static create() { - const resolvers = new BridgeResolver(); - return { - Query: { - bridgeEvents: resolvers.bridgeEvents, - bridgeEvent: resolvers.bridgeEvent, - }, - }; - } - - async bridgeEvents(_: any, params: GQLQueryBridgeEventsArgs) { - logger.debug('GraphQL', 'BridgeResolver.bridgeEvents'); - const address = params.address; - const limit = params.limit || 10; - const offset = params.offset || 0; - const bridgeDAO = new BridgeDAO(); - const output = await bridgeDAO.getEvents(address, limit, offset); - for (const element of output.nodes) { - element.__typename = `Bridge${element.type}Response`; - } - return output; - } - - async bridgeEvent(_: any, params: GQLQueryBridgeEventArgs) { - logger.debug('GraphQL', 'BridgeResolver.bridgeEvent'); - const eventId = params.eventId; - const eventType = params.eventType; - const bridgeDAO = new BridgeDAO(); - const output = await bridgeDAO.getEvent(eventType, eventId); - if (!output) return {}; - return { - __typename: - `Bridge${output.type}Response` as GQLBridgeResponse['__typename'], - ...output, - }; - } -} diff --git a/packages/graphql/src/graphql/resolvers/ChainResolver.ts b/packages/graphql/src/graphql/resolvers/ChainResolver.ts deleted file mode 100644 index 977a682dc..000000000 --- a/packages/graphql/src/graphql/resolvers/ChainResolver.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { logger } from '~/core/Logger'; -import type { GQLChainInfo } from '~/graphql/generated/sdk-provider'; -import type { GraphQLContext } from '../GraphQLContext'; - -type Source = GQLChainInfo; -type Params = { - chain: null; -}; - -export class ChainResolver { - static create() { - const resolvers = new ChainResolver(); - return { - Query: { - chain: resolvers.chain, - }, - }; - } - - async chain(_: Source, _params: Params['chain'], { client }: GraphQLContext) { - logger.debug('GraphQL', 'ChainResolver.chain'); - const res = await client.sdk.chain(); - return res.data.chain; - } -} diff --git a/packages/graphql/src/graphql/resolvers/ContractResolver.ts b/packages/graphql/src/graphql/resolvers/ContractResolver.ts deleted file mode 100644 index 149969976..000000000 --- a/packages/graphql/src/graphql/resolvers/ContractResolver.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { logger } from '~/core/Logger'; -import type { - GQLContract, - GQLQueryContractArgs, - GQLQueryContractBalanceArgs, - GQLQueryContractBalancesArgs, -} from '~/graphql/generated/sdk-provider'; -import ContractDAO from '~/infra/dao/ContractDAO'; -import { convertToUsd } from '~/infra/dao/utils'; -import AssetGateway from '~/infra/gateway/AssetGateway'; -import PaginatedParams from '~/infra/paginator/PaginatedParams'; -import type { GraphQLContext } from '../GraphQLContext'; -import type { GQLContractBalance } from '../generated/sdk'; - -type Source = GQLContract; -type Params = { - contracts: any; - contract: GQLQueryContractArgs; - contractBalance: GQLQueryContractBalanceArgs; - contractBalances: GQLQueryContractBalancesArgs; -}; - -export class ContractResolver { - static create() { - const resolvers = new ContractResolver(); - return { - Query: { - contract: resolvers.contract, - contracts: resolvers.contracts, - contractBalance: resolvers.contractBalance, - contractBalances: resolvers.contractBalances, - }, - }; - } - - async contract(_: Source, { id }: Params['contract']) { - logger.debug('GraphQL', 'ContractResolver.contract'); - if (!id) { - throw new Error('Contract ID is required'); - } - const contractDAO = new ContractDAO(); - const contract = await contractDAO.getByHash(id); - return contract?.toGQLNode(); - } - - async contracts(_: Source, params: Params['contracts']) { - logger.debug('GraphQL', 'ContractResolver.contracts'); - const contractDAO = new ContractDAO(); - const contracts = await contractDAO.getPaginatedContracts( - new PaginatedParams(params), - ); - return contracts; - } - - async contractBalance( - _: Source, - params: Params['contractBalance'], - { client }: GraphQLContext, - ) { - logger.debug('GraphQL', 'ContractResolver.contractBalance'); - const res = await client.sdk.contractBalance(params); - return res.data.contractBalance; - } - - async contractBalances( - _: Source, - params: Params['contractBalances'], - { client, chain }: GraphQLContext, - ) { - logger.debug('GraphQL', 'ContractResolver.contractBalances'); - const assetGateway = new AssetGateway(); - params.first = 100; - const res = await client.sdk.contractBalances(params); - const chainId = chain ? Number.parseInt(chain.chainId) : undefined; - const output = res.data.contractBalances; - for (const edge of output.edges) { - const node = edge.node as GQLContractBalance; - if (node.assetId) { - const asset = await assetGateway.getAsset(node.assetId, chainId); - if (asset) { - node.assetId = asset.assetId; - node.name = asset.name; - node.symbol = asset.symbol; - node.decimals = asset.decimals; - node.icon = asset.icon; - node.suspicious = asset.suspicious; - node.amountInUsd = convertToUsd( - node.amount, - Number(node.decimals), - asset.rate, - ).formatted; - } - } - } - return output; - } -} diff --git a/packages/graphql/src/graphql/resolvers/NodeResolver.ts b/packages/graphql/src/graphql/resolvers/NodeResolver.ts deleted file mode 100644 index f3a3e155c..000000000 --- a/packages/graphql/src/graphql/resolvers/NodeResolver.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { logger } from '~/core/Logger'; -import type { GQLNodeInfo } from '~/graphql/generated/sdk-provider'; -import type { GraphQLContext } from '../GraphQLContext'; - -type Source = GQLNodeInfo; -type Params = { - nodeInfo: null; -}; - -export class NodeResolver { - static create() { - const resolvers = new NodeResolver(); - return { - Query: { - nodeInfo: resolvers.nodeInfo, - }, - }; - } - - async nodeInfo( - _: Source, - _params: Params['nodeInfo'], - { client }: GraphQLContext, - ) { - logger.debug('GraphQL', 'NodeResolver.nodeInfo'); - const res = await client.sdk.nodeInfo(); - return res.data.nodeInfo; - } -} diff --git a/packages/graphql/src/graphql/resolvers/PredicateResolver.ts b/packages/graphql/src/graphql/resolvers/PredicateResolver.ts deleted file mode 100644 index cac09a89a..000000000 --- a/packages/graphql/src/graphql/resolvers/PredicateResolver.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { logger } from '~/core/Logger'; -import PredicateDAO from '~/infra/dao/PredicateDAO'; - -type Params = { - predicate: { address: string }; -}; - -export class PredicateResolver { - static create() { - const resolvers = new PredicateResolver(); - return { - Query: { - predicate: resolvers.predicate, - }, - }; - } - - async predicate(_: any, params: Params['predicate']) { - logger.debug('GraphQL', 'PredicateResolver.predicate'); - const predicateDAO = new PredicateDAO(); - const predicate = await predicateDAO.getByAddress(params.address); - if (!predicate || predicate.bytecode === '0x') return; - return predicate.toGQLNode(); - } -} diff --git a/packages/graphql/src/graphql/resolvers/PublicResolver.ts b/packages/graphql/src/graphql/resolvers/PublicResolver.ts deleted file mode 100644 index bfd4c699c..000000000 --- a/packages/graphql/src/graphql/resolvers/PublicResolver.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { logger } from '~/core/Logger'; -import AssetGateway from '~/infra/gateway/AssetGateway'; -import type { GraphQLContext } from '../GraphQLContext'; - -type Params = { - asset: { assetId: string }; -}; - -export class PublicResolver { - static create() { - const resolvers = new PublicResolver(); - return { - Query: { - asset: resolvers.asset, - }, - }; - } - - async asset(_: any, _params: Params['asset'], { chain }: GraphQLContext) { - logger.debug('GraphQL', 'PublicResolver.asset'); - const assetId = _params.assetId; - const assetGateway = new AssetGateway(); - const chainId = chain ? Number.parseInt(chain.chainId) : undefined; - return assetGateway.getAsset(assetId, chainId); - } -} diff --git a/packages/graphql/src/graphql/resolvers/SearchResolver.ts b/packages/graphql/src/graphql/resolvers/SearchResolver.ts deleted file mode 100644 index 044c96b21..000000000 --- a/packages/graphql/src/graphql/resolvers/SearchResolver.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { Hash256 } from '~/application/vo'; -import DataCache from '~/infra/cache/DataCache'; -import BlockDAO from '~/infra/dao/BlockDAO'; -import ContractDAO from '~/infra/dao/ContractDAO'; -import PredicateDAO from '~/infra/dao/PredicateDAO'; -import TransactionDAO from '~/infra/dao/TransactionDAO'; - -type Params = { - search: { query: string }; -}; - -export class SearchResolver { - static create() { - const resolvers = new SearchResolver(); - return { - Query: { - search: resolvers.search, - }, - }; - } - - async search(_null: any, params: Params['search']) { - const cacheKey = `search:${params.query.toLowerCase()}`; - const cachedResult = DataCache.getInstance().get(cacheKey); - if (cachedResult !== undefined) { - return cachedResult; - } - - // Check if query is a block height (numeric, not starting with 0x) - if (!params.query.startsWith('0x') && !Number.isNaN(Number(params.query))) { - const blockDAO = new BlockDAO(); - const block = await blockDAO.getByHeight(Number(params.query)); - if (block) { - const result = { - block: block.toGQLNode(), - }; - DataCache.getInstance().save(cacheKey, 1 * 60 * 1000, result); - return result; - } - } - - let address: string; - try { - address = Hash256.create(params.query).value(); - } catch { - DataCache.getInstance().save(cacheKey, 1 * 60 * 1000, null); - return null; - } - - const blockDAO = new BlockDAO(); - const contractDAO = new ContractDAO(); - const transactionDAO = new TransactionDAO(); - const predicateDAO = new PredicateDAO(); - - const results = await Promise.allSettled([ - blockDAO.getByHash(address), - contractDAO.getByHash(address), - transactionDAO.getByHash(address), - predicateDAO.getByAddress(address), - transactionDAO.accountExists(address), - ]); - - const [ - blockResult, - contractResult, - transactionResult, - predicateResult, - accountExistsResult, - ] = results; - - // Priority order: Block > Contract > Transaction > Account (only if has transactions) > Predicate - - if (blockResult.status === 'fulfilled' && blockResult.value) { - const result = { - block: blockResult.value.toGQLNode(), - }; - DataCache.getInstance().save(cacheKey, 1 * 60 * 1000, result); - return result; - } - - if (contractResult.status === 'fulfilled' && contractResult.value) { - const result = { - contract: contractResult.value.toGQLNode(), - }; - DataCache.getInstance().save(cacheKey, 1 * 60 * 1000, result); - return result; - } - - if (transactionResult.status === 'fulfilled' && transactionResult.value) { - const result = { - transaction: transactionResult.value.toGQLNode(), - }; - DataCache.getInstance().save(cacheKey, 1 * 60 * 1000, result); - return result; - } - - // Only return account if it has transactions (validate it exists) - const accountExists = - accountExistsResult.status === 'fulfilled' && accountExistsResult.value; - if (accountExists) { - const result = { - account: { - address, - }, - }; - DataCache.getInstance().save(cacheKey, 1 * 60 * 1000, result); - return result; - } - - // Only return predicate if it has bytecode (validate it exists) - if ( - predicateResult.status === 'fulfilled' && - predicateResult.value && - predicateResult.value.bytecode !== '0x' - ) { - const result = { - predicate: predicateResult.value.toGQLNode(), - }; - DataCache.getInstance().save(cacheKey, 1 * 60 * 1000, result); - return result; - } - - DataCache.getInstance().save(cacheKey, 1 * 60 * 1000, null); - return null; - } -} diff --git a/packages/graphql/src/graphql/resolvers/StakingResolver.ts b/packages/graphql/src/graphql/resolvers/StakingResolver.ts deleted file mode 100644 index c9275d0ac..000000000 --- a/packages/graphql/src/graphql/resolvers/StakingResolver.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { logger } from '~/core/Logger'; -import StakingDAO from '~/infra/dao/StakingDAO'; -import PaginatedParams from '~/infra/paginator/PaginatedParams'; -import type { - GQLQueryStakingEventArgs, - GQLQueryStakingEventsArgs, - GQLStakingEventResponse, - GQLStakingEventsResult, -} from '../generated/sdk-provider'; - -export class StakingResolver { - static create() { - const resolvers = new StakingResolver(); - return { - Query: { - stakingEvents: resolvers.stakingEvents, - stakingEvent: resolvers.stakingEvent, - }, - }; - } - - async stakingEvents( - _: GQLStakingEventsResult, - params: GQLQueryStakingEventsArgs, - ) { - logger.debug('GraphQL', 'StakingResolver.stakingEvents'); - const paginatedParams = new PaginatedParams(params); - const stakingDAO = new StakingDAO(); - const output = await stakingDAO.getEvents(params.address, paginatedParams); - for (const element of output.nodes) { - element.__typename = `${element.type}Response`; - } - return output; - } - - async stakingEvent( - _: GQLStakingEventsResult, - params: GQLQueryStakingEventArgs, - ) { - logger.debug('GraphQL', 'StakingResolver.stakingEvent'); - const eventId = params.eventId; - const stakingDAO = new StakingDAO(); - const output = await stakingDAO.getEvent(eventId); - return { - __typename: - `${output.type}Response` as GQLStakingEventResponse['__typename'], - ...output, - }; - } -} diff --git a/packages/graphql/src/graphql/resolvers/TransactionResolver.ts b/packages/graphql/src/graphql/resolvers/TransactionResolver.ts deleted file mode 100644 index dee9b17ce..000000000 --- a/packages/graphql/src/graphql/resolvers/TransactionResolver.ts +++ /dev/null @@ -1,165 +0,0 @@ -import GetTransaction from '~/application/uc/GetTransaction'; -import { logger } from '~/core/Logger'; -import type { - GQLQueryTransactionArgs, - GQLQueryTransactionsArgs, - GQLQueryTransactionsByBlockIdArgs, - GQLQueryTransactionsByOwnerArgs, - GQLTransaction, -} from '~/graphql/generated/sdk-provider'; -import DataCache from '~/infra/cache/DataCache'; -import TransactionDAO from '~/infra/dao/TransactionDAO'; -import { convertToUsd } from '~/infra/dao/utils'; -import AssetGateway from '~/infra/gateway/AssetGateway'; -import PaginatedParams from '~/infra/paginator/PaginatedParams'; -import type { GraphQLContext } from '../GraphQLContext'; - -type Source = GQLTransaction; -type Params = { - transaction: GQLQueryTransactionArgs; - transactions: GQLQueryTransactionsArgs; - transactionByOwner: GQLQueryTransactionsByOwnerArgs; - transactionByBlockId: GQLQueryTransactionsByBlockIdArgs; -}; - -export class TransactionResolver { - static create() { - const resolvers = new TransactionResolver(); - return { - Query: { - transaction: resolvers.transaction, - transactions: resolvers.transactions, - transactionsByOwner: resolvers.transactionsByOwner, - transactionsByBlockId: resolvers.transactionsByBlockId, - }, - }; - } - - async transaction( - _: Source, - params: Params['transaction'], - { chain }: GraphQLContext, - ) { - logger.debug('GraphQL', 'TransactionResolver.transaction'); - const baseAssetId = chain?.data.consensusParameters.baseAssetId; - const chainId = chain ? Number.parseInt(chain.chainId) : undefined; - const getTransaction = new GetTransaction(); - const transaction = await getTransaction.execute( - params.id, - chainId, - baseAssetId, - ); - if (transaction && baseAssetId != null) { - const assetGateway = new AssetGateway(); - const baseAsset = await assetGateway.getAsset(baseAssetId, chainId); - - transaction.mintAmountUsd = baseAsset?.rate - ? convertToUsd( - transaction?.mintAmount, - baseAsset.decimals, - baseAsset.rate, - ).formatted - : ''; - } - return transaction; - } - - async transactions( - _: Source, - params: Params['transactions'], - { chain }: GraphQLContext, - ) { - logger.debug('GraphQL', 'TransactionResolver.transactions'); - const transactionDAO = new TransactionDAO(); - const paginatedParams = new PaginatedParams(params); - const baseAssetId = chain?.data.consensusParameters.baseAssetId || ''; - const chainId = chain ? Number.parseInt(chain.chainId) : undefined; - const assetGateway = new AssetGateway(); - const baseAsset = await assetGateway.getAsset(baseAssetId, chainId); - const transactions = - await transactionDAO.getPaginatedTransactions(paginatedParams); - for (const transaction of transactions.nodes) { - if (transaction.gasCosts?.fee) { - transaction.gasCosts.feeInUsd = baseAsset?.rate - ? convertToUsd( - transaction.gasCosts.fee || '', - baseAsset.decimals, - baseAsset.rate, - ).formatted - : null; - } - } - return transactions; - } - - async transactionsByOwner( - _: Source, - params: Params['transactionByOwner'] & { ownerType?: string }, - { chain }: GraphQLContext, - ) { - logger.debug('GraphQL', 'TransactionResolver.transactionsByOwner'); - const paginatedParams = new PaginatedParams(params); - const ownerType = params.ownerType; - const cacheKey = `txByOwner:${params.owner}:${paginatedParams.cursor || 'init'}:${paginatedParams.direction}:${paginatedParams.last}:${ownerType || 'all'}`; - - const cached = DataCache.getInstance().get(cacheKey); - if (cached) { - return cached; - } - - const transactionDAO = new TransactionDAO(); - const baseAssetId = chain?.data.consensusParameters.baseAssetId || ''; - const chainId = chain ? Number.parseInt(chain.chainId) : undefined; - const assetGateway = new AssetGateway(); - const baseAsset = await assetGateway.getAsset(baseAssetId, chainId); - const transactions = await transactionDAO.getPaginatedTransactionsByOwner( - params.owner, - paginatedParams, - ownerType, - ); - for (const transaction of transactions.nodes) { - if (transaction.gasCosts?.fee) { - transaction.gasCosts.feeInUsd = baseAsset?.rate - ? convertToUsd( - transaction.gasCosts.fee || '', - baseAsset.decimals, - baseAsset.rate, - ).formatted - : null; - } - } - - DataCache.getInstance().save(cacheKey, 30000, transactions); - return transactions; - } - - async transactionsByBlockId( - _: Source, - params: Params['transactionByBlockId'], - { chain }: GraphQLContext, - ) { - logger.debug('GraphQL', 'TransactionResolver.transactionsByBlockId'); - const transactionDAO = new TransactionDAO(); - const paginatedParams = new PaginatedParams(params); - const baseAssetId = chain?.data.consensusParameters.baseAssetId || ''; - const chainId = chain ? Number.parseInt(chain.chainId) : undefined; - const assetGateway = new AssetGateway(); - const baseAsset = await assetGateway.getAsset(baseAssetId, chainId); - const transactions = await transactionDAO.getPaginatedTransactionsByBlockId( - params.blockId, - paginatedParams, - ); - for (const transaction of transactions.nodes) { - if (transaction.gasCosts?.fee) { - transaction.gasCosts.feeInUsd = baseAsset?.rate - ? convertToUsd( - transaction.gasCosts.fee || '', - baseAsset.decimals, - baseAsset.rate, - ).formatted - : null; - } - } - return transactions; - } -} diff --git a/packages/graphql/src/graphql/resolvers/index.ts b/packages/graphql/src/graphql/resolvers/index.ts deleted file mode 100644 index d9e01aa72..000000000 --- a/packages/graphql/src/graphql/resolvers/index.ts +++ /dev/null @@ -1,58 +0,0 @@ -import GraphQLAuth from '~/infra/auth/GraphQLAuth'; -import { APYResolver } from './APYResolver'; -import { AssetResolver } from './AssetResolver'; -import { BalanceResolver } from './BalanceResolver'; -import { BlockResolver } from './BlockResolver'; -import { BridgeResolver } from './BridgeResolver'; -import { ChainResolver } from './ChainResolver'; -import { ContractResolver } from './ContractResolver'; -import { NodeResolver } from './NodeResolver'; -import { PoliciesResolver } from './PoliciesResolver'; -import { PredicateResolver } from './PredicateResolver'; -import { PublicResolver } from './PublicResolver'; -import { SearchResolver } from './SearchResolver'; -import { StakingResolver } from './StakingResolver'; -import { TransactionResolver } from './TransactionResolver'; - -export const blockResolver = BlockResolver.create(); -const balanceResolver = BalanceResolver.create(); -const chainResolver = ChainResolver.create(); -const contractResolver = ContractResolver.create(); -const nodeResolver = NodeResolver.create(); -const policiesResolver = PoliciesResolver.create(); -const predicateResolver = PredicateResolver.create(); -const searchResolver = SearchResolver.create(); -const transactionResolver = TransactionResolver.create(); -const assetResolver = AssetResolver.create(); -const stakingResolver = StakingResolver.create(); -const bridgeResolver = BridgeResolver.create(); - -// Public Resolvers -const apyResolver = APYResolver.create(); -const publicResolver = PublicResolver.create(); - -export const resolvers = { - Query: { - ...GraphQLAuth.apply({ - ...balanceResolver.Query, - ...blockResolver.Query, - ...chainResolver.Query, - ...contractResolver.Query, - ...nodeResolver.Query, - ...predicateResolver.Query, - ...searchResolver.Query, - ...transactionResolver.Query, - ...assetResolver.Query, - ...stakingResolver.Query, - ...bridgeResolver.Query, - }), - ...apyResolver.Query, - ...publicResolver.Query, - }, - Balance: balanceResolver.Balance, - Transaction: { - ...transactionResolver.Transaction, - ...policiesResolver.Transaction, - }, - Policies: policiesResolver.Policies, -}; diff --git a/packages/graphql/src/index-nft-collections.ts b/packages/graphql/src/index-nft-collections.ts deleted file mode 100644 index ebd9b546d..000000000 --- a/packages/graphql/src/index-nft-collections.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { DatabaseConnection } from './infra/database/DatabaseConnection'; - -const connection = DatabaseConnection.getInstance(); - -export async function indexNftCollections(contractId: string) { - const [collection] = await connection.query( - 'select * from indexer.collections where contract_id = $1', - [contractId], - ); - if (!collection) return; - console.log(collection); - const assets = await connection.query( - `select * from indexer.assets_contracts where contract_id = $1 and metadata->>'name' is null`, - [collection.contract_id], - ); - console.log(assets.length); - for (const asset of assets) { - console.log(asset.asset_id); - try { - if (asset.metadata) { - const url = collection.url.replace('{subId}', Number(asset.sub_id)); - console.log(url); - const response = await fetch(url); - const resolvedMetadata = await response.json(); - const metadata = Object.assign(asset.metadata, resolvedMetadata); - await connection.query( - 'update indexer.assets_contracts set metadata = $1 where asset_id = $2', - [metadata, asset.asset_id], - ); - } - } catch (e: any) { - console.log(e); - } - } -} - -(async () => { - const collections = [ - '0x202b55f66b8bafaf3b4fdf0653f1a4320607781dbd368bb576bc09250dd7dbbe', - '0x59b10bd361740618f12bba00f1083ef304a294b37ed7a8756c1b9cfc9b491b16', - '0x5d0188a9f77c4e5e48c459b5d02ccedac1a26d45b9f9c9e886f8563395bad32d', - '0xc5c219d360dcddbdaad2e0a33afc3550794ed4dfc484efb13562023189a08851', - '0xf0b6e2320caccb9071e45b1150b4da6f5edf74e7375ac6c87084822a87832de2', - ]; - for (const collection of collections) { - await indexNftCollections(collection); - } -})(); diff --git a/packages/graphql/src/index-total-supply.ts b/packages/graphql/src/index-total-supply.ts deleted file mode 100644 index ac0c6b442..000000000 --- a/packages/graphql/src/index-total-supply.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Contract, Provider } from 'fuels'; -import { bn } from 'fuels'; -import { abi } from '~/infra/abi/SRC7Abi'; -import { env } from './config'; -import { DatabaseConnection } from './infra/database/DatabaseConnection'; - -const connection = DatabaseConnection.getInstance(); - -export async function indexTotalSupply() { - const providerUrl = env.get('FUEL_PROVIDER'); - if (!providerUrl) { - throw new Error('FUEL_PROVIDER is not set'); - } - const provider = new Provider(providerUrl); - const assets = await connection.query( - 'select asset_id, contract_id from indexer.assets_contracts where total_supply is null', - [], - ); - console.log(assets.length); - let index = 0; - for (const asset of assets) { - try { - console.log(index++, assets.length, asset.asset_id); - const contract = new Contract(asset.contract_id, abi, provider); - const outputTotalSupply = await contract.functions - .total_supply({ bits: asset.asset_id }) - .dryRun(); - const totalSupply = bn(outputTotalSupply.value).toString() as any; - await connection.query( - 'update indexer.assets_contracts set total_supply = $1 where asset_id = $2', - [totalSupply, asset.asset_id], - ); - } catch (e: any) { - console.log(e); - } - } -} - -(async () => { - await indexTotalSupply(); -})(); diff --git a/packages/graphql/src/infra/abi/BridgeAbi.ts b/packages/graphql/src/infra/abi/BridgeAbi.ts deleted file mode 100644 index b8148031d..000000000 --- a/packages/graphql/src/infra/abi/BridgeAbi.ts +++ /dev/null @@ -1,825 +0,0 @@ -export const bridgeAbi = { - programType: 'contract', - specVersion: '1', - encodingVersion: '1', - concreteTypes: [ - { - type: '()', - concreteTypeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - type: 'b256', - concreteTypeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - type: 'enum errors::BridgeFungibleTokenError', - concreteTypeId: - '0b110bf0bfe47de46ec4252cf33a4c4225e4f8185d7382091b5a7cae96b05136', - metadataTypeId: 0, - }, - { - type: 'enum standards::src7::Metadata', - concreteTypeId: - 'f44b531974c6c04e17e66ab54e9868d230b9a24b3710b184399c363f0190180d', - metadataTypeId: 1, - }, - { - type: 'enum std::option::Option', - concreteTypeId: - 'fe93748eeb5d91a422fcea06e1b374216ad4ac0b2db01be0a6316af7f90dfa4f', - metadataTypeId: 3, - typeArguments: [ - 'f44b531974c6c04e17e66ab54e9868d230b9a24b3710b184399c363f0190180d', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - '7c06d929390a9aeeb8ffccf8173ac0d101a9976d99dda01cce74541a81e75ac0', - metadataTypeId: 3, - typeArguments: [ - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - 'd852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d', - metadataTypeId: 3, - typeArguments: [ - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - '2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1', - metadataTypeId: 3, - typeArguments: [ - 'c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b', - ], - }, - { - type: 'enum sway_libs::reentrancy::errors::ReentrancyError', - concreteTypeId: - '4d216c57b3357523323f59401c7355785b41bdf832f6e1106272186b94797038', - metadataTypeId: 4, - }, - { - type: 'struct events::ClaimRefundEvent', - concreteTypeId: - '43a196568054cc5857b7b8949732aea78a79c356fbbf23605d9057655fbaabc8', - metadataTypeId: 7, - }, - { - type: 'struct events::DepositEvent', - concreteTypeId: - 'aeb9b947da259c606e2c25be1150e2150f609fe5f2ec593c9a7ebb771e4e7065', - metadataTypeId: 8, - }, - { - type: 'struct events::RefundRegisteredEvent', - concreteTypeId: - '53314ca6f7d49036353511ef4d38a91d77a13dceeb09509b89c707fcbb3b4a71', - metadataTypeId: 9, - }, - { - type: 'struct events::WithdrawalEvent', - concreteTypeId: - '4b2a1039798597241d783edcc2292afb341e5f5beb9858521a9740426db8138a', - metadataTypeId: 10, - }, - { - type: 'struct standards::src20::SetDecimalsEvent', - concreteTypeId: - 'fbe071a6e7ca2b2b5e503e82638f9f11c861a6fb452b65473eca8260db87392d', - metadataTypeId: 11, - }, - { - type: 'struct standards::src20::SetNameEvent', - concreteTypeId: - '6ce295b0fb4c1c15e8ed1cfa4babda47d8a04940a5266a3229e12243a2e37c2c', - metadataTypeId: 12, - }, - { - type: 'struct standards::src20::SetSymbolEvent', - concreteTypeId: - 'a8a4b78066c51a50da6349bd395fe1c67e774d75c1db2c5c22288a432d7a363d', - metadataTypeId: 13, - }, - { - type: 'struct standards::src20::TotalSupplyEvent', - concreteTypeId: - 'f255d5cc2114d1b6bc34bef4c28d4b60caccffd9a672ed16b79ea217e1c4a8a3', - metadataTypeId: 14, - }, - { - type: 'struct standards::src7::SetMetadataEvent', - concreteTypeId: - 'f1b1cc90b68559aa4bb5cc58201ebb5c5402ed3aa28927140761e8ff7dcd3ab8', - metadataTypeId: 15, - }, - { - type: 'struct std::asset_id::AssetId', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - metadataTypeId: 17, - }, - { - type: 'struct std::string::String', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - metadataTypeId: 21, - }, - { - type: 'u64', - concreteTypeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - type: 'u8', - concreteTypeId: - 'c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b', - }, - ], - metadataTypes: [ - { - type: 'enum errors::BridgeFungibleTokenError', - metadataTypeId: 0, - components: [ - { - name: 'UnauthorizedSender', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'NoCoinsSent', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'NoRefundAvailable', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'AssetNotFound', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'WithdrawalToZeroAddress', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum standards::src7::Metadata', - metadataTypeId: 1, - components: [ - { - name: 'B256', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - name: 'Bytes', - typeId: 18, - }, - { - name: 'Int', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - name: 'String', - typeId: 21, - }, - ], - }, - { - type: 'enum std::identity::Identity', - metadataTypeId: 2, - components: [ - { - name: 'Address', - typeId: 16, - }, - { - name: 'ContractId', - typeId: 20, - }, - ], - }, - { - type: 'enum std::option::Option', - metadataTypeId: 3, - components: [ - { - name: 'None', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'Some', - typeId: 5, - }, - ], - typeParameters: [5], - }, - { - type: 'enum sway_libs::reentrancy::errors::ReentrancyError', - metadataTypeId: 4, - components: [ - { - name: 'NonReentrant', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'generic T', - metadataTypeId: 5, - }, - { - type: 'raw untyped ptr', - metadataTypeId: 6, - }, - { - type: 'struct events::ClaimRefundEvent', - metadataTypeId: 7, - components: [ - { - name: 'amount', - typeId: 22, - }, - { - name: 'from', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - name: 'token_address', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - name: 'token_id', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - }, - { - type: 'struct events::DepositEvent', - metadataTypeId: 8, - components: [ - { - name: 'amount', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - name: 'from', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - name: 'to', - typeId: 2, - }, - ], - }, - { - type: 'struct events::RefundRegisteredEvent', - metadataTypeId: 9, - components: [ - { - name: 'amount', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - name: 'token_address', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - name: 'token_id', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - name: 'from', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - }, - { - type: 'struct events::WithdrawalEvent', - metadataTypeId: 10, - components: [ - { - name: 'amount', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - name: 'from', - typeId: 2, - }, - { - name: 'to', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - }, - { - type: 'struct standards::src20::SetDecimalsEvent', - metadataTypeId: 11, - components: [ - { - name: 'asset', - typeId: 17, - }, - { - name: 'decimals', - typeId: - 'c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b', - }, - { - name: 'sender', - typeId: 2, - }, - ], - }, - { - type: 'struct standards::src20::SetNameEvent', - metadataTypeId: 12, - components: [ - { - name: 'asset', - typeId: 17, - }, - { - name: 'name', - typeId: 3, - typeArguments: [ - { - name: '', - typeId: 21, - }, - ], - }, - { - name: 'sender', - typeId: 2, - }, - ], - }, - { - type: 'struct standards::src20::SetSymbolEvent', - metadataTypeId: 13, - components: [ - { - name: 'asset', - typeId: 17, - }, - { - name: 'symbol', - typeId: 3, - typeArguments: [ - { - name: '', - typeId: 21, - }, - ], - }, - { - name: 'sender', - typeId: 2, - }, - ], - }, - { - type: 'struct standards::src20::TotalSupplyEvent', - metadataTypeId: 14, - components: [ - { - name: 'asset', - typeId: 17, - }, - { - name: 'supply', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - name: 'sender', - typeId: 2, - }, - ], - }, - { - type: 'struct standards::src7::SetMetadataEvent', - metadataTypeId: 15, - components: [ - { - name: 'asset', - typeId: 17, - }, - { - name: 'metadata', - typeId: 3, - typeArguments: [ - { - name: '', - typeId: 1, - }, - ], - }, - { - name: 'key', - typeId: 21, - }, - { - name: 'sender', - typeId: 2, - }, - ], - }, - { - type: 'struct std::address::Address', - metadataTypeId: 16, - components: [ - { - name: 'bits', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - }, - { - type: 'struct std::asset_id::AssetId', - metadataTypeId: 17, - components: [ - { - name: 'bits', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - }, - { - type: 'struct std::bytes::Bytes', - metadataTypeId: 18, - components: [ - { - name: 'buf', - typeId: 19, - }, - { - name: 'len', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - }, - { - type: 'struct std::bytes::RawBytes', - metadataTypeId: 19, - components: [ - { - name: 'ptr', - typeId: 6, - }, - { - name: 'cap', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - }, - { - type: 'struct std::contract_id::ContractId', - metadataTypeId: 20, - components: [ - { - name: 'bits', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - }, - { - type: 'struct std::string::String', - metadataTypeId: 21, - components: [ - { - name: 'bytes', - typeId: 18, - }, - ], - }, - { - type: 'u256', - metadataTypeId: 22, - }, - ], - functions: [ - { - inputs: [ - { - name: 'msg_idx', - concreteTypeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - name: 'process_message', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'payable', - arguments: [], - }, - { - name: 'storage', - arguments: ['read', 'write'], - }, - ], - }, - { - inputs: [ - { - name: 'asset_id', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'asset_to_l1_address', - output: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - attributes: [ - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset_id', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'asset_to_sub_id', - output: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - attributes: [ - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [], - name: 'bridged_token_gateway', - output: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - attributes: null, - }, - { - inputs: [ - { - name: 'from', - concreteTypeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - name: 'token_address', - concreteTypeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - name: 'token_id', - concreteTypeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - name: 'claim_refund', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'storage', - arguments: ['read', 'write'], - }, - ], - }, - { - inputs: [ - { - name: 'to', - concreteTypeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - name: 'withdraw', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'payable', - arguments: [], - }, - { - name: 'storage', - arguments: ['read', 'write'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'decimals', - output: - '2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1', - attributes: [ - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'name', - output: - '7c06d929390a9aeeb8ffccf8173ac0d101a9976d99dda01cce74541a81e75ac0', - attributes: [ - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'symbol', - output: - '7c06d929390a9aeeb8ffccf8173ac0d101a9976d99dda01cce74541a81e75ac0', - attributes: [ - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [], - name: 'total_assets', - output: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - attributes: [ - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'total_supply', - output: - 'd852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d', - attributes: [ - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: 'key', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - }, - ], - name: 'metadata', - output: - 'fe93748eeb5d91a422fcea06e1b374216ad4ac0b2db01be0a6316af7f90dfa4f', - attributes: [ - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - ], - loggedTypes: [ - { - logId: '5557842539076482339', - concreteTypeId: - '4d216c57b3357523323f59401c7355785b41bdf832f6e1106272186b94797038', - }, - { - logId: '797431737660767716', - concreteTypeId: - '0b110bf0bfe47de46ec4252cf33a4c4225e4f8185d7382091b5a7cae96b05136', - }, - { - logId: '5994656859013025846', - concreteTypeId: - '53314ca6f7d49036353511ef4d38a91d77a13dceeb09509b89c707fcbb3b4a71', - }, - { - logId: '17415926155927968170', - concreteTypeId: - 'f1b1cc90b68559aa4bb5cc58201ebb5c5402ed3aa28927140761e8ff7dcd3ab8', - }, - { - logId: '18149631459970394923', - concreteTypeId: - 'fbe071a6e7ca2b2b5e503e82638f9f11c861a6fb452b65473eca8260db87392d', - }, - { - logId: '17462098202904023478', - concreteTypeId: - 'f255d5cc2114d1b6bc34bef4c28d4b60caccffd9a672ed16b79ea217e1c4a8a3', - }, - { - logId: '12590297951544646752', - concreteTypeId: - 'aeb9b947da259c606e2c25be1150e2150f609fe5f2ec593c9a7ebb771e4e7065', - }, - { - logId: '7845998088195677205', - concreteTypeId: - '6ce295b0fb4c1c15e8ed1cfa4babda47d8a04940a5266a3229e12243a2e37c2c', - }, - { - logId: '12152039456660331088', - concreteTypeId: - 'a8a4b78066c51a50da6349bd395fe1c67e774d75c1db2c5c22288a432d7a363d', - }, - { - logId: '4873341570055982168', - concreteTypeId: - '43a196568054cc5857b7b8949732aea78a79c356fbbf23605d9057655fbaabc8', - }, - { - logId: '5416159340904421156', - concreteTypeId: - '4b2a1039798597241d783edcc2292afb341e5f5beb9858521a9740426db8138a', - }, - ], - messagesTypes: [], - configurables: [ - { - name: 'BRIDGED_TOKEN_GATEWAY', - concreteTypeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - offset: 57016, - }, - ], -}; diff --git a/packages/graphql/src/infra/abi/SRC7Abi.ts b/packages/graphql/src/infra/abi/SRC7Abi.ts deleted file mode 100644 index 955b05b0e..000000000 --- a/packages/graphql/src/infra/abi/SRC7Abi.ts +++ /dev/null @@ -1,2833 +0,0 @@ -export const abi = { - programType: 'contract', - specVersion: '1', - encodingVersion: '1', - concreteTypes: [ - { - type: '()', - concreteTypeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - type: 'b256', - concreteTypeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - type: 'bool', - concreteTypeId: - 'b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903', - }, - { - type: 'enum errors::MintError', - concreteTypeId: - 'ee89c439b5472cab716006d7c677d16e15301e6c82cfce12cebfa57919f537de', - metadataTypeId: 0, - }, - { - type: 'enum errors::SetError', - concreteTypeId: - 'bf6597cf3d56a5e47a920520e275ccd481a27e7c988ea6af6f253170d5374c5a', - metadataTypeId: 1, - }, - { - type: 'enum standards::src5::AccessError', - concreteTypeId: - '3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d', - metadataTypeId: 2, - }, - { - type: 'enum standards::src5::State', - concreteTypeId: - '192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c', - metadataTypeId: 3, - }, - { - type: 'enum standards::src7::Metadata', - concreteTypeId: - 'f44b531974c6c04e17e66ab54e9868d230b9a24b3710b184399c363f0190180d', - metadataTypeId: 4, - }, - { - type: 'enum std::identity::Identity', - concreteTypeId: - 'ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335', - metadataTypeId: 5, - }, - { - type: 'enum std::option::Option', - concreteTypeId: - '0c2beb9013490c4f753f2757dfe2d8340b22ce3827d596d81d249b7038033cb6', - metadataTypeId: 6, - typeArguments: [ - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - 'fe93748eeb5d91a422fcea06e1b374216ad4ac0b2db01be0a6316af7f90dfa4f', - metadataTypeId: 6, - typeArguments: [ - 'f44b531974c6c04e17e66ab54e9868d230b9a24b3710b184399c363f0190180d', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - '7c06d929390a9aeeb8ffccf8173ac0d101a9976d99dda01cce74541a81e75ac0', - metadataTypeId: 6, - typeArguments: [ - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - 'd852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d', - metadataTypeId: 6, - typeArguments: [ - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - '2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1', - metadataTypeId: 6, - typeArguments: [ - 'c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b', - ], - }, - { - type: 'enum sway_libs::asset::errors::BurnError', - concreteTypeId: - '3acdc2adac8e0589c5864525e0edc9dc61a9571a4d09c3c57b58ea76d33f4b46', - metadataTypeId: 7, - }, - { - type: 'enum sway_libs::asset::errors::MintError', - concreteTypeId: - 'dff9dfec998a49b40f1c4b09567400f0e712aaf939c08f7d07bc5c63116e1084', - metadataTypeId: 8, - }, - { - type: 'enum sway_libs::asset::errors::SetMetadataError', - concreteTypeId: - 'c6c09c148c1a1341c7ab81697b3545cc695fa67668a169cddc59790a9a0b6b44', - metadataTypeId: 9, - }, - { - type: 'enum sway_libs::ownership::errors::InitializationError', - concreteTypeId: - '1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893', - metadataTypeId: 10, - }, - { - type: 'enum sway_libs::pausable::errors::PauseError', - concreteTypeId: - '8b3afcadf894415a10b09fc3717487e33802c8ffbb030edafe84ca4a71b280bc', - metadataTypeId: 11, - }, - { - type: 'struct standards::src20::SetNameEvent', - concreteTypeId: - '6ce295b0fb4c1c15e8ed1cfa4babda47d8a04940a5266a3229e12243a2e37c2c', - metadataTypeId: 14, - }, - { - type: 'struct standards::src20::SetSymbolEvent', - concreteTypeId: - 'a8a4b78066c51a50da6349bd395fe1c67e774d75c1db2c5c22288a432d7a363d', - metadataTypeId: 15, - }, - { - type: 'struct standards::src20::TotalSupplyEvent', - concreteTypeId: - 'f255d5cc2114d1b6bc34bef4c28d4b60caccffd9a672ed16b79ea217e1c4a8a3', - metadataTypeId: 16, - }, - { - type: 'struct standards::src7::SetMetadataEvent', - concreteTypeId: - 'f1b1cc90b68559aa4bb5cc58201ebb5c5402ed3aa28927140761e8ff7dcd3ab8', - metadataTypeId: 17, - }, - { - type: 'struct std::asset_id::AssetId', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - metadataTypeId: 19, - }, - { - type: 'struct std::string::String', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - metadataTypeId: 23, - }, - { - type: 'struct sway_libs::ownership::events::OwnershipSet', - concreteTypeId: - 'e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5', - metadataTypeId: 24, - }, - { - type: 'u64', - concreteTypeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - type: 'u8', - concreteTypeId: - 'c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b', - }, - ], - metadataTypes: [ - { - type: 'enum errors::MintError', - metadataTypeId: 0, - components: [ - { - name: 'CannotMintMoreThanOneNFTWithSubId', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'MaxNFTsMinted', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'NFTAlreadyMinted', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'SubIdCannotBeNone', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum errors::SetError', - metadataTypeId: 1, - components: [ - { - name: 'ValueAlreadySet', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum standards::src5::AccessError', - metadataTypeId: 2, - components: [ - { - name: 'NotOwner', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum standards::src5::State', - metadataTypeId: 3, - components: [ - { - name: 'Uninitialized', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'Initialized', - typeId: 5, - }, - { - name: 'Revoked', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum standards::src7::Metadata', - metadataTypeId: 4, - components: [ - { - name: 'B256', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - name: 'Bytes', - typeId: 20, - }, - { - name: 'Int', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - name: 'String', - typeId: 23, - }, - ], - }, - { - type: 'enum std::identity::Identity', - metadataTypeId: 5, - components: [ - { - name: 'Address', - typeId: 18, - }, - { - name: 'ContractId', - typeId: 22, - }, - ], - }, - { - type: 'enum std::option::Option', - metadataTypeId: 6, - components: [ - { - name: 'None', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'Some', - typeId: 12, - }, - ], - typeParameters: [12], - }, - { - type: 'enum sway_libs::asset::errors::BurnError', - metadataTypeId: 7, - components: [ - { - name: 'NotEnoughCoins', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'ZeroAmount', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum sway_libs::asset::errors::MintError', - metadataTypeId: 8, - components: [ - { - name: 'ZeroAmount', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum sway_libs::asset::errors::SetMetadataError', - metadataTypeId: 9, - components: [ - { - name: 'EmptyString', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'EmptyBytes', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum sway_libs::ownership::errors::InitializationError', - metadataTypeId: 10, - components: [ - { - name: 'CannotReinitialized', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'enum sway_libs::pausable::errors::PauseError', - metadataTypeId: 11, - components: [ - { - name: 'Paused', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'NotPaused', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - ], - }, - { - type: 'generic T', - metadataTypeId: 12, - }, - { - type: 'raw untyped ptr', - metadataTypeId: 13, - }, - { - type: 'struct standards::src20::SetNameEvent', - metadataTypeId: 14, - components: [ - { - name: 'asset', - typeId: 19, - }, - { - name: 'name', - typeId: 6, - typeArguments: [ - { - name: '', - typeId: 23, - }, - ], - }, - { - name: 'sender', - typeId: 5, - }, - ], - }, - { - type: 'struct standards::src20::SetSymbolEvent', - metadataTypeId: 15, - components: [ - { - name: 'asset', - typeId: 19, - }, - { - name: 'symbol', - typeId: 6, - typeArguments: [ - { - name: '', - typeId: 23, - }, - ], - }, - { - name: 'sender', - typeId: 5, - }, - ], - }, - { - type: 'struct standards::src20::TotalSupplyEvent', - metadataTypeId: 16, - components: [ - { - name: 'asset', - typeId: 19, - }, - { - name: 'supply', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - name: 'sender', - typeId: 5, - }, - ], - }, - { - type: 'struct standards::src7::SetMetadataEvent', - metadataTypeId: 17, - components: [ - { - name: 'asset', - typeId: 19, - }, - { - name: 'metadata', - typeId: 6, - typeArguments: [ - { - name: '', - typeId: 4, - }, - ], - }, - { - name: 'key', - typeId: 23, - }, - { - name: 'sender', - typeId: 5, - }, - ], - }, - { - type: 'struct std::address::Address', - metadataTypeId: 18, - components: [ - { - name: 'bits', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - }, - { - type: 'struct std::asset_id::AssetId', - metadataTypeId: 19, - components: [ - { - name: 'bits', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - }, - { - type: 'struct std::bytes::Bytes', - metadataTypeId: 20, - components: [ - { - name: 'buf', - typeId: 21, - }, - { - name: 'len', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - }, - { - type: 'struct std::bytes::RawBytes', - metadataTypeId: 21, - components: [ - { - name: 'ptr', - typeId: 13, - }, - { - name: 'cap', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - }, - { - type: 'struct std::contract_id::ContractId', - metadataTypeId: 22, - components: [ - { - name: 'bits', - typeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - ], - }, - { - type: 'struct std::string::String', - metadataTypeId: 23, - components: [ - { - name: 'bytes', - typeId: 20, - }, - ], - }, - { - type: 'struct sway_libs::ownership::events::OwnershipSet', - metadataTypeId: 24, - components: [ - { - name: 'new_owner', - typeId: 5, - }, - ], - }, - ], - functions: [ - { - inputs: [ - { - name: '_asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'decimals', - output: - '2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1', - attributes: [ - { - name: 'doc-comment', - arguments: [' Returns the number of decimals the asset uses.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Additional Information'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' The standardized decimals for NFTs is 0u8.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to query the decimals.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * [Option] - The decimal precision used by `asset`.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId, asset: AssedId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [ - ' let decimals = contract_abi.decimals(asset).unwrap();', - ], - }, - { - name: 'doc-comment', - arguments: [' assert(decimals == 0u8);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'name', - output: - '7c06d929390a9aeeb8ffccf8173ac0d101a9976d99dda01cce74541a81e75ac0', - attributes: [ - { - name: 'doc-comment', - arguments: [' Returns the name of the asset, such as “Ether”.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to query the name.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * [Option] - The name of `asset`.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [' use std::string::String;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_ic: ContractId, asset: AssetId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let name = contract_abi.name(asset).unwrap();'], - }, - { - name: 'doc-comment', - arguments: [' assert(name.len() != 0);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'symbol', - output: - '7c06d929390a9aeeb8ffccf8173ac0d101a9976d99dda01cce74541a81e75ac0', - attributes: [ - { - name: 'doc-comment', - arguments: [' Returns the symbol of the asset, such as “ETH”.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to query the symbol.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * [Option] - The symbol of `asset`.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [' use std::string::String;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId, asset: AssetId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let symbol = contract_abi.symbol(asset).unwrap();'], - }, - { - name: 'doc-comment', - arguments: [' assert(symbol.len() != 0);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [], - name: 'total_assets', - output: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - attributes: [ - { - name: 'doc-comment', - arguments: [ - ' Returns the total number of individual NFTs for this contract.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * [u64] - The number of assets that this contract has minted.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let total_assets = contract_abi.total_assets();'], - }, - { - name: 'doc-comment', - arguments: [' assert(total_assets != 0);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'total_supply', - output: - 'd852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Returns the total supply of coins for an asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Additional Information'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' This must always be at most 1 for NFTs.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to query the total supply.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * [Option] - The total supply of coins for `asset`.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId, asset: AssetId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [ - ' let total_supply = contract_abi.total_supply(asset).unwrap();', - ], - }, - { - name: 'doc-comment', - arguments: [' assert(total_supply == 1);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'sub_id', - concreteTypeId: - '7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b', - }, - { - name: 'amount', - concreteTypeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - name: 'burn', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Burns assets sent with the given `sub_id`.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Additional Information'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' NOTE: The sha-256 hash of `(ContractId, SubId)` must match the `AssetId` where `ContractId` is the id of', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' the implementing contract and `SubId` is the given `sub_id` argument.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `sub_id`: [SubId] - The sub-identifier of the asset to burn.', - ], - }, - { - name: 'doc-comment', - arguments: [' * `amount`: [u64] - The quantity of coins to burn.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the contract is paused.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src3::SRC3;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId, asset_id: AssetId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SR3, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' contract_abi.burn {'], - }, - { - name: 'doc-comment', - arguments: [' gas: 10000,'], - }, - { - name: 'doc-comment', - arguments: [' coins: 1,'], - }, - { - name: 'doc-comment', - arguments: [' asset_id: AssetId,'], - }, - { - name: 'doc-comment', - arguments: [' } (ZERO_B256, 1);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'payable', - arguments: [], - }, - { - name: 'storage', - arguments: ['read', 'write'], - }, - ], - }, - { - inputs: [ - { - name: 'recipient', - concreteTypeId: - 'ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335', - }, - { - name: 'sub_id', - concreteTypeId: - '0c2beb9013490c4f753f2757dfe2d8340b22ce3827d596d81d249b7038033cb6', - }, - { - name: 'amount', - concreteTypeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - name: 'mint', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Mints new assets using the `sub_id` sub-identifier.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Additional Information'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' This conforms to the SRC-20 NFT portion of the standard for a maximum', - ], - }, - { - name: 'doc-comment', - arguments: [' mint amount of 1 coin per asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `recipient`: [Identity] - The user to which the newly minted assets are transferred to.', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' * `sub_id`: [SubId] - The sub-identifier of the newly minted asset.', - ], - }, - { - name: 'doc-comment', - arguments: [' * `amount`: [u64] - The quantity of coins to mint.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the contract is paused.'], - }, - { - name: 'doc-comment', - arguments: [' * When amount is greater than one.'], - }, - { - name: 'doc-comment', - arguments: [' * When the asset has already been minted.'], - }, - { - name: 'doc-comment', - arguments: [ - ' * When more than the MAX_SUPPLY NFTs have been minted.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `3`'], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `2`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src3::SRC3;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SR3, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [ - ' contract_abi.mint(Identity::ContractId(ContractId::this()), ZERO_B256, 1);', - ], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read', 'write'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: 'key', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - }, - ], - name: 'metadata', - output: - 'fe93748eeb5d91a422fcea06e1b374216ad4ac0b2db01be0a6316af7f90dfa4f', - attributes: [ - { - name: 'doc-comment', - arguments: [ - ' Returns metadata for the corresponding `asset` and `key`.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to query the metadata.', - ], - }, - { - name: 'doc-comment', - arguments: [' * `key`: [String] - The key to the specific metadata.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * [Option] - `Some` metadata that corresponds to the `key` or `None`.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src_7::{SRC7, Metadata};'], - }, - { - name: 'doc-comment', - arguments: [' use std::string::String;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId, asset: AssetId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SRC7, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let key = String::from_ascii_str("image");'], - }, - { - name: 'doc-comment', - arguments: [' let data = contract_abi.metadata(asset, key);'], - }, - { - name: 'doc-comment', - arguments: [' assert(data.is_some());'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [], - name: 'owner', - output: - '192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c', - attributes: [ - { - name: 'doc-comment', - arguments: [' Returns the owner.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Return Values'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * [State] - Represents the state of ownership for this contract.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use standards::src5::SRC5;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [' let ownership_abi = abi(contract_id, SRC_5);'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' match ownership_abi.owner() {'], - }, - { - name: 'doc-comment', - arguments: [ - ' State::Uninitalized => log("The ownership is uninitalized"),', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' State::Initialized(owner) => log("The ownership is initalized"),', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' State::Revoked => log("The ownership is revoked"),', - ], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: '_asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: '_decimals', - concreteTypeId: - 'c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b', - }, - ], - name: 'set_decimals', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' This function should never be called.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Additional Information'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' NFT decimals are always `0u8` and thus must not be set.', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' This function is an artifact of the SetAssetAttributes ABI definition,', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' but does not have a use in this contract as the decimal value is hardcoded.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the function is called.'], - }, - { - name: 'storage', - arguments: ['write'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: 'name', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - }, - ], - name: 'set_name', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Sets the name of an asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to set the name.', - ], - }, - { - name: 'doc-comment', - arguments: [' * `name`: [String] - The name of the asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the caller is not the owner of the contract.'], - }, - { - name: 'doc-comment', - arguments: [' * When the name has already been set for an asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `2`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use asset::SetAssetAttributes;'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [' use std::string::String;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(asset: AssetId, contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [ - ' let set_abi = abi(SetAssetAttributes, contract_id);', - ], - }, - { - name: 'doc-comment', - arguments: [' let src_20_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let name = String::from_ascii_str("Ether");'], - }, - { - name: 'doc-comment', - arguments: [' set_abi.set_name(asset, name);'], - }, - { - name: 'doc-comment', - arguments: [' assert(src_20_abi.name(asset) == name);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['write'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: 'symbol', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - }, - ], - name: 'set_symbol', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Sets the symbol of an asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to set the symbol.', - ], - }, - { - name: 'doc-comment', - arguments: [' * `symbol`: [String] - The symbol of the asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the caller is not the owner of the contract.'], - }, - { - name: 'doc-comment', - arguments: [' * When the symbol has already been set for an asset.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `2`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use asset::SetAssetAttributes;'], - }, - { - name: 'doc-comment', - arguments: [' use src20::SRC20;'], - }, - { - name: 'doc-comment', - arguments: [' use std::string::String;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(asset: AssetId, contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [ - ' let set_abi = abi(SetAssetAttributes, contract_id);', - ], - }, - { - name: 'doc-comment', - arguments: [' let src_20_abi = abi(SRC20, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let symbol = String::from_ascii_str("ETH");'], - }, - { - name: 'doc-comment', - arguments: [' set_abi.set_symbol(asset, symbol);'], - }, - { - name: 'doc-comment', - arguments: [' assert(src_20_abi.symbol(asset) == symbol);'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['write'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: 'key', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - }, - { - name: 'metadata', - concreteTypeId: - 'f44b531974c6c04e17e66ab54e9868d230b9a24b3710b184399c363f0190180d', - }, - ], - name: 'set_metadata', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Stores metadata for a specific asset and key pair.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset for the metadata to be stored.', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' * `key`: [String] - The key for the metadata to be stored.', - ], - }, - { - name: 'doc-comment', - arguments: [' * `metadata`: [Metadata] - The metadata to be stored.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * When the metadata has already been set for an asset.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `2`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Example'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use asset::metdata::SetAssetMetadata;'], - }, - { - name: 'doc-comment', - arguments: [' use src_7::{SRC7, Metadata};'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' fn foo(asset: AssetId, key: String, contract_id: ContractId, metadata: Metadata) {', - ], - }, - { - name: 'doc-comment', - arguments: [' let set_abi = abi(SetAssetMetadata, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let src_7_abi = abi(SRC7, contract);'], - }, - { - name: 'doc-comment', - arguments: [ - ' set_abi.set_metadata(storage.metadata, asset, key, metadata);', - ], - }, - { - name: 'doc-comment', - arguments: [ - ' assert(src_7_abi.metadata(asset, key) == metadata);', - ], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read', 'write'], - }, - ], - }, - { - inputs: [], - name: 'is_paused', - output: - 'b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903', - attributes: [ - { - name: 'doc-comment', - arguments: [' Returns whether the contract is paused.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * [bool] - The pause state for the contract.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use sway_libs::pausable::Pausable;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [' let pausable_abi = abi(Pausable, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' assert(!pausable_abi.is_paused());'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [], - name: 'pause', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Pauses the contract.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the caller is not the contract owner.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use sway_libs::pausable::Pausable;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [' let pausable_abi = abi(Pausable, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' pausable_abi.pause();'], - }, - { - name: 'doc-comment', - arguments: [' assert(pausable_abi.is_paused());'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['write'], - }, - ], - }, - { - inputs: [], - name: 'unpause', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Unpauses the contract.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When the caller is not the contract owner.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Accesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Writes: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use sway_libs::pausable::Pausable;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId) {'], - }, - { - name: 'doc-comment', - arguments: [' let pausable_abi = abi(Pausable, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' pausable_abi.unpause();'], - }, - { - name: 'doc-comment', - arguments: [' assert(!pausable_abi.is_paused());'], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['write'], - }, - ], - }, - { - inputs: [ - { - name: 'owner', - concreteTypeId: - 'ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335', - }, - ], - name: 'constructor', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'doc-comment', - arguments: [' Sets the defaults for the contract.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `owner`: [Identity] - The `Identity` that will be the first owner.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Reverts'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * When ownership has been set before.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Number of Storage Acesses'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' * Reads: `1`'], - }, - { - name: 'doc-comment', - arguments: [' * Write: `1`'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use standards::src5::SRC5;'], - }, - { - name: 'doc-comment', - arguments: [' use nft::Constructor;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract: ContractId, owner: Identity) {'], - }, - { - name: 'doc-comment', - arguments: [' let src_5_abi = abi(SRC5, contract.bits());'], - }, - { - name: 'doc-comment', - arguments: [ - ' assert(src_5_abi.owner() == State::Uninitialized);', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' let constructor_abi = abi(Constructor, contract.bits());', - ], - }, - { - name: 'doc-comment', - arguments: [' constructor_abi.constructor(owner);'], - }, - { - name: 'doc-comment', - arguments: [ - ' assert(src_5_abi.owner() == State::Initialized(owner));', - ], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read', 'write'], - }, - ], - }, - ], - loggedTypes: [ - { - logId: '10032608944051208538', - concreteTypeId: - '8b3afcadf894415a10b09fc3717487e33802c8ffbb030edafe84ca4a71b280bc', - }, - { - logId: '4237256875605624201', - concreteTypeId: - '3acdc2adac8e0589c5864525e0edc9dc61a9571a4d09c3c57b58ea76d33f4b46', - }, - { - logId: '17462098202904023478', - concreteTypeId: - 'f255d5cc2114d1b6bc34bef4c28d4b60caccffd9a672ed16b79ea217e1c4a8a3', - }, - { - logId: '17188485204969729195', - concreteTypeId: - 'ee89c439b5472cab716006d7c677d16e15301e6c82cfce12cebfa57919f537de', - }, - { - logId: '16139176946940135860', - concreteTypeId: - 'dff9dfec998a49b40f1c4b09567400f0e712aaf939c08f7d07bc5c63116e1084', - }, - { - logId: '13791596350235125220', - concreteTypeId: - 'bf6597cf3d56a5e47a920520e275ccd481a27e7c988ea6af6f253170d5374c5a', - }, - { - logId: '14321618427101975361', - concreteTypeId: - 'c6c09c148c1a1341c7ab81697b3545cc695fa67668a169cddc59790a9a0b6b44', - }, - { - logId: '7845998088195677205', - concreteTypeId: - '6ce295b0fb4c1c15e8ed1cfa4babda47d8a04940a5266a3229e12243a2e37c2c', - }, - { - logId: '12152039456660331088', - concreteTypeId: - 'a8a4b78066c51a50da6349bd395fe1c67e774d75c1db2c5c22288a432d7a363d', - }, - { - logId: '17415926155927968170', - concreteTypeId: - 'f1b1cc90b68559aa4bb5cc58201ebb5c5402ed3aa28927140761e8ff7dcd3ab8', - }, - { - logId: '4571204900286667806', - concreteTypeId: - '3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d', - }, - { - logId: '2161305517876418151', - concreteTypeId: - '1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893', - }, - { - logId: '16280289466020123285', - concreteTypeId: - 'e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5', - }, - ], - messagesTypes: [], - configurables: [], -}; diff --git a/packages/graphql/src/infra/auth/GraphQLAuth.ts b/packages/graphql/src/infra/auth/GraphQLAuth.ts deleted file mode 100644 index 63c76c367..000000000 --- a/packages/graphql/src/infra/auth/GraphQLAuth.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { GraphQLError } from 'graphql'; -import type { GraphQLContext } from '~/graphql/GraphQLContext'; - -export default class GraphQLAuth { - static apply(resolvers: any) { - for (const resolver in resolvers) { - resolvers[resolver] = GraphQLAuth.auth(resolvers[resolver]); - } - return resolvers; - } - - static auth(fn: Function) { - return (_: any, params: any, context: GraphQLContext) => { - if (!context.isAuthenticated) { - throw new GraphQLError('Authorization header is required'); - } - return fn(_, params, context); - }; - } -} diff --git a/packages/graphql/src/infra/cache/AssetMetadata.ts b/packages/graphql/src/infra/cache/AssetMetadata.ts deleted file mode 100644 index 9ac97f11d..000000000 --- a/packages/graphql/src/infra/cache/AssetMetadata.ts +++ /dev/null @@ -1,797 +0,0 @@ -import { Contract, Provider } from 'fuels'; -import { env } from '~/config'; - -export default class AssetMetadata { - static instance: AssetMetadata; - private lastDate?: Date; - private provider?: Provider; - private values: Record = {}; - - private constructor() {} - - async getProvider() { - if (!this.provider) { - const providerUrl = env.get('FUEL_PROVIDER'); - if (!providerUrl) { - throw new Error('FUEL_PROVIDER is not set'); - } - this.provider = new Provider(providerUrl); - } - return this.provider; - } - - shouldFetch(asset_id: string) { - const now = new Date(); - return ( - !this.lastDate || - !this.values[asset_id] || - now.getTime() - this.lastDate.getTime() > 60000 - ); - } - - returnValue(asset_id: string, value: any) { - this.lastDate = new Date(); - this.values[asset_id] = value; - return value; - } - - static parseUrl(url: string): string { - // Check if the input is a valid CID - const isCID = - /^(Qm[1-9A-HJ-NP-Za-km-z]{44}|b[A-Za-z2-7]{58}|B[A-Z2-7]{58}|z[1-9A-HJ-NP-Za-km-z]{48}|F[0-9A-F]{50})$/.test( - url, - ); - - if (isCID) { - // If it's a CID, convert it to an IPFS gateway URL - return `https://ipfs.io/ipfs/${url}`; - } - if (url.startsWith('ipfs://')) { - // Convert IPFS URI to a gateway URL - const cid = url.slice(7); - return `https://ipfs.io/ipfs/${cid}`; - } - if (url.startsWith('ar://')) { - // Convert Arweave URI to a gateway URL - const id = url.slice(5); - return `https://arweave.net/${id}`; - } - if (url.startsWith('data:')) { - // Data URIs are returned as-is - return url; - } - if (!url.startsWith('http://') && !url.startsWith('https://')) { - // Assume HTTPS for URLs without a protocol - return `https://${url}`; - } - // Return other URLs as-is - return url; - } - - async fetch(contractId: string, asset_id: string) { - if (this.shouldFetch(asset_id)) { - try { - const provider = await this.getProvider(); - const contract = new Contract(contractId, ABI_SRC7, provider); - const { value } = await contract.functions - .metadata( - { - bits: asset_id, - }, - 'uri', - ) - .get(); - if (!value?.String) return null; - const uri = AssetMetadata.parseUrl(value.String); - return this.returnValue(asset_id, uri); - } catch { - return null; - } - } - return this.values[asset_id]; - } - - static getInstance() { - if (!AssetMetadata.instance) { - AssetMetadata.instance = new AssetMetadata(); - } - return AssetMetadata.instance; - } -} - -const ABI_SRC7 = { - programType: 'contract', - specVersion: '1', - encodingVersion: '1', - concreteTypes: [ - { - type: '()', - concreteTypeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - type: 'enum standards::src7::Metadata', - concreteTypeId: - 'f44b531974c6c04e17e66ab54e9868d230b9a24b3710b184399c363f0190180d', - metadataTypeId: 1, - }, - { - type: 'enum std::option::Option', - concreteTypeId: - 'fe93748eeb5d91a422fcea06e1b374216ad4ac0b2db01be0a6316af7f90dfa4f', - metadataTypeId: 3, - typeArguments: [ - 'f44b531974c6c04e17e66ab54e9868d230b9a24b3710b184399c363f0190180d', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - '7c06d929390a9aeeb8ffccf8173ac0d101a9976d99dda01cce74541a81e75ac0', - metadataTypeId: 3, - typeArguments: [ - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - 'd852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d', - metadataTypeId: 3, - typeArguments: [ - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - ], - }, - { - type: 'enum std::option::Option', - concreteTypeId: - '2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1', - metadataTypeId: 3, - typeArguments: [ - 'c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b', - ], - }, - { - type: 'str[12]', - concreteTypeId: - 'd41cd041a54363a3d61ab80537895c873f2315f976fc58def6e5035f6b1f0710', - }, - { - type: 'str[27]', - concreteTypeId: - '4692ce1cc6bd808ea5fe87f76008be9b96a38c78a8b1b86957d486351b10ff75', - }, - { - type: 'str[5]', - concreteTypeId: - '84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7', - }, - { - type: 'str[7]', - concreteTypeId: - '5bc5f5dfcd28de7e77d30dec3e6392905198dac3b172c043b403f669f66585ca', - }, - { - type: 'struct standards::src20::SetDecimalsEvent', - concreteTypeId: - 'fbe071a6e7ca2b2b5e503e82638f9f11c861a6fb452b65473eca8260db87392d', - metadataTypeId: 6, - }, - { - type: 'struct standards::src20::SetNameEvent', - concreteTypeId: - '6ce295b0fb4c1c15e8ed1cfa4babda47d8a04940a5266a3229e12243a2e37c2c', - metadataTypeId: 7, - }, - { - type: 'struct standards::src20::SetSymbolEvent', - concreteTypeId: - 'a8a4b78066c51a50da6349bd395fe1c67e774d75c1db2c5c22288a432d7a363d', - metadataTypeId: 8, - }, - { - type: 'struct standards::src20::TotalSupplyEvent', - concreteTypeId: - 'f255d5cc2114d1b6bc34bef4c28d4b60caccffd9a672ed16b79ea217e1c4a8a3', - metadataTypeId: 9, - }, - { - type: 'struct standards::src7::SetMetadataEvent', - concreteTypeId: - 'f1b1cc90b68559aa4bb5cc58201ebb5c5402ed3aa28927140761e8ff7dcd3ab8', - metadataTypeId: 10, - }, - { - type: 'struct std::asset_id::AssetId', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - metadataTypeId: 12, - }, - { - type: 'struct std::string::String', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - metadataTypeId: 16, - }, - { - type: 'u64', - concreteTypeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - type: 'u8', - concreteTypeId: - 'c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b', - }, - ], - metadataTypes: [ - { - type: 'b256', - metadataTypeId: 0, - }, - { - type: 'enum standards::src7::Metadata', - metadataTypeId: 1, - components: [ - { - name: 'B256', - typeId: 0, - }, - { - name: 'Bytes', - typeId: 13, - }, - { - name: 'Int', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - name: 'String', - typeId: 16, - }, - ], - }, - { - type: 'enum std::identity::Identity', - metadataTypeId: 2, - components: [ - { - name: 'Address', - typeId: 11, - }, - { - name: 'ContractId', - typeId: 15, - }, - ], - }, - { - type: 'enum std::option::Option', - metadataTypeId: 3, - components: [ - { - name: 'None', - typeId: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - }, - { - name: 'Some', - typeId: 4, - }, - ], - typeParameters: [4], - }, - { - type: 'generic T', - metadataTypeId: 4, - }, - { - type: 'raw untyped ptr', - metadataTypeId: 5, - }, - { - type: 'struct standards::src20::SetDecimalsEvent', - metadataTypeId: 6, - components: [ - { - name: 'asset', - typeId: 12, - }, - { - name: 'decimals', - typeId: - 'c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b', - }, - { - name: 'sender', - typeId: 2, - }, - ], - }, - { - type: 'struct standards::src20::SetNameEvent', - metadataTypeId: 7, - components: [ - { - name: 'asset', - typeId: 12, - }, - { - name: 'name', - typeId: 3, - typeArguments: [ - { - name: '', - typeId: 16, - }, - ], - }, - { - name: 'sender', - typeId: 2, - }, - ], - }, - { - type: 'struct standards::src20::SetSymbolEvent', - metadataTypeId: 8, - components: [ - { - name: 'asset', - typeId: 12, - }, - { - name: 'symbol', - typeId: 3, - typeArguments: [ - { - name: '', - typeId: 16, - }, - ], - }, - { - name: 'sender', - typeId: 2, - }, - ], - }, - { - type: 'struct standards::src20::TotalSupplyEvent', - metadataTypeId: 9, - components: [ - { - name: 'asset', - typeId: 12, - }, - { - name: 'supply', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - { - name: 'sender', - typeId: 2, - }, - ], - }, - { - type: 'struct standards::src7::SetMetadataEvent', - metadataTypeId: 10, - components: [ - { - name: 'asset', - typeId: 12, - }, - { - name: 'metadata', - typeId: 3, - typeArguments: [ - { - name: '', - typeId: 1, - }, - ], - }, - { - name: 'key', - typeId: 16, - }, - { - name: 'sender', - typeId: 2, - }, - ], - }, - { - type: 'struct std::address::Address', - metadataTypeId: 11, - components: [ - { - name: 'bits', - typeId: 0, - }, - ], - }, - { - type: 'struct std::asset_id::AssetId', - metadataTypeId: 12, - components: [ - { - name: 'bits', - typeId: 0, - }, - ], - }, - { - type: 'struct std::bytes::Bytes', - metadataTypeId: 13, - components: [ - { - name: 'buf', - typeId: 14, - }, - { - name: 'len', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - }, - { - type: 'struct std::bytes::RawBytes', - metadataTypeId: 14, - components: [ - { - name: 'ptr', - typeId: 5, - }, - { - name: 'cap', - typeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - }, - { - type: 'struct std::contract_id::ContractId', - metadataTypeId: 15, - components: [ - { - name: 'bits', - typeId: 0, - }, - ], - }, - { - type: 'struct std::string::String', - metadataTypeId: 16, - components: [ - { - name: 'bytes', - typeId: 13, - }, - ], - }, - ], - functions: [ - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: 'key', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - }, - ], - name: 'metadata', - output: - 'fe93748eeb5d91a422fcea06e1b374216ad4ac0b2db01be0a6316af7f90dfa4f', - attributes: [ - { - name: 'doc-comment', - arguments: [ - ' Returns metadata for the corresponding `asset` and `key`.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Arguments'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * `asset`: [AssetId] - The asset of which to query the metadata.', - ], - }, - { - name: 'doc-comment', - arguments: [' * `key`: [String] - The key to the specific metadata.'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Returns'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [ - ' * [Option] - `Some` metadata that corresponds to the `key` or `None`.', - ], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' # Examples'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' ```sway'], - }, - { - name: 'doc-comment', - arguments: [' use src7::{SRC7, Metadata};'], - }, - { - name: 'doc-comment', - arguments: [' use std::string::String;'], - }, - { - name: 'doc-comment', - arguments: [''], - }, - { - name: 'doc-comment', - arguments: [' fn foo(contract_id: ContractId, asset: AssetId) {'], - }, - { - name: 'doc-comment', - arguments: [' let contract_abi = abi(SRC7, contract_id);'], - }, - { - name: 'doc-comment', - arguments: [' let key = String::from_ascii_str("social:x");'], - }, - { - name: 'doc-comment', - arguments: [' let data = contract_abi.metadata(asset, key);'], - }, - { - name: 'doc-comment', - arguments: [ - ' assert(data.unwrap() == Metadata::String(String::from_ascii_str("fuel_network")));', - ], - }, - { - name: 'doc-comment', - arguments: [' }'], - }, - { - name: 'doc-comment', - arguments: [' ```'], - }, - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: 'svg_image', - concreteTypeId: - '9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c', - }, - { - name: 'health_attribute', - concreteTypeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - name: 'set_src7_events', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: [ - { - name: 'storage', - arguments: ['read', 'write'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'decimals', - output: - '2da102c46c7263beeed95818cd7bee801716ba8303dddafdcd0f6c9efda4a0f1', - attributes: [ - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'name', - output: - '7c06d929390a9aeeb8ffccf8173ac0d101a9976d99dda01cce74541a81e75ac0', - attributes: [ - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'symbol', - output: - '7c06d929390a9aeeb8ffccf8173ac0d101a9976d99dda01cce74541a81e75ac0', - attributes: [ - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [], - name: 'total_assets', - output: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - attributes: [ - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - ], - name: 'total_supply', - output: - 'd852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d', - attributes: [ - { - name: 'storage', - arguments: ['read'], - }, - ], - }, - { - inputs: [ - { - name: 'asset', - concreteTypeId: - 'c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974', - }, - { - name: 'supply', - concreteTypeId: - '1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0', - }, - ], - name: 'set_src20_data', - output: - '2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d', - attributes: null, - }, - ], - loggedTypes: [ - { - logId: '17415926155927968170', - concreteTypeId: - 'f1b1cc90b68559aa4bb5cc58201ebb5c5402ed3aa28927140761e8ff7dcd3ab8', - }, - { - logId: '7845998088195677205', - concreteTypeId: - '6ce295b0fb4c1c15e8ed1cfa4babda47d8a04940a5266a3229e12243a2e37c2c', - }, - { - logId: '12152039456660331088', - concreteTypeId: - 'a8a4b78066c51a50da6349bd395fe1c67e774d75c1db2c5c22288a432d7a363d', - }, - { - logId: '18149631459970394923', - concreteTypeId: - 'fbe071a6e7ca2b2b5e503e82638f9f11c861a6fb452b65473eca8260db87392d', - }, - { - logId: '17462098202904023478', - concreteTypeId: - 'f255d5cc2114d1b6bc34bef4c28d4b60caccffd9a672ed16b79ea217e1c4a8a3', - }, - ], - messagesTypes: [], - configurables: [ - { - name: 'DECIMALS', - concreteTypeId: - 'c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b', - offset: 34624, - }, - { - name: 'NAME', - concreteTypeId: - '5bc5f5dfcd28de7e77d30dec3e6392905198dac3b172c043b403f669f66585ca', - offset: 34632, - }, - { - name: 'SYMBOL', - concreteTypeId: - '84877f6e98274b9e4721db68b4c0bdb9e52b8e9572c5bd7811c07a41ced882c7', - offset: 34688, - }, - { - name: 'SOCIAL_X', - concreteTypeId: - 'd41cd041a54363a3d61ab80537895c873f2315f976fc58def6e5035f6b1f0710', - offset: 34672, - }, - { - name: 'SITE_FORUM', - concreteTypeId: - '4692ce1cc6bd808ea5fe87f76008be9b96a38c78a8b1b86957d486351b10ff75', - offset: 34640, - }, - ], -}; diff --git a/packages/graphql/src/infra/dao/AssetDAO.ts b/packages/graphql/src/infra/dao/AssetDAO.ts deleted file mode 100644 index ace3e415e..000000000 --- a/packages/graphql/src/infra/dao/AssetDAO.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { isB256 } from 'fuels'; -import { DatabaseConnectionReplica } from '../database/DatabaseConnectionReplica'; -import type PaginatedParams from '../paginator/PaginatedParams'; - -export default class AssetDAO { - databaseConnection: DatabaseConnectionReplica; - - constructor() { - this.databaseConnection = DatabaseConnectionReplica.getInstance(); - } - - async getAssetOwner(assetId: string) { - if (!isB256(assetId)) return null; - const [asset] = await this.databaseConnection.query( - 'select a.owner from indexer.assets_contracts a where a.asset_id = $1', - [assetId], - ); - if (!asset) return; - return asset.owner; - } - - async getByAssetId(assetId: string) { - const assetData = ( - await this.databaseConnection.query( - ` - select ac.*, c.name as collection from indexer.assets_contracts ac left join indexer.collections c using (contract_id) where ac.asset_id = $1 - `, - [assetId], - ) - )[0]; - if (!assetData) return; - return { - assetId: assetData.asset_id, - contractId: assetData.contract_id, - subId: assetData.sub_id, - name: assetData.name, - symbol: assetData.symbol, - decimals: assetData.decimals, - totalSupply: assetData.total_supply, - suspicious: false, - metadata: assetData.metadata, - collection: assetData.collection, - }; - } - - async getPaginatedByContractId( - contractId: string, - paginatedParams: PaginatedParams, - ) { - const direction = paginatedParams.direction === 'before' ? '<' : '>'; - const order = paginatedParams.direction === 'before' ? 'desc' : 'asc'; - const assetsData = await this.databaseConnection.query( - ` - select - * - from - indexer.assets_contracts c - where - c.contract_id = $1 and - ($2::text is null or c._id ${direction} $2) - order by - c._id ${order} - limit - $3 - `, - [contractId.toLowerCase(), paginatedParams.cursor, paginatedParams.last], - ); - assetsData.sort((a: any, b: any) => { - return a._id.localeCompare(b._id) * -1; - }); - if (assetsData.length === 0) { - return { - nodes: [], - edges: [], - pageInfo: { - hasNextPage: false, - hasPreviousPage: false, - endCursor: '', - startCursor: '', - }, - }; - } - const startCursor = assetsData[0]._id; - const endCursor = assetsData[assetsData.length - 1]._id; - const hasPreviousPage = ( - await this.databaseConnection.query( - 'select exists(select 1 from indexer.assets_contracts t where t._id < $1 and t.contract_id = $2)', - [endCursor, contractId], - ) - )[0].exists; - const hasNextPage = ( - await this.databaseConnection.query( - 'select exists(select 1 from indexer.assets_contracts t where t._id > $1 and t.contract_id = $2)', - [startCursor, contractId], - ) - )[0].exists; - const [previousRows] = await this.databaseConnection.query( - 'select count(*)::integer as count from indexer.assets_contracts where _id > $1 and contract_id = $2', - [startCursor, contractId], - ); - const [totalCount] = await this.databaseConnection.query( - 'select count(*)::integer as count from indexer.assets_contracts where contract_id = $1', - [contractId], - ); - const newNodes = assetsData.map((assetData) => ({ - _id: assetData._id, - assetId: assetData.asset_id, - contractId: assetData.contract_id, - subId: assetData.sub_id, - name: assetData.name, - symbol: assetData.symbol, - decimals: assetData.decimals, - totalSupply: assetData.total_supply, - suspicious: false, - icon: '', - networks: [], - rate: null, - })); - const edges = newNodes.map((node) => ({ - node, - cursor: paginatedParams.cursor, - })); - const paginatedResults = { - nodes: newNodes, - edges, - pageInfo: { - startCount: previousRows.count + 1, - endCount: previousRows.count + paginatedParams.last, - totalCount: totalCount.count, - hasNextPage, - hasPreviousPage, - endCursor, - startCursor, - }, - }; - - return paginatedResults; - } - - async getAssetsRate() { - const data = await this.databaseConnection.query( - 'select symbol, rate from indexer.assets_rates where _id in (select max(_id) from indexer.assets_rates group by symbol)', - [], - ); - return data.map((assetRate) => ({ - symbol: assetRate.symbol, - rate: Number(assetRate.rate), - })); - } - - async getAssetsRateByAssetId(assetId: string) { - const [data] = await this.databaseConnection.query( - 'select symbol, rate from indexer.assets_rates where _id = (select max(_id) from indexer.assets_rates where asset_id = $1)', - [assetId], - ); - if (!data) return; - return { - symbol: data.symbol, - rate: Number(data.rate), - }; - } - - async getAssetsRateBySymbol(symbol: string) { - const [data] = await this.databaseConnection.query( - 'select symbol, rate from indexer.assets_rates where _id = (select max(_id) from indexer.assets_rates where symbol = $1)', - [symbol], - ); - if (!data) return; - return { - symbol: data.symbol, - rate: Number(data.rate), - }; - } -} diff --git a/packages/graphql/src/infra/dao/BalanceDAO.ts b/packages/graphql/src/infra/dao/BalanceDAO.ts deleted file mode 100644 index 3a17d54e6..000000000 --- a/packages/graphql/src/infra/dao/BalanceDAO.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { DatabaseConnectionReplica } from '../database/DatabaseConnectionReplica'; - -export default class BalanceDAO { - databaseConnection: DatabaseConnectionReplica; - - constructor() { - this.databaseConnection = DatabaseConnectionReplica.getInstance(); - } - - async getBalance( - accountHash: string, - assetId: string, - blockHeight: number | null, - ) { - const [balanceData] = await this.databaseConnection.query( - ` - select - block_height, - account_hash, - asset_id, - balance - from - indexer.balance - where - _id = ( - select - max(_id) - from - indexer.balance - where - account_hash = $1 and - asset_id = $2 and - ($3::integer is null or block_height = $3) - ); - `, - [accountHash, assetId, blockHeight], - ); - return balanceData; - } -} diff --git a/packages/graphql/src/infra/dao/BlockDAO.ts b/packages/graphql/src/infra/dao/BlockDAO.ts deleted file mode 100644 index a74247f73..000000000 --- a/packages/graphql/src/infra/dao/BlockDAO.ts +++ /dev/null @@ -1,333 +0,0 @@ -import dayjs from 'dayjs'; -import utc from 'dayjs/plugin/utc'; -import { DatabaseConnectionReplica } from '../database/DatabaseConnectionReplica'; -import type PaginatedParams from '../paginator/PaginatedParams'; -import Block from './Block'; -dayjs.extend(utc); - -export default class BlockDAO { - databaseConnection: DatabaseConnectionReplica; - - constructor() { - this.databaseConnection = DatabaseConnectionReplica.getInstance(); - } - - async getByHeight(height: number) { - const blockData = ( - await this.databaseConnection.query( - ` - select - b.* - from - indexer.blocks b - where - b._id = $1 - `, - [height], - ) - )[0]; - if (!blockData) return; - return new Block(blockData); - } - - async getByHash(hash: string) { - const blockData = ( - await this.databaseConnection.query( - ` - select - b.* - from - indexer.blocks b - where - b.id = $1 - `, - [hash.toLowerCase()], - ) - )[0]; - if (!blockData) return; - return new Block(blockData); - } - - async getPaginatedBlocks(paginatedParams: PaginatedParams) { - const direction = paginatedParams.direction === 'before' ? '<' : '>'; - const order = paginatedParams.direction === 'before' ? 'desc' : 'asc'; - const blocksData = await this.databaseConnection.query( - ` - select - * - from - indexer.blocks b - where - $1::integer is null or b._id ${direction} $1 - order by - b._id ${order} - limit 10 - `, - [paginatedParams.cursor], - ); - blocksData.sort((a: any, b: any) => { - return (a._id - b._id) * -1; - }); - const blocks = []; - for (const blockData of blocksData) { - blocks.push(new Block(blockData)); - } - if (blocks.length === 0) { - return { - nodes: [], - edges: [], - pageInfo: { - hasNextPage: false, - hasPreviousPage: false, - endCursor: '', - startCursor: '', - }, - }; - } - const startCursor = blocksData[0]._id; - const endCursor = blocksData[blocksData.length - 1]._id; - const hasPreviousPage = ( - await this.databaseConnection.query( - 'select exists(select 1 from indexer.blocks where _id < $1)', - [endCursor], - ) - )[0].exists; - const hasNextPage = ( - await this.databaseConnection.query( - 'select exists(select 1 from indexer.blocks where _id > $1)', - [startCursor], - ) - )[0].exists; - const newNodes = blocks.map((n) => n.toGQLNode()); - const edges = newNodes.map((node) => ({ - node, - cursor: paginatedParams.cursor, - })); - const paginatedResults = { - nodes: newNodes, - edges, - pageInfo: { - hasNextPage, - hasPreviousPage, - endCursor, - startCursor, - }, - }; - return paginatedResults; - } - - async findLatestBlockHeight(): Promise { - const [row] = await this.databaseConnection.query( - 'select _id from indexer.blocks order by _id desc limit 1', - [], - ); - return row ? row._id : null; - } - - async getBlocksDashboard() { - const blocksData = await this.databaseConnection.query( - ` - select - b._id as blockno, - b.id as hash, - b.gas_used as gasused, - b.total_fee as totalfee, - b.producer, - b.timestamp as timestamp, - b.transactions_count as transactionscount, - pg_column_size(b.data) as blocksize - from - indexer.blocks b - order by - b._id desc - limit 6 - `, - [], - ); - const formattedBlocksData = blocksData.map((block) => ({ - timestamp: new Date(Number(block.timestamp)).getTime(), - gasUsed: Number(block.gasused) || 0, - gasUsedInUsd: '', - totalFee: Number(block.totalfee) || 0, - totalFeeInUsd: '', - blockNo: block.blockno, - blockHash: block.hash, - producer: block.producer, - transactionsCount: Number(block.transactionscount) || 0, - blockSize: Number(block.blocksize) || 0, - })); - return { - nodes: formattedBlocksData, - }; - } - - // The window-anchor `MAX("timestamp")` is computed once via getMaxTimestamp() - // and passed in as $1. Embedding the subquery turned the WHERE filter into a - // runtime parameter the planner can't size, which made it pick a Parallel Seq - // Scan over the whole 50M-row blocks table. With $1 bound to a literal, the - // planner uses the histogram on `timestamp` and picks an Index Scan on - // blocks_timestamp_idx that touches only the recent ~89K rows. - - async getMaxTimestamp(): Promise { - const [row] = await this.databaseConnection.query( - 'SELECT MAX("timestamp") AS max_ts FROM indexer.blocks', - [], - ); - return row?.max_ts ?? null; - } - - async tps(maxTs: Date | null) { - if (!maxTs) return { nodes: [] }; - const data = await this.databaseConnection.query( - `SELECT to_char(date_trunc('hour', "timestamp"), 'YYYY-MM-DD HH24') AS date, - SUM(transactions_count) AS total_tps, - SUM(gas_used::int) AS total_gas_used - FROM indexer.blocks - WHERE "timestamp" > date_trunc('hour', $1::timestamptz) - INTERVAL '24 hours' - AND "timestamp" < date_trunc('hour', $1::timestamptz) - GROUP BY 1 - ORDER BY 1 ASC`, - [maxTs], - ); - const intervals = []; - for (const row of data) { - const interval: any = {}; - interval.start = dayjs(row.date) - .startOf('hour') - .utcOffset(0, true) - .toDate(); - interval.end = dayjs(row.date) - .startOf('hour') - .add(1, 'hour') - .utcOffset(0, true) - .toDate(); - interval.txCount = Number(row.total_tps); - interval.totalGas = Number(row.total_gas_used); - intervals.push(interval); - } - return { - nodes: intervals, - }; - } - - // Single scan that emits all six per-hour aggregates the dashboard needs. - // Replaces six individual queries (getTotalTps/getAverageTps/getMaxTps and - // their gas equivalents) which were each doing the same 24h scan. - async getHourlyStatistics(maxTs: Date | null) { - const empty = { - totalTps: [], - averageTps: [], - maxTps: [], - totalGasUsed: [], - averageGasUsed: [], - maxGasUsed: [], - }; - if (!maxTs) return empty; - const rows = await this.databaseConnection.query( - `SELECT to_char(date_trunc('hour', "timestamp"), 'YYYY-MM-DD HH24') AS date, - SUM(transactions_count)::numeric AS sum_txs, - AVG(transactions_count)::numeric AS avg_txs, - MAX(transactions_count)::numeric AS max_txs, - SUM(gas_used::numeric) AS sum_gas, - AVG(gas_used::numeric) AS avg_gas, - MAX(gas_used::numeric) AS max_gas - FROM indexer.blocks - WHERE "timestamp" > date_trunc('hour', $1::timestamptz) - INTERVAL '24 hours' - GROUP BY 1 - ORDER BY 1`, - [maxTs], - ); - const toBucket = (col: string) => - rows.map((r: any) => ({ - date: dayjs(r.date).startOf('hour').utcOffset(0, true).toDate(), - value: Number(r[col]), - })); - // The legacy getMaxTps used a 23-hour window (vs 24h here); preserve the - // historical entry count to keep any external SDK consumer's expectations - // intact. - return { - totalTps: toBucket('sum_txs'), - averageTps: toBucket('avg_txs'), - maxTps: toBucket('max_txs').slice(-24), - totalGasUsed: toBucket('sum_gas'), - averageGasUsed: toBucket('avg_gas'), - maxGasUsed: toBucket('max_gas'), - }; - } - - async getAverageTpsPerMinute(maxTs: Date | null) { - if (!maxTs) return []; - const data = await this.databaseConnection.query( - `SELECT to_char(date_trunc('minute', "timestamp"), 'YYYY-MM-DD HH24:MI') AS date, - SUM(transactions_count)::float / 60 AS value - FROM indexer.blocks - WHERE "timestamp" > $1::timestamptz - INTERVAL '24 hours' - GROUP BY 1 - ORDER BY 1 ASC`, - [maxTs], - ); - return data.map((row) => ({ - date: dayjs(row.date).startOf('minute').utcOffset(0, true).toDate(), - value: Number(row.value) || 0, - })); - } - - async getRollingStats60s(maxTs: Date | null) { - if (!maxTs) { - return { - tps: 0, - avgTxPerBlock: 0, - avgGasPerBlock: 0, - avgBlockSize: 0, - peakTps: 0, - }; - } - const [stats, peak] = await Promise.all([ - this.databaseConnection.query( - `SELECT - COALESCE(SUM(transactions_count)::float / 60, 0) AS tps, - CASE WHEN COUNT(*) > 0 THEN SUM(transactions_count)::float / COUNT(*) ELSE 0 END AS avg_tx_per_block, - CASE WHEN COUNT(*) > 0 THEN AVG(gas_used::numeric) ELSE 0 END AS avg_gas_per_block, - CASE WHEN COUNT(*) > 0 THEN AVG(pg_column_size(data)) ELSE 0 END AS avg_block_size - FROM indexer.blocks - WHERE "timestamp" > $1::timestamptz - INTERVAL '60 seconds'`, - [maxTs], - ), - this.databaseConnection.query( - `SELECT COALESCE(MAX(minute_tps), 0) AS peak_tps - FROM ( - SELECT SUM(transactions_count)::float / 60 AS minute_tps - FROM indexer.blocks - WHERE "timestamp" > $1::timestamptz - INTERVAL '24 hours' - GROUP BY date_trunc('minute', "timestamp") - ) t`, - [maxTs], - ), - ]); - return { - tps: Number(stats[0]?.tps) || 0, - avgTxPerBlock: Number(stats[0]?.avg_tx_per_block) || 0, - avgGasPerBlock: Number(stats[0]?.avg_gas_per_block) || 0, - avgBlockSize: Number(stats[0]?.avg_block_size) || 0, - peakTps: Number(peak[0]?.peak_tps) || 0, - }; - } - - async getTotalFee() { - // Optimized query using materialized view for pre-computed hourly statistics - // View refreshes every 10 minutes and eliminates expensive JSON extraction - const data = await this.databaseConnection.query( - `SELECT to_char(hour, 'YYYY-MM-DD HH24') AS date, - total_fee AS value - FROM indexer.hourly_statistics_agg - WHERE hour > (SELECT MAX(hour) FROM indexer.hourly_statistics_agg) - INTERVAL '24 hours' - AND hour <= (SELECT MAX(hour) FROM indexer.hourly_statistics_agg) - ORDER BY hour`, - [], - ); - return data.map((row) => ({ - date: dayjs(row.date).startOf('hour').utcOffset(0, true).toDate(), - value: Number(row.value), - })); - } -} diff --git a/packages/graphql/src/infra/dao/BridgeDAO.ts b/packages/graphql/src/infra/dao/BridgeDAO.ts deleted file mode 100644 index 033d209e2..000000000 --- a/packages/graphql/src/infra/dao/BridgeDAO.ts +++ /dev/null @@ -1,735 +0,0 @@ -import dayjs from 'dayjs'; -import { dataLength, ethers, toUtf8Bytes, zeroPadValue } from 'ethers'; -import { - Address, - type BytesLike, - InputMessageCoder, - ZeroBytes32, - arrayify, - bn, - concat, - sha256, -} from 'fuels'; -import { DatabaseConnectionReplica } from '../database/DatabaseConnectionReplica'; -import { - type BridgeResponse, - type CommitQueryItem, - type DepositEvent, - DepositQueryType, - type DepositResponse, - DepositStatusType, - type EventRow, - type MessageDecoded, - type MessageSpent, - ResponseType, - type WithdrawEvent, - type WithdrawResponse, - WithdrawStatusType, -} from './BridgeDAO.types'; - -// Time to finalize withdraw in days -const TIME_TO_FINALIZE_COMMIT = 7; -const TIME_TO_INCLUDE_BLOCK = 30; - -// TODO: Contract changes base on the network -const BRIDGE_CONTRACT_L2_ADDRESS = - '0xd02112ef9c39f1cea7c8527c26242ca1f5d26bcfe8d1564bee054d3b04175471'; - -function getTokenId(_tokenAddress: BytesLike) { - const tokenId: BytesLike = ZeroBytes32; - let tokenAddress = _tokenAddress; - if (dataLength(tokenAddress) < 32) { - tokenAddress = zeroPadValue(tokenAddress, 32); - } - const subId = sha256(concat([toUtf8Bytes('1'), tokenAddress, tokenId])); - const assetId = sha256(concat([BRIDGE_CONTRACT_L2_ADDRESS, subId])); - return assetId; -} - -export const MESSAGE_TYPES = { - DEPOSIT: '0x0000000000000000000000000000000000000000000000000000000000000000', - DEPOSIT_WITH_DATA: - '0x0000000000000000000000000000000000000000000000000000000000000002', -} as const; - -// This is default used on mainnet and testnet -const ETH_ASSET_ID = - '0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07'; - -function decodeMessageOut(bytes: string): { - recipient: string; - assetId: string; - amount: string; - ethAssetId: string; -} { - const [recipient, tokenId, amount] = ethers.AbiCoder.defaultAbiCoder().decode( - new Array(3).fill('bytes32'), - arrayify(bytes).slice(4), - ); - return { - recipient, - assetId: getTokenId(tokenId), - ethAssetId: tokenId, - amount: bn(amount).toString(), - }; -} - -function decodeMessageIn(bytes: string): MessageDecoded { - const [ - contractId, - _messageType, - address, - _tokenId, - sender, - recipient, - amount, - decimals, - ] = ethers.AbiCoder.defaultAbiCoder().decode( - new Array(8).fill('bytes32'), - arrayify(bytes), - ); - - return { - address, - assetId: getTokenId(contractId), - sender, - recipient, - amount: bn(amount).toString(), - decimals: bn(decimals).toNumber(), - }; -} - -function getValidAddress(address: string) { - try { - return Address.fromString(address); - } catch (_error) { - throw new Error('Invalid address format, expected a valid FUEL address'); - } -} - -export default class BridgeDAO { - databaseConnection: DatabaseConnectionReplica; - - constructor() { - this.databaseConnection = DatabaseConnectionReplica.getInstance(); - } - - averageTimeDifferenceInSeconds(dates: Date[]) { - if (dates.length < 2) return 0; - const timestamps = dates - .map((date) => date.getTime()) - .sort((a, b) => b - a); - let totalDiff = 0; - for (let i = 1; i < timestamps.length; i++) { - totalDiff += timestamps[i - 1] - timestamps[i]; - } - const avgDiffInMilliseconds = totalDiff / (timestamps.length - 1); - return avgDiffInMilliseconds / 1000; - } - - async getLastCommits(): Promise<{ - lastCommit: CommitQueryItem; - lastFinalizedCommit: CommitQueryItem; - commitPeriod: number; - }> { - const blocks = await this.databaseConnection.query( - `select - cl."timestamp", - cl.tx_hash, - b._id as fuel_block_height, - b.id as fuel_block_hash, - cl.block_height as eth_block_height, - (cl."timestamp" < (now() - interval '7 days')) as is_finalized - from - indexer.contract_l1_logs cl - join - indexer.blocks b - on b.id = cl.decoded_args->>'blockHash' - where - cl."event" = 'CommitSubmitted' and - cl."timestamp" > (now() - interval '10 days') and - cl.contract_hash in (select contract_hash from indexer.contract_l1_index where name = 'FuelChainState') - order by cl."timestamp" desc`, - [], - ); - const diff = this.averageTimeDifferenceInSeconds( - blocks.map((block) => block.timestamp), - ); - return { - lastCommit: blocks[0], - lastFinalizedCommit: blocks.find((b) => b.is_finalized === true), - commitPeriod: diff, - }; - } - - async getBlockCommit(block_height: string): Promise<{ - fuel_block_height: string; - fuel_block_hash: string; - eth_block_height: string; - tx_hash: string; - timestamp: Date; - } | null> { - const [block] = await this.databaseConnection.query( - `select - b._id as fuel_block_height, - b.id as fuel_block_hash, - cl.block_height as eth_block_height, - cl.tx_hash as tx_hash, - cl."timestamp" - from - indexer.blocks b - join - indexer.contract_l1_args ca - on ca."key" = 'blockHash' - and ca."value" = b.id - join - indexer.contract_l1_logs cl - on cl._id = ca.contract_l1_log_id - where - b._id >= $1 - order by b._id asc - limit 1`, - [block_height], - ); - return block; - } - - async blockIsSynced(blockHeight: string) { - const [blockIsSynced] = await this.databaseConnection.query( - `select - b.da_height - from - indexer.blocks b - where - b.da_height >= $1 - order by b._id desc - limit 1`, - [blockHeight], - ); - return blockIsSynced ? blockIsSynced.da_height > 0 : false; - } - - async getMessageSpent( - address: string, - nonce: string, - ): Promise { - const [messageSpent] = await this.databaseConnection.query( - `select - t.tx_hash, - t.block_id, - t."timestamp", - i.nonce - from - indexer.transactions_accounts t_a - join - indexer.inputs i - on i.transaction_id = t_a._id - and i.nonce = $1 - join - indexer.transactions t - on t.tx_hash = t_a.tx_hash - where - t_a.account_hash = $2`, - [String(nonce), Address.fromString(address).toB256()], - ); - return messageSpent - ? { - tx_hash: messageSpent.tx_hash, - block_height: messageSpent.block_id, - nonce: messageSpent.nonce, - timestamp: messageSpent.timestamp, - } - : null; - } - - parseWithdrawEvent(event: any): EventRow & WithdrawEvent { - const messageId = InputMessageCoder.getMessageId({ - sender: event.sender, - amount: bn(event.amount), - nonce: event.nonce, - recipient: event.recipient, - data: event.data, - }); - const data: EventRow & WithdrawEvent = { - event_id: event.event_id, - event_type: event.event_type, - tx_hash: event.tx_id, - block_height: event.block_id, - timestamp: event.timestamp, - data: event.data, - messageId, - sender: event.sender, - recipient: event.recipient, - amount: bn(event.amount).toString(), - assetId: ETH_ASSET_ID, - ethAssetId: ETH_ASSET_ID, - }; - - if (bn(data.amount).isZero()) { - const { recipient, amount, assetId, ethAssetId } = decodeMessageOut( - event.data, - ); - data.amount = amount; - data.recipient = recipient; - data.assetId = assetId; - data.ethAssetId = ethAssetId; - } - - return data; - } - - parseDepositEvent(event: any): EventRow & DepositEvent { - if (event.key === 'data') { - const data = decodeMessageIn(event.decoded_args.data); - return { - event_id: event.event_id, - event_type: event.event_type, - type: DepositQueryType.ERC_20, - tx_hash: event.tx_hash, - block_height: event.block_height, - timestamp: event.timestamp, - nonce: bn(event.decoded_args.nonce).toHex(32), - ...data, - }; - } - return { - event_id: event.event_id, - event_type: event.event_type, - type: DepositQueryType.ETH, - tx_hash: event.tx_hash, - block_height: event.block_height, - timestamp: event.timestamp, - nonce: bn(event.decoded_args.nonce).toHex(32), - address: ZeroBytes32, - assetId: ETH_ASSET_ID, - sender: event.decoded_args.sender, - recipient: event.decoded_args.recipient, - amount: bn(event.decoded_args.amount).toString(), - decimals: 9, - }; - } - - async processDepositEvent(event: EventRow & DepositEvent) { - const data: EventRow & DepositResponse = { - event_id: event.event_id, - event_type: event.event_type, - type: ResponseType.Deposit, - amount: event.amount, - ethAssetId: event.address, - assetId: event.assetId, - from: event.sender, - to: event.recipient, - status: DepositStatusType.WaitingSync, - statusInfo: { - [DepositStatusType.TransactionSent]: { - ethTx: { - height: event.block_height, - txHash: event.tx_hash, - timestamp: event.timestamp, - }, - }, - [DepositStatusType.WaitingSync]: { - dateExpectedToComplete: dayjs(event.timestamp) - .add(TIME_TO_INCLUDE_BLOCK, 'minutes') - .toDate(), - }, - }, - }; - const isSynced = await this.blockIsSynced(event.block_height); - - if (event.type === DepositQueryType.ERC_20) { - const messageSpent = await this.getMessageSpent( - event.recipient, - event.nonce, - ); - if (isSynced) { - data.status = DepositStatusType.ReadyToProcessDeposit; - data.statusInfo[DepositStatusType.ReadyToProcessDeposit] = { - nonce: event.nonce, - }; - } - if (messageSpent) { - data.status = DepositStatusType.Finalized; - data.statusInfo[DepositStatusType.Finalized] = {}; - } - } - - if (event.type === DepositQueryType.ETH && isSynced) { - data.status = DepositStatusType.Finalized; - data.statusInfo[DepositStatusType.Finalized] = {}; - } - - return data; - } - - async processWithdrawEvent(event: EventRow & WithdrawEvent) { - const { lastCommit, lastFinalizedCommit, commitPeriod } = - await this.getLastCommits(); - const data: EventRow & WithdrawResponse = { - event_id: event.event_id, - event_type: event.event_type, - type: ResponseType.Withdraw, - amount: event.amount, - ethAssetId: event.ethAssetId, - assetId: event.assetId, - from: event.sender, - to: event.recipient, - status: WithdrawStatusType.WaitingCommittingToL1, - statusInfo: { - [WithdrawStatusType.TransactionSent]: { - fuelTx: { - height: event.block_height, - txHash: event.tx_hash, - timestamp: event.timestamp, - }, - }, - [WithdrawStatusType.WaitingCommittingToL1]: { - dateExpectedToComplete: dayjs(lastCommit.timestamp) - .add(commitPeriod, 'seconds') - .toDate(), - }, - }, - }; - const blockCommited = await this.getBlockCommit(event.block_height); - if (blockCommited) { - const dateToFinalize = dayjs(blockCommited.timestamp).add( - TIME_TO_FINALIZE_COMMIT, - 'days', - ); - data.status = WithdrawStatusType.WaitingFinalization; - data.statusInfo[WithdrawStatusType.WaitingFinalization] = { - dateExpectedToComplete: dateToFinalize.toDate(), - ethTx: { - height: blockCommited.eth_block_height, - txHash: blockCommited.tx_hash, - timestamp: blockCommited.timestamp, - }, - }; - if (dateToFinalize.isBefore()) { - data.status = WithdrawStatusType.ReadyToProcessWithdraw; - data.statusInfo[WithdrawStatusType.ReadyToProcessWithdraw] = { - transactionId: event.tx_hash, - nonce: event.messageId, - commitBlockId: blockCommited.fuel_block_height, - commitBlockHeight: blockCommited.fuel_block_hash, - }; - if ( - Number(lastFinalizedCommit.fuel_block_height) > - Number(blockCommited.fuel_block_height) - ) { - data.statusInfo[WithdrawStatusType.ReadyToProcessWithdraw] = { - transactionId: event.tx_hash, - nonce: event.messageId, - commitBlockId: lastFinalizedCommit.fuel_block_height, - commitBlockHeight: lastFinalizedCommit.fuel_block_hash, - }; - } - } - } - - const [messageRelayed] = await this.databaseConnection.query( - `SELECT - cl."timestamp", - cl.tx_hash, - cl.block_height - FROM - indexer.contract_l1_logs cl - JOIN - indexer.contract_l1_args ca - on ca."key" = 'messageId' - and ca.contract_l1_log_id = cl._id - and ca."value" = $1 - WHERE - cl.signature = 'MessageRelayed(bytes32,bytes32,bytes32,uint64)' - ORDER BY cl."timestamp" DESC`, - [event.messageId], - ); - if (messageRelayed) { - data.status = WithdrawStatusType.Finalized; - data.statusInfo[WithdrawStatusType.Finalized] = { - ethTx: { - height: messageRelayed.block_height, - txHash: messageRelayed.tx_hash, - timestamp: messageRelayed.timestamp, - }, - }; - } - return data; - } - - async queryEvents(address: Address, limit: number, offset: number) { - const events: Array = - await this.databaseConnection.query( - `select - 'deposit' as event_type, - cl._id as event_id, - cl."timestamp", - cl.contract_hash, - cl.block_height, - cl.tx_hash, - cl.decoded_args as decoded_args, - ca."key", - null as tx_id, - null as block_id, - null as contract_id, - null as sender, - null as nonce, - null as amount, - null as recipient, - null as data - from - indexer.contract_l1_logs cl - join - indexer.contract_l1_args ca - on ca.contract_l1_log_id = cl._id - and (( - ca."key" = 'recipient' - and ca."value" = $1 - ) or ( - ca."key" = 'data' - and ca."value" LIKE '%${address.toB256().replace('0x', '')}%' - )) - where - cl.event = 'MessageSent' - AND cl.contract_hash in ( - select ci.contract_hash from indexer.contract_l1_index ci where ci."name" in ( - 'FuelMessagePortal', 'FuelERC20GatewayV4' - ) - ) - union all - select - 'withdraw' as event_type, - r._id as event_id, - t."timestamp" as timestamp, - null as contract_hash, - null as block_height, - null as tx_hash, - null as decoded_args, - null as key, - t.tx_hash as tx_id, - t.block_id as block_id, - a_c.account_hash as contract_id, - r.receipt_sender as sender, - r.receipt_nonce as nonce, - r.receipt_amount as amount, - r.receipt_recipient as recipient, - r.receipt_data as data - from - indexer.transactions_accounts a_c - join indexer.transactions t on (t.tx_hash = a_c.tx_hash) - join indexer.receipts r on (r.tx_hash = t.tx_hash) - where - a_c.account_hash = $1 and - r.receipt_type = 'MESSAGE_OUT' - order by timestamp desc - limit $2 - offset $3 - `, - [address.toB256(), limit, offset], - ); - return events; - } - - async queryLogsForRecipient( - address: string, - recipient: string, - predicate: string, - ) { - // Remove 0x prefix and convert to lowercase for comparison - const recipientHex = recipient.toLowerCase().replace('0x', ''); - - const events: Array = - await this.databaseConnection.query( - `SELECT - ca.value as recipient, - cl."raw_log"->>'blockHash' as "blockHash", - cl."raw_log"->>'topics' as "topics", - cl."raw_log"->>'data' as "data", - cl."decoded_args"->>'nonce' as "nonce", - cl.tx_hash as "transactionHash" - FROM - indexer.contract_l1_logs cl - JOIN - indexer.contract_l1_args ca - ON ca.contract_l1_log_id = cl._id - AND ca."key" = 'recipient' - WHERE cl.contract_hash = $1 - AND ( - -- Direct recipient match (ETH deposits) - LOWER(ca."value") = LOWER($2) - OR ( - -- ERC20 deposits: recipient is predicate, but check if data contains actual recipient - LOWER(ca."value") = LOWER($3) - AND EXISTS ( - SELECT 1 - FROM indexer.contract_l1_args ca_data - WHERE ca_data.contract_l1_log_id = cl._id - AND ca_data."key" = 'data' - AND LOWER(ca_data."value") LIKE '%' || $4 || '%' - ) - ) - ) - ORDER BY cl."timestamp" DESC - `, - [address, recipient, predicate, recipientHex], - ); - return events; - } - - async queryBlockHashes(address: string, fromBlock: number) { - const events: Array = - await this.databaseConnection.query( - `SELECT - cl."decoded_args"->>'blockHash' as "fuelBlockHash", - cl."raw_log"->>'blockHash' as "ethBlockHash" - FROM - indexer.contract_l1_logs cl - WHERE - cl.contract_hash = $1 AND - cl.event = 'CommitSubmitted' AND - cl.block_height > $2 - ORDER BY cl."timestamp" ASC - `, - [address, fromBlock], - ); - return events; - } - - async queryMessageRelayedTxHash(address: string, messageId: string) { - const events: Array = - await this.databaseConnection.query( - `SELECT - cl.tx_hash as "transactionHash" - FROM - indexer.contract_l1_logs cl - WHERE - cl.contract_hash = $1 AND - cl.event = 'MessageRelayed' AND - cl.decoded_args->>'messageId' = $2 - ORDER BY cl."timestamp" ASC - `, - [address, messageId], - ); - return events; - } - - async existsQueryEvents(address: Address, limit: number, offset: number) { - if (offset < 0) return false; - const events = await this.queryEvents(address, limit, offset); - return events.length > 0; - } - - async getEvents( - rawAddress: string, - limit: number, - offset: number, - ): Promise { - if (limit < 0 || offset < 0) return []; - const address = getValidAddress(rawAddress); - const events = await this.queryEvents(address, limit, offset); - const hasPreviousPage = await this.existsQueryEvents( - address, - limit, - offset + limit, - ); - const hasNextPage = await this.existsQueryEvents( - address, - limit, - offset - limit, - ); - const promises = events.map( - async (event: EventRow & DepositEvent & WithdrawEvent) => { - if (event.event_type === 'deposit') { - const deposit = await this.processDepositEvent( - this.parseDepositEvent(event), - ); - return deposit; - } - if (event.event_type === 'withdraw') { - const withdraw = await this.processWithdrawEvent( - this.parseWithdrawEvent(event), - ); - return withdraw; - } - throw new Error(''); - }, - ); - const mergedEvents: Array = await Promise.all(promises); - return { - nodes: mergedEvents, - pageInfo: { - limit, - offset, - hasPreviousPage, - hasNextPage, - }, - }; - } - - async queryDepositEvent(eventId: number) { - const [event] = await this.databaseConnection.query( - `select - 'deposit' as event_type, - cl._id as event_id, - cl."timestamp", - cl.contract_hash, - cl.block_height, - cl.tx_hash, - cl.decoded_args as decoded_args, - ca."key" - from - indexer.contract_l1_logs cl - join indexer.contract_l1_args ca on ca.contract_l1_log_id = cl._id - where - cl._id = $1 and - ((ca."key" = 'recipient' and (cl.decoded_args->>'amount')::numeric > 0) or (ca."key" = 'data' and (cl.decoded_args->>'amount')::numeric = 0)) - `, - [eventId], - ); - return event; - } - - async queryWithdrawEvent(eventId: number) { - const [event] = await this.databaseConnection.query( - ` - select - 'withdraw' as event_type, - r._id as event_id, - t."timestamp" as timestamp, - t.tx_hash as tx_id, - t.block_id as block_id, - a_c.account_hash as contract_id, - r.receipt_sender as sender, - r.receipt_nonce as nonce, - r.receipt_amount as amount, - r.receipt_recipient as recipient, - r.receipt_data as data - from - indexer.transactions_accounts a_c - join indexer.transactions t on (t.tx_hash = a_c.tx_hash) - join indexer.receipts r on (r.tx_hash = t.tx_hash) - where - r._id = $1 - `, - [eventId], - ); - return event; - } - - async getEvent(eventType: string, eventId: number) { - if (eventType === 'deposit') { - const event = await this.queryDepositEvent(eventId); - const deposit = await this.processDepositEvent( - this.parseDepositEvent(event), - ); - return deposit; - } - if (eventType === 'withdraw') { - const event = await this.queryWithdrawEvent(eventId); - const withdraw = await this.processWithdrawEvent( - this.parseWithdrawEvent(event), - ); - return withdraw; - } - } -} diff --git a/packages/graphql/src/infra/dao/BridgeDAO.types.ts b/packages/graphql/src/infra/dao/BridgeDAO.types.ts deleted file mode 100644 index 0f0a37b9b..000000000 --- a/packages/graphql/src/infra/dao/BridgeDAO.types.ts +++ /dev/null @@ -1,157 +0,0 @@ -export type EventRow = { - event_id: string; - event_type: string; -}; - -export type CommitQueryItem = { - timestamp: Date; - tx_hash: string; - eth_block_height: string; - fuel_block_height: string; - fuel_block_hash: string; - is_finalized: boolean; -}; - -export enum ResponseType { - Withdraw = 'Withdraw', - Deposit = 'Deposit', -} - -export enum WithdrawStatusType { - TransactionSent = 'TransactionSent', - WaitingCommittingToL1 = 'WaitingCommittingToL1', - WaitingFinalization = 'WaitingFinalization', - ReadyToProcessWithdraw = 'ReadyToProcessWithdraw', - Finalized = 'Finalized', -} - -export enum DepositStatusType { - TransactionSent = 'TransactionSent', - WaitingSync = 'WaitingSync', - ReadyToProcessDeposit = 'ReadyToProcessDeposit', - Finalized = 'Finalized', -} - -export type MessageDecoded = { - address: string; - assetId: string; - sender: string; - recipient: string; - amount: string; - decimals: number; -}; - -export type MessageSpent = { - tx_hash: string; - block_height: string; - timestamp: Date; - nonce: string; -}; - -export enum DepositQueryType { - ERC_20 = 'ERC_20', - ETH = 'ETH', -} - -export type DepositEvent = MessageDecoded & { - tx_hash: string; - block_height: string; - timestamp: Date; - nonce: string; - type: DepositQueryType; -}; - -export type WithdrawEvent = { - tx_hash: string; - block_height: string; - timestamp: Date; - data: string; - messageId: string; - sender: string; - recipient: string; - amount: string; - assetId: string; - ethAssetId: string; -}; - -export type WithdrawResponse = { - type: ResponseType.Withdraw; - from: string; - to: string; - amount: string; - assetId: string; - ethAssetId: string; - status: WithdrawStatusType; - statusInfo: { - [WithdrawStatusType.TransactionSent]?: { - fuelTx: { - height: string; - txHash: string; - timestamp: Date; - }; - }; - [WithdrawStatusType.WaitingCommittingToL1]?: { - dateExpectedToComplete: Date; - }; - [WithdrawStatusType.WaitingFinalization]?: { - dateExpectedToComplete: Date; - ethTx: { - height: string; - txHash: string; - timestamp: Date; - }; - }; - [WithdrawStatusType.ReadyToProcessWithdraw]?: { - transactionId: string; - nonce: string; - commitBlockId: string; - commitBlockHeight: string; - }; - [WithdrawStatusType.Finalized]?: { - ethTx: { - height: string; - txHash: string; - timestamp: Date; - }; - }; - }; -}; - -export type DepositResponse = { - type: ResponseType.Deposit; - from: string; - to: string; - amount: string; - assetId: string; - ethAssetId: string; - status: DepositStatusType; - statusInfo: { - [DepositStatusType.TransactionSent]?: { - ethTx: { - height: string; - txHash: string; - timestamp: Date; - }; - }; - [DepositStatusType.WaitingSync]?: { - dateExpectedToComplete: Date; - }; - [DepositStatusType.ReadyToProcessDeposit]?: { - nonce: string; - }; - [DepositStatusType.Finalized]?: {}; - }; -}; - -export type BridgeDepositResponse = EventRow & DepositResponse; -export type BridgeWithdrawResponse = EventRow & WithdrawResponse; -export type BridgeResponse = BridgeDepositResponse | BridgeWithdrawResponse; -export type GraphQLBridgeResponse = { - nodes: BridgeResponse[]; - pageInfo: { - limit: number; - offset: number; - hasPreviousPage: boolean; - hasNextPage: boolean; - }; -}; diff --git a/packages/graphql/src/infra/dao/Contract.ts b/packages/graphql/src/infra/dao/Contract.ts deleted file mode 100644 index 7a6899cb9..000000000 --- a/packages/graphql/src/infra/dao/Contract.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { GQLContract } from '~/graphql/generated/sdk-provider'; - -export default class Contract { - id: number; - contract_hash: string; - data: any; - - constructor(contract: any) { - this.id = contract._id; - this.contract_hash = contract.contract_hash; - this.data = contract.data; - } - - toGQLNode(): GQLContract { - return { - ...this.data, - _id: this.id, - }; - } -} diff --git a/packages/graphql/src/infra/dao/ContractDAO.ts b/packages/graphql/src/infra/dao/ContractDAO.ts deleted file mode 100644 index 462f17d80..000000000 --- a/packages/graphql/src/infra/dao/ContractDAO.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { DatabaseConnectionReplica } from '../database/DatabaseConnectionReplica'; -import type PaginatedParams from '../paginator/PaginatedParams'; -import Contract from './Contract'; - -export default class ContractDAO { - databaseConnection: DatabaseConnectionReplica; - - constructor() { - this.databaseConnection = DatabaseConnectionReplica.getInstance(); - } - - async getByHash(hash: string) { - const contractData = ( - await this.databaseConnection.query( - ` - select - c.* - from - indexer.contracts c - where - c.contract_hash = $1 - `, - [hash.toLowerCase()], - ) - )[0]; - if (!contractData) return; - const contract = new Contract(contractData); - return contract; - } - - async getPaginatedContracts(paginatedParams: PaginatedParams) { - const direction = paginatedParams.direction === 'before' ? '<' : '>'; - const order = paginatedParams.direction === 'before' ? 'desc' : 'asc'; - const contractsData = await this.databaseConnection.query( - ` - select - * - from - indexer.contracts c - where - $1::integer is null or c._id ${direction} $1 - order by - c._id ${order} - limit 10 - `, - [paginatedParams.cursor], - ); - contractsData.sort((a: any, b: any) => { - return (a._id - b._id) * -1; - }); - const contracts: Contract[] = []; - for (const contractData of contractsData) { - contracts.push(new Contract(contractData)); - } - if (contracts.length === 0) { - return { - nodes: [], - edges: [], - pageInfo: { - hasNextPage: false, - hasPreviousPage: false, - endCursor: '', - startCursor: '', - }, - }; - } - const startCursor = contractsData[0]._id; - const endCursor = contractsData[contractsData.length - 1]._id; - const hasPreviousPage = ( - await this.databaseConnection.query( - 'select exists(select 1 from indexer.contracts where _id < $1)', - [endCursor], - ) - )[0].exists; - const hasNextPage = ( - await this.databaseConnection.query( - 'select exists(select 1 from indexer.contracts where _id > $1)', - [startCursor], - ) - )[0].exists; - const newNodes = contracts.map((n) => n.toGQLNode()); - const edges = newNodes.map((node) => ({ - node, - cursor: paginatedParams.cursor, - })); - const paginatedResults = { - nodes: newNodes, - edges, - pageInfo: { - hasNextPage, - hasPreviousPage, - endCursor, - startCursor, - }, - }; - return paginatedResults; - } -} diff --git a/packages/graphql/src/infra/dao/CosmosDAO.ts b/packages/graphql/src/infra/dao/CosmosDAO.ts deleted file mode 100644 index 5cdc08aee..000000000 --- a/packages/graphql/src/infra/dao/CosmosDAO.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { DatabaseConnectionReplica } from '../database/DatabaseConnectionReplica'; - -export default class CosmosDAO { - databaseConnection: DatabaseConnectionReplica; - - constructor() { - this.databaseConnection = DatabaseConnectionReplica.getInstance(); - } - - async getCosmosEvents(type: string, key: string, value: string) { - const events = await this.databaseConnection.query( - 'select r.*, e.* from indexer.cosmos_responses r join indexer.cosmos_events e on (e.cosmos_response_id = r._id) where type = $1 and key = $2 and value = $3', - [type, key, value], - ); - return events; - } -} diff --git a/packages/graphql/src/infra/dao/L1DAO.ts b/packages/graphql/src/infra/dao/L1DAO.ts deleted file mode 100644 index 95f0999a2..000000000 --- a/packages/graphql/src/infra/dao/L1DAO.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { DatabaseConnectionReplica } from '../database/DatabaseConnectionReplica'; - -export default class L1DAO { - databaseConnection: DatabaseConnectionReplica; - - constructor() { - this.databaseConnection = DatabaseConnectionReplica.getInstance(); - } - - async getContractEvent( - contractHash: string, - event: string, - key: string, - value: string, - ) { - const events = await this.databaseConnection.query( - 'select * from indexer.contract_l1_logs l join indexer.contract_l1_args a on (a.contract_l1_log_id = l._id) where contract_hash = $1 and event = $2 and key = $3 and value = $4', - [contractHash, event, key, value], - ); - return events; - } -} diff --git a/packages/graphql/src/infra/dao/Predicate.ts b/packages/graphql/src/infra/dao/Predicate.ts deleted file mode 100644 index ef3a24a99..000000000 --- a/packages/graphql/src/infra/dao/Predicate.ts +++ /dev/null @@ -1,18 +0,0 @@ -export default class Predicate { - id: number; - address: string; - bytecode: any; - - constructor(predicate: any) { - this.id = predicate._id; - this.address = predicate.address; - this.bytecode = predicate.bytecode; - } - - toGQLNode() { - return { - bytecode: this.bytecode, - address: this.address, - }; - } -} diff --git a/packages/graphql/src/infra/dao/PredicateDAO.ts b/packages/graphql/src/infra/dao/PredicateDAO.ts deleted file mode 100644 index 2c1f3fb24..000000000 --- a/packages/graphql/src/infra/dao/PredicateDAO.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { DatabaseConnectionReplica } from '../database/DatabaseConnectionReplica'; -import Predicate from './Predicate'; - -export default class PredicateDAO { - databaseConnection: DatabaseConnectionReplica; - - constructor() { - this.databaseConnection = DatabaseConnectionReplica.getInstance(); - } - - async getByAddress(address: string) { - const predicateData = ( - await this.databaseConnection.query( - ` - select - p.* - from - indexer.predicates p - where - p.address = $1 - `, - [address.toLowerCase()], - ) - )[0]; - if (!predicateData) return; - const predicate = new Predicate(predicateData); - return predicate; - } -} diff --git a/packages/graphql/src/infra/dao/StakingDAO.ts b/packages/graphql/src/infra/dao/StakingDAO.ts deleted file mode 100644 index 7a556f36c..000000000 --- a/packages/graphql/src/infra/dao/StakingDAO.ts +++ /dev/null @@ -1,1620 +0,0 @@ -import { fuelsequencer } from '@fuel-infrastructure/fuelsequencerjs'; -import { MsgWithdrawDelegatorReward } from '@fuel-infrastructure/fuelsequencerjs/dist/codegen/cosmos/distribution/v1beta1/tx'; -import { - MsgBeginRedelegate, - MsgDelegate, - MsgUndelegate, -} from '@fuel-infrastructure/fuelsequencerjs/dist/codegen/cosmos/staking/v1beta1/tx'; -import { MsgWithdrawToEthereum } from '@fuel-infrastructure/fuelsequencerjs/dist/codegen/fuelsequencer/bridge/v1/tx'; -import dayjs from 'dayjs'; -import { ethers } from 'ethers'; -import { arrayify } from 'fuels'; -import { DatabaseConnectionReplica } from '../database/DatabaseConnectionReplica'; -import type PaginatedParams from '../paginator/PaginatedParams'; -import { convertEthAddressToSequencerUserAddress } from '../util/util'; -import { - BaseStatusType, - type ClaimRewardsResponse, - type CommitQueryItem, - type ComosTx, - type DelegateResponse, - type ProccessedWithdrawQueryItem, - type QueryItem, - type RedelegateResponse, - ResponseType, - type SequencerEventItem, - type UndelegateEvent, - type UndelegateResponse, - UndelegateStatusType, - type WithdrawEvent, - type WithdrawResponse, - WithdrawStatusType, -} from './StakingDAO.types'; -import { getTimeToFinalize } from './TEMP_StakingDAO'; - -// Time to synchronize in sequencer (minutes) -const TIME_TO_SYNCHRONIZE_IN_SEQUENCER = 30; - -// Time to commit to L1 (hours) -const TIME_TO_COMMIT_SEQUENCER_BLOCK_TO_L1 = 8; - -enum DecodersTypes { - MsgWithdrawToEthereum = '/fuelsequencer.bridge.v1.MsgWithdrawToEthereum', - MsgDelegate = '/cosmos.staking.v1beta1.MsgDelegate', - MsgUndelegate = '/cosmos.staking.v1beta1.MsgUndelegate', - MsgBeginRedelegate = '/cosmos.staking.v1beta1.MsgBeginRedelegate', - MsgWithdrawDelegatorReward = '/cosmos.distribution.v1beta1.MsgWithdrawDelegatorReward', -} - -const decodersMapping = { - [DecodersTypes.MsgWithdrawToEthereum]: MsgWithdrawToEthereum, - [DecodersTypes.MsgDelegate]: MsgDelegate, - [DecodersTypes.MsgUndelegate]: MsgUndelegate, - [DecodersTypes.MsgBeginRedelegate]: MsgBeginRedelegate, - [DecodersTypes.MsgWithdrawDelegatorReward]: MsgWithdrawDelegatorReward, -} as const; -type Param = ReturnType< - (typeof decodersMapping)[T]['decode'] ->; - -function normalizeCosmosQueryResponse( - items: Array, - preferredEventType?: string, -): Array> { - // Combine events with same event_index and same event_type - const tryParse = (value: string) => { - try { - if (typeof value !== 'string') return value; - return JSON.parse(value); - } catch (_error) { - return value; - } - }; - const result: Record> = {}; - for (const item of items) { - result[item.tx_hash] = result[item.tx_hash] || { - height: item.block_height, - txHash: item.tx_hash, - timestamp: item.timestamp, - id: item.id, - events: [], - }; - result[item.tx_hash].events[item.event_index] = { - ...result[item.tx_hash].events[item.event_index], - type: item.event_type, - [item.event_key]: tryParse(item.event_value), - }; - } - - return Object.values(result).map((tx) => { - const events = tx.events.filter((e) => !!e); - - // If a preferred event type is specified, filter events to only include that type - // and set the 'event' property to the first event of that type - if (preferredEventType) { - const filteredEvents = events.filter( - (e) => (e as any).type === preferredEventType, - ); - return { - ...tx, - events: filteredEvents, - event: filteredEvents.length > 0 ? filteredEvents[0] : events[0], - }; - } - - return { - ...tx, - events, - event: events[0], - }; - }); -} - -function getValidAddress(address: string) { - try { - return ethers.getAddress(address); - } catch (_error) { - throw new Error( - 'Invalid address format, expected a valid Ethereum address', - ); - } -} - -export default class StakingDAO { - databaseConnection: DatabaseConnectionReplica; - private singleQueryCounter = 0; - private batchQueryCounter = 0; - private skippedQueryCounter = 0; - - constructor() { - this.databaseConnection = DatabaseConnectionReplica.getInstance(); - } - - // Method to get and reset counters for logging - getQueryCounters() { - const counters = { - singleQueries: this.singleQueryCounter, - batchQueries: this.batchQueryCounter, - skippedQueries: this.skippedQueryCounter, - }; - return counters; - } - - // Reset counters for next set of operations - resetQueryCounters() { - this.singleQueryCounter = 0; - this.batchQueryCounter = 0; - this.skippedQueryCounter = 0; - } - - averageTimeDifferenceInSeconds(dates: Date[]) { - if (dates.length < 2) return 0; - const timestamps = dates - .map((date) => date.getTime()) - .sort((a, b) => b - a); - let totalDiff = 0; - for (let i = 1; i < timestamps.length; i++) { - totalDiff += timestamps[i - 1] - timestamps[i]; - } - const avgDiffInMilliseconds = totalDiff / (timestamps.length - 1); - return avgDiffInMilliseconds / 1000; - } - - async getLastCommittedBlock(): Promise< - CommitQueryItem & { commit_period: number } - > { - const blocks = await this.databaseConnection.query( - `SELECT - ca.value as cosmos_block_number, - cl."timestamp" as timestamp, - cl.tx_hash as tx_hash, - cl.block_height as eth_block_height - FROM - indexer.contract_l1_logs cl - JOIN - indexer.contract_l1_args ca - ON ca.contract_l1_log_id = cl._id - AND ca."key" = 'blockNumber' - ORDER BY - cl."timestamp" desc - LIMIT 10`, - [], - ); - const diff = this.averageTimeDifferenceInSeconds( - blocks.map((block) => block.timestamp), - ); - return { - commit_period: diff, - timestamp: blocks[0].timestamp, - tx_hash: blocks[0].tx_hash, - eth_block_height: blocks[0].eth_block_height, - cosmos_block_number: blocks[0].cosmos_block_number, - }; - } - - async blockIsSynced(blockHeight: number) { - const [blockIsSynced] = await this.databaseConnection.query( - `SELECT - cr.block_height as block_height - FROM - indexer.cosmos_events ce2 - JOIN indexer.cosmos_responses cr ON cr._id = ce2.cosmos_response_id - WHERE - ce2."type" = 'fuelsequencer.bridge.EventEthereumBlockSynced' - AND ce2."key" = 'block_number' - AND CAST(TRIM(BOTH '"' FROM ce2."value") AS INT) > $1 - LIMIT 1`, - [blockHeight], - ); - return blockIsSynced ? blockIsSynced.block_height > 0 : false; - } - - async cosmos_queryEvents( - blockHeight: number, - eventsQuery: Array<{ - type: string; - key: string; - value: string; - }>, - ) { - // Increment counter for single queries - this.singleQueryCounter++; - - // console.log( - // `[StakingDAO] Querying SINGLE block ${blockHeight} with ${eventsQuery.length} event queries (Total single queries: ${this.singleQueryCounter})`, - // ); - - const whereClause = eventsQuery - .map( - (eventQuery) => ` - ( - ce3."type" = '${eventQuery.type}' - AND ce3."key" = '${eventQuery.key}' - AND LOWER(ce3."value") = LOWER('${eventQuery.value}') - )`, - ) - .join(' OR '); - const whereClauseType = eventsQuery - .map((eventQuery) => `ce."type" = '${eventQuery.type}'`) - .join(' OR '); - const events: Array = await this.databaseConnection.query( - `SELECT - cr._id AS id, - cr.tx_hash AS tx_hash, - cr.block_height AS block_height, - cr.timestamp AS timestamp, - ce.index AS event_index, - ce.type AS event_type, - ce.key AS event_key, - ce.value AS event_value - FROM - indexer.cosmos_responses cr - JOIN - indexer.cosmos_events ce - ON ce.cosmos_response_id = cr._id - AND ( - ${whereClauseType} - ) - WHERE - cr.block_height IN ( - SELECT - cr.block_height - FROM - indexer.cosmos_events ce2 - JOIN - indexer.cosmos_responses cr - ON cr._id = ce2.cosmos_response_id - WHERE - ce2."type" = 'fuelsequencer.bridge.EventEthereumBlockSynced' - AND ce2."key" = 'block_number' - AND ce2."value" = $1 - ) - AND cr._id IN ( - SELECT - ce3.cosmos_response_id - FROM - indexer.cosmos_events ce3 - WHERE - ${whereClause} - ) - ORDER BY cr._id, ce.index`, - [`"${blockHeight}"`], - ); - - if (events.length === 0) { - return []; - } - - // Pass the preferred event type when there's only one query type - const preferredEventType = - eventsQuery.length === 1 ? eventsQuery[0].type : undefined; - return normalizeCosmosQueryResponse(events, preferredEventType); - } - - async cosmos_queryEventsMultipleBlocks( - blockHeights: number[], - eventsQueries: Array<{ - type: string; - key: string; - value: string; - queryId?: string; // Optional identifier to distinguish between different queries - }>, - ) { - // Increment counter for batch queries - this.batchQueryCounter++; - - // console.log( - // `[StakingDAO] Querying MULTIPLE blocks (${blockHeights.length} blocks) with ${eventsQueries.length} event queries (Total batch queries: ${this.batchQueryCounter})`, - // ); - - if (blockHeights.length === 0 || eventsQueries.length === 0) { - return {}; - } - - const whereClause = eventsQueries - .map( - (eventQuery) => ` - ( - ce3."type" = '${eventQuery.type}' - AND ce3."key" = '${eventQuery.key}' - AND LOWER(ce3."value") = LOWER('${eventQuery.value}') - )`, - ) - .join(' OR '); - - // Create placeholders for block heights with proper formatting - const blockHeightsPlaceholders = blockHeights - .map((_, index) => `$${index + 1}`) - .join(','); - const blockHeightsValues = blockHeights.map((height) => `"${height}"`); - - // First, get all cosmos blocks associated with the Ethereum blocks - const ethToCosmosBlocks: Record = {}; - - // Initialize with empty arrays for each Ethereum block - for (const blockHeight of blockHeights) { - ethToCosmosBlocks[blockHeight] = []; - } - - // Query for all cosmos blocks that contain these Ethereum blocks - const cosmosBlocksForEthBlocks = await this.databaseConnection.query( - `SELECT DISTINCT - cr.block_height AS cosmos_block_height, - CAST(TRIM(BOTH '"' FROM ce2.value) AS INT) AS eth_block_height - FROM - indexer.cosmos_responses cr - JOIN - indexer.cosmos_events ce2 - ON ce2.cosmos_response_id = cr._id - AND ce2."type" = 'fuelsequencer.bridge.EventEthereumBlockSynced' - AND ce2."key" = 'block_number' - AND ce2."value" IN (${blockHeightsPlaceholders}) - ORDER BY cr.block_height`, - blockHeightsValues, - ); - - // Populate the mapping - for (const mapping of cosmosBlocksForEthBlocks) { - const ethBlock = mapping.eth_block_height; - const cosmosBlock = mapping.cosmos_block_height; - - if (!ethToCosmosBlocks[ethBlock]) { - ethToCosmosBlocks[ethBlock] = []; - } - - ethToCosmosBlocks[ethBlock].push(cosmosBlock); - } - - // Log the relationship between Ethereum and Cosmos blocks - // console.log( - // '[StakingDAO] Ethereum->Cosmos block mappings:', - // Object.entries(ethToCosmosBlocks) - // .map(([eth, cosmos]) => `${eth}->[${cosmos.join(', ')}]`) - // .join('; '), - // ); - - // Now query for all the cosmos_response_ids that match our event types - // For each of the cosmos blocks we found above - const cosmosBlocks = Object.values(ethToCosmosBlocks).flat(); - - if (cosmosBlocks.length === 0) { - // console.log( - // '[StakingDAO] No cosmos blocks found for the ethereum blocks', - // ); - return {}; - } - - const cosmosBlocksPlaceholders = cosmosBlocks - .map((_, index) => `$${index + 1}`) - .join(','); - - const matchedResponseIds = await this.databaseConnection.query( - `SELECT DISTINCT - cr._id AS response_id, - cr.block_height AS cosmos_block_height, - ce3.type AS event_type, - CASE - ${eventsQueries - .map( - (eq) => - `WHEN ce3."type" = '${eq.type}' AND ce3."key" = '${eq.key}' THEN '${eq.queryId || eq.type}'`, - ) - .join('\n ')} - END AS query_type - FROM - indexer.cosmos_responses cr - JOIN - indexer.cosmos_events ce3 - ON ce3.cosmos_response_id = cr._id - AND (${whereClause}) - WHERE - cr.block_height IN (${cosmosBlocksPlaceholders}) - ORDER BY cr._id`, - cosmosBlocks, - ); - - if (matchedResponseIds.length === 0) { - // console.log('[StakingDAO] No matching events found in cosmos blocks'); - return {}; - } - - // Group response IDs by query type and store event types - const responseIdsByQueryType: Record< - string, - { ids: number[]; eventType: string } - > = {}; - - // Create a reverse mapping from cosmos blocks to ethereum blocks - const cosmosToEthBlocks: Record = {}; - - // Build the reverse mapping - for (const [ethBlock, cosmosBlocks] of Object.entries(ethToCosmosBlocks)) { - const ethNum = Number.parseInt(ethBlock, 10); - for (const cosmosBlock of cosmosBlocks) { - if (!cosmosToEthBlocks[cosmosBlock]) { - cosmosToEthBlocks[cosmosBlock] = []; - } - cosmosToEthBlocks[cosmosBlock].push(ethNum); - } - } - - // Process each matched response - for (const match of matchedResponseIds) { - if (match.query_type) { - // Store response info by query type - responseIdsByQueryType[match.query_type] = responseIdsByQueryType[ - match.query_type - ] || { - ids: [], - eventType: match.event_type, - }; - responseIdsByQueryType[match.query_type].ids.push(match.response_id); - } - } - - // Now fetch ALL events for these response IDs, not just the ones matching our criteria - const result: Record = {}; - - for (const [queryType, queryData] of Object.entries( - responseIdsByQueryType, - )) { - if (queryData.ids.length === 0) continue; - - const idPlaceholders = queryData.ids - .map((_, idx) => `$${idx + 1}`) - .join(','); - - const events: Array = await this.databaseConnection.query( - `SELECT - cr._id AS id, - cr.tx_hash AS tx_hash, - cr.block_height AS block_height, - cr.timestamp AS timestamp, - ce.index AS event_index, - ce.type AS event_type, - ce.key AS event_key, - ce.value AS event_value - FROM - indexer.cosmos_responses cr - JOIN - indexer.cosmos_events ce - ON ce.cosmos_response_id = cr._id - WHERE - cr._id IN (${idPlaceholders}) - ORDER BY cr._id, ce.index`, - queryData.ids, - ); - - if (events.length > 0) { - // Pass the preferred event type to normalizeCosmosQueryResponse - result[queryType] = normalizeCosmosQueryResponse( - events, - queryData.eventType, - ); - } else { - result[queryType] = []; - } - } - - // Add the mappings to the result - result.__ethToCosmosBlocks = ethToCosmosBlocks; - result.__cosmosToEthBlocks = cosmosToEthBlocks; - - return result; - } - - async processEvent( - address: string, - event: any, - prefetchedData?: { - withdrawEvents: ComosTx[]; - delegateEvents: ComosTx[]; - undelegateEvents: ComosTx[]; - withdrawRewardsEvents: ComosTx[]; - redelegateEvents: ComosTx[]; - lastCommittedBlock: CommitQueryItem & { commit_period: number }; - contractTimeToFinalizeInMinutes: number; - }, - ) { - const finalHistory: any[] = []; - - // Create a flexible mapping to handle different event signatures - const eventProcessingMap: Array<{ - type: string; - data: any; - }> = []; - - // Handle different event signatures - switch (event.signature) { - case 'Authorize(address,bytes)': { - const bytes = arrayify(event.decoded_args.data); - const eventDecoded = fuelsequencer.bridge.AuthorizeTx.decode(bytes); - - // For Authorize events, decode messages immediately and add to processing map - for (const message of eventDecoded.messages) { - let decodedData; - switch (message.typeUrl) { - case DecodersTypes.MsgDelegate: - decodedData = MsgDelegate.decode(message.value); - break; - case DecodersTypes.MsgUndelegate: - decodedData = MsgUndelegate.decode(message.value); - break; - case DecodersTypes.MsgBeginRedelegate: - decodedData = MsgBeginRedelegate.decode(message.value); - break; - case DecodersTypes.MsgWithdrawDelegatorReward: - decodedData = MsgWithdrawDelegatorReward.decode(message.value); - break; - case DecodersTypes.MsgWithdrawToEthereum: - decodedData = MsgWithdrawToEthereum.decode(message.value); - break; - default: - continue; // Skip unknown message types - } - - eventProcessingMap.push({ - type: message.typeUrl, - data: decodedData, - }); - } - break; - } - case 'Delegate(address,address,uint256)': { - eventProcessingMap.push({ - type: DecodersTypes.MsgDelegate, - data: { - delegatorAddress: event.decoded_args.delegator, - validatorAddress: event.decoded_args.validator, - amount: { - amount: event.decoded_args.amount, - }, - }, - }); - break; - } - case 'Redelegate(address,address,address,uint256)': { - eventProcessingMap.push({ - type: DecodersTypes.MsgBeginRedelegate, - data: { - delegatorAddress: event.decoded_args.delegator, - validatorSrcAddress: event.decoded_args.srcValidator, - validatorDstAddress: event.decoded_args.dstValidator, - amount: { - amount: event.decoded_args.amount, - }, - }, - }); - break; - } - case 'ClaimRewards(address,address)': { - eventProcessingMap.push({ - type: DecodersTypes.MsgWithdrawDelegatorReward, - data: { - delegatorAddress: event.decoded_args.delegator, - validatorAddress: event.decoded_args.validator, - }, - }); - break; - } - case 'Unbond(address,address,uint256)': { - eventProcessingMap.push({ - type: DecodersTypes.MsgUndelegate, - data: { - delegatorAddress: event.decoded_args.delegator, - validatorAddress: event.decoded_args.validator, - amount: { - amount: event.decoded_args.amount, - }, - }, - }); - break; - } - case 'Withdraw(address,address,uint256)': { - eventProcessingMap.push({ - type: DecodersTypes.MsgWithdrawToEthereum, - data: { - from: event.decoded_args.sender, - to: event.decoded_args.recipient, - amount: { - amount: event.decoded_args.amount, - }, - }, - }); - break; - } - default: - console.log(`Unknown event signature: ${event.signature}`); - return finalHistory; - } - - // Process each item in the mapping - for (const item of eventProcessingMap) { - switch (item.type) { - case DecodersTypes.MsgDelegate: { - finalHistory.push( - await this.createDelegateHistory( - address, - event, - item.data, - prefetchedData?.delegateEvents, - ), - ); - break; - } - case DecodersTypes.MsgUndelegate: { - finalHistory.push( - await this.createUndelegateHistory( - address, - event, - item.data, - prefetchedData?.undelegateEvents, - ), - ); - break; - } - case DecodersTypes.MsgBeginRedelegate: { - finalHistory.push( - await this.createRedelegateHistory( - address, - event, - item.data, - prefetchedData?.redelegateEvents, - ), - ); - break; - } - case DecodersTypes.MsgWithdrawDelegatorReward: { - finalHistory.push( - await this.createClaimRewardsHistory( - address, - event, - item.data, - prefetchedData?.withdrawRewardsEvents, - ), - ); - break; - } - case DecodersTypes.MsgWithdrawToEthereum: { - finalHistory.push( - await this.createWithdrawHistory( - address, - event, - item.data, - prefetchedData?.withdrawEvents, - prefetchedData?.lastCommittedBlock, - prefetchedData?.contractTimeToFinalizeInMinutes, - ), - ); - break; - } - } - } - return finalHistory; - } - - async createWithdrawHistory( - address: string, - event: SequencerEventItem, - withdraw: Param, - prefetchedWithdrawEvents?: ComosTx[], - prefetchedLastCommittedBlock?: CommitQueryItem & { commit_period: number }, - prefetchedContractTimeToFinalizeInMinutes?: number, - ): Promise { - const contractTimeToFinalizeInMinutes = - prefetchedContractTimeToFinalizeInMinutes || (await getTimeToFinalize()); - - const data: WithdrawResponse = { - id: event._id, - type: ResponseType.Withdraw, - from: withdraw.from, - to: withdraw.to, - amount: withdraw.amount.amount, - status: BaseStatusType.WaitingSync, - timestampToFinish: dayjs(event.timestamp) - .add(TIME_TO_SYNCHRONIZE_IN_SEQUENCER, 'minutes') - .add(TIME_TO_COMMIT_SEQUENCER_BLOCK_TO_L1, 'hours') - .add(contractTimeToFinalizeInMinutes, 'minutes') - .toDate() - .toISOString(), - statusInfo: { - [BaseStatusType.TransactionSent]: { - ethTx: { - height: event.block_height.toString(), - txHash: event.tx_hash, - timestamp: event.timestamp, - }, - }, - [BaseStatusType.WaitingSync]: { - dateExpectedToComplete: dayjs(event.timestamp) - .add(TIME_TO_SYNCHRONIZE_IN_SEQUENCER, 'minutes') - .toDate(), - }, - }, - }; - - // Use prefetched events if available, otherwise query the database - let withdrawEvents: ComosTx[] = []; - if (prefetchedWithdrawEvents) { - this.skippedQueryCounter++; - // console.log( - // `[StakingDAO] SKIPPING single cosmos_queryEvents call - using prefetched data for withdraw event at block ${event.block_height} (Total skipped: ${this.skippedQueryCounter})`, - // ); - withdrawEvents = prefetchedWithdrawEvents; - } else { - // console.log( - // `[StakingDAO] NO prefetched data available - making single cosmos_queryEvents call for withdraw event at block ${event.block_height}`, - // ); - withdrawEvents = await this.cosmos_queryEvents( - event.block_height, - [ - { - key: 'from', - type: 'fuelsequencer.bridge.EventWithdrawToEthereumReported', - value: `"${address.toLowerCase()}"`, - }, - ], - ); - } - - // Transaction sent but not synced with sequencer - if (withdrawEvents.length === 0) { - const blockIsSynced = await this.blockIsSynced(event.block_height); - if (blockIsSynced) { - data.status = BaseStatusType.Skipped; - data.statusInfo[BaseStatusType.Skipped] = { - message: - 'Event was sent but not synced with sequencer due to be invalid', - }; - } - return data; - } - - // TODO: once we treat multiple events per tx, we need to find the right one - const lastestCommittedBlock = - prefetchedLastCommittedBlock || (await this.getLastCommittedBlock()); - const withdrawSequencerTX = withdrawEvents[0]; - - // updates previous status with the tx that completed it - data.statusInfo[BaseStatusType.WaitingSync] = { - ...data.statusInfo[BaseStatusType.WaitingSync], - sequencerTx: { - height: withdrawSequencerTX.height, - txHash: withdrawSequencerTX.txHash, - timestamp: withdrawSequencerTX.timestamp, - }, - }; - - // move to new status and update its information - data.status = WithdrawStatusType.WaitingCommittingToL1; - data.statusInfo[WithdrawStatusType.WaitingCommittingToL1] = { - dateExpectedToComplete: dayjs(lastestCommittedBlock.timestamp) - .add(lastestCommittedBlock.commit_period, 'seconds') - .toDate(), - }; - - // Ensure that the event property contains the expected values - if (withdrawSequencerTX.event && 'nonce' in withdrawSequencerTX.event) { - data.nonce = withdrawSequencerTX.event.nonce; - } - - // now that sequencer computed the initial ethTx, we can more precisely estimate the time to finalize - data.timestampToFinish = dayjs(withdrawSequencerTX.timestamp) - .add(lastestCommittedBlock.commit_period, 'seconds') - .add(contractTimeToFinalizeInMinutes, 'minutes') - .toDate() - .toISOString(); - - const blockCommmiteds: Array = - await this.databaseConnection.query( - `SELECT - ca.value as cosmos_block_number, - cl."timestamp" as timestamp, - cl.tx_hash as tx_hash, - cl.block_height as eth_block_height - FROM - indexer.contract_l1_logs cl - JOIN - indexer.contract_l1_args ca - ON ca.contract_l1_log_id = cl._id - AND ca."key" = 'blockNumber' - AND CAST(ca."value" AS INT) >= $1 - ORDER BY cl."timestamp" ASC - LIMIT 1`, - [withdrawSequencerTX.height], - ); - const [blockCommited] = blockCommmiteds; - if (blockCommmiteds.length === 0) { - return data; - } - - // updates previous status with the tx that completed it - data.statusInfo[WithdrawStatusType.WaitingCommittingToL1] = { - ethTx: { - height: blockCommited.eth_block_height, - txHash: blockCommited.tx_hash, - timestamp: blockCommited.timestamp, - }, - }; - - // move to new status and update its information - data.status = WithdrawStatusType.WaitingFinalization; - data.statusInfo[WithdrawStatusType.WaitingFinalization] = { - dateExpectedToComplete: dayjs(blockCommited.timestamp) - .add(contractTimeToFinalizeInMinutes, 'minutes') - .toDate(), - }; - - // now that sequencer block is commited to L1, we can more precisely estimate the time to finalize - data.timestampToFinish = dayjs(blockCommited.timestamp) - .add(contractTimeToFinalizeInMinutes, 'minutes') - .toDate() - .toISOString(); - - // Check if the finalization period has passed based on timestampToFinish - if (dayjs().isAfter(dayjs(data.timestampToFinish))) { - // move to new status and update its information - data.status = WithdrawStatusType.ReadyToProcessWithdraw; - data.statusInfo[WithdrawStatusType.ReadyToProcessWithdraw] = { - proof: `fetch-proof?nonce=${data.nonce}`, - }; - } - - const [withdrawFinalized]: Array = - await this.databaseConnection.query( - `select - cl.block_height as block_height, - cl."timestamp" as timestamp, - cl.tx_hash as tx_hash - from - indexer.contract_l1_logs cl - join - indexer.contract_l1_args ca - ON ca.contract_l1_log_id = cl._id - AND ca."key" = 'nonce' - AND ca."value" = $1 - where - event = 'WithdrawalProcessed'`, - [data.nonce], - ); - - if (withdrawFinalized) { - // updates previous status with the tx that completed it - data.statusInfo[WithdrawStatusType.ReadyToProcessWithdraw] = { - ...data.statusInfo[WithdrawStatusType.ReadyToProcessWithdraw], - ethTx: { - height: withdrawFinalized.block_height, - txHash: withdrawFinalized.tx_hash, - timestamp: withdrawFinalized.timestamp, - }, - }; - - // move to new status and update its information - data.status = BaseStatusType.Finalized; - data.statusInfo[BaseStatusType.Finalized] = {}; - } - - return data; - } - - async createDelegateHistory( - address: string, - event: SequencerEventItem, - delegate: Param, - prefetchedDelegateEvents?: ComosTx[], - ): Promise { - const data: DelegateResponse = { - id: event._id, - type: ResponseType.Stake, - from: delegate.delegatorAddress, - amount: delegate.amount.amount, - validator: delegate.validatorAddress, - status: BaseStatusType.WaitingSync, - timestampToFinish: dayjs(event.timestamp) - .add(TIME_TO_SYNCHRONIZE_IN_SEQUENCER, 'minutes') - .toDate() - .toISOString(), - statusInfo: { - [BaseStatusType.TransactionSent]: { - ethTx: { - height: event.block_height.toString(), - txHash: event.tx_hash, - timestamp: event.timestamp, - }, - }, - [BaseStatusType.WaitingSync]: { - dateExpectedToComplete: dayjs(event.timestamp) - .add(TIME_TO_SYNCHRONIZE_IN_SEQUENCER, 'minutes') - .toDate(), - }, - }, - }; - - // Use prefetched events if available, otherwise query the database - let delegateTX; - if (prefetchedDelegateEvents && prefetchedDelegateEvents.length > 0) { - this.skippedQueryCounter++; - // console.log( - // `[StakingDAO] SKIPPING single cosmos_queryEvents call - using prefetched data for delegate event at block ${event.block_height} (Total skipped: ${this.skippedQueryCounter})`, - // ); - delegateTX = prefetchedDelegateEvents[0]; - } else { - // console.log( - // `[StakingDAO] NO prefetched data available - making single cosmos_queryEvents call for delegate event at block ${event.block_height}`, - // ); - [delegateTX] = await this.cosmos_queryEvents(event.block_height, [ - { - key: 'delegator', - type: 'delegate', - value: address.toLowerCase(), - }, - ]); - } - - if (!delegateTX) { - const blockIsSynced = await this.blockIsSynced(event.block_height); - if (blockIsSynced) { - data.status = BaseStatusType.Skipped; - data.statusInfo[BaseStatusType.Skipped] = { - message: - 'Event was sent but not synced with sequencer due to be invalid', - }; - } - return data; - } - - // updates previous status with the tx that completed it - data.statusInfo[BaseStatusType.WaitingSync] = { - ...data.statusInfo[BaseStatusType.WaitingSync], - sequencerTx: { - height: delegateTX.height, - txHash: delegateTX.txHash, - timestamp: delegateTX.timestamp, - }, - }; - - // move to new status and update its information - data.status = BaseStatusType.Finalized; - data.statusInfo[BaseStatusType.Finalized] = {}; - return data; - } - - async createRedelegateHistory( - address: string, - event: SequencerEventItem, - delegate: Param, - prefetchedRedelegateEvents?: ComosTx[], - ): Promise { - const data: RedelegateResponse = { - id: event._id, - type: ResponseType.ReDelegate, - from: delegate.delegatorAddress, - amount: delegate.amount.amount, - toValidator: delegate.validatorDstAddress, - fromValidator: delegate.validatorSrcAddress, - timestampToFinish: dayjs(event.timestamp) - .add(TIME_TO_SYNCHRONIZE_IN_SEQUENCER, 'minutes') - .toDate() - .toISOString(), - status: BaseStatusType.WaitingSync, - statusInfo: { - [BaseStatusType.TransactionSent]: { - ethTx: { - height: event.block_height.toString(), - txHash: event.tx_hash, - timestamp: event.timestamp, - }, - }, - [BaseStatusType.WaitingSync]: { - dateExpectedToComplete: dayjs(event.timestamp) - .add(TIME_TO_SYNCHRONIZE_IN_SEQUENCER, 'minutes') - .toDate(), - }, - }, - }; - - const sequencerAddress = convertEthAddressToSequencerUserAddress(address); - - // Use prefetched events if available, otherwise query the database - let redelegateTX; - if (prefetchedRedelegateEvents && prefetchedRedelegateEvents.length > 0) { - this.skippedQueryCounter++; - // console.log( - // `[StakingDAO] SKIPPING single cosmos_queryEvents call - using prefetched data for redelegate event at block ${event.block_height} (Total skipped: ${this.skippedQueryCounter})`, - // ); - // Note: For redelegate, we check the tx hash rather than delegate type - const txHash = - data.statusInfo[BaseStatusType.TransactionSent]?.ethTx?.txHash || ''; - redelegateTX = prefetchedRedelegateEvents.find( - (evt) => evt.txHash === txHash, - ); - } else { - // console.log( - // `[StakingDAO] NO prefetched data available - making single cosmos_queryEvents call for redelegate event at block ${event.block_height}`, - // ); - [redelegateTX] = await this.cosmos_queryEvents(event.block_height, [ - { - type: 'redelegate', - key: 'destination_validator', - value: delegate.validatorDstAddress, - }, - { - type: 'withdraw_rewards', - key: 'delegator', - value: sequencerAddress!, - }, - ]); - } - - if (!redelegateTX) { - const blockIsSynced = await this.blockIsSynced(event.block_height); - if (blockIsSynced) { - data.status = BaseStatusType.Skipped; - data.statusInfo[BaseStatusType.Skipped] = { - message: - 'Event was sent but not synced with sequencer due to be invalid', - }; - } - return data; - } - - // updates previous status with the tx that completed it - data.statusInfo[BaseStatusType.WaitingSync] = { - ...data.statusInfo[BaseStatusType.WaitingSync], - sequencerTx: { - height: redelegateTX.height, - txHash: redelegateTX.txHash, - timestamp: redelegateTX.timestamp, - }, - }; - - // move to new status and update its information - data.status = BaseStatusType.Finalized; - data.statusInfo[BaseStatusType.Finalized] = {}; - - return data; - } - - async createClaimRewardsHistory( - address: string, - event: SequencerEventItem, - claimRewards: Param, - prefetchedWithdrawRewardsEvents?: ComosTx[], - ): Promise { - const data: ClaimRewardsResponse = { - id: event._id, - type: ResponseType.ClaimRewards, - from: claimRewards.delegatorAddress, - validator: claimRewards.validatorAddress, - timestampToFinish: dayjs(event.timestamp) - .add(TIME_TO_SYNCHRONIZE_IN_SEQUENCER, 'minutes') - .toDate() - .toISOString(), - status: BaseStatusType.WaitingSync, - statusInfo: { - [BaseStatusType.TransactionSent]: { - ethTx: { - height: event.block_height.toString(), - txHash: event.tx_hash, - timestamp: event.timestamp, - }, - }, - [BaseStatusType.WaitingSync]: { - dateExpectedToComplete: dayjs(event.timestamp) - .add(TIME_TO_SYNCHRONIZE_IN_SEQUENCER, 'minutes') - .toDate(), - }, - }, - }; - - const sequencerAddress = convertEthAddressToSequencerUserAddress(address); - - // Use prefetched events if available, otherwise query the database - let claimRewardsTX; - if ( - prefetchedWithdrawRewardsEvents && - prefetchedWithdrawRewardsEvents.length > 0 - ) { - this.skippedQueryCounter++; - // console.log( - // `[StakingDAO] SKIPPING single cosmos_queryEvents call - using prefetched data for claim rewards event at block ${event.block_height} (Total skipped: ${this.skippedQueryCounter})`, - // ); - claimRewardsTX = prefetchedWithdrawRewardsEvents[0]; - } else { - // console.log( - // `[StakingDAO] NO prefetched data available - making single cosmos_queryEvents call for claim rewards event at block ${event.block_height}`, - // ); - [claimRewardsTX] = await this.cosmos_queryEvents(event.block_height, [ - { - type: 'withdraw_rewards', - key: 'delegator', - value: sequencerAddress!, - }, - ]); - } - - if (!claimRewardsTX) { - const blockIsSynced = await this.blockIsSynced(event.block_height); - if (blockIsSynced) { - data.status = BaseStatusType.Skipped; - data.statusInfo[BaseStatusType.Skipped] = { - message: - 'Event was sent but not synced with sequencer due to be invalid', - }; - } - return data; - } - - // updates previous status with the tx that completed it - data.statusInfo[BaseStatusType.WaitingSync] = { - ...data.statusInfo[BaseStatusType.WaitingSync], - sequencerTx: { - height: claimRewardsTX.height, - txHash: claimRewardsTX.txHash, - timestamp: claimRewardsTX.timestamp, - }, - }; - - // move to new status and update its information - data.status = BaseStatusType.Finalized; - data.statusInfo[BaseStatusType.Finalized] = {}; - - return data; - } - - async createUndelegateHistory( - address: string, - event: SequencerEventItem, - undelegate: Param, - prefetchedUndelegateEvents?: ComosTx[], - ): Promise { - const data: UndelegateResponse = { - id: event._id, - type: ResponseType.Undelegate, - from: undelegate.delegatorAddress, - amount: undelegate.amount.amount, - validator: undelegate.validatorAddress, - timestampToFinish: dayjs(event.timestamp) - .add(TIME_TO_SYNCHRONIZE_IN_SEQUENCER, 'minutes') - .toDate() - .toISOString(), - status: BaseStatusType.WaitingSync, - statusInfo: { - [BaseStatusType.TransactionSent]: { - ethTx: { - height: event.block_height.toString(), - txHash: event.tx_hash, - timestamp: event.timestamp, - }, - }, - [BaseStatusType.WaitingSync]: { - dateExpectedToComplete: dayjs(event.timestamp) - .add(TIME_TO_SYNCHRONIZE_IN_SEQUENCER, 'minutes') - .toDate(), - }, - }, - }; - - // Use prefetched events if available, otherwise query the database - let undelegateTX; - if (prefetchedUndelegateEvents && prefetchedUndelegateEvents.length > 0) { - this.skippedQueryCounter++; - // console.log( - // `[StakingDAO] SKIPPING single cosmos_queryEvents call - using prefetched data for undelegate event at block ${event.block_height} (Total skipped: ${this.skippedQueryCounter})`, - // ); - undelegateTX = prefetchedUndelegateEvents[0]; - } else { - // console.log( - // `[StakingDAO] NO prefetched data available - making single cosmos_queryEvents call for undelegate event at block ${event.block_height}`, - // ); - [undelegateTX] = await this.cosmos_queryEvents( - event.block_height, - [ - { - type: 'unbond', - key: 'delegator', - value: address.toLowerCase(), - }, - ], - ); - } - - if (!undelegateTX) { - const blockIsSynced = await this.blockIsSynced(event.block_height); - if (blockIsSynced) { - data.status = BaseStatusType.Skipped; - data.statusInfo[BaseStatusType.Skipped] = { - message: - 'Event was sent but not synced with sequencer due to be invalid', - }; - } - return data; - } - - // updates previous status with the tx that completed it - data.statusInfo[BaseStatusType.WaitingSync] = { - ...data.statusInfo[BaseStatusType.WaitingSync], - sequencerTx: { - height: undelegateTX.height, - txHash: undelegateTX.txHash, - timestamp: undelegateTX.timestamp, - }, - }; - - // move to new status and update its information - data.status = UndelegateStatusType.WaitingUnbonding; - const dateToComplete = dayjs(undelegateTX.event.completion_time).toDate(); - data.statusInfo[UndelegateStatusType.WaitingUnbonding] = { - dateExpectedToComplete: dateToComplete, - }; - - // now that sequencer computed the initial ethTx, we can more precisely estimate the time to finalize unbondiong - data.timestampToFinish = dateToComplete.toISOString(); - - if (dayjs(undelegateTX.event.completion_time).isBefore(Date.now())) { - data.status = BaseStatusType.Finalized; - data.statusInfo[BaseStatusType.Finalized] = {}; - } - - return data; - } - - async eth_queryEvents( - address: string, - paginatedParams: PaginatedParams, - ): Promise { - const direction = paginatedParams.direction === 'before' ? '<' : '>'; - const order = paginatedParams.direction === 'before' ? 'desc' : 'asc'; - const events: Array = - await this.databaseConnection.query( - `select - log.tx_hash, - log.signature, - log._id, - log.block_height, - log.decoded_args, - log.timestamp - from - indexer.contract_l1_logs log - where - ( - ( - log._id in ( - select - distinct contract_l1_log_id - from - indexer.contract_l1_args - where - key = 'sender' and - value = $1 - ) and - signature IN ('Authorize(address,bytes)', 'Withdraw(address,address,uint256)') - ) OR - ( - log._id in ( - select - distinct contract_l1_log_id - from - indexer.contract_l1_args - where - key = 'delegator' and - value = $1 - ) and - signature IN ('Delegate(address,address,uint256)', 'Redelegate(address,address,address,uint256)', 'ClaimRewards(address,address)', 'Unbond(address,address,uint256)') - ) - ) and - ($2::integer is null or log._id ${direction} $2) - order by - log.block_height ${order} - limit $3 - `, - [address, paginatedParams.cursor, paginatedParams.last], - ); - - events.sort((a: any, b: any) => { - return b._id - a._id; - }); - - if (events.length === 0) { - return { - nodes: [], - edges: [], - pageInfo: { - hasNextPage: false, - hasPreviousPage: false, - endCursor: '', - startCursor: '', - }, - }; - } - const startCursor = events[0]._id; - const endCursor = events[events.length - 1]._id; - const hasPreviousPage = ( - await this.databaseConnection.query( - ` - select exists( - select - 1 - from - indexer.contract_l1_logs log - where - ( - ( - log._id in ( - select - distinct contract_l1_log_id - from - indexer.contract_l1_args - where - key = 'sender' and - value = $1 - ) and - signature IN ('Authorize(address,bytes)', 'Withdraw(address,address,uint256)') - ) OR - ( - log._id in ( - select - distinct contract_l1_log_id - from - indexer.contract_l1_args - where - key = 'delegator' and - value = $1 - ) and - signature IN ('Delegate(address,address,uint256)', 'Redelegate(address,address,address,uint256)', 'ClaimRewards(address,address)', 'Unbond(address,address,uint256)') - ) - ) and - log._id < $2) - `, - [address, endCursor], - ) - )[0].exists; - const hasNextPage = ( - await this.databaseConnection.query( - ` - select exists( - select - 1 - from - indexer.contract_l1_logs log - where - ( - ( - log._id in ( - select - distinct contract_l1_log_id - from - indexer.contract_l1_args - where - key = 'sender' and - value = $1 - ) and - signature IN ('Authorize(address,bytes)', 'Withdraw(address,address,uint256)') - ) OR - ( - log._id in ( - select - distinct contract_l1_log_id - from - indexer.contract_l1_args - where - key = 'delegator' and - value = $1 - ) and - signature IN ('Delegate(address,address,uint256)', 'Redelegate(address,address,address,uint256)', 'ClaimRewards(address,address)', 'Unbond(address,address,uint256)') - ) - ) and - log._id > $2) - `, - [address, startCursor], - ) - )[0].exists; - return { - nodes: events, - edges: [], - pageInfo: { - hasNextPage, - hasPreviousPage, - endCursor, - startCursor, - }, - }; - } - - async eth_queryEvent(eventId: number): Promise { - const [event] = await this.databaseConnection.query( - ` - select - log.tx_hash, - log.signature, - log._id, - log.block_height, - log.decoded_args, - log.timestamp, - arg.value - from - indexer.contract_l1_logs log - left join indexer.contract_l1_args arg on ( - log._id = arg.contract_l1_log_id and - ( - (arg.key = 'sender' and log.signature IN ('Authorize(address,bytes)', 'Withdraw(address,address,uint256)')) OR - (arg.key = 'delegator' and log.signature IN ('Delegate(address,address,uint256)', 'Redelegate(address,address,address,uint256)', 'ClaimRewards(address,address)', 'Unbond(address,address,uint256)')) - ) - ) - where - log._id = $1 - and - log.signature IN ('Authorize(address,bytes)', 'Delegate(address,address,uint256)', 'Redelegate(address,address,address,uint256)', 'ClaimRewards(address,address)', 'Unbond(address,address,uint256)', 'Withdraw(address,address,uint256)') - `, - [eventId], - ); - return event; - } - - async getEvents(rawAddress: string, paginatedParams: PaginatedParams) { - // Reset counters at start of new event query - this.resetQueryCounters(); - - const address = getValidAddress(rawAddress); - const events = await this.eth_queryEvents(address, paginatedParams); - - // Extract all block heights from events for batched query - const blockHeights = events.nodes.map((event: any) => event.block_height); - - const sequencerAddress = convertEthAddressToSequencerUserAddress(address); - - // Build the queries array with all event types we need to fetch - const eventsQueries = [ - { - key: 'from', - type: 'fuelsequencer.bridge.EventWithdrawToEthereumReported', - value: `"${address.toLowerCase()}"`, - queryId: 'withdraw', - }, - { - key: 'delegator', - type: 'delegate', - value: address.toLowerCase(), - queryId: 'delegate', - }, - { - type: 'unbond', - key: 'delegator', - value: address.toLowerCase(), - queryId: 'undelegate', - }, - ]; - - // Add withdraw rewards query if sequencer address exists - if (sequencerAddress) { - eventsQueries.push({ - type: 'withdraw_rewards', - key: 'delegator', - value: sequencerAddress, - queryId: 'withdraw_rewards', - }); - } - - // Pre-fetch all event types in a single query - const [ - allEventsResult, - lastCommittedBlock, - contractTimeToFinalizeInMinutes, - ] = await Promise.all([ - this.cosmos_queryEventsMultipleBlocks(blockHeights, eventsQueries), - this.getLastCommittedBlock(), - getTimeToFinalize(), - ]); - - // Extract individual event types - const withdrawEvents = allEventsResult.withdraw || []; - const delegateEvents = allEventsResult.delegate || []; - const undelegateEvents = allEventsResult.undelegate || []; - const withdrawRewardsEvents = allEventsResult.withdraw_rewards || []; - - // Extract the mapping from Ethereum block to Cosmos blocks - const ethToCosmosBlocks = allEventsResult.__ethToCosmosBlocks || {}; - - // Store all events by their cosmos block height for easy lookup - const cosmosBlockToEvents = new Map(); - - // Process all events and organize them by Cosmos block height - const allEventsArray = [ - ...withdrawEvents, - ...delegateEvents, - ...undelegateEvents, - ...withdrawRewardsEvents, - ]; - - for (const event of allEventsArray) { - const cosmosHeight = - typeof event.height === 'string' - ? Number.parseInt(event.height, 10) - : event.height; - - if (!cosmosBlockToEvents.has(cosmosHeight)) { - cosmosBlockToEvents.set(cosmosHeight, []); - } - - cosmosBlockToEvents.get(cosmosHeight)?.push(event); - } - - // Store the prefetched data by ETHEREUM block height - const prefetchedEventsByBlock: Record< - number, - { - withdrawEvents: any[]; - delegateEvents: any[]; - undelegateEvents: any[]; - withdrawRewardsEvents: any[]; - redelegateEvents: any[]; - } - > = {}; - - // Initialize each Ethereum block with empty arrays - for (const ethBlock of blockHeights) { - prefetchedEventsByBlock[ethBlock] = { - withdrawEvents: [], - delegateEvents: [], - undelegateEvents: [], - withdrawRewardsEvents: [], - redelegateEvents: [], - }; - - // Get all Cosmos blocks associated with this Ethereum block - const cosmosBlocks = ethToCosmosBlocks[ethBlock] || []; - - // For each Cosmos block, collect all relevant events - for (const cosmosBlock of cosmosBlocks) { - const eventsForBlock = cosmosBlockToEvents.get(cosmosBlock) || []; - - // Process each event and add to appropriate category - for (const event of eventsForBlock) { - if ( - event.event?.type === - 'fuelsequencer.bridge.EventWithdrawToEthereumReported' - ) { - prefetchedEventsByBlock[ethBlock].withdrawEvents.push(event); - } else if (event.event?.type === 'delegate') { - prefetchedEventsByBlock[ethBlock].delegateEvents.push(event); - } else if (event.event?.type === 'unbond') { - prefetchedEventsByBlock[ethBlock].undelegateEvents.push(event); - } else if (event.event?.type === 'withdraw_rewards') { - prefetchedEventsByBlock[ethBlock].withdrawRewardsEvents.push(event); - } else if (event.event?.type === 'redelegate') { - prefetchedEventsByBlock[ethBlock].redelegateEvents.push(event); - } - } - } - } - - // With parallel processing using Promise.all - - const historyPromises = events.nodes.map((event: any) => { - const blockHeight = event.block_height; - const prefetchedData = prefetchedEventsByBlock[blockHeight]; - return this.processEvent(address, event, { - ...prefetchedData, - lastCommittedBlock, - contractTimeToFinalizeInMinutes, - }); - }); - - const historyResults = await Promise.all(historyPromises); - - // Directly assign flattened results to events.nodes - events.nodes = historyResults.flat(); - - return events; - } - - async getEvent(eventId: number) { - const event = await this.eth_queryEvent(eventId); - if (!event) { - throw new Error('Event not found'); - } - const address = getValidAddress(event.value); - const [tx] = await this.processEvent(address, event); - return tx; - } -} diff --git a/packages/graphql/src/infra/dao/StakingDAO.types.ts b/packages/graphql/src/infra/dao/StakingDAO.types.ts deleted file mode 100644 index 7d0c5cb8c..000000000 --- a/packages/graphql/src/infra/dao/StakingDAO.types.ts +++ /dev/null @@ -1,198 +0,0 @@ -export type SequencerEventItem = { - _id: number; - tx_hash: string; - signature: string; - block_height: number; - timestamp: Date; - decoded_args: { - data: string; - }; -}; - -export type QueryItem = { - id: number; - tx_hash: string; - block_height: string; - timestamp: Date; - event_index: number; - event_type: string; - event_key: string; - event_value: string; -}; - -export type WithdrawEvent = { - type: string; - amount: { - amount: string; - denom: string; - }; - from: string; - to: string; - nonce: string; -}; - -export type UndelegateEvent = { - type: string; - validator: string; - delegator: string; - completion_time: string; -}; - -export type ComosTx = { - height: string; - txHash: string; - timestamp: Date; - events: Array; - event: T; -}; - -export type CommitQueryItem = { - cosmos_block_number: string; - timestamp: Date; - tx_hash: string; - eth_block_height: string; -}; - -export type ProccessedWithdrawQueryItem = { - block_height: string; - timestamp: Date; - tx_hash: string; -}; - -export enum ResponseType { - Withdraw = 'Withdraw', - Stake = 'Stake', - ReDelegate = 'ReDelegate', - Undelegate = 'Undelegate', - ClaimRewards = 'ClaimRewards', -} - -export enum WithdrawStatusType { - WaitingCommittingToL1 = 'WaitingCommittingToL1', - WaitingFinalization = 'WaitingFinalization', - ReadyToProcessWithdraw = 'ReadyToProcessWithdraw', -} - -export enum UndelegateStatusType { - WaitingUnbonding = 'WaitingUnbonding', -} - -export enum BaseStatusType { - TransactionSent = 'TransactionSent', - WaitingSync = 'WaitingSync', - Finalized = 'Finalized', - Skipped = 'Skipped', -} - -type EthTxStatusInfo = { - height: string; - txHash: string; - timestamp: Date; -}; -type SequencerTxStatusInfo = { - height: string; - txHash: string; - timestamp: Date; -}; - -type BaseStatusInfo = { - [BaseStatusType.TransactionSent]?: { - ethTx?: EthTxStatusInfo; - }; - [BaseStatusType.WaitingSync]?: { - dateExpectedToComplete?: Date; - sequencerTx?: SequencerTxStatusInfo; - }; - [BaseStatusType.Skipped]?: { - message: string; - }; - [BaseStatusType.Finalized]?: {}; -}; - -export type WithdrawResponse = StakingHistoryRow & { - type: ResponseType.Withdraw; - from: string; - to: string; - amount: string; - status: BaseStatusType | WithdrawStatusType; - statusInfo: BaseStatusInfo & { - [WithdrawStatusType.WaitingCommittingToL1]?: { - dateExpectedToComplete?: Date; - ethTx?: EthTxStatusInfo; - }; - [WithdrawStatusType.WaitingFinalization]?: { - dateExpectedToComplete?: Date; - ethTx?: EthTxStatusInfo; - }; - [WithdrawStatusType.ReadyToProcessWithdraw]?: { - proof?: string; - ethTx?: EthTxStatusInfo; - }; - }; - nonce?: string; -}; - -export type UndelegateResponse = StakingHistoryRow & { - type: ResponseType.Undelegate; - from: string; - amount: string; - validator: string; - status: BaseStatusType | UndelegateStatusType; - statusInfo: BaseStatusInfo & { - [UndelegateStatusType.WaitingUnbonding]?: { - dateExpectedToComplete?: Date; - }; - }; -}; - -export type DelegateResponse = StakingHistoryRow & { - type: ResponseType.Stake; - from: string; - amount: string; - validator: string; - status: BaseStatusType; - statusInfo: BaseStatusInfo; -}; - -export type RedelegateResponse = StakingHistoryRow & { - type: ResponseType.ReDelegate; - from: string; - amount: string; - toValidator: string; - fromValidator: string; - status: BaseStatusType; - statusInfo: BaseStatusInfo; -}; - -export type ClaimRewardsResponse = StakingHistoryRow & { - type: ResponseType.ClaimRewards; - from: string; - validator: string; - status: BaseStatusType; - statusInfo: BaseStatusInfo; -}; - -type StakingHistoryRow = { - id: number; - timestampToFinish?: string; -}; - -export type StakingHistory = Array< - StakingHistoryRow & - ( - | WithdrawResponse - | DelegateResponse - | RedelegateResponse - | UndelegateResponse - | ClaimRewardsResponse - ) ->; - -export type PrefetchedData = { - withdrawEvents?: ComosTx[]; - delegateEvents?: ComosTx[]; - undelegateEvents?: ComosTx[]; - withdrawRewardsEvents?: ComosTx[]; - lastCommittedBlock?: CommitQueryItem & { commit_period: number }; - contractTimeToFinalizeInMinutes?: number; -}; diff --git a/packages/graphql/src/infra/dao/TEMP_StakingDAO.ts b/packages/graphql/src/infra/dao/TEMP_StakingDAO.ts deleted file mode 100644 index 6c92cd182..000000000 --- a/packages/graphql/src/infra/dao/TEMP_StakingDAO.ts +++ /dev/null @@ -1,589 +0,0 @@ -import { fuelsequencer } from '@fuel-infrastructure/fuelsequencerjs'; -import { MsgWithdrawToEthereum } from '@fuel-infrastructure/fuelsequencerjs/dist/codegen/fuelsequencer/bridge/v1/tx'; -import { getCurrentNetworkContracts } from 'app-commons/stakingAddresses'; -import { ethers } from 'ethers'; -import { arrayify, bn } from 'fuels'; -import AbiFactory from '~/application/uc/IndexL1/abi/AbiFactory'; -import { env } from '~/config'; -import { logger } from '~/core/Logger'; -import DataCache from '../cache/DataCache'; - -// 10 Hours to commit -export const TIME_TO_COMMIT = 10 * 60 * 60; -// 30 minutes to sequencer indexer sync the info -export const TIME_TO_SEQUENCER_INDEXER_SYNC = 1800; - -const network = env.get('FUEL_CHAIN')!; -const currentNetworkContracts = getCurrentNetworkContracts(network); -const envPrefix = network === 'mainnet' ? 'mainnet' : 'testnet'; - -const COSMOS_URL_RPC = `https://rest.seq.${envPrefix}.fuel.network`; -const COSMOS_URL_INDEXER = `https://index-api.sequencer.${envPrefix}.fuel.network`; -const base = network === 'mainnet' ? 'mainnet' : 'sepolia'; -const ETH_PROVIDER_URL = `https://eth-${base}.g.alchemy.com/v2/${env.get('ALCHEMY_API_KEY')}`; -const ETH_PROVIDER = new ethers.JsonRpcProvider(ETH_PROVIDER_URL); -const fuelStreamXAbi: any = AbiFactory.create(network, 'FuelStreamX'); -const sequencerProxyAbi: any = AbiFactory.create(network, 'SequencerProxy'); - -function getValidAddress(address: string) { - try { - return ethers.getAddress(address); - } catch (_error) { - throw new Error( - 'Invalid address format, expected a valid Ethereum address', - ); - } -} - -interface StakingTransactionFactoryBase { - event: Omit & { - timestamp: number; - blockNumber: number; - amount: string; - txHash: string; - }; -} - -interface StakingTransactionFactoryError extends StakingTransactionFactoryBase { - error: true; - timeToFinalizeFromStart?: never; -} - -interface StakingTransactionFactory extends StakingTransactionFactoryBase { - error?: never; - timeToFinalizeFromStart: number; -} - -function stakingTransactionFactory({ - event, - error, - timeToFinalizeFromStart = Number.NEGATIVE_INFINITY, -}: StakingTransactionFactoryError | StakingTransactionFactory) { - return { - amount: event.amount, - from: event.from, - totalTimeToFinalize: timeToFinalizeFromStart, // @TODO: + time to block finalization ETH - status: { - current: WithdrawStatus.SyncingWithSequencer, - dateExpectedToFinalize: new Date( - secondsToMs(event.timestamp + timeToFinalizeFromStart), - ), - error, - all: { - [WithdrawStatus.WithdrawSent]: { - ethTx: { - height: event.blockNumber.toString(), - txHash: event.txHash, - timestamp: event.timestamp, - }, - dateExpectedToComplete: new Date(), - }, - [WithdrawStatus.SyncingWithSequencer]: { - dateExpectedToComplete: new Date( - new Date( - secondsToMs(event.timestamp + TIME_TO_SEQUENCER_INDEXER_SYNC), - ), - ), - }, - }, - }, - }; -} - -interface BridgeCommitmentProof { - total: number; - index: number; - leaf_hash: string; - aunts: string[]; -} - -interface LastResultsProof { - total: number; - index: number; - leaf_hash: string; - aunts: string[]; -} - -interface BridgeCommitmentLeaf { - height: number; - last_results_hash: string; -} - -interface GetSequencerCommitmentInclusionProofResponse { - proof: { - bridge_commitment_proof: BridgeCommitmentProof; - last_results_proof: LastResultsProof; - bridge_commitment_leaf: BridgeCommitmentLeaf; - tx_result_marshalled: string; - }; - bridge_commitment_proof_nonce: string; -} - -type Withdraw = { - TxHash: string; - Nonce: string; - FromAddress: string; - Denom: string; - Amount: string; - IsProvable: boolean; -}; - -enum WithdrawStatus { - WithdrawSent = 'Withdraw sent', - SyncingWithSequencer = 'Synchronizing with Sequencer', - SyncingWithL1 = 'Sequencer committing to L1', - WaitingFinalization = 'Waiting for finalization', - ReadyToProcessWithdraw = 'Ready for withdrawal', - Finalized = 'Finalized', -} - -type StakingTransaction = { - from: string; - amount: string; - nonce?: string; - proof?: GetSequencerCommitmentInclusionProofResponse; - status: StatusWithETA; - totalTimeToFinalize: number; -}; - -type StatusWithETA = { - current: WithdrawStatus; - dateExpectedToFinalize: Date; - error?: boolean; - all: Partial>; -}; - -type StatusStep = { - ethTx?: { - height: string; - txHash: string; - timestamp: number; - }; - sequencerTx?: { - height: string; - txHash: string; - timestamp: number; - }; - dateExpectedToComplete?: Date; -}; - -// 60 minutes -const CACHE_EXPIRATION = 1000 * 60 * 60; - -function secondsToMs(seconds: number) { - return seconds * 1000; -} - -async function fetchSequencer(pathname: string) { - const url = new URL(pathname, COSMOS_URL_RPC); - const result = await fetch(url.toString()).then((response) => - response.json(), - ); - return result as T; -} - -async function fetchPendingWithdrawals(address: string) { - const url = new URL('/seq/withdrawals', COSMOS_URL_INDEXER); - url.searchParams.append('address', address); - const result: { Withdraws: null | Withdraw[] } = await fetch( - url.toString(), - ).then((response) => response.json()); - const withdraws = result?.Withdraws ?? []; - return withdraws.sort((a, b) => { - return Number(a.Nonce) > Number(b.Nonce) ? 1 : -1; - }); -} - -async function fetchWithdrawProof(nonce: string) { - const url = new URL('/seq/proof', COSMOS_URL_INDEXER); - url.searchParams.append('nonce', nonce); - const result: GetSequencerCommitmentInclusionProofResponse = await fetch( - url.toString(), - ).then((response) => response.json()); - return result; -} - -async function getTransactionOnSequencer(txHash: string) { - const data = await fetchSequencer<{ - tx_response: { - height: string; - timestamp: number; - }; - }>(`/cosmos/tx/v1beta1/txs/${txHash}`); - return data; -} - -async function queryContractEvents( - contractAddress: string, - contractABI: readonly any[], - eventName: string, - options: any = {}, -): Promise> { - try { - // Create contract interface - const contract = new ethers.Contract( - contractAddress, - contractABI, - ETH_PROVIDER, - ); - - // Get the event fragment from the contract interface - const eventFragment = contract.interface.getEvent(eventName)?.topicHash; - - // Query the events - const events = await ETH_PROVIDER.getLogs({ - address: options.address || contractAddress, - topics: [eventFragment ?? null].concat(options.topics || []), - fromBlock: options.fromBlock || 0, - toBlock: options.toBlock || 'finalized', - }); - - // Parse the events - return events.map((log) => { - const parsedLog = contract.interface.parseLog({ - topics: log.topics, - data: log.data, - }); - return { - ...parsedLog?.args, - blockNumber: log.blockNumber, - transactionHash: log.transactionHash, - logIndex: (log as any).logIndex, - }; - }); - } catch (error) { - console.error('Error querying events:', error); - throw error; - } -} - -export async function getTimeToFinalize() { - const result = await getTimeToFinalizeStrict(); - return result ?? 2880; // fallback to current mainnet value -} - -export async function getTimeToFinalizeStrict(): Promise { - const cachedTimeToFinalizeWithdraw = DataCache.getInstance().get( - 'time-to-finalize-withdraw-minutes', - ); - if (cachedTimeToFinalizeWithdraw) { - return Number(cachedTimeToFinalizeWithdraw); - } - - try { - const contract = new ethers.Contract( - currentNetworkContracts.FUEL_STREAM_X, - fuelStreamXAbi, - ETH_PROVIDER, - ); - const value = await contract.timeToFinalize(); - const valueInMinutes = Number(value) / 60; - DataCache.getInstance().save( - 'time-to-finalize-withdraw-minutes', - CACHE_EXPIRATION, - valueInMinutes.toString(), - ); - return Number(valueInMinutes); - } catch (error) { - logger.error('Staking: getTimeToFinalize', error); - return null; - } -} - -export async function getUnbondingTimeSeconds(): Promise { - const cached = DataCache.getInstance().get('unbonding-time-seconds'); - if (cached) { - return Number(cached); - } - - try { - const res = await fetch( - new URL('/cosmos/staking/v1beta1/params', COSMOS_URL_RPC), - ); - const data = await res.json(); - // Cosmos returns unbonding_time as a duration string like "1814400s" - const unbondingTimeStr: string = data?.params?.unbonding_time ?? ''; - const seconds = Number.parseInt(unbondingTimeStr.replace('s', ''), 10); - if (Number.isNaN(seconds)) { - logger.error( - 'Staking: getUnbondingTime', - 'Invalid unbonding_time format', - ); - return null; - } - DataCache.getInstance().save( - 'unbonding-time-seconds', - CACHE_EXPIRATION, - seconds.toString(), - ); - return seconds; - } catch (error) { - logger.error('Staking: getUnbondingTime', error); - return null; - } -} - -async function getEventsToSequencer(sender: string) { - // Contract details - const contractAddress = currentNetworkContracts.SEQUENCER_PROXY; - // Query events with options - const events = await queryContractEvents( - contractAddress, - sequencerProxyAbi, - 'Authorize', - { - fromBlock: 1, - toBlock: 'latest', - topics: [ethers.zeroPadValue(sender, 32)], - }, - ); - - for (const event of events) { - const block = await ETH_PROVIDER.getBlock(event.blockNumber); - (event as any).timestamp = block?.timestamp; - } - - return events.sort((a, b) => { - return (a as any)[0].timestamp > (b as any).timestamp ? -1 : 1; - }); -} - -async function getCommitsFromSequencer(contractTimeToFinalize: number) { - // add 8 day buffer to get more blocks and sure finalization is correct - const buffer = 8 * 24 * 60 * 60; - // consider 10 blocks per second - const amountOfBlocksToCheckCommits = (contractTimeToFinalize + buffer) / 10; - const latestBlockHeight = await ETH_PROVIDER.getBlockNumber(); - const contractAddress = currentNetworkContracts.FUEL_STREAM_X; - // Query events with options - const events = await queryContractEvents( - contractAddress, - fuelStreamXAbi, - 'HeadUpdate', - { - fromBlock: latestBlockHeight - amountOfBlocksToCheckCommits, - toBlock: 'finalized', - topics: [], - }, - ); - - for (const event of events) { - const block = await ETH_PROVIDER.getBlock(event.blockNumber); - (event as any).timestamp = block?.timestamp; - } - - // sort ASC by block number (oldest first) - return events.sort((a, b) => { - return (a as any)[0] > (b as any)[0] ? 1 : -1; - }); -} - -function getWithdrawToEthereumEvents( - event: Awaited>[0], -) { - const bytes = arrayify((event as any)[1]); - const txDecoded = fuelsequencer.bridge.AuthorizeTx.decode(bytes); - const messages: Array = []; - - for (const message of txDecoded.messages) { - switch (message.typeUrl) { - case '/fuelsequencer.bridge.v1.MsgWithdrawToEthereum': - messages.push(MsgWithdrawToEthereum.decode(message.value)); - break; - default: - null; - } - } - - return messages; -} - -export async function getStakingTransactions(_address: string) { - const address = getValidAddress(_address); - const now = new Date(); - const [authorizedEvents, withdrawalsOnSequencer, _contractTimeToFinalize] = - await Promise.all([ - getEventsToSequencer(address), - fetchPendingWithdrawals(address), - getTimeToFinalize(), - ]); - - // add 10 minutes to ensure finalization is correct - const contractTimeToFinalize = _contractTimeToFinalize + 10 * 60; - const commitsFromSequencer = await getCommitsFromSequencer( - contractTimeToFinalize, - ); - const lastCommit = commitsFromSequencer.slice(-1)[0]; - - const withdrawEventsEth: Array< - Omit & { - timestamp: number; - blockNumber: number; - amount: string; - txHash: string; - } - > = []; - for (const event of authorizedEvents) { - const messages = await getWithdrawToEthereumEvents(event); - messages.map((message) => { - withdrawEventsEth.push({ - ...message, - amount: message.amount.amount.toString(), - timestamp: (event as any).timestamp, - blockNumber: event.blockNumber, - txHash: event.transactionHash, - }); - }); - } - - const stakingTransactions: Array = []; - - // Retry Pattern, if the withdraw is not found on sequencer, we will retry with the next event - let withdrawSeqEventBuffer = 0; - - for (const [index, event] of withdrawEventsEth.entries()) { - try { - const timePassedFromLastCommit = - (new Date().getTime() - secondsToMs((lastCommit as any)?.timestamp)) / - 1000; - const estimatedTimeToNextCommit = - TIME_TO_COMMIT - timePassedFromLastCommit; - const timeToFinalizeFromStart = - contractTimeToFinalize + estimatedTimeToNextCommit; - - const stakingTransaction: any = stakingTransactionFactory({ - event, - timeToFinalizeFromStart, - }); - - const withdrawOnSequencer = - withdrawalsOnSequencer[withdrawSeqEventBuffer]; - if (withdrawOnSequencer) { - if (withdrawOnSequencer.Amount !== event.amount) { - stakingTransactions.push({ - ...stakingTransaction, - status: { - ...stakingTransaction.status, - error: true, - }, - }); - throw new Error(`--Amounts on EthIndex ${index} SeqIndex: ${withdrawSeqEventBuffer} do not match!-- - Sequencer: ${withdrawOnSequencer.TxHash} ${withdrawOnSequencer.Amount} - Ethereum: ${event.txHash} ${event.amount} - `); - } - stakingTransaction.status.current = WithdrawStatus.SyncingWithL1; - stakingTransaction.nonce = withdrawOnSequencer.Nonce; - - const [proof, txSequencer] = await Promise.all([ - stakingTransaction.nonce - ? fetchWithdrawProof(stakingTransaction.nonce) - : null, - getTransactionOnSequencer(withdrawOnSequencer.TxHash), - ]); - - if (proof) { - stakingTransaction.proof = proof; - } - const sequencerTx = { - height: txSequencer.tx_response.height, - txHash: withdrawOnSequencer.TxHash, - timestamp: - new Date(txSequencer.tx_response.timestamp).getTime() / 1000, - }; - - stakingTransaction.status.all[WithdrawStatus.SyncingWithSequencer] = { - ...stakingTransaction.status.all[WithdrawStatus.SyncingWithSequencer], - dateExpectedToComplete: new Date(), - sequencerTx, - }; - - const timeToSequencerCommitOnL1 = - new Date().getTime() + secondsToMs(estimatedTimeToNextCommit); - stakingTransaction.status.all[WithdrawStatus.SyncingWithL1] = { - dateExpectedToComplete: new Date( - secondsToMs(event.timestamp) + - secondsToMs(estimatedTimeToNextCommit), - ), - }; - - // Time to finalize from sequencer tx to end - const timeToFinishFromSequencerTx = - timeToSequencerCommitOnL1 + secondsToMs(contractTimeToFinalize); - - stakingTransaction.status.dateExpectedToFinalize = new Date( - timeToFinishFromSequencerTx, - ); - - const commit = commitsFromSequencer.find( - (commit) => - (commit as any)['0'] >= Number(txSequencer.tx_response.height), - ); - if (commit) { - stakingTransaction.status.dateExpectedToFinalize = new Date( - secondsToMs((commit as any)?.timestamp) + - secondsToMs(contractTimeToFinalize), - ); - - stakingTransaction.status.all[WithdrawStatus.SyncingWithL1] = { - ...stakingTransaction.status.all[WithdrawStatus.SyncingWithL1], - ethTx: { - height: commit.blockNumber.toString(), - txHash: commit.transactionHash, - timestamp: (commit as any).timestamp, - }, - dateExpectedToComplete: new Date(), - }; - stakingTransaction.status.current = - WithdrawStatus.WaitingFinalization; - stakingTransaction.status.all[WithdrawStatus.WaitingFinalization] = { - dateExpectedToComplete: - stakingTransaction.status.dateExpectedToFinalize, - }; - const diffUntilFinalize = Math.max( - stakingTransaction.status.dateExpectedToFinalize.getTime() - - now.getTime(), - 0, - ); - if (diffUntilFinalize === 0) { - stakingTransaction.status.current = - WithdrawStatus.ReadyToProcessWithdraw; - - const ethHexNonce = bn(stakingTransaction.nonce, 10).toHex(32); - const events = await queryContractEvents( - currentNetworkContracts.FUEL_STREAM_X, - fuelStreamXAbi, - 'WithdrawalProcessed', - { - fromBlock: 1, - toBlock: 'latest', - topics: [ethHexNonce], - }, - ); - - if (events.length > 0) { - stakingTransaction.status.current = WithdrawStatus.Finalized; - stakingTransaction.status.all[ - WithdrawStatus.ReadyToProcessWithdraw - ] = { - ethTx: { - height: events[0].blockNumber.toString(), - txHash: events[0].transactionHash, - timestamp: (events[0] as any).timestamp, - }, - }; - } - } - } - } - - stakingTransactions.push(stakingTransaction); - withdrawSeqEventBuffer++; - } catch (error) { - console.error(error); - } - } - return { - data: stakingTransactions, - }; -} diff --git a/packages/graphql/src/infra/dao/TransactionDAO.ts b/packages/graphql/src/infra/dao/TransactionDAO.ts deleted file mode 100644 index bfd164f12..000000000 --- a/packages/graphql/src/infra/dao/TransactionDAO.ts +++ /dev/null @@ -1,372 +0,0 @@ -import { isB256 } from 'fuels'; -import { TransactionEntity } from '~/domain/Transaction/TransactionEntity'; -import { DatabaseConnectionReplica } from '../database/DatabaseConnectionReplica'; -import type PaginatedParams from '../paginator/PaginatedParams'; - -const VALID_OWNER_TYPES = ['ACCOUNT', 'CONTRACT'] as const; -type OwnerType = (typeof VALID_OWNER_TYPES)[number]; - -/** - * Builds the SQL clause for filtering transactions by owner type. - * This is a static string mapping to prevent SQL injection. - * - * @param ownerType - The type of owner to filter by ('ACCOUNT' or 'CONTRACT') - * @returns SQL clause string or empty string if no filtering needed - */ -function buildOwnerTypeClause(ownerType?: string): string { - if (ownerType === 'ACCOUNT') { - return 'and not exists (select 1 from indexer.contracts c where c.contract_hash = ta.account_hash)'; - } - if (ownerType === 'CONTRACT') { - return 'and exists (select 1 from indexer.contracts c where c.contract_hash = ta.account_hash)'; - } - return ''; -} - -/** - * @param ownerType - The owner type value to validate - * @returns The validated ownerType (uppercase) or undefined - */ -function validateOwnerType(ownerType?: string): OwnerType | undefined { - if (ownerType === undefined || ownerType === null) { - return undefined; - } - const normalized = ownerType.toUpperCase() as OwnerType; - if (!VALID_OWNER_TYPES.includes(normalized)) { - throw new Error( - `Invalid ownerType value: ${ownerType}. Expected 'ACCOUNT', 'CONTRACT', or undefined.`, - ); - } - return normalized; -} - -export default class TransactionDAO { - databaseConnection: DatabaseConnectionReplica; - - constructor() { - this.databaseConnection = DatabaseConnectionReplica.getInstance(); - } - - async getByHash(txHash: string) { - const transactionData = ( - await this.databaseConnection.query( - ` - select - t.* - from - indexer.transactions t - where - t.tx_hash = $1 - `, - [txHash.toLowerCase()], - ) - )[0]; - if (!transactionData) return; - return TransactionEntity.createFromDAO(transactionData); - } - - async getPaginatedTransactionsByOwner( - accountHash: string, - paginatedParams: PaginatedParams, - ownerType?: string, - ) { - const validatedOwnerType = validateOwnerType(ownerType); - const ownerTypeClause = buildOwnerTypeClause(validatedOwnerType); - - const direction = paginatedParams.direction === 'before' ? '<' : '>'; - const order = paginatedParams.direction === 'before' ? 'desc' : 'asc'; - - const transactionsData = await this.databaseConnection.query( - ` - select t.*, ta._id as ta_id - from indexer.transactions_accounts ta - inner join indexer.transactions t on t.tx_hash = ta.tx_hash - where ta.account_hash = $1 and ($2::text is null or ta._id ${direction} $2) - ${ownerTypeClause} - order by ta._id ${order} - limit 10 - `, - [accountHash.toLowerCase(), paginatedParams.cursor], - ); - - transactionsData.sort((a: any, b: any) => { - return a.ta_id.localeCompare(b.ta_id) * -1; - }); - - if (transactionsData.length === 0) { - return { - nodes: [], - edges: [], - pageInfo: { - hasNextPage: false, - hasPreviousPage: false, - endCursor: '', - startCursor: '', - }, - }; - } - - const transactions = []; - for (const transactionData of transactionsData) { - transactions.push(TransactionEntity.createFromDAO(transactionData)); - } - - // Use ta_id (transactions_accounts._id) for cursors, not t._id - const startCursor = transactionsData[0].ta_id; - const endCursor = transactionsData[transactionsData.length - 1].ta_id; - - // Check pagination + position count (uses endCursor for accurate positioning) - const [paginationInfo] = await this.databaseConnection.query( - ` - select - exists(select 1 from indexer.transactions_accounts ta where ta.account_hash = $1 and ta._id < $2 ${ownerTypeClause} limit 1) as has_prev, - exists(select 1 from indexer.transactions_accounts ta where ta.account_hash = $1 and ta._id > $3 ${ownerTypeClause} limit 1) as has_next, - (select count(*) from (select 1 from indexer.transactions_accounts ta where ta.account_hash = $1 ${ownerTypeClause} limit 1001) sub) as total_count, - (select count(*) from (select 1 from indexer.transactions_accounts ta where ta.account_hash = $1 and ta._id > $2 ${ownerTypeClause} limit 1001) sub) as items_before_end - `, - [accountHash.toLowerCase(), endCursor, startCursor], - ); - - const hasPreviousPage = paginationInfo?.has_prev || false; - const hasNextPage = paginationInfo?.has_next || false; - // Capped at 1000 to avoid slow full counts; frontend shows "1000+" when totalCount === 1000 - const totalCount = Math.min(Number(paginationInfo?.total_count) || 0, 1000); - const endPosition = - Math.min(Number(paginationInfo?.items_before_end) || 0, 1000) + 1; - const pageSize = transactionsData.length; - const startPosition = endPosition - pageSize + 1; - - const newNodes = transactions.map((n) => n.toGQLListNode()); - - const edges = newNodes.map((node) => ({ - node, - cursor: paginatedParams.cursor, - })); - - return { - nodes: newNodes, - edges, - pageInfo: { - startCount: startPosition, - endCount: startPosition + pageSize - 1, - totalCount, - hasNextPage, - hasPreviousPage, - endCursor, - startCursor, - }, - }; - } - - async getPaginatedTransactions(paginatedParams: PaginatedParams) { - const direction = paginatedParams.direction === 'before' ? '<' : '>'; - const order = paginatedParams.direction === 'before' ? 'desc' : 'asc'; - const transactionsData = await this.databaseConnection.query( - ` - select - * - from - indexer.transactions t - where - $1::text is null or t._id ${direction} $1 - order by - t._id ${order} - limit $2 - `, - [paginatedParams.cursor, paginatedParams.last], - ); - transactionsData.sort((a: any, b: any) => { - return a._id.localeCompare(b._id) * -1; - }); - const transactions = []; - for (const transactionData of transactionsData) { - transactions.push(TransactionEntity.createFromDAO(transactionData)); - } - if (transactions.length === 0) { - return { - nodes: [], - edges: [], - pageInfo: { - hasNextPage: false, - hasPreviousPage: false, - endCursor: '', - startCursor: '', - }, - }; - } - const startCursor = transactionsData[0]._id; - const endCursor = transactionsData[transactionsData.length - 1]._id; - const hasPreviousPage = ( - await this.databaseConnection.query( - 'select exists(select 1 from indexer.transactions where _id < $1)', - [endCursor], - ) - )[0].exists; - const hasNextPage = ( - await this.databaseConnection.query( - 'select exists(select 1 from indexer.transactions where _id > $1)', - [startCursor], - ) - )[0].exists; - const newNodes = transactions.map((n) => n.toGQLListNode()); - - const edges = newNodes.map((node) => ({ - node, - cursor: paginatedParams.cursor, - })); - const paginatedResults = { - nodes: newNodes, - edges, - pageInfo: { - hasNextPage, - hasPreviousPage, - endCursor, - startCursor, - }, - }; - return paginatedResults; - } - - async accountExists(accountHash: string): Promise { - // Fast check: does this account have any transactions? - // Used for search validation only - const result = await this.databaseConnection.query( - 'SELECT EXISTS(SELECT 1 FROM indexer.transactions_accounts WHERE account_hash = $1) as exists', - [accountHash.toLowerCase()], - ); - - return result[0]?.exists || false; - } - - async getTransactionsByOwner(accountHash: string) { - const transactionsData = await this.databaseConnection.query( - ` - select - t.* - from - indexer.transactions t - where - t.tx_hash in ( - select distinct on (tx_hash) - tx_hash - from - indexer.transactions_accounts - where - account_hash = $1 - order by - tx_hash, _id desc - limit 5 - ) - order by - t._id desc - `, - [accountHash.toLowerCase()], - ); - const transactions = []; - for (const transactionData of transactionsData) { - transactions.push(TransactionEntity.createFromDAO(transactionData)); - } - return transactions; - } - - async getPaginatedTransactionsByBlockId( - blockId: string, - paginatedParams: PaginatedParams, - ) { - let height = blockId; - if (isB256(blockId)) { - const [block] = await this.databaseConnection.query( - ` - select - b._id - from - indexer.blocks b - where - b.id = $1 - `, - [blockId], - ); - height = block._id; - } - const direction = paginatedParams.direction === 'before' ? '<' : '>'; - const order = paginatedParams.direction === 'before' ? 'desc' : 'asc'; - const transactionsData = await this.databaseConnection.query( - ` - select - t.* - from - indexer.transactions t - where - t.block_id = $1 and - ($2::text is null or t._id ${direction} $2) - order by - t._id ${order} - limit - 10 - `, - [height, paginatedParams.cursor], - ); - transactionsData.sort((a: any, b: any) => { - return a._id.localeCompare(b._id) * -1; - }); - const transactions = []; - for (const transactionData of transactionsData) { - transactions.push(TransactionEntity.createFromDAO(transactionData)); - } - if (transactions.length === 0) { - return { - nodes: [], - edges: [], - pageInfo: { - hasNextPage: false, - hasPreviousPage: false, - endCursor: '', - startCursor: '', - }, - }; - } - const startCursor = transactionsData[0]._id; - const endCursor = transactionsData[transactionsData.length - 1]._id; - const hasPreviousPage = ( - await this.databaseConnection.query( - 'select exists(select 1 from indexer.transactions t where t._id < $1 and t.block_id = $2)', - [endCursor, height], - ) - )[0].exists; - const hasNextPage = ( - await this.databaseConnection.query( - 'select exists(select 1 from indexer.transactions t where t._id > $1 and t.block_id = $2)', - [startCursor, height], - ) - )[0].exists; - const [previousRows] = await this.databaseConnection.query( - 'select count(*)::integer as count from indexer.transactions where _id > $1 and block_id = $2', - [startCursor, height], - ); - const [totalCount] = await this.databaseConnection.query( - 'select count(*)::integer as count from indexer.transactions where block_id = $1', - [height], - ); - const newNodes = transactions.map((n) => n.toGQLListNode()); - - const edges = newNodes.map((node) => ({ - node, - cursor: paginatedParams.cursor, - })); - const paginatedResults = { - nodes: newNodes, - edges, - pageInfo: { - startCount: previousRows.count + 1, - endCount: previousRows.count + paginatedParams.last, - totalCount: totalCount.count, - hasNextPage, - hasPreviousPage, - endCursor, - startCursor, - }, - }; - - return paginatedResults; - } -} diff --git a/packages/graphql/src/infra/dao/utils.test.ts b/packages/graphql/src/infra/dao/utils.test.ts deleted file mode 100644 index ad4fd6356..000000000 --- a/packages/graphql/src/infra/dao/utils.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { - convertToUsd, - removeExtraDecimals, - removeScientificNotation, -} from './utils'; - -test('Should remove scientific notation', () => { - expect(removeScientificNotation(0.0000000000001)).toBe('0.0000000000001'); - expect(removeScientificNotation(0.0000000000002798798)).toBe( - '0.0000000000002798798', - ); -}); - -test('Should remove extra decimals', () => { - expect(removeExtraDecimals('0.0000000000017897987')).toBe('0.000000000001'); - expect(removeExtraDecimals('1.11111')).toBe('1.11111'); - expect(removeExtraDecimals('0.0000101010101')).toBe('0.00001'); - expect(removeExtraDecimals('0.000028')).toBe('0.00002'); - expect(removeExtraDecimals('0.00008')).toBe('0.00008'); - expect(removeExtraDecimals('0')).toBe('0'); - expect(removeExtraDecimals('10000')).toBe('10000'); -}); - -test('Should format to usd', () => { - expect(convertToUsd('1', 9, 1).formatted).toBe('$0.000000001'); - expect(convertToUsd('100', 9, 3088.54).formatted).toBe('$0.0003'); - expect(convertToUsd('4763069935', 9, 3088.54).formatted).toBe('$14,710.93'); - expect(convertToUsd('50914437160339649', 9, 0.058969).formatted).toBe( - '$3,002,373.44', - ); - expect(convertToUsd('50914437160339649', 9, 0.000000001).formatted).toBe( - '$0.05', - ); -}); - -test('Should handle zero and no rate cases', () => { - expect(convertToUsd('0', 9, 1)).toEqual({ value: 0, formatted: '$0' }); - - expect(convertToUsd(null as any, 9, 1)).toEqual({ - value: 0, - formatted: '$0', - }); - - expect(convertToUsd(undefined as any, 9, 1)).toEqual({ - value: 0, - formatted: '$0', - }); - - expect(convertToUsd('1000', 9, 0)).toEqual({ value: 0, formatted: '$0' }); - expect(convertToUsd('0', 9, 0)).toEqual({ value: 0, formatted: '$0' }); - expect(convertToUsd(null as any, 9, 0)).toEqual({ - value: 0, - formatted: '$0', - }); - expect(convertToUsd(undefined as any, 9, 0)).toEqual({ - value: 0, - formatted: '$0', - }); -}); - -test('Should handle very small numbers', () => { - expect(convertToUsd('1', 18, 0.000000001).formatted).toBe('$0.000000001'); - expect(convertToUsd('1', 18, 0.0000000001).formatted).toBe('$0.0000000001'); -}); diff --git a/packages/graphql/src/infra/dao/utils.ts b/packages/graphql/src/infra/dao/utils.ts index ab1ba8799..8ac5e07bf 100644 --- a/packages/graphql/src/infra/dao/utils.ts +++ b/packages/graphql/src/infra/dao/utils.ts @@ -1,69 +1,5 @@ import { type BN, bn } from 'fuels'; -export function roundToNearest(time: number, roundUp = false): number { - const msInHour = 60 * 60 * 1000; - return roundUp - ? Math.ceil(time / msInHour) * msInHour - : Math.floor(time / msInHour) * msInHour; -} - -// General interval creation function -export function createIntervals( - startTime: number, - endTime: number, - unit: 'minute' | 'hour' | 'day', - intervalSize: number, -): Array<{ start: Date; end: Date; txCount: number; totalGas: number }> { - const roundedStartTime = roundToNearest(startTime); - const roundedEndTime = roundToNearest(endTime, true); - - const intervals: Array<{ - start: Date; - end: Date; - txCount: number; - totalGas: number; - }> = []; - - let currentTime = roundedStartTime; - - // Handle minute, hour, and day intervals - const msInUnit = { - minute: 60 * 1000, - hour: 60 * 60 * 1000, - day: 24 * 60 * 60 * 1000, - }; - - const intervalDuration = intervalSize * msInUnit[unit]; - - while (currentTime < roundedEndTime) { - const startInterval = new Date(currentTime); - const endInterval = new Date(currentTime + intervalDuration); - intervals.push({ - start: startInterval, - end: endInterval, - txCount: 0, - totalGas: 0, - }); - currentTime += intervalDuration; - } - - return intervals; -} - -export function removeScientificNotation(value: number) { - const valueString = String(value); - if (valueString.includes('e') || valueString.includes('E')) { - return value.toFixed(20).replace(/\.?0+$/, ''); - } - return String(value); -} - -export function removeExtraDecimals(value: string) { - const numberOfZeros = String(value).match(/(0\.0*)/)?.[0].length || 0; - if (!numberOfZeros) return value; - return String(value).slice(0, numberOfZeros + 1); -} - const MONEY_PRECISION = 2; function countDecimals(value: number): number { diff --git a/packages/graphql/src/infra/database/DatabaseConnection.ts b/packages/graphql/src/infra/database/DatabaseConnection.ts deleted file mode 100644 index 21ea50602..000000000 --- a/packages/graphql/src/infra/database/DatabaseConnection.ts +++ /dev/null @@ -1,124 +0,0 @@ -import { Pool } from 'pg'; -import { env } from '~/config'; - -const DB_HOST = env.get('DB_HOST'); -const DB_PORT = env.get('DB_PORT'); -const DB_USER = env.get('DB_USER'); -const DB_PASS = env.get('DB_PASS'); -const DB_NAME = env.get('DB_NAME'); - -export class DatabaseConnection { - private static instance: DatabaseConnection; - private pool: Pool; - - constructor() { - const config = { - host: DB_HOST as string, - port: Number(DB_PORT) as number, - user: DB_USER as string, - password: DB_PASS as string, - database: DB_NAME as string, - ssl: - process.env.NODE_ENV === 'production' - ? { rejectUnauthorized: false } - : false, - max: 25, - min: 2, - idleTimeoutMillis: 30000, - connectionTimeoutMillis: 10000, - }; - this.pool = new Pool(config); - } - - static getInstance() { - if (!DatabaseConnection.instance) { - DatabaseConnection.instance = new DatabaseConnection(); - } - return DatabaseConnection.instance; - } - - async query(statement: string, params: any) { - const connection = await this.pool.connect(); - try { - const result = await connection.query(statement, params); - return result.rows; - } catch (error) { - try { - await connection.query('ROLLBACK'); - } catch {} - throw error; - } finally { - connection.release(); - } - } - - /** - * Execute a query with per-session statement_timeout and lock_timeout. - * - * REFRESH MATERIALIZED VIEW CONCURRENTLY cannot run inside a transaction block. - * For those queries, timeouts are applied as session-level SET commands and - * reset afterward. For all other queries, SET LOCAL inside BEGIN/COMMIT is used - * so timeouts don't leak to other connections. - */ - async queryWithTimeout( - statement: string, - params: any, - statementTimeoutMs: number, - lockTimeoutMs: number, - ) { - // VACUUM and REFRESH MATERIALIZED VIEW CONCURRENTLY cannot run inside a transaction block - const requiresNoTransaction = - /REFRESH\s+MATERIALIZED\s+VIEW\s+CONCURRENTLY/i.test(statement) || - /^\s*VACUUM\b/i.test(statement); - const connection = await this.pool.connect(); - try { - if (requiresNoTransaction) { - // Cannot use BEGIN/COMMIT — apply timeouts at session level and reset after - await connection.query(`SET statement_timeout = ${statementTimeoutMs}`); - await connection.query(`SET lock_timeout = ${lockTimeoutMs}`); - const result = await connection.query(statement, params); - await connection.query('RESET statement_timeout'); - await connection.query('RESET lock_timeout'); - return result.rows; - } - await connection.query('BEGIN'); - await connection.query( - `SET LOCAL statement_timeout = ${statementTimeoutMs}`, - ); - await connection.query(`SET LOCAL lock_timeout = ${lockTimeoutMs}`); - const result = await connection.query(statement, params); - await connection.query('COMMIT'); - return result.rows; - } catch (error) { - if (!requiresNoTransaction) { - try { - await connection.query('ROLLBACK'); - } catch {} - } else { - try { - await connection.query('RESET statement_timeout'); - await connection.query('RESET lock_timeout'); - } catch {} - } - throw error; - } finally { - connection.release(); - } - } - - async executeTransaction(queries: { statement: string; params: any }[]) { - const connection = await this.pool.connect(); - try { - await connection.query('begin'); - for (const query of queries) { - await connection.query(query.statement, query.params); - } - await connection.query('commit'); - } catch (e: any) { - await connection.query('rollback'); - throw e; - } finally { - connection.release(); - } - } -} diff --git a/packages/graphql/src/infra/database/DatabaseConnectionReplica.ts b/packages/graphql/src/infra/database/DatabaseConnectionReplica.ts deleted file mode 100644 index 434af614a..000000000 --- a/packages/graphql/src/infra/database/DatabaseConnectionReplica.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { Pool } from 'pg'; -import { env } from '~/config'; - -const DB_HOST = env.get('DB_HOST_REPLICA') || env.get('DB_HOST'); -const DB_PORT = env.get('DB_PORT_REPLICA') || env.get('DB_PORT'); -const DB_USER = env.get('DB_USER_REPLICA') || env.get('DB_USER'); -const DB_PASS = env.get('DB_PASS_REPLICA') || env.get('DB_PASS'); -const DB_NAME = env.get('DB_NAME_REPLICA') || env.get('DB_NAME'); - -export class DatabaseConnectionReplica { - private static instance: DatabaseConnectionReplica; - private pool: Pool; - - constructor() { - const config = { - host: DB_HOST as string, - port: Number(DB_PORT) as number, - user: DB_USER as string, - password: DB_PASS as string, - database: DB_NAME as string, - // Disable SSL for local development - ssl: - process.env.NODE_ENV === 'production' - ? { rejectUnauthorized: false } - : false, - max: 20, - min: 2, - idleTimeoutMillis: 30000, - connectionTimeoutMillis: 10000, - acquireTimeoutMillis: 10000, - allowExitOnIdle: false, - }; - this.pool = new Pool(config); - } - - static getInstance() { - if (!DatabaseConnectionReplica.instance) { - DatabaseConnectionReplica.instance = new DatabaseConnectionReplica(); - } - return DatabaseConnectionReplica.instance; - } - - async query(statement: string, params: any) { - let connection; - try { - connection = await this.pool.connect(); - const result = await connection.query(statement, params); - return result.rows; - } catch (error) { - console.error('Database query error:', { - statement: statement.substring(0, 100), - error, - }); - throw error; - } finally { - if (connection) { - connection.release(); - } - } - } - - async executeTransaction(queries: { statement: string; params: any }[]) { - const connection = await this.pool.connect(); - try { - await connection.query('begin'); - for (const query of queries) { - await connection.query(query.statement, query.params); - } - await connection.query('commit'); - } catch (e: any) { - await connection.query('rollback'); - throw e; - } finally { - connection.release(); - } - } - - /** - * Execute multiple queries in a single transaction with custom planner settings. - * Settings are applied with SET LOCAL and only affect this transaction. - * - * @param settings - PostgreSQL settings to apply - * @param queries - Queries to execute sequentially - * @returns Array of result sets - */ - async batchQueryWithSettings( - settings: { name: string; value: string }[], - queries: { statement: string; params: any }[], - ) { - const connection = await this.pool.connect(); - try { - await connection.query('BEGIN'); - - for (const setting of settings) { - await connection.query(`SET LOCAL ${setting.name} = ${setting.value}`); - } - - const results = []; - for (const query of queries) { - const result = await connection.query(query.statement, query.params); - results.push(result.rows); - } - - await connection.query('COMMIT'); - - return results; - } catch (error) { - await connection.query('ROLLBACK'); - console.error('Database batch query error:', { error }); - throw error; - } finally { - connection.release(); - } - } -} diff --git a/packages/graphql/src/infra/gateway/AssetGateway.ts b/packages/graphql/src/infra/gateway/AssetGateway.ts deleted file mode 100644 index bf1eeda74..000000000 --- a/packages/graphql/src/infra/gateway/AssetGateway.ts +++ /dev/null @@ -1,108 +0,0 @@ -import type { Provider } from 'fuels'; -import DataCache from '../cache/DataCache'; -import VerifiedAssets from '../cache/VerifiedAssets'; -import AssetDAO from '../dao/AssetDAO'; - -export default class AssetGateway { - async getAsset(assetId: string, chainId?: number, _provider?: Provider) { - const assetDAO = new AssetDAO(); - const nonVerifiedAsset = await assetDAO.getByAssetId(assetId); - const isNFT = - (nonVerifiedAsset?.decimals === 0 || - nonVerifiedAsset?.decimals === null) && - nonVerifiedAsset.totalSupply === '1' && - nonVerifiedAsset?.contractId; - const verifiedAssets = await VerifiedAssets.getInstance().fetch(); - for (const verifiedAsset of verifiedAssets) { - for (const network of verifiedAsset.networks) { - if (network.type === 'fuel') { - network.__typename = 'AssetNetworkFuel'; - } - if (network.type === 'ethereum') { - network.__typename = 'AssetNetworkEthereum'; - } - } - } - for (const verifiedAsset of verifiedAssets) { - for (const network of verifiedAsset.networks) { - if (network.chainId === chainId && network.assetId === assetId) { - let assetRate = DataCache.getInstance().get(`${assetId}-rate`); - if (!assetRate) { - assetRate = await assetDAO.getAssetsRateByAssetId(assetId); - DataCache.getInstance().save(`${assetId}-rate`, 300000, assetRate); - } - const asset = Object.assign(verifiedAsset, { - assetId: assetId, - contractId: network.contractId, - subId: nonVerifiedAsset?.subId, - decimals: network.decimals, - totalSupply: nonVerifiedAsset?.totalSupply, - suspicious: false, - verified: true, - metadata: nonVerifiedAsset?.metadata, - rate: assetRate?.rate || null, - }); - return asset; - } - } - if ( - nonVerifiedAsset && - (nonVerifiedAsset?.symbol === verifiedAsset.symbol || - nonVerifiedAsset?.name === verifiedAsset.name) - ) { - nonVerifiedAsset.suspicious = true; - } - } - if (!nonVerifiedAsset) return; - if (isNFT) { - const owner = await assetDAO.getAssetOwner(assetId); - const uri = this.parseUrl( - nonVerifiedAsset.metadata.uri || nonVerifiedAsset.metadata.URI, - ); - return Object.assign(nonVerifiedAsset, { - isNFT: true, - verified: false, - owner, - uri, - }); - } - return Object.assign(nonVerifiedAsset, { - verified: false, - isNFT, - }); - } - - parseUrl(url: string): string { - if (!url) return ''; - // Check if the input is a valid CID - const isCID = - /^(Qm[1-9A-HJ-NP-Za-km-z]{44}|b[A-Za-z2-7]{58}|B[A-Z2-7]{58}|z[1-9A-HJ-NP-Za-km-z]{48}|F[0-9A-F]{50})$/.test( - url, - ); - - if (isCID) { - // If it's a CID, convert it to an IPFS gateway URL - return `https://ipfs.io/ipfs/${url}`; - } - if (url.startsWith('ipfs://')) { - // Convert IPFS URI to a gateway URL - const cid = url.slice(7); - return `https://ipfs.io/ipfs/${cid}`; - } - if (url.startsWith('ar://')) { - // Convert Arweave URI to a gateway URL - const id = url.slice(5); - return `https://arweave.net/${id}`; - } - if (url.startsWith('data:')) { - // Data URIs are returned as-is - return url; - } - if (!url.startsWith('http://') && !url.startsWith('https://')) { - // Assume HTTPS for URLs without a protocol - return `https://${url}`; - } - // Return other URLs as-is - return url; - } -} diff --git a/packages/graphql/src/infra/paginator/PaginatedParams.ts b/packages/graphql/src/infra/paginator/PaginatedParams.ts deleted file mode 100644 index 9559c4427..000000000 --- a/packages/graphql/src/infra/paginator/PaginatedParams.ts +++ /dev/null @@ -1,24 +0,0 @@ -export default class PaginatedParams { - cursor: any; - direction: string; - last: number; - - constructor(params: any, maxPageSize = 50) { - this.cursor = null; - this.direction = 'before'; - if (params.after) { - this.cursor = params.after; - this.direction = 'after'; - } - if (params.before) { - this.cursor = params.before; - this.direction = 'before'; - } - - if (params.last > maxPageSize) { - throw new Error(`Maximum page size allowed is ${maxPageSize}`); - } - - this.last = params.last || 10; - } -} diff --git a/packages/graphql/src/infra/server/App.ts b/packages/graphql/src/infra/server/App.ts deleted file mode 100644 index b6a6d4a15..000000000 --- a/packages/graphql/src/infra/server/App.ts +++ /dev/null @@ -1,401 +0,0 @@ -import cors from 'cors'; -import express, { - type NextFunction, - type Request, - type Response, -} from 'express'; -import { Provider } from 'fuels'; -import GetAccountAssets from '~/application/uc/GetAccountAssets'; -import GetAssetsRate from '~/application/uc/GetAssetsRate'; -import GetMetrics from '~/application/uc/GetMetrics'; -import GetAssetDetails from '~/application/uc/IndexAsset/GetAssetDetails'; -import { env } from '~/config'; -import { logger } from '~/core/Logger'; -import { blockResolver } from '~/graphql/resolvers'; -import { APYResolver } from '~/graphql/resolvers/APYResolver'; -import BalanceDAO from '../dao/BalanceDAO'; -import BlockDAO from '../dao/BlockDAO'; -import BridgeDAO from '../dao/BridgeDAO'; -import CosmosDAO from '../dao/CosmosDAO'; -import L1DAO from '../dao/L1DAO'; -import StakingDAO from '../dao/StakingDAO'; -import { - TIME_TO_COMMIT, - TIME_TO_SEQUENCER_INDEXER_SYNC, - getStakingTransactions, - getTimeToFinalizeStrict, - getUnbondingTimeSeconds, -} from '../dao/TEMP_StakingDAO'; -import { convertToUsd } from '../dao/utils'; -import AssetGateway from '../gateway/AssetGateway'; -import PaginatedParams from '../paginator/PaginatedParams'; - -export class Server { - // Metrics cache with 3-second TTL - private cachedMetrics: string | null = null; - private lastMetricsTime = 0; - private readonly METRICS_CACHE_TTL = 3000; // 3 seconds - - async setup() { - const app = express(); - app.use(cors()); - app.use(express.json()); - - const providerUrl = env.get('FUEL_PROVIDER'); - if (!providerUrl) { - throw new Error('FUEL_PROVIDER is not set'); - } - const provider = new Provider(providerUrl); - const chainId = await provider.getChainId(); - const baseAssetId = await provider.getBaseAssetId(); - blockResolver.startPoolingAnalytics({ chainId, baseAssetId }); - - app.get('/staking/apy', async (_req: Request, res: Response) => { - logger.debug('API', 'Get staking APY'); - const getStakingAPY = new APYResolver(); - const result = await getStakingAPY.stakingAPY(); - res.json(result); - }); - - app.get('/staking/events', async (_req: Request, res: Response) => { - logger.debug('API', 'Get staking events'); - const address = _req.query.address; - const paginatedParams = new PaginatedParams(_req.query); - const stakingDAO = new StakingDAO(); - const output = await stakingDAO.getEvents( - String(address), - paginatedParams, - ); - res.json(output); - }); - - app.get('/bridge/events', async (req: Request, res: Response) => { - logger.debug('API', 'Get bridge events'); - const address = req.query.address; - const limit = Math.min(Number(req.query.limit), 20); - const offset = Number(req.query.offset); - const bridgeDAO = new BridgeDAO(); - const output = await bridgeDAO.getEvents(String(address), limit, offset); - res.json(output); - }); - - app.get('/bridge/deposit/logs', async (req: Request, res: Response) => { - logger.debug('API', 'Get deposit logs'); - const address = req.query.address; - const recipient = req.query.recipient; - const predicate = req.query.predicate; - const bridgeDAO = new BridgeDAO(); - const output = await bridgeDAO.queryLogsForRecipient( - String(address), - String(recipient), - String(predicate), - ); - res.json(output); - }); - - app.get('/bridge/block/hashes', async (req: Request, res: Response) => { - logger.debug('API', 'Get block hashes'); - const address = req.query.address; - const fromBlock = req.query.from_block; - const bridgeDAO = new BridgeDAO(); - const output = await bridgeDAO.queryBlockHashes( - String(address), - Number(fromBlock), - ); - res.json(output); - }); - - app.get( - '/bridge/message/relayed/hash', - async (req: Request, res: Response) => { - logger.debug('API', 'Get message relayed logs'); - const address = req.query.address; - const messageId = req.query.message_id; - const bridgeDAO = new BridgeDAO(); - const output = await bridgeDAO.queryMessageRelayedTxHash( - String(address), - String(messageId), - ); - res.json(output); - }, - ); - - app.get( - '/bridge/:eventType/:eventId', - async (req: Request, res: Response) => { - logger.debug('API', 'Get bridge event'); - const eventId = Number(req.params.eventId); - const eventType = String(req.params.eventType); - const bridgeDAO = new BridgeDAO(); - const output = await bridgeDAO.getEvent(eventType, eventId); - res.json(output); - }, - ); - - app.get( - '/staking/finalization-period/withdraw', - async (_req: Request, res: Response) => { - logger.debug('API', 'Get withdraw finalization period'); - try { - const timeToFinalizeMinutes = await getTimeToFinalizeStrict(); - if (timeToFinalizeMinutes == null) { - res.json({ seconds: null }); - return; - } - const totalSeconds = - timeToFinalizeMinutes * 60 + - TIME_TO_COMMIT + - TIME_TO_SEQUENCER_INDEXER_SYNC; - res.json({ seconds: totalSeconds }); - } catch (_error) { - logger.error('API', 'Error fetching withdraw finalization period'); - res.status(500).json({ seconds: null }); - } - }, - ); - - app.get( - '/staking/finalization-period/undelegate', - async (_req: Request, res: Response) => { - logger.debug('API', 'Get undelegate finalization period'); - try { - const unbondingSeconds = await getUnbondingTimeSeconds(); - if (unbondingSeconds == null) { - res.json({ seconds: null }); - return; - } - const totalSeconds = - unbondingSeconds + TIME_TO_SEQUENCER_INDEXER_SYNC; - res.json({ seconds: totalSeconds }); - } catch (_error) { - logger.error('API', 'Error fetching undelegate finalization period'); - res.status(500).json({ seconds: null }); - } - }, - ); - - app.get('/staking/events/:eventId', async (req: Request, res: Response) => { - logger.debug('API', 'Get staking event by id'); - const eventId = Number(req.params.eventId); - if (!Number.isInteger(eventId)) { - throw new Error('Invalid event id'); - } - const stakingDAO = new StakingDAO(); - const output = await stakingDAO.getEvent(eventId); - res.json(output); - }); - - app.get('/health', async (_req: Request, res: Response) => { - logger.debug('API', 'Health'); - res.json({ - status: 'ok', - }); - }); - - app.get('/metrics', async (_req: Request, res: Response) => { - logger.debug('API', 'Metrics'); - const now = Date.now(); - - // Return cached metrics if still valid (within TTL) - if ( - this.cachedMetrics && - now - this.lastMetricsTime < this.METRICS_CACHE_TTL - ) { - res.setHeader('content-type', 'text/plain'); - res.send(this.cachedMetrics); - return; - } - - // Fetch fresh metrics if cache expired - const getMetrics = new GetMetrics(); - const output = await getMetrics.execute(); - const lines: any = []; - for (const element in output) { - lines.push(`${element} ${output[element]}`); - } - - // Cache the result - const metricsText = lines.join('\n'); - this.cachedMetrics = metricsText; - this.lastMetricsTime = now; - - res.setHeader('content-type', 'text/plain'); - res.send(metricsText); - }); - - app.get('/blocks/:height', async (_req: Request, res: Response) => { - const height = _req.params.height; - logger.debug('API', 'Get Block', height); - const blockDAO = new BlockDAO(); - const output = await blockDAO.getByHeight(Number(height)); - if (!output) { - return res.status(404).end(); - } - res.json(output.data); - }); - - app.get( - '/accounts/:accountHash/balance', - async (_req: Request, res: Response) => { - const accountHash = _req.params.accountHash; - const assetId = String(_req.query.asset_id); - const blockHeight = _req.query.block_height - ? Number(_req.query.block_height) - : null; - logger.debug( - 'API', - 'Get Balance', - `Account: ${accountHash} Asset: ${assetId} Block: ${blockHeight}`, - ); - const balanceDAO = new BalanceDAO(); - const output = await balanceDAO.getBalance( - accountHash, - assetId, - blockHeight, - ); - if (!output) { - return res.status(404).end(); - } - const assetGateway = new AssetGateway(); - const asset = await assetGateway.getAsset(assetId, chainId); - res.json({ - accountHash: output.account_hash, - assetId: output.asset_id, - blockHeight: output.block_height, - balance: output.balance, - balanceInUsd: asset.rate - ? convertToUsd(output.balance, asset.decimals, asset.rate).formatted - : null, - }); - }, - ); - - app.get('/assets/:assetId', async (_req: Request, res: Response) => { - const assetId = _req.params.assetId; - logger.debug('API', 'Get Asset', assetId); - const assetGateway = new AssetGateway(); - const output = await assetGateway.getAsset(assetId, chainId); - res.json(output); - }); - - app.get('/assets/:assetId/details', async (req: Request, res: Response) => { - const assetId = req.params.assetId; - logger.debug('API', 'Get Asset Details', assetId); - - const getAssetDetails = new GetAssetDetails(); - const output = await getAssetDetails.executeCached(assetId); - - if (!output) { - return res.status(404).json({ message: 'Asset not found' }); - } - - res.json(output); - }); - - app.get( - '/accounts/:accountId/assets', - async (_req: Request, res: Response) => { - const accountId = _req.params.accountId; - const last = Number(_req.query.last) || 100; - logger.debug('API', 'Get Account Assets', accountId); - const getAccountAssets = new GetAccountAssets(); - const output = await getAccountAssets.execute({ accountId, last }); - res.json(output); - }, - ); - - app.get('/assets_rate', async (_req: Request, res: Response) => { - logger.debug('API', 'Get Assets Rate'); - const getAssetsRate = new GetAssetsRate(); - const output = await getAssetsRate.executeCached(); - res.json(output); - }); - - app.post('/convert_rate', async (_req: Request, res: Response) => { - logger.debug('API', 'Post Convert Rate'); - const assetId = _req.body.assetId; - const amount = _req.body.amount; - const assetGateway = new AssetGateway(); - const asset = await assetGateway.getAsset(assetId, chainId); - if (!asset) { - return res.status(422).json({ - message: 'Could not convert because asset was not found', - }); - } - if (!asset.verified || !asset.rate) { - return res.status(422).json({ - message: 'Could not convert because asset has no conversion rate', - }); - } - return res.json({ - amount: asset.rate - ? convertToUsd(amount, asset.decimals, asset.rate).formatted - : null, - }); - }); - - app.get( - '/contracts_l1/:contractHash', - async (_req: Request, res: Response) => { - const contractHash = _req.params.contractHash; - const event = _req.query.event; - const key = _req.query.key; - const value = _req.query.value; - if (!contractHash || !event || !key) { - logger.error('API', 'Contracts L1 missing params'); - return res.status(442).end(); - } - logger.debug('API', 'Contracts L1', contractHash); - const l1DAO = new L1DAO(); - const output = await l1DAO.getContractEvent( - contractHash, - String(event), - String(key), - String(value), - ); - res.json(output); - }, - ); - - app.get('/staking-transactions', async (req: Request, res: Response) => { - logger.debug('API', 'Get TEMP staking transactions by address'); - const address = req.query.address as string; - const output = await getStakingTransactions(address); - res.json(output); - }); - - app.get('/cosmos', async (_req: Request, res: Response) => { - const type = _req.query.type; - const key = _req.query.key; - const value = _req.query.value; - if (!type || !key) { - logger.error('API', 'Cosmos missing params'); - return res.status(422).end(); - } - logger.debug('API', 'Cosmos', type); - const cosmosDAO = new CosmosDAO(); - const output = await cosmosDAO.getCosmosEvents( - String(type), - String(key), - String(value), - ); - res.json(output); - }); - - // Return all errors as 400 with a message payload - app.use((err: Error, _req: Request, res: Response, _next: NextFunction) => { - logger.error('API', `Error occurred: ${err.message}`, err); - res.status(400).json({ message: err.message }); - }); - - return app; - } - - async listen(app: any, port: number) { - return new Promise((resolve) => { - app.listen(port, async () => { - resolve(null); - }); - }); - } -} diff --git a/packages/graphql/src/infra/timer/Timer.ts b/packages/graphql/src/infra/timer/Timer.ts deleted file mode 100644 index 9b6e43fc7..000000000 --- a/packages/graphql/src/infra/timer/Timer.ts +++ /dev/null @@ -1,8 +0,0 @@ -export default class Timer { - static async register(interval: number, callback: Function) { - await callback(); - setInterval(async () => { - await callback(); - }, interval); - } -} diff --git a/packages/graphql/src/infra/util/util.ts b/packages/graphql/src/infra/util/util.ts deleted file mode 100644 index c90d870a9..000000000 --- a/packages/graphql/src/infra/util/util.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { bech32 } from 'bech32'; -import { arrayify, hexlify } from 'fuels'; - -export function decodeMessage(messageData: string) { - if (!messageData) return {}; - if (messageData === '0x') return {}; - const DEPOSIT_WITH_DATA = - '0x0000000000000000000000000000000000000000000000000000000000000002'; - const data = Array.from(arrayify(messageData)); - const contractId = hexlify(Uint8Array.from(data.splice(0, 32))); - const messageType = hexlify(Uint8Array.from(data.splice(0, 32))); - if (messageType === DEPOSIT_WITH_DATA) { - const tokenAddress = hexlify(Uint8Array.from(data.splice(0, 32))); - const tokenId = hexlify(Uint8Array.from(data.splice(0, 32))); - const msgSender = hexlify(Uint8Array.from(data.splice(0, 32))); - const toContract = hexlify(Uint8Array.from(data.splice(0, 32))); - return { - contractId, - messageType, - tokenAddress, - tokenId, - msgSender, - toContract, - }; - } - return { - contractId, - messageType, - }; -} - -const hrp = 'fuelsequencer'; - -export function convertEthAddressToSequencerUserAddress( - ethAddress: string, -): `fuelsequencer${string}` | undefined { - if (!ethAddress) { - return undefined; - } - - // Remove the '0x' prefix and convert the address to a Buffer - const addressBuffer = Buffer.from(ethAddress.slice(2), 'hex'); - - // Convert the address Buffer to a Bech32 encoded address - const bech32Address = bech32.encode(hrp, bech32.toWords(addressBuffer)); - - return bech32Address as `fuelsequencer${string}`; -} diff --git a/packages/graphql/src/jobs.ts b/packages/graphql/src/jobs.ts deleted file mode 100644 index bd8bb6ae0..000000000 --- a/packages/graphql/src/jobs.ts +++ /dev/null @@ -1,14 +0,0 @@ -import RunDatabaseJobs from './application/uc/RunDatabaseJobs'; -import { logger } from './core/Logger'; - -async function main() { - logger.debug('DE', 'Starting database executor service'); - const runDatabaseJobs = new RunDatabaseJobs(); - await runDatabaseJobs.execute(); -} - -main().catch(async (error: any) => { - logger.error('DE', 'Uncaught error', error); - logger.error('DE', 'Process exit'); - process.exit(1); -}); diff --git a/packages/graphql/src/l1.ts b/packages/graphql/src/l1.ts deleted file mode 100644 index f5298af2a..000000000 --- a/packages/graphql/src/l1.ts +++ /dev/null @@ -1,16 +0,0 @@ -import IndexL1 from './application/uc/IndexL1/IndexL1'; -import L1ReorgSentinel from './application/uc/IndexL1/L1ReorgSentinel'; -import { logger } from './core/Logger'; - -async function main() { - logger.debug('L1', 'Starting l1 indexing service'); - const indexL1 = new IndexL1(); - const sentinel = new L1ReorgSentinel(); - await Promise.all([indexL1.execute(), sentinel.execute()]); -} - -main().catch(async (error: any) => { - logger.error('L1', 'Uncaught error', error); - logger.error('L1', 'Process exit'); - process.exit(1); -}); diff --git a/packages/graphql/src/migrate-receipts.ts b/packages/graphql/src/migrate-receipts.ts deleted file mode 100644 index 39340aa24..000000000 --- a/packages/graphql/src/migrate-receipts.ts +++ /dev/null @@ -1,37 +0,0 @@ -import IndexReceipts from './application/uc/IndexReceipt'; -import { DatabaseConnection } from './infra/database/DatabaseConnection'; - -(async () => { - const startHeight = Number.parseInt(process.argv[2]); - const endHeight = Number.parseInt(process.argv[3]); - await migrate(startHeight, endHeight); -})(); - -async function migrate(startHeight: number, endHeight: number) { - console.log('migrate'); - const indexReceipts = new IndexReceipts(); - const connection = DatabaseConnection.getInstance(); - let height = startHeight || 1; - while (true) { - if (height > endHeight) { - console.log('last height reached'); - break; - } - const transactions = await connection.query( - 'select * from indexer.transactions where block_id = $1', - [height], - ); - console.log(height, transactions.length); - if (!transactions.length) { - console.log('No transactions found'); - break; - } - for (const transaction of transactions) { - transaction.blockId = transaction.block_id; - transaction.transactionHash = transaction.tx_hash; - transaction.id = transaction._id; - await indexReceipts.execute(transaction); - } - height++; - } -} diff --git a/packages/graphql/src/migrate-timestamp.ts b/packages/graphql/src/migrate-timestamp.ts deleted file mode 100644 index db47c9e14..000000000 --- a/packages/graphql/src/migrate-timestamp.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { DatabaseConnection } from './infra/database/DatabaseConnection'; - -(async () => { - const startHeight = Number.parseInt(process.argv[2]); - const endHeight = Number.parseInt(process.argv[3]); - await migrate(startHeight, endHeight); -})(); - -async function migrate(startHeight: number, endHeight: number) { - console.log('migrate'); - const connection = DatabaseConnection.getInstance(); - let height = startHeight || 1; - while (true) { - if (height > endHeight) { - console.log('last height reached'); - break; - } - await connection.query( - 'update indexer.transactions set timestamp2 = timestamp where block_id = $1', - [height], - ); - height++; - } -} diff --git a/packages/graphql/src/recover.ts b/packages/graphql/src/recover.ts deleted file mode 100644 index 2a1679acb..000000000 --- a/packages/graphql/src/recover.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { setTimeout } from 'node:timers/promises'; -import NewAddBlockRange from './application/uc/NewAddBlockRange'; -import { logger } from './core/Logger'; -import { DatabaseConnection } from './infra/database/DatabaseConnection'; - -async function main() { - const addBlockRange = new NewAddBlockRange(); - const databaseConnection = DatabaseConnection.getInstance(); - const from = 1; - const to = 12875752; - const rows = (await databaseConnection.query( - `select seq from generate_series(${from}, ${to}) as seq left join indexer.blocks b on (b._id = seq) where b._id is null`, - [], - )) as any; - if (rows.length === 0) { - logger.debug('Recover', `No blocks to recover between #${from} and #${to}`); - } else { - logger.debug( - 'Recover', - `Recovering ${rows.length} blocks between #${from} and #${to}`, - ); - } - let i = 0; - for (const row of rows) { - try { - await addBlockRange.execute({ from: row.seq, to: row.seq }); - console.log(`Recovering block #${row.seq} ${i++}`); - } catch (err: any) { - console.error(`Failed to recover block #${row.seq}: ${err.message}`); - } - await setTimeout(100); - } -} - -main(); diff --git a/packages/graphql/src/schemas/fuelcore.graphql b/packages/graphql/src/schemas/fuelcore.graphql deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/graphql/src/services/extends.graphql b/packages/graphql/src/services/extends.graphql deleted file mode 100644 index a45648eb7..000000000 --- a/packages/graphql/src/services/extends.graphql +++ /dev/null @@ -1,170 +0,0 @@ -scalar U64 -scalar HexString -scalar Address -scalar AssetId -scalar ContractId -scalar UtxoId - -# -------------------------------- -# Transaction -# -------------------------------- - -extend type TransactionConnection { - # custom - tokens: [Token] - # custom - accounts: [Account] -} - -enum TransactionStatusType { - Success - Failure - Submitted -} - -type ParsedTime { - fromNow: String - full: String - rawTai64: String - rawUnix: String -} - -enum GroupedInputType { - InputCoin - InputContract - InputMessage -} - -type GroupedInput { - type: GroupedInputType - totalAmount: U64 - inputs: [Input] - contractId: ContractId - assetId: AssetId - sender: Address - recipient: Address - data: HexString - owner: Address -} - -enum GroupedOutputType { - CoinOutput - ContractOutput - MessageOutput - ChangeOutput - VariableOutput - ContractCreated -} - -type GroupedOutput { - type: GroupedOutputType - totalAmount: U64 - outputs: [Output] - to: Address - assetId: AssetId - inputIndex: Int - recipient: Address - contractId: ContractId -} - -enum TransactionAccountType { - Contract - Predicate - Wallet -} - -type TransactionAccount { - type: TransactionAccountType - id: String -} - -enum OperationType { - FROM_CONTRACT - FROM_ACCOUNT - FINAL_RESULT -} - -type OperationReceipt { - item: Receipt - receipts: [OperationReceipt] -} - -type Operation { - type: OperationType - receipts: [OperationReceipt] -} - -extend type Transaction { - title: String - time: ParsedTime - blockHeight: String - statusType: TransactionStatusType - totalAccounts: Int - totalAssets: Int - totalOperations: Int - gasUsed: U64 - operations: [Operation] - accountsInvolved: [TransactionAccount] - groupedInputs: [GroupedInput] - groupedOutputs: [GroupedOutput] - isPredicate: Boolean - fee: U64 -} - -# -------------------------------- -# Balance -# -------------------------------- - -type UtxoItem { - utxoId: UtxoId! - amount: U64! - blockCreated: U32 - txCreatedIdx: U64 -} - -extend type Balance { - utxos: [UtxoItem] -} - -# -------------------------------- -# Block -# -------------------------------- - -extend type Block { - time: ParsedTime - totalGasUsed: U64 - totalFee: U64 - producer: Address -} - -# -------------------------------- -# Query -# -------------------------------- -type SearchAccount { - address: Address - transactions: [SearchTransaction] -} - -type SearchContract { - id: ContractId -} - -type SearchBlock { - id: BlockId - height: String -} - -type SearchTransaction { - id: TransactionId -} - -type SearchResult { - account: SearchAccount - contract: SearchContract - block: SearchBlock - transaction: SearchTransaction -} - -extend type Query { - search(query: String!): SearchResult -} diff --git a/packages/graphql/src/sync-block-range.ts b/packages/graphql/src/sync-block-range.ts deleted file mode 100644 index 2111da5fd..000000000 --- a/packages/graphql/src/sync-block-range.ts +++ /dev/null @@ -1,14 +0,0 @@ -import NewAddBlockRange from './application/uc/NewAddBlockRange'; - -async function main() { - const from = Number.parseInt(process.argv[2]); - const to = Number.parseInt(process.argv[3]) || from; - const addBlockRange = new NewAddBlockRange(); - const input = { - from, - to, - }; - await addBlockRange.execute(input); -} - -main(); diff --git a/packages/graphql/src/syncer.ts b/packages/graphql/src/syncer.ts deleted file mode 100644 index 43e187e22..000000000 --- a/packages/graphql/src/syncer.ts +++ /dev/null @@ -1,221 +0,0 @@ -import { setTimeout } from 'node:timers/promises'; -import NewAddBlockRange from './application/uc/NewAddBlockRange'; -import { logger } from './core/Logger'; -import { client } from './graphql/GraphQLSDK'; -import type { GQLBlock } from './graphql/generated/sdk'; -import { LATEST_HEIGHT_QUERY } from './graphql/queries/syncer'; -import BlockDAO from './infra/dao/BlockDAO'; - -const FUEL_CORE_TIMEOUT_MS = 5000; -const BACKOFF_INITIAL_MS = 1000; -const BACKOFF_MAX_MS = 5000; -const BATCH_SIZE = 2; -const MAX_RANGE = 1000; -const CONCURRENCY = 10; - -function createBatchEvents(idsRange: { from: number; to: number }) { - const diff = idsRange.to - idsRange.from; - const numberOfBatches = Math.ceil(diff / BATCH_SIZE); - return Array.from({ length: numberOfBatches }).map((_, page) => { - const from = idsRange.from + page * BATCH_SIZE; - const to = Math.min(from + BATCH_SIZE, idsRange.to); - return { from, to }; - }); -} - -function fetchLatestHeight(): Promise { - const p = Promise.race([ - client.client.request<{ - blocks: { nodes: { header: { height: string } }[] }; - }>(LATEST_HEIGHT_QUERY), - setTimeout(FUEL_CORE_TIMEOUT_MS).then(() => null), - ]).then((response) => { - if (!response) return null; - const lastBlock = response.blocks?.nodes[0]; - return Number(lastBlock?.header.height ?? '0'); - }); - p.catch(() => {}); - return p; -} - -async function main() { - const addBlockRange = new NewAddBlockRange(); - const blockDAO = new BlockDAO(); - let backoffMs = BACKOFF_INITIAL_MS; - let cursor = (await blockDAO.findLatestBlockHeight()) ?? 0; - - let prefetchedBlocks: Promise<{ - blocks: GQLBlock[]; - from: number; - to: number; - }> | null = null; - let heightPromise: Promise = fetchLatestHeight(); - - let statsBlockCount = 0; - let statsStartTime = Date.now(); - let lastKnownHeight = 0; - const STATS_INTERVAL_MS = 30_000; - - function emitStats() { - const now = Date.now(); - if (now - statsStartTime < STATS_INTERVAL_MS) return; - const elapsed = (now - statsStartTime) / 1000; - const bps = (statsBlockCount / elapsed).toFixed(1); - const behind = lastKnownHeight > cursor ? lastKnownHeight - cursor : 0; - logger.info( - 'Syncer', - `[stats] blocks=${statsBlockCount} elapsed=${elapsed.toFixed(0)}s throughput=${bps} blocks/sec cursor=${cursor} behind=${behind}`, - ); - statsBlockCount = 0; - statsStartTime = now; - } - - function startPrefetch(from: number, to: number) { - const p = addBlockRange.getBlocks(from, to).then((blocks) => { - return { blocks, from, to }; - }); - p.catch(() => {}); - return p; - } - - while (true) { - emitStats(); - const startTime = Date.now(); - let height: number; - try { - const result = await heightPromise; - const latencyMs = Date.now() - startTime; - if (result === null) { - logger.warn( - 'Syncer', - `Fuel core timeout after ${latencyMs}ms, backing off ${backoffMs}ms`, - ); - await setTimeout(backoffMs); - backoffMs = Math.min(backoffMs * 2, BACKOFF_MAX_MS); - prefetchedBlocks = null; - heightPromise = fetchLatestHeight(); - continue; - } - logger.debug('Syncer', `Fuel core response time: ${latencyMs}ms`); - backoffMs = BACKOFF_INITIAL_MS; - height = result; - lastKnownHeight = height; - } catch (e: any) { - const latencyMs = Date.now() - startTime; - logger.error( - 'Syncer', - `Could not fetch blocks from fuel core after ${latencyMs}ms, backing off ${backoffMs}ms`, - e, - ); - await setTimeout(backoffMs); - backoffMs = Math.min(backoffMs * 2, BACKOFF_MAX_MS); - prefetchedBlocks = null; - heightPromise = fetchLatestHeight(); - continue; - } - - logger.debug('Syncer', `Fuel core height: ${height}`); - logger.debug('Syncer', `Indexer height: ${cursor}`); - - if (cursor >= height) { - if (height < cursor) { - logger.warn( - 'Syncer', - `Fuel core is behind indexer (${height} < ${cursor}), waiting for node to catch up`, - ); - await setTimeout(5000); - } else { - await setTimeout(100); - } - prefetchedBlocks = null; - heightPromise = fetchLatestHeight(); - continue; - } - - const to = cursor + MAX_RANGE; - const range = { from: cursor, to: Math.min(to, height) }; - const events = createBatchEvents(range); - - let failed = false; - for (let i = 0; i < events.length && !failed; i += CONCURRENCY) { - const chunk = events.slice(i, i + CONCURRENCY); - - // Fetch all batches in this chunk concurrently - // Reuse prefetched data only if its range covers the event's range - const fetchPromises = chunk.map(async (event, idx) => { - if (idx === 0 && prefetchedBlocks) { - const p = prefetchedBlocks; - prefetchedBlocks = null; - try { - const prefetched = await p; - if (prefetched.from === event.from && prefetched.to >= event.to) { - return prefetched; - } - } catch {} - } - return startPrefetch(event.from, event.to); - }); - - const fetched = await Promise.allSettled(fetchPromises); - - // Start prefetching the NEXT chunk's first batch while we process this one - // Also prefetch the height check concurrently - heightPromise = fetchLatestHeight(); - const nextChunkStart = i + CONCURRENCY; - if (nextChunkStart < events.length) { - prefetchedBlocks = startPrefetch( - events[nextChunkStart].from, - events[nextChunkStart].to, - ); - } else { - // Speculatively prefetch next 2 blocks (small window — large ranges - // past the tip make Fuel Core very slow) - const nextFrom = chunk[chunk.length - 1].to; - const nextTo = nextFrom + 2; - prefetchedBlocks = startPrefetch(nextFrom, nextTo); - } - - // Process all fetched batches concurrently - const results = await Promise.allSettled( - fetched.map(async (fetchResult) => { - if (fetchResult.status === 'rejected') throw fetchResult.reason; - const { blocks, from: bFrom, to: bTo } = fetchResult.value; - logger.debug('Syncer', `Processing blocks #${bFrom} - #${bTo}`); - return addBlockRange.processBlocks(blocks, bFrom, bTo); - }), - ); - - let hasFailure = false; - for (let j = 0; j < results.length; j++) { - if (results[j].status === 'fulfilled') { - const highest = (results[j] as PromiseFulfilledResult) - .value; - const prevCursor = cursor; - if (!hasFailure) cursor = highest ?? chunk[j].to; - statsBlockCount += cursor - prevCursor; - } else { - hasFailure = true; - const err = (results[j] as PromiseRejectedResult).reason; - const is429 = err?.status === 429 || /\b429\b/.test(err?.message); - logger.error( - 'Syncer', - `Failed batch #${chunk[j].from}-#${chunk[j].to}${is429 ? ' (rate limited)' : ''}: ${err?.message}`, - ); - } - } - - if (hasFailure) { - await setTimeout(2000); - failed = true; - prefetchedBlocks = null; - heightPromise = fetchLatestHeight(); - } - } - } -} - -main().catch(async (error: any) => { - logger.error('Syncer', 'Uncaught error', error); - logger.error('Syncer', 'Process exit'); - process.exit(1); -}); diff --git a/packages/graphql/tsconfig.json b/packages/graphql/tsconfig.json index 2dd54eff4..6c1fe1ba7 100644 --- a/packages/graphql/tsconfig.json +++ b/packages/graphql/tsconfig.json @@ -8,7 +8,7 @@ "module": "ESNext", "moduleResolution": "Bundler", "strict": true, - "types": ["node", "jest"], + "types": ["node"], "jsx": "react-jsx", "esModuleInterop": true, "isolatedModules": true, @@ -24,5 +24,5 @@ } }, "exclude": ["node_modules", "generated"], - "include": ["src", "scripts", "*.config.*", "codegen.*"] + "include": ["src", "*.config.*", "codegen.*"] } diff --git a/packages/graphql/tsup.config.mjs b/packages/graphql/tsup.config.mjs index 915b8c948..2bf37d26a 100644 --- a/packages/graphql/tsup.config.mjs +++ b/packages/graphql/tsup.config.mjs @@ -15,13 +15,6 @@ export default defineConfig(() => [ index: 'src/index.ts', sdk: 'src/graphql/generated/sdk.ts', 'sdk-provider': 'src/graphql/generated/sdk-provider.ts', - app: 'src/app.ts', - syncer: 'src/syncer.ts', - assets: 'src/assets.ts', - balance: 'src/balance.ts', - l1: 'src/l1.ts', - cosmos: 'src/cosmos.ts', - jobs: 'src/jobs.ts', }, async onSuccess() { const cwd = process.cwd(); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1382e6951..08e60396b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -26,22 +26,22 @@ importers: dependencies: '@fuel-ts/account': specifier: 0.100.0 - version: 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + version: 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/math': specifier: 0.100.0 version: 0.100.0 '@fuels/connectors': specifier: 0.45.0 - version: 0.45.0(@tanstack/query-core@5.56.2)(@types/react@18.2.54)(@wagmi/connectors@5.1.7(@types/react@18.2.54)(@wagmi/core@2.13.4(@tanstack/query-core@5.56.2)(@types/react@18.2.54)(react@18.2.0)(typescript@5.4.5)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.9)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.46.2)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8))(bufferutil@4.0.9)(fuels@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8) + version: 0.45.0(@tanstack/query-core@5.56.2)(@types/react@18.2.54)(@wagmi/connectors@5.1.7(@types/react@18.2.54)(@wagmi/core@2.13.4(@tanstack/query-core@5.56.2)(@types/react@18.2.54)(react@18.2.0)(typescript@5.4.5)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.9)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.46.2)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8))(bufferutil@4.0.9)(fuels@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8) '@fuels/react': specifier: 0.44.1 - version: 0.44.1(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react-dom@18.2.22)(@types/react@18.2.54)(fuels@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 0.44.1(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react-dom@18.2.22)(@types/react@18.2.54)(fuels@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@fuels/react-xstore': specifier: 0.23.0 - version: 0.23.0(@babel/core@7.28.0)(@babel/template@7.27.2)(@types/react@18.2.54)(@types/ws@8.18.1)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 0.23.0(@babel/core@7.28.0)(@babel/template@7.27.2)(@types/react@18.2.54)(@types/ws@8.18.1)(@xstate/react@3.2.2(@types/react@18.2.54)(react@18.2.0)(xstate@5.0.0-beta.54))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(xstate@5.0.0-beta.54) fuels: specifier: 0.103.0 - version: 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + version: 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) lodash: specifier: ^4.17.21 version: 4.17.21 @@ -63,13 +63,13 @@ importers: version: 1.9.4 '@fuels/jest': specifier: 0.20.0 - version: 0.20.0(@jest/globals@29.7.0)(@types/jest@29.5.12)(bufferutil@4.0.9)(jest@29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)))(utf-8-validate@5.0.10)(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + version: 0.20.0(@jest/globals@29.7.0)(@types/jest@29.5.12)(bufferutil@4.0.9)(jest@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)))(utf-8-validate@5.0.10)(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuels/ts-config': specifier: 0.26.0 version: 0.26.0(typescript@5.4.5) '@fuels/tsup-config': specifier: 0.26.0 - version: 0.26.0(tsup@8.0.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5)) + version: 0.26.0(tsup@8.0.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.4.5)) '@jest/types': specifier: 29.6.3 version: 29.6.3 @@ -78,7 +78,7 @@ importers: version: 3.1.8 '@openzeppelin/hardhat-upgrades': specifier: ^3.0.3 - version: 3.9.1(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 3.9.1(ethers@6.11.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@playwright/test': specifier: 1.48.2 version: 1.48.2 @@ -117,7 +117,7 @@ importers: version: 9.1.5 jest: specifier: 29.7.0 - version: 29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + version: 29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) jest-environment-jsdom: specifier: 29.7.0 version: 29.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -132,13 +132,13 @@ importers: version: 4.1.5 ts-jest: specifier: ^29.1.2 - version: 29.4.1(@babel/core@7.28.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)))(typescript@5.4.5) + version: 29.4.1(@babel/core@7.28.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)))(typescript@5.4.5) ts-node: specifier: 10.9.2 - version: 10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5) + version: 10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5) tsup: specifier: 8.0.2 - version: 8.0.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5) + version: 8.0.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.4.5) tsx: specifier: 4.7.1 version: 4.7.1 @@ -156,7 +156,7 @@ importers: version: 2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8) vitest: specifier: '>=3.2.6' - version: 4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) + version: 4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) wagmi: specifier: 2.12.7 version: 2.12.7(@tanstack/query-core@5.56.2)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.54)(bufferutil@4.0.9)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.46.2)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8) @@ -175,13 +175,13 @@ importers: version: 16.4.1 fuels: specifier: 0.103.0 - version: 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + version: 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) tsx: specifier: 4.7.1 version: 4.7.1 vitest: specifier: '>=3.2.6' - version: 4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) + version: 4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) docker/erc20-deployer/deployer: dependencies: @@ -197,7 +197,7 @@ importers: devDependencies: ts-node: specifier: ^10.9.2 - version: 10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5) + version: 10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5) typescript: specifier: 5.4.5 version: 5.4.5 @@ -343,7 +343,7 @@ importers: version: 0.1.20(tailwindcss@4.1.11) tsup: specifier: ^8.0.2 - version: 8.1.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5) + version: 8.1.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.4.5) typescript: specifier: 5.4.5 version: 5.4.5 @@ -466,7 +466,7 @@ importers: version: 1.0.0 tailwind-variants: specifier: 0.1.20 - version: 0.1.20(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))) + version: 0.1.20(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))) viem: specifier: 2.23.2 version: 2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.22.4) @@ -482,7 +482,7 @@ importers: devDependencies: '@tailwindcss/vite': specifier: 4.1.11 - version: 4.1.11(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) + version: 4.1.11(vite@6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) '@tanstack/react-query-devtools': specifier: 5.56.2 version: 5.56.2(@tanstack/react-query@5.56.2(react@18.2.0))(react@18.2.0) @@ -497,7 +497,7 @@ importers: version: 1.8.8 '@vitejs/plugin-react-swc': specifier: ^3.7.0 - version: 3.11.0(@swc/helpers@0.5.17)(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) + version: 3.11.0(@swc/helpers@0.5.17)(vite@6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) autoprefixer: specifier: 10.4.17 version: 10.4.17(postcss@8.4.35) @@ -512,10 +512,10 @@ importers: version: 16.0.1(postcss@8.4.35) tailwindcss: specifier: 3.4.4 - version: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + version: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) tailwindcss-animate: specifier: 1.0.7 - version: 1.0.7(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))) + version: 1.0.7(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))) tailwindcss-radix: specifier: 3.0.3 version: 3.0.3 @@ -527,13 +527,13 @@ importers: version: 5.4.5 vite: specifier: ^6.0.0 - version: 6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) + version: 6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) vite-plugin-node-polyfills: specifier: 0.24.0 - version: 0.24.0(rollup@4.46.2)(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) + version: 0.24.0(rollup@4.46.2)(vite@6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) vite-plugin-svgr: specifier: 4.2.0 - version: 4.2.0(rollup@4.46.2)(typescript@5.4.5)(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) + version: 4.2.0(rollup@4.46.2)(typescript@5.4.5)(vite@6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) packages/app-portal: dependencies: @@ -548,7 +548,7 @@ importers: version: 1.0.0 '@fuels/react-xstore': specifier: 0.23.0 - version: 0.23.0(@babel/core@7.28.0)(@babel/template@7.27.2)(@types/react@18.2.54)(@types/ws@8.18.1)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + version: 0.23.0(@babel/core@7.28.0)(@babel/template@7.27.2)(@types/react@18.2.54)(@types/ws@8.18.1)(@xstate/react@3.2.2(@types/react@18.2.54)(react@18.2.0)(xstate@4.38.3))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(xstate@4.38.3) '@hookform/resolvers': specifier: ^3.1.1 version: 3.3.4(react-hook-form@7.54.0(react@18.2.0)) @@ -784,61 +784,22 @@ importers: devDependencies: '@fuels/playwright-utils': specifier: 0.57.1 - version: 0.57.1(@playwright/test@1.48.2)(fuels@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))) + version: 0.57.1(@playwright/test@1.48.2)(fuels@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))) '@synthetixio/synpress': specifier: 4.1.0 - version: 4.1.0(@depay/solana-web3.js@1.98.3)(@depay/web3-blockchains@9.8.6)(@playwright/test@1.48.2)(@swc/core@1.13.3(@swc/helpers@0.5.17))(bufferutil@4.0.9)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.23.8) + version: 4.1.0(@depay/solana-web3.js@1.98.3)(@depay/web3-blockchains@9.8.6)(@playwright/test@1.48.2)(@swc/core@1.13.3(@swc/helpers@0.5.17))(bufferutil@4.0.9)(ethers@6.11.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.23.8) app-commons: specifier: workspace:* version: link:../app-commons fuels: specifier: 0.103.0 - version: 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) + version: 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) viem: specifier: 2.23.2 version: 2.23.2(bufferutil@4.0.9)(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.23.8) packages/graphql: dependencies: - '@fuel-infrastructure/fuelsequencerjs': - specifier: 0.0.14 - version: 0.0.14(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@graphql-tools/load': - specifier: 8.0.2 - version: 8.0.2(graphql@16.10.0) - '@graphql-tools/load-files': - specifier: 7.0.0 - version: 7.0.0(graphql@16.10.0) - '@graphql-tools/merge': - specifier: 9.0.4 - version: 9.0.4(graphql@16.10.0) - '@graphql-tools/schema': - specifier: 10.0.4 - version: 10.0.4(graphql@16.10.0) - '@graphql-tools/stitch': - specifier: ^9.2.10 - version: 9.4.28(graphql@16.10.0) - '@graphql-tools/utils': - specifier: ^10.2.3 - version: 10.9.1(graphql@16.10.0) - '@types/cors': - specifier: ^2.8.17 - version: 2.8.19 - app-commons: - specifier: workspace:* - version: link:../app-commons - bech32: - specifier: 2.0.0 - version: 2.0.0 - bignumber.js: - specifier: 9.1.2 - version: 9.1.2 - commander: - specifier: 12.1.0 - version: 12.1.0 - cors: - specifier: ^2.8.5 - version: 2.8.5 dayjs: specifier: 1.11.11 version: 1.11.11 @@ -847,64 +808,22 @@ importers: version: 16.4.5 drizzle-orm: specifier: ^0.31.2 - version: 0.31.4(@types/better-sqlite3@7.6.11)(@types/pg@8.15.5)(@types/react@18.2.54)(better-sqlite3@11.3.0)(pg@8.16.3)(react@18.2.0) - ethers: - specifier: ^6.13.1 - version: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - express: - specifier: 5.0.0 - version: 5.0.0 + version: 0.31.4(@types/better-sqlite3@7.6.11)(@types/react@18.2.54)(better-sqlite3@11.3.0)(react@18.2.0) graphql: specifier: 16.10.0 version: 16.10.0 - graphql-yoga: - specifier: 5.6.0 - version: 5.6.0(graphql@16.10.0) - kafkajs: - specifier: 2.2.4 - version: 2.2.4 lodash: specifier: ^4.17.21 version: 4.17.21 - node-fetch: - specifier: 3.3.2 - version: 3.3.2 npm-run-all: specifier: ^4.1.5 version: 4.1.5 - pg: - specifier: ^8.12.0 - version: 8.16.3 - pg-boss: - specifier: 9.0.3 - version: 9.0.3 - pg-promise: - specifier: 11.9.1 - version: 11.9.1 - pino: - specifier: 9.2.0 - version: 9.2.0 - pino-pretty: - specifier: 11.2.1 - version: 11.2.1 - pm2: - specifier: ^5.4.1 - version: 5.4.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) shallow-equal-object: specifier: 1.1.1 version: 1.1.1 tai64: specifier: ^1.0.0 version: 1.0.0 - winston: - specifier: 3.13.0 - version: 3.13.0 - xstate: - specifier: ^5.14.0 - version: 5.20.2 - yargs: - specifier: 17.7.2 - version: 17.7.2 zod: specifier: 3.23.8 version: 3.23.8 @@ -914,7 +833,7 @@ importers: version: 0.26.0(typescript@5.9.2) '@graphql-codegen/cli': specifier: ^5.0.2 - version: 5.0.7(@types/node@20.19.10)(bufferutil@4.0.9)(crossws@0.3.5)(enquirer@2.3.6)(graphql@16.10.0)(typescript@5.9.2)(utf-8-validate@5.0.10) + version: 5.0.7(@types/node@20.19.10)(bufferutil@4.0.9)(crossws@0.3.5)(graphql@16.10.0)(typescript@5.9.2)(utf-8-validate@5.0.10) '@graphql-codegen/introspection': specifier: ^4.0.3 version: 4.0.3(graphql@16.10.0) @@ -933,39 +852,15 @@ importers: '@graphql-tools/graphql-file-loader': specifier: 8.0.1 version: 8.0.1(graphql@16.10.0) - '@swc/core': - specifier: 1.4.1 - version: 1.4.1(@swc/helpers@0.5.17) - '@swc/jest': - specifier: 0.2.36 - version: 0.2.36(@swc/core@1.4.1(@swc/helpers@0.5.17)) - '@testcontainers/postgresql': - specifier: 10.10.0 - version: 10.10.0 '@types/fs-extra': specifier: 11.0.4 version: 11.0.4 - '@types/jest': - specifier: 29.5.12 - version: 29.5.12 '@types/lodash': specifier: 4.17.6 version: 4.17.6 '@types/node': specifier: ^20.14.9 version: 20.19.10 - '@types/pg': - specifier: ^8.11.6 - version: 8.15.5 - '@types/yargs': - specifier: 17.0.32 - version: 17.0.32 - chalk: - specifier: 5.3.0 - version: 5.3.0 - drizzle-kit: - specifier: ^0.22.8 - version: 0.22.8 fs-extra: specifier: 11.2.0 version: 11.2.0 @@ -984,15 +879,9 @@ importers: graphql-tag: specifier: ^2.12.6 version: 2.12.6(graphql@16.10.0) - jest: - specifier: 29.7.0 - version: 29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)) - testcontainers: - specifier: 10.10.0 - version: 10.10.0 tsup: specifier: 8.1.0 - version: 8.1.0(@swc/core@1.4.1(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2))(typescript@5.9.2) + version: 8.1.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2))(typescript@5.9.2) tsx: specifier: 4.16.0 version: 4.16.0 @@ -1034,7 +923,7 @@ importers: version: 2.46.0(react@18.2.0) '@tailwindcss/typography': specifier: 0.5.10 - version: 0.5.10(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))) + version: 0.5.10(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))) clsx: specifier: 2.1.0 version: 2.1.0 @@ -1079,23 +968,23 @@ importers: version: 17.5.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) tailwind-variants: specifier: 0.1.20 - version: 0.1.20(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))) + version: 0.1.20(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))) tailwindcss: specifier: 3.4.4 - version: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + version: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) tailwindcss-animate: specifier: 1.0.7 - version: 1.0.7(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))) + version: 1.0.7(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))) tailwindcss-radix: specifier: 3.0.3 version: 3.0.3 tailwindcss-themer: specifier: 4.0.0 - version: 4.0.0(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))) + version: 4.0.0(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))) devDependencies: '@chialab/esbuild-plugin-postcss': specifier: ^0.18.0 - version: 0.18.0(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + version: 0.18.0(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) '@types/lodash': specifier: 4.14.202 version: 4.14.202 @@ -1128,10 +1017,10 @@ importers: version: 5.4.5 vite: specifier: ^6.0.0 - version: 6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) + version: 6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^4.3.1 - version: 4.3.2(typescript@5.4.5)(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) + version: 4.3.2(typescript@5.4.5)(vite@6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) packages: @@ -1777,9 +1666,6 @@ packages: resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} engines: {node: '>=6.9.0'} - '@balena/dockerignore@1.0.2': - resolution: {integrity: sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==} - '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -1878,10 +1764,6 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} - '@colors/colors@1.6.0': - resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} - engines: {node: '>=0.1.90'} - '@confio/ics23@0.6.8': resolution: {integrity: sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==} deprecated: Unmaintained. The codebase for this package was moved to https://github.com/cosmos/ics23 but then the JS implementation was removed in https://github.com/cosmos/ics23/pull/353. Please consult the maintainers of https://github.com/cosmos for further assistance. @@ -2167,9 +2049,6 @@ packages: peerDependencies: postcss: ^8.4 - '@dabh/diagnostics@2.0.3': - resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} - '@depay/solana-web3.js@1.98.3': resolution: {integrity: sha512-wxr+2gpjKRZ1eVBLhQYJxImDsRukk0DvCsEElkTMyybP+7SamWRs48o3DYE6VLEgQJFZgOoUec3t5FM5s1J1ww==} @@ -2223,14 +2102,6 @@ packages: resolution: {integrity: sha512-CsFmA3u3c2QoLDTfEpGr4t25fjMU31nyvse7IzWTvb0ZycuPjMjb0fjlheh+PbhBYb9YLugnT2uY6Mwcg1o+Zg==} engines: {node: '>=18.0.0'} - '@esbuild-kit/core-utils@3.3.2': - resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} - deprecated: 'Merged into tsx: https://tsx.hirok.io' - - '@esbuild-kit/esm-loader@2.6.5': - resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} - deprecated: 'Merged into tsx: https://tsx.hirok.io' - '@esbuild/aix-ppc64@0.25.3': resolution: {integrity: sha512-W8bFfPA8DowP8l//sxjJLSLkD8iEjMc7cBVyP+u4cEv9sM7mdUCkgsj+t0n/BWPFtv7WWCN5Yzj0N6FJNUUqBQ==} engines: {node: '>=18'} @@ -2925,6 +2796,11 @@ packages: '@fuels/react-xstore@0.23.0': resolution: {integrity: sha512-MJdHDiGL1/X9mjSUhRWpO1IvHK+0K1DATEBtmKyY0zW75zZx5v2t46uYlbG4DwqCJsFHuwMkswe2M/2NaMwrcg==} + peerDependencies: + '@xstate/react': ^3.2.2 + react: ^18.2.0 + react-dom: ^18.2.0 + xstate: ^4.38.2 '@fuels/react@0.44.1': resolution: {integrity: sha512-cc2cYzIAB66yYGl5ENoZCWyvcrEfVAyjSqTBtX95411BNXzd2uvfAEh3Yrh/DS3G7/1hiORZeRMXSdEWDQUAaA==} @@ -3066,12 +2942,6 @@ packages: peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - '@graphql-tools/batch-delegate@9.0.41': - resolution: {integrity: sha512-ypPT32Ba4imLoXuDYbmCzU7E7i6y9TzJW/JYgt1CQZZy5BJUNnIQ2SE4AnttnyzSfGbYd3aMiVVSK9Ta3E3dKA==} - engines: {node: '>=18.0.0'} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - '@graphql-tools/batch-execute@9.0.19': resolution: {integrity: sha512-VGamgY4PLzSx48IHPoblRw0oTaBa7S26RpZXt0Y4NN90ytoE0LutlpB2484RbkfcTjv9wa64QD474+YP1kEgGA==} engines: {node: '>=18.0.0'} @@ -3239,12 +3109,6 @@ packages: peerDependencies: graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - '@graphql-tools/stitch@9.4.28': - resolution: {integrity: sha512-an9j0x5C1bV6OgHcrLtKCFsNDKeiaX9BNUzJpOaVlUzmEEpiLaSTLOen+MBEMaNZ49ZA688UQtOMa2JJHusNsA==} - engines: {node: '>=18.0.0'} - peerDependencies: - graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - '@graphql-tools/url-loader@8.0.33': resolution: {integrity: sha512-Fu626qcNHcqAj8uYd7QRarcJn5XZ863kmxsg1sm0fyjyfBJnsvC7ddFt6Hayz5kxVKfsnjxiDfPMXanvsQVBKw==} engines: {node: '>=16.0.0'} @@ -3665,20 +3529,6 @@ packages: engines: {node: '>=18'} hasBin: true - '@pm2/agent@2.0.4': - resolution: {integrity: sha512-n7WYvvTJhHLS2oBb1PjOtgLpMhgImOq8sXkPBw6smeg9LJBWZjiEgPKOpR8mn9UJZsB5P3W4V/MyvNnp31LKeA==} - - '@pm2/io@6.0.1': - resolution: {integrity: sha512-KiA+shC6sULQAr9mGZ1pg+6KVW9MF8NpG99x26Lf/082/Qy8qsTCtnJy+HQReW1A9Rdf0C/404cz0RZGZro+IA==} - engines: {node: '>=6.0'} - - '@pm2/js-api@0.8.0': - resolution: {integrity: sha512-nmWzrA/BQZik3VBz+npRcNIu01kdBhWL0mxKmP1ciF/gTcujPTQqt027N9fc1pK9ERM8RipFhymw7RcmCyOEYA==} - engines: {node: '>=4.0'} - - '@pm2/pm2-version-check@1.0.4': - resolution: {integrity: sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==} - '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -6035,9 +5885,6 @@ packages: peerDependencies: react: ^18 || ^19 - '@testcontainers/postgresql@10.10.0': - resolution: {integrity: sha512-cgzYnhzsYPVwN370bjJCuyAkkjLhGD6EBoQi4j+xKomMU4e6FWu0SYDolP+tiFGKWaS95SsIY3CPp6bnuxBh/A==} - '@testing-library/dom@9.3.4': resolution: {integrity: sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==} engines: {node: '>=14'} @@ -6080,9 +5927,6 @@ packages: resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} - '@tootallnate/quickjs-emscripten@0.23.0': - resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - '@tsconfig/node10@1.0.11': resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} @@ -6125,9 +5969,6 @@ packages: '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} - '@types/cors@2.8.19': - resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} - '@types/d3-array@3.2.1': resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} @@ -6161,12 +6002,6 @@ packages: '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} - '@types/docker-modem@3.0.6': - resolution: {integrity: sha512-yKpAGEuKRSS8wwx0joknWxsmLha78wNMe9R2S3UNsVOkZded8UqOrV8KoeDXoXsjndxwyF3eIhyClGbO1SEhEg==} - - '@types/dockerode@3.3.42': - resolution: {integrity: sha512-U1jqHMShibMEWHdxYhj3rCMNCiLx5f35i4e3CEUuW+JSSszc/tVqc6WCAPdhwBymG5R/vgbcceagK0St7Cq6Eg==} - '@types/dom-screen-wake-lock@1.0.3': resolution: {integrity: sha512-3Iten7X3Zgwvk6kh6/NRdwN7WbZ760YgFCsF5AxDifltUQzW1RaW+WRmcVtgwFzLjaNu64H+0MPJ13yRa8g3Dw==} @@ -6239,15 +6074,9 @@ packages: '@types/node@20.19.10': resolution: {integrity: sha512-iAFpG6DokED3roLSP0K+ybeDdIX6Bc0Vd3mLW5uDqThPWtNos3E+EqOM11mPQHKzfWHqEBuLjIlsBQQ8CsISmQ==} - '@types/node@22.7.5': - resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} - '@types/pbkdf2@3.1.2': resolution: {integrity: sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==} - '@types/pg@8.15.5': - resolution: {integrity: sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==} - '@types/prop-types@15.7.15': resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} @@ -6266,15 +6095,6 @@ packages: '@types/secp256k1@4.0.6': resolution: {integrity: sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==} - '@types/ssh2-streams@0.1.12': - resolution: {integrity: sha512-Sy8tpEmCce4Tq0oSOYdfqaBpA3hDM8SoxoFh5vzFsu2oL+znzGz8oVWW7xb4K920yYMUY+PIG31qZnFMfPWNCg==} - - '@types/ssh2@0.5.52': - resolution: {integrity: sha512-lbLLlXxdCZOSJMCInKH2+9V/77ET2J6NPQHpFI0kda61Dd1KglJs+fPQBchizmzYSOJBgdTajhPqBO1xxLywvg==} - - '@types/ssh2@1.15.5': - resolution: {integrity: sha512-N1ASjp/nXH3ovBHddRJpli4ozpk6UdDYIX4RJWFa9L1YKnzdhTlVmiGHm4DZnj/jLbqZpes4aeR30EFGQtvhQQ==} - '@types/stack-utils@2.0.3': resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} @@ -6284,9 +6104,6 @@ packages: '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} - '@types/triple-beam@1.3.5': - resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} - '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -6780,10 +6597,6 @@ packages: 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-globals@7.0.1: resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} @@ -6828,16 +6641,6 @@ packages: amazon-cognito-identity-js@6.3.15: resolution: {integrity: sha512-G2mzTlGYHKYh9oZDO0Gk94xVQ4iY9GYWBaYScbDYvz05ps6dqi0IvdNx1Lxi7oA3tjS5X+mUN7/svFJJdOB9YA==} - amp-message@0.1.2: - resolution: {integrity: sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg==} - - amp@0.3.1: - resolution: {integrity: sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw==} - - 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'} @@ -6881,18 +6684,6 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - archiver-utils@2.1.0: - resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} - engines: {node: '>= 6'} - - archiver-utils@3.0.4: - resolution: {integrity: sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==} - engines: {node: '>= 10'} - - archiver@5.3.2: - resolution: {integrity: sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==} - engines: {node: '>= 10'} - arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} @@ -6934,13 +6725,6 @@ packages: asn1.js@4.10.1: resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} - asn1@0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - - assert-options@0.8.1: - resolution: {integrity: sha512-5lNGRB5g5i2bGIzb+J1QQE1iKU/WEMVBReFIc5pPDWjcPj23otPL0eI6PB2v7QPi0qU6Mhym5D3y0ZiSIOf3GA==} - engines: {node: '>=10.0.0'} - assert@2.1.0: resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} @@ -6948,10 +6732,6 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - ast-types@0.13.4: - resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} - engines: {node: '>=4'} - ast-types@0.16.1: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} @@ -6964,9 +6744,6 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} - async-lock@1.4.1: - resolution: {integrity: sha512-Az2ZTpuytrtqENulXwO3GGv1Bztugx6TT37NIo7imr/Qo0gsYiGtSdBa2B6fsXhTpVZDNfu1Qn3pk531e3q+nQ==} - async-mutex@0.2.6: resolution: {integrity: sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==} @@ -6976,9 +6753,6 @@ packages: async@2.6.4: resolution: {integrity: sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==} - async@3.2.6: - resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} - asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} @@ -7019,9 +6793,6 @@ packages: axios@1.15.0: resolution: {integrity: sha512-wWyJDlAatxk30ZJer+GeCWS209sA42X+N5jU2jy6oHTp7ufw8uzUTVFBX9+wTfAlhiJXGS0Bq7X6efruWjuK9Q==} - b4a@1.6.7: - resolution: {integrity: sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==} - babel-jest@29.7.0: resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7063,36 +6834,6 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - bare-events@2.6.1: - resolution: {integrity: sha512-AuTJkq9XmE6Vk0FJVNq5QxETrSA/vKHarWVBG5l/JbdCL1prJemiyJqUS0jrlXO0MftuPq4m3YVYhoNc5+aE/g==} - - bare-fs@4.2.0: - resolution: {integrity: sha512-oRfrw7gwwBVAWx9S5zPMo2iiOjxyiZE12DmblmMQREgcogbNO0AFaZ+QBxxkEXiPspcpvO/Qtqn8LabUx4uYXg==} - engines: {bare: '>=1.16.0'} - peerDependencies: - bare-buffer: '*' - peerDependenciesMeta: - bare-buffer: - optional: true - - bare-os@3.6.1: - resolution: {integrity: sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==} - engines: {bare: '>=1.14.0'} - - bare-path@3.0.0: - resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} - - bare-stream@2.7.0: - resolution: {integrity: sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==} - peerDependencies: - bare-buffer: '*' - bare-events: '*' - peerDependenciesMeta: - bare-buffer: - optional: true - bare-events: - optional: true - base-x@3.0.11: resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} @@ -7105,14 +6846,6 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - basic-ftp@5.2.0: - resolution: {integrity: sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==} - engines: {node: '>=10.0.0'} - deprecated: Security vulnerability fixed in 5.2.1, please upgrade - - bcrypt-pbkdf@1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - bech32@1.1.4: resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} @@ -7149,11 +6882,6 @@ packages: blakejs@1.2.1: resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} - blessed@0.1.81: - resolution: {integrity: sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==} - engines: {node: '>= 0.8.0'} - hasBin: true - bluebird@3.4.7: resolution: {integrity: sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==} @@ -7166,13 +6894,6 @@ packages: bn.js@5.2.2: resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} - bodec@0.1.0: - resolution: {integrity: sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ==} - - body-parser@2.2.0: - resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} - engines: {node: '>=18'} - borsh@0.7.0: resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} @@ -7245,9 +6966,6 @@ packages: buffer-alloc@1.2.0: resolution: {integrity: sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==} - buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - buffer-fill@1.0.0: resolution: {integrity: sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ==} @@ -7278,10 +6996,6 @@ packages: resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} engines: {node: '>=6.14.2'} - buildcheck@0.0.6: - resolution: {integrity: sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==} - engines: {node: '>=10.0.0'} - builtin-status-codes@3.0.0: resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} @@ -7301,14 +7015,6 @@ packages: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} - byline@5.0.0: - resolution: {integrity: sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==} - engines: {node: '>=0.10.0'} - - bytes@3.1.2: - resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} - engines: {node: '>= 0.8'} - cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -7410,9 +7116,6 @@ packages: chardet@2.1.0: resolution: {integrity: sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==} - charm@0.1.2: - resolution: {integrity: sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==} - chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -7466,10 +7169,6 @@ packages: resolution: {integrity: sha512-IqLQi4lO0nIB4tcdTpN4LCB9FI3uqrJZK7RC515EnhZ6qBaglkIgICb1wjeAqpdoOabm1+SuQtkXIPdYC93jhQ==} engines: {node: '>= 0.2.0'} - cli-tableau@2.0.1: - resolution: {integrity: sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==} - engines: {node: '>=8.10.0'} - cli-truncate@2.1.0: resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} engines: {node: '>=8'} @@ -7531,9 +7230,6 @@ packages: resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} hasBin: true - color@3.2.1: - resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} - color@4.2.3: resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} engines: {node: '>=12.5.0'} @@ -7545,9 +7241,6 @@ packages: resolution: {integrity: sha512-pFGrxThWcWQ2MsAz6RtgeWe4NK2kUE1WfsrvvlctdII745EW9I0yflqhe7++M5LEc7bV2c/9/5zc8sFcpL0Drw==} engines: {node: '>=0.1.90'} - colorspace@1.1.4: - resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} - combined-stream@1.0.8: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} @@ -7572,9 +7265,6 @@ packages: resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} engines: {node: '>=20'} - commander@2.15.1: - resolution: {integrity: sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==} - commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -7593,10 +7283,6 @@ packages: compare-versions@6.1.1: resolution: {integrity: sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==} - compress-commons@4.1.2: - resolution: {integrity: sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==} - engines: {node: '>= 10'} - concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -7619,38 +7305,18 @@ packages: constants-browserify@1.0.0: resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} - 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@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} cookie-es@1.2.2: resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} - 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'} - copy-to-clipboard@3.3.3: resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} 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'} - cosmiconfig@8.3.6: resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} engines: {node: '>=14'} @@ -7663,19 +7329,11 @@ packages: cosmjs-types@0.9.0: resolution: {integrity: sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ==} - cpu-features@0.0.10: - resolution: {integrity: sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==} - engines: {node: '>=10.0.0'} - crc-32@1.2.2: resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} engines: {node: '>=0.8'} hasBin: true - crc32-stream@4.0.3: - resolution: {integrity: sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==} - engines: {node: '>= 10'} - create-ecdh@4.0.4: resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} @@ -7696,14 +7354,6 @@ packages: create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} - cron-parser@4.9.0: - resolution: {integrity: sha512-p0SaNjrHOnQeR8/VnfGbmg9te2kfyYSQ7Sc/j/6DtPL3JQvKxmjO9TSjNFpujqV3vEYYBvNNvXSxzyksBWAx1Q==} - engines: {node: '>=12.0.0'} - deprecated: v4 is no longer maintained, upgrade to v5 - - croner@4.1.97: - resolution: {integrity: sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==} - cross-argv@2.0.0: resolution: {integrity: sha512-YIaY9TR5Nxeb8SMdtrU8asWVM4jqJDNDYlKV21LxtYcfNJhp1kEsgSa6qXwXgzN0WQWGODps0+TlGp2xQSHwOg==} @@ -7788,9 +7438,6 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - culvert@0.1.2: - resolution: {integrity: sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==} - d3-array@3.2.4: resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} engines: {node: '>=12'} @@ -7839,10 +7486,6 @@ packages: resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} engines: {node: '>= 12'} - data-uri-to-buffer@6.0.2: - resolution: {integrity: sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==} - engines: {node: '>= 14'} - data-urls@3.0.2: resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} engines: {node: '>=12'} @@ -7866,18 +7509,12 @@ packages: resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} engines: {node: '>=0.11'} - dateformat@4.6.3: - resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} - dayjs@1.11.10: resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==} dayjs@1.11.11: resolution: {integrity: sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==} - dayjs@1.8.36: - resolution: {integrity: sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==} - debounce@1.2.1: resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} @@ -7898,15 +7535,6 @@ packages: 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.3.7: resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} engines: {node: '>=6.0'} @@ -7990,10 +7618,6 @@ packages: defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - degenerator@5.0.1: - resolution: {integrity: sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==} - engines: {node: '>= 14'} - delay@5.0.0: resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} engines: {node: '>=10'} @@ -8002,10 +7626,6 @@ packages: 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'} - dependency-graph@0.11.0: resolution: {integrity: sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==} engines: {node: '>= 0.6.0'} @@ -8070,18 +7690,6 @@ packages: dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} - docker-compose@0.24.8: - resolution: {integrity: sha512-plizRs/Vf15H+GCVxq2EUvyPK7ei9b/cVesHvjnX4xaXjM9spHe2Ytq0BitndFgvTJ3E3NljPNUEl7BAN43iZw==} - engines: {node: '>= 6.0.0'} - - docker-modem@3.0.8: - resolution: {integrity: sha512-f0ReSURdM3pcKPNS30mxOHSbaFLcknGmQjwSfmbcdOw1XWKXVhukM3NJHhr7NpY9BIyyWQb0EBo3KQvvuU5egQ==} - engines: {node: '>= 8.0'} - - dockerode@3.3.5: - resolution: {integrity: sha512-/0YNa3ZDNeLr/tSckmD69+Gq+qVNhvKfAHNeZJBnp7EOP6RGKV8ORrJHkUn20So5wU+xxT7+1n5u8PjHbfjbSA==} - engines: {node: '>= 8.0'} - dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} @@ -8111,10 +7719,6 @@ packages: resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} - drizzle-kit@0.22.8: - resolution: {integrity: sha512-VjI4wsJjk3hSqHSa3TwBf+uvH6M6pRHyxyoVbt935GUzP9tUR/BRZ+MhEJNgryqbzN2Za1KP0eJMTgKEPsalYQ==} - hasBin: true - drizzle-orm@0.31.4: resolution: {integrity: sha512-VGD9SH9aStF2z4QOTnVlVX/WghV/EnuEzTmsH3fSVp2E4fFgc8jl3viQrS/XUJx1ekW4rVVLJMH42SfGQdjX3Q==} peerDependencies: @@ -8224,9 +7828,6 @@ packages: eciesjs@0.3.21: resolution: {integrity: sha512-6FiThm7KlTihph8ROhq/BHEglGCJSwq6c8KVgcCcJiNJFNlbrFtfnTqZobVmWIB764mzhZTOBFyinADSXXvTLg==} - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.200: resolution: {integrity: sha512-rFCxROw7aOe4uPTfIAx+rXv9cEcGx+buAF4npnhtTqCJk5KDFRnh3+KYj7rdVh6lsFt5/aPs+Irj9rZ33WMA7w==} @@ -8262,16 +7863,9 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - enabled@2.0.0: - resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} - encode-utf8@1.0.3: resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} @@ -8289,10 +7883,6 @@ packages: resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} - enquirer@2.3.6: - resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} - engines: {node: '>=8.6'} - entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -8350,11 +7940,6 @@ packages: es6-promisify@5.0.0: resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} - esbuild-register@3.6.0: - resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} - peerDependencies: - esbuild: '>=0.25.0' - esbuild@0.25.3: resolution: {integrity: sha512-qKA6Pvai73+M2FtftpNKRxJ78GIjmFXFxd/1DVBqGo/qNhLSfv+G12n9pNoWdytJC8U00TrViOwpjT0zgqQS8Q==} engines: {node: '>=18'} @@ -8369,9 +7954,6 @@ packages: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} - 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'} @@ -8380,10 +7962,6 @@ packages: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} engines: {node: '>=8'} - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - escodegen@2.1.0: resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} engines: {node: '>=6.0'} @@ -8408,10 +7986,6 @@ packages: 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'} - eth-block-tracker@7.1.0: resolution: {integrity: sha512-8YdplnuE1IK4xfqpf4iU7oBxnOYAc35934o083G8ao+8WM8QQtt/mVlAY6yIAdY1eMeLqg4Z//PZjJGmWGPMRg==} engines: {node: '>=14.0.0'} @@ -8443,20 +8017,10 @@ packages: resolution: {integrity: sha512-kPHNTnhVWiWU6AVo6CAeTjXEK24SpCXyZvwG9ROFjT0Vlux0EOhWKBAeC+45iDj80QNJTYaT1SDEmeunT0vDNw==} engines: {node: '>=14.0.0'} - ethers@6.15.0: - resolution: {integrity: sha512-Kf/3ZW54L4UT0pZtsY/rf+EkBU7Qi5nnhonjUb8yTXcxH3cdcWrV2cRyk0Xk/4jK6OoHhxxZHriyhje20If2hQ==} - engines: {node: '>=14.0.0'} - event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} - eventemitter2@0.4.14: - resolution: {integrity: sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==} - - eventemitter2@5.0.1: - resolution: {integrity: sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==} - eventemitter2@6.4.9: resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} @@ -8507,10 +8071,6 @@ packages: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - express@5.0.0: - resolution: {integrity: sha512-V4UkHQc+B7ldh1YC84HCXHwf60M4BOMvp9rkvTUWCK5apqDC1Esnbid4wm6nFyVuDy8XMfETsJw5lsIGBWyo0A==} - engines: {node: '>= 18'} - extension-port-stream@3.0.0: resolution: {integrity: sha512-an2S5quJMiy5bnZKEf6AkfH/7r8CzHvhchU40gxN+OM6HPhe7Z9T1FUychcf2M9PpPOO0Hf7BAEfJkw2TDIBDw==} engines: {node: '>=12.0.0'} @@ -8519,9 +8079,6 @@ packages: resolution: {integrity: sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==} engines: {node: ^10.17.0 || ^12.0.0 || >= 13.7.0} - extrareqp2@1.0.0: - resolution: {integrity: sha512-Gum0g1QYb6wpPJCVypWP3bbIuaibcFiJcpuPM10YSXp/tzqi84x9PJageob+eN4xVRIOto4wjSGNLyMD54D2xA==} - eyes@0.1.8: resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} engines: {node: '> 0.1.90'} @@ -8529,9 +8086,6 @@ packages: fast-base64-decode@1.0.0: resolution: {integrity: sha512-qwaScUgUGBYeDNRnbc/KyllVU88Jk1pRHPStuF/lO7B0/RTRLj7U0lkdTAutlBblY08rwZDff6tNU9cjv6j//Q==} - fast-copy@3.0.2: - resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==} - fast-decode-uri-component@1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} @@ -8542,16 +8096,10 @@ packages: resolution: {integrity: sha512-V7/RktU11J3I36Nwq2JnZEM7tNm17eBJz+u25qdxBZeCKiX6BkVSZQjwWIr+IobgnZy+ag73tTZgZi7tr0LrBw==} engines: {node: '>=6.0.0'} - 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-patch@3.1.1: - resolution: {integrity: sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==} - fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} @@ -8593,9 +8141,6 @@ packages: fbjs@3.0.5: resolution: {integrity: sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg==} - fclone@1.0.11: - resolution: {integrity: sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==} - fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -8605,9 +8150,6 @@ packages: picomatch: optional: true - fecha@4.2.3: - resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} - fetch-blob@3.2.0: resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} engines: {node: ^12.20 || >= 14.13} @@ -8630,10 +8172,6 @@ packages: resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} engines: {node: '>=0.10.0'} - finalhandler@2.1.0: - resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} - engines: {node: '>= 0.8'} - find-up@3.0.0: resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} engines: {node: '>=6'} @@ -8646,9 +8184,6 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - fn.name@1.1.0: - resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} - follow-redirects@1.15.11: resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} engines: {node: '>=4.0'} @@ -8674,10 +8209,6 @@ packages: resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} engines: {node: '>=12.20.0'} - forwarded@0.2.0: - resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} - engines: {node: '>= 0.6'} - fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} @@ -8712,10 +8243,6 @@ packages: framesync@6.0.1: resolution: {integrity: sha512-fUY88kXvGiIItgNC7wcTOl0SNRCVXMKSWW2Yzfmn7EKNc+MpCzcz9DhdHcdjbrtN3c6R4H5dTY2jiCpPdysEjA==} - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} - fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -8803,10 +8330,6 @@ packages: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} - get-port@5.1.1: - resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} - engines: {node: '>=8'} - get-port@6.1.2: resolution: {integrity: sha512-BrGGraKm2uPqurfGVj/z97/zv8dPleC6x9JBNRTrDNtCkkRF4rPwrQXFgL7+I+q8QSdU4ntLQX2D7KIxSy8nGw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -8833,21 +8356,6 @@ packages: get-tsconfig@4.7.2: resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} - get-uri@6.0.5: - resolution: {integrity: sha512-b1O07XYq8eRuVzBNgJLstU6FYc1tS6wnMtF1I1D9lE8LxZSOGZ7LhxN54yPP6mGw5f2CkXY2BQUL9Fx41qvcIg==} - engines: {node: '>= 14'} - - git-node-fs@1.0.0: - resolution: {integrity: sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ==} - peerDependencies: - js-git: ^0.7.8 - peerDependenciesMeta: - js-git: - optional: true - - git-sha1@0.1.2: - resolution: {integrity: sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==} - github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} @@ -9066,9 +8574,6 @@ packages: header-case@2.0.4: resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} - help-me@5.0.0: - resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} - hey-listen@1.0.8: resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} @@ -9088,10 +8593,6 @@ packages: html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - http-errors@2.0.0: - resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} - engines: {node: '>= 0.8'} - http-parser-js@0.5.10: resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} @@ -9150,10 +8651,6 @@ packages: i18next@23.11.5: resolution: {integrity: sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==} - iconv-lite@0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -9235,14 +8732,6 @@ packages: invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} - ip-address@10.0.1: - resolution: {integrity: sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA==} - engines: {node: '>= 12'} - - ipaddr.js@1.9.1: - resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} - engines: {node: '>= 0.10'} - iron-webcrypto@1.2.1: resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} @@ -9367,9 +8856,6 @@ packages: is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} - 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'} @@ -9698,9 +9184,6 @@ packages: js-cookies@1.0.4: resolution: {integrity: sha512-cO1SHDH7zJsi8FihHmDtcWx90mWmrfGOrcLKPeaEX6tLyuTK2wnzgdmNa34Q6rNAd6VhQUgjDt5Eyl90VI/Fpg==} - js-git@0.7.8: - resolution: {integrity: sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==} - js-sha3@0.8.0: resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} @@ -9772,10 +9255,6 @@ packages: just-unique@4.2.0: resolution: {integrity: sha512-cxQGGUiit6CGUpuuiezY8N4m1wgF4o7127rXEXDFcxeDUFfdV7gSkwA26Fe2wWBiNQq2SZOgN4gSmMxB/StA8Q==} - kafkajs@2.2.4: - resolution: {integrity: sha512-j/YeapB1vfPT2iOIUn/vxdyKEuhuY2PxMBvf5JWux6iSaukAccrMtXEY/Lb7OvavDhOWME589bpLrEdnVHjfjA==} - engines: {node: '>=14.0.0'} - keccak@3.0.4: resolution: {integrity: sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==} engines: {node: '>=10.0.0'} @@ -9787,17 +9266,6 @@ packages: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} - kuler@2.0.0: - resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} - - lazy@1.0.11: - resolution: {integrity: sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==} - engines: {node: '>=0.2.0'} - - lazystream@1.0.1: - resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} - engines: {node: '>= 0.6.3'} - leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} @@ -9961,15 +9429,6 @@ packages: lodash.clonedeep@4.5.0: resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} - lodash.debounce@4.0.8: - resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} - - lodash.defaults@4.2.0: - resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} - - lodash.difference@4.5.0: - resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==} - lodash.flatten@4.4.0: resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==} @@ -9995,9 +9454,6 @@ packages: lodash.truncate@4.4.2: resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} - lodash.union@4.6.0: - resolution: {integrity: sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==} - lodash@4.17.21: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} @@ -10013,10 +9469,6 @@ packages: resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==} engines: {node: '>=18'} - logform@2.7.0: - resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==} - engines: {node: '>= 12.0.0'} - long@4.0.0: resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} @@ -10039,18 +9491,6 @@ packages: lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lru-cache@6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - - lru-cache@7.18.3: - resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} - engines: {node: '>=12'} - - luxon@3.7.1: - resolution: {integrity: sha512-RkRWjA926cTvz5rAb1BqyWkKbbjzCGchDUIKMCUvNi17j6f6j8uHGDV82Aqcqtzd+icoYpELmG3ksgGiFNNcNg==} - engines: {node: '>=12'} - lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true @@ -10088,10 +9528,6 @@ packages: mdn-data@2.0.14: resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} - media-typer@1.1.0: - resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} - engines: {node: '>= 0.8'} - memoize-one@5.2.1: resolution: {integrity: sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==} @@ -10099,10 +9535,6 @@ packages: resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} engines: {node: '>= 0.10.0'} - merge-descriptors@2.0.0: - resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} - engines: {node: '>=18'} - merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -10122,10 +9554,6 @@ packages: mersenne-twister@1.1.0: resolution: {integrity: sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA==} - methods@1.1.2: - resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} - engines: {node: '>= 0.6'} - micro-ftch@0.3.1: resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==} @@ -10145,18 +9573,10 @@ packages: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - 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.1: - resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} - engines: {node: '>= 0.6'} - mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -10190,10 +9610,6 @@ packages: resolution: {integrity: sha512-lIUdtK5hdofgCTu3aT0sOaHsYR37viUuIc0rwnnDXImbwFRcumyLMeZaM0t0I/fgxS6s6JMfu0rLD1Wz9pv1ng==} 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'} @@ -10224,11 +9640,6 @@ packages: 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.1: resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} engines: {node: '>=10'} @@ -10238,9 +9649,6 @@ packages: resolution: {integrity: sha512-CxBoEVKh5U4DH3XuNbc5ONLF6dQBc8dSc7pdZ1957FGbIO5JBqGqqchhET9dTexri8/pk9xBL6+5ceOtCIp1QA==} engines: {node: '>=6'} - module-details-from-path@1.0.4: - resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} - moment@2.30.1: resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==} @@ -10262,9 +9670,6 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - nan@2.23.0: - resolution: {integrity: sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==} - nano-css@5.6.2: resolution: {integrity: sha512-+6bHaC8dSDGALM1HJjOHVXpuastdu2xFoZlC77Jh4cg+33Zcgm+Gxd+1xsnpZK14eyHObSp82+ll5y3SX75liw==} peerDependencies: @@ -10282,22 +9687,9 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - needle@2.4.0: - resolution: {integrity: sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==} - engines: {node: '>= 4.4.x'} - hasBin: true - - 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==} - netmask@2.0.2: - resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} - engines: {node: '>= 0.4.0'} - nice-try@1.0.5: resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} @@ -10384,10 +9776,6 @@ packages: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - nssocket@0.6.0: - resolution: {integrity: sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==} - engines: {node: '>= 0.10.x'} - nullthrows@1.1.1: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} @@ -10431,14 +9819,6 @@ packages: on-exit-leak-free@0.2.0: resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} - 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'} - on-net-listen@1.1.2: resolution: {integrity: sha512-y1HRYy8s/RlcBvDUwKXSmkODMdx4KSuIvloCnQYJ2LdBBC1asY4HtfhXwe3UWknLakATZDnbzht2Ijw3M1EqFg==} engines: {node: '>=9.4.0 || ^8.9.4'} @@ -10446,9 +9826,6 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - one-time@1.0.0: - resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} - onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} @@ -10512,20 +9889,9 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - pac-proxy-agent@7.2.0: - resolution: {integrity: sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==} - engines: {node: '>= 14'} - - pac-resolver@7.0.1: - resolution: {integrity: sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==} - engines: {node: '>= 14'} - package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - pako@0.2.9: - resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} - pako@1.0.11: resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} @@ -10555,10 +9921,6 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - parseurl@1.3.3: - resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} - engines: {node: '>= 0.8'} - pascal-case@3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} @@ -10607,10 +9969,6 @@ packages: 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@3.0.0: resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} engines: {node: '>=4'} @@ -10630,61 +9988,6 @@ packages: resolution: {integrity: sha512-wfRLBZ0feWRhCIkoMB6ete7czJcnNnqRpcoWQBLqatqXXmelSRqfdDK4F3u9T2s2cXas/hQJcryI/4lAL+XTlA==} engines: {node: '>=0.12'} - pg-boss@9.0.3: - resolution: {integrity: sha512-cUWUiv3sr563yNy0nCZ25Tv5U0m59Y9MhX/flm0vTR012yeVCrqpfboaZP4xFOQPdWipMJpuu4g94HR0SncTgw==} - engines: {node: '>=16'} - - pg-cloudflare@1.2.7: - resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==} - - pg-connection-string@2.9.1: - resolution: {integrity: sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==} - - pg-int8@1.0.1: - resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} - engines: {node: '>=4.0.0'} - - pg-minify@1.6.5: - resolution: {integrity: sha512-u0UE8veaCnMfJmoklqneeBBopOAPG3/6DHqGVHYAhz8DkJXh9dnjPlz25fRxn4e+6XVzdOp7kau63Rp52fZ3WQ==} - engines: {node: '>=14.0.0'} - - pg-pool@3.10.1: - resolution: {integrity: sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==} - peerDependencies: - pg: '>=8.0' - - pg-promise@11.9.1: - resolution: {integrity: sha512-qvMmyDvWd64X0a25hCuWV40GLMbgeYf4z7ZmzxQqGHtUIlzMtxcMtaBHAMr7XVOL62wFv2ZVKW5pFruD/4ZAOg==} - engines: {node: '>=14.0'} - - pg-protocol@1.10.3: - resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==} - - pg-types@2.2.0: - resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} - engines: {node: '>=4'} - - pg@8.12.0: - resolution: {integrity: sha512-A+LHUSnwnxrnL/tZ+OLfqR1SxLN3c/pgDztZ47Rpbsd4jUytsTtwQo/TLPRzPJMp/1pbhYVhH9cuSZLAajNfjQ==} - engines: {node: '>= 8.0.0'} - peerDependencies: - pg-native: '>=3.0.1' - peerDependenciesMeta: - pg-native: - optional: true - - pg@8.16.3: - resolution: {integrity: sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==} - engines: {node: '>= 16.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==} @@ -10710,14 +10013,6 @@ packages: engines: {node: '>=0.10'} hasBin: true - pidusage@2.0.21: - resolution: {integrity: sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==} - engines: {node: '>=8'} - - pidusage@3.0.2: - resolution: {integrity: sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w==} - engines: {node: '>=10'} - pify@2.3.0: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} @@ -10733,27 +10028,13 @@ packages: pino-abstract-transport@0.5.0: resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} - pino-abstract-transport@1.2.0: - resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==} - - pino-pretty@11.2.1: - resolution: {integrity: sha512-O05NuD9tkRasFRWVaF/uHLOvoRDFD7tb5VMertr78rbsYFjYp48Vg3477EshVAF5eZaEw+OpDl/tu+B0R5o+7g==} - hasBin: true - pino-std-serializers@4.0.0: resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} - pino-std-serializers@7.0.0: - resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} - pino@7.11.0: resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} hasBin: true - pino@9.2.0: - resolution: {integrity: sha512-g3/hpwfujK5a4oVbaefoJxezLzsDgLcNJeITvC6yrfwYeT9la+edCK42j5QpEQSQCZgTKapXvnQIdgZwvRaZug==} - hasBin: true - pirates@4.0.7: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} @@ -10776,29 +10057,6 @@ packages: engines: {node: '>=18'} hasBin: true - pm2-axon-rpc@0.7.1: - resolution: {integrity: sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==} - engines: {node: '>=5'} - - pm2-axon@4.0.1: - resolution: {integrity: sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg==} - engines: {node: '>=5'} - - pm2-deploy@1.0.2: - resolution: {integrity: sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==} - engines: {node: '>=4.0.0'} - - pm2-multimeter@0.1.2: - resolution: {integrity: sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==} - - pm2-sysmonit@1.2.8: - resolution: {integrity: sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA==} - - pm2@5.4.3: - resolution: {integrity: sha512-4/I1htIHzZk1Y67UgOCo4F1cJtas1kSds31N8zN0PybO230id1nigyjGuGFzUnGmUFPmrJ0On22fO1ChFlp7VQ==} - engines: {node: '>=12.0.0'} - hasBin: true - pngjs@3.4.0: resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==} engines: {node: '>=4.0.0'} @@ -11044,22 +10302,6 @@ packages: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} - 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'} - preact@10.27.0: resolution: {integrity: sha512-/DTYoB6mwwgPytiqQTh/7SFRL98ZdiD8Sk8zIUVOxtwq4oWcwrcd1uno9fE/zZmUaUrFNYzbH14CPebOz9tZQw==} @@ -11098,9 +10340,6 @@ packages: process-warning@1.0.0: resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} - process-warning@3.0.0: - resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} - process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} @@ -11112,9 +10351,6 @@ packages: promise@7.3.1: resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} - promptly@2.2.0: - resolution: {integrity: sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==} - prompts@2.4.2: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} @@ -11125,10 +10361,6 @@ packages: proper-lockfile@4.1.2: resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} - properties-reader@2.3.0: - resolution: {integrity: sha512-z597WicA7nDZxK12kZqHr2TcvwNU1GCfA5UwfDY/HDp3hXPoPlb5rlEx9bwGTiJnc0OqbBTkU975jDToth8Gxw==} - engines: {node: '>=14'} - property-expr@2.0.6: resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} @@ -11136,20 +10368,9 @@ packages: resolution: {integrity: sha512-NWWCCscLjs+cOKF/s/XVNFRW7Yih0fdH+9brffR5NZCy8k42yRdl5KlWKMVXuI1vfCoy4o1z80XR/W/QUb3V3w==} engines: {node: '>=12.0.0'} - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} - engines: {node: '>= 0.10'} - - proxy-agent@6.3.1: - resolution: {integrity: sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==} - engines: {node: '>= 14'} - proxy-compare@2.5.1: resolution: {integrity: sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA==} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - proxy-from-env@2.1.0: resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} engines: {node: '>=10'} @@ -11199,10 +10420,6 @@ packages: engines: {node: '>=10.13.0'} hasBin: true - 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'} @@ -11236,14 +10453,6 @@ packages: 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 @@ -11441,10 +10650,6 @@ packages: resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} engines: {node: '>=4'} - read@1.0.7: - resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} - engines: {node: '>=0.8'} - readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} @@ -11456,9 +10661,6 @@ packages: resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - readdir-glob@1.1.3: - resolution: {integrity: sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==} - readdirp@3.6.0: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} @@ -11474,10 +10676,6 @@ packages: resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} engines: {node: '>= 12.13.0'} - real-require@0.2.0: - resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} - engines: {node: '>= 12.13.0'} - recast@0.23.11: resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} engines: {node: '>= 4'} @@ -11528,10 +10726,6 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} - require-in-the-middle@5.2.0: - resolution: {integrity: sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg==} - engines: {node: '>=6'} - require-main-filename@2.0.0: resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} @@ -11628,10 +10822,6 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true - router@2.2.0: - resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} - engines: {node: '>= 18'} - rpc-websockets@7.11.0: resolution: {integrity: sha512-IkLYjayPv6Io8C/TdCL5gwgzd1hFz2vmBZrjMw/SPEXo51ETOhnzgS4Qy5GWi2JQN7HKHa66J3+2mv0fgNh/7w==} deprecated: deprecate 7.11.0 @@ -11649,9 +10839,6 @@ packages: run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - run-series@1.1.9: - resolution: {integrity: sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==} - rxjs@7.8.2: resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} @@ -11680,9 +10867,6 @@ packages: safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - sax@1.4.1: - resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==} - saxes@6.0.0: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} @@ -11708,9 +10892,6 @@ packages: resolution: {integrity: sha512-lDFs9AAIaWP9UCdtWrotXWWF9t8PWgQDcxqgAnpM9rMqxb3Oaq2J0thzPVSxBwdJgyQtkU/sYtFtbM1RSt/iYA==} engines: {node: '>=18.0.0'} - secure-json-parse@2.7.0: - resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} - semver@5.7.2: resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} hasBin: true @@ -11719,11 +10900,6 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} - engines: {node: '>=10'} - hasBin: true - semver@7.7.2: resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} engines: {node: '>=10'} @@ -11734,21 +10910,9 @@ packages: engines: {node: '>=10'} hasBin: true - send@1.2.0: - resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} - engines: {node: '>= 18'} - sentence-case@3.0.4: resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} - serialize-error@8.1.0: - resolution: {integrity: sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==} - engines: {node: '>=10'} - - serve-static@2.2.0: - resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} - engines: {node: '>= 18'} - set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} @@ -11771,9 +10935,6 @@ packages: setimmediate@1.0.5: resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - sha.js@2.4.12: resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} engines: {node: '>= 0.10'} @@ -11805,9 +10966,6 @@ packages: resolution: {integrity: sha512-Iov+JwFv/2HcTpcwNMKd8+IWNb8tboQJNQTkAY/LLVK7gGH9jy+LGkVqPxfekHl+yMmiqXszdGWXgkfml7hjqA==} engines: {node: '>= 0.4'} - shimmer@1.2.1: - resolution: {integrity: sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==} - side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -11873,10 +11031,6 @@ packages: resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} engines: {node: '>=18'} - smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} @@ -11892,23 +11046,12 @@ packages: resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} engines: {node: '>=10.0.0'} - socks-proxy-agent@8.0.5: - resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} - engines: {node: '>= 14'} - - socks@2.8.7: - resolution: {integrity: sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - solidity-ast@0.4.60: resolution: {integrity: sha512-UwhasmQ37ji1ul8cIp0XlrQ/+SVQhy09gGqJH4jnwdo2TgI6YIByzi0PI5QvIGcIdFOs1pbSmJW1pnWB7AVh2w==} sonic-boom@2.8.0: resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} - 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'} @@ -11916,9 +11059,6 @@ packages: 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.5.6: resolution: {integrity: sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA==} engines: {node: '>=0.10.0'} @@ -11948,13 +11088,6 @@ packages: spdx-license-ids@3.0.22: resolution: {integrity: sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==} - spex@3.3.0: - resolution: {integrity: sha512-VNiXjFp6R4ldPbVRYbpxlD35yRHceecVXlct1J4/X80KuuPnW2AXMq3sGwhnJOhKkUsOxAT6nRGfGE5pocVw5w==} - engines: {node: '>=10.0.0'} - - split-ca@1.0.1: - resolution: {integrity: sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ==} - split-on-first@1.1.0: resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} engines: {node: '>=6'} @@ -11969,22 +11102,9 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - sprintf-js@1.1.2: - resolution: {integrity: sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==} - - ssh-remote-port-forward@1.0.4: - resolution: {integrity: sha512-x0LV1eVDwjf1gmG7TTnfqIzf+3VPRz7vrNIjX6oYLbeCrf/PeVY6hkT68Mg+q02qXxQhrLjB0jfgvhevoCRmLQ==} - - ssh2@1.16.0: - resolution: {integrity: sha512-r1X4KsBGedJqo7h8F5c4Ybpcr5RjyP+aWIG007uBPRjmdQWfEiVLzSK71Zji1B9sKxwaCvD8y8cwSkYrlLiRRg==} - engines: {node: '>=10.16.0'} - stack-generator@2.0.10: resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==} - stack-trace@0.0.10: - resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} - stack-utils@2.0.6: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} @@ -12001,10 +11121,6 @@ packages: stacktrace-js@2.0.2: resolution: {integrity: sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==} - statuses@2.0.1: - resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} - engines: {node: '>= 0.8'} - std-env@4.1.0: resolution: {integrity: sha512-Rq7ybcX2RuC55r9oaPVEW7/xu3tj8u4GeBYHBWCychFtzMIr86A7e3PPEBPT37sHStKX3+TiX/Fr/ACmJLVlLQ==} @@ -12031,9 +11147,6 @@ packages: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} - streamx@2.22.1: - resolution: {integrity: sha512-znKXEBxfatz2GBNK02kRnCXjV+AA4kjZIUxeWSr3UGirZMJfTE9uiwKHobnbgxWyL/JWro8tTq+vOqAK1/qbSA==} - strict-uri-encode@2.0.0: resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} engines: {node: '>=4'} @@ -12196,12 +11309,6 @@ packages: resolution: {integrity: sha512-c7AfkZ9udatCuAy9RSfiGPpeOKKUAUK5e1cXadLOGUjasdxqYqAK0jTNkM/FSEyJ3a5Ra27j/tw/PS0qLmaF/A==} engines: {node: '>=18'} - systeminformation@5.27.7: - resolution: {integrity: sha512-saaqOoVEEFaux4v0K8Q7caiauRwjXC4XbD2eH60dxHXbpKxQ8kH9Rf7Jh+nryKpOUSEFxtCdBlSUx0/lO6rwRg==} - engines: {node: '>=8.0.0'} - os: [darwin, linux, win32, freebsd, openbsd, netbsd, sunos, android] - hasBin: true - table@6.9.0: resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} engines: {node: '>=10.0.0'} @@ -12246,16 +11353,10 @@ packages: tar-fs@2.0.1: resolution: {integrity: sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA==} - tar-fs@3.1.0: - resolution: {integrity: sha512-5Mty5y/sOF1YWj1J6GiBodjlDc05CUR8PKXrsnFAiSG0xA+GHeWLovaZPYUDXkH/1iKRf2+M5+OrRgzC7O9b7w==} - tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} - tar-stream@3.1.7: - resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==} - tar@7.4.3: resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} engines: {node: '>=18'} @@ -12265,18 +11366,9 @@ packages: resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} engines: {node: '>=8'} - testcontainers@10.10.0: - resolution: {integrity: sha512-XlAdr6XzxM9ywTc5D6xA97Ug8dCotDnrOgOqmy3vYnAwUYrzhzAwrp791g97QAMvDOYp2pxkJl/P4WxuUbGShw==} - - text-decoder@1.2.3: - resolution: {integrity: sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==} - text-encoding-utf-8@1.0.2: resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} - text-hex@1.0.0: - resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} - thenify-all@1.6.0: resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} engines: {node: '>=0.8'} @@ -12287,9 +11379,6 @@ packages: thread-stream@0.15.2: resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} - thread-stream@3.1.0: - resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} - throttle-debounce@3.0.1: resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==} engines: {node: '>=10'} @@ -12343,10 +11432,6 @@ packages: title-case@3.0.3: resolution: {integrity: sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA==} - tmp@0.2.5: - resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} - engines: {node: '>=14.14'} - tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} @@ -12361,10 +11446,6 @@ packages: toggle-selection@1.0.6: resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - toml@3.0.0: resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} @@ -12392,10 +11473,6 @@ packages: resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} hasBin: true - triple-beam@1.4.1: - resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} - engines: {node: '>= 14.0.0'} - ts-easing@0.2.0: resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==} @@ -12468,9 +11545,6 @@ packages: tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - tslib@1.9.3: - resolution: {integrity: sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==} - tslib@2.4.0: resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} @@ -12480,9 +11554,6 @@ packages: tslib@2.6.3: resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} - tslib@2.7.0: - resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} - tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -12574,24 +11645,10 @@ packages: resolution: {integrity: sha512-DUHWQAcC8BTiUZDRzAYGvpSpGLiaOQPfYXlCieQbwUvmml/LRGIe3raKdrOPOoiX0DYlzxs2nH6BoWJoZrj8hA==} hasBin: true - tv4@1.3.0: - resolution: {integrity: sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==} - engines: {node: '>= 0.8.0'} - - tweetnacl@0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} - - tx2@1.0.5: - resolution: {integrity: sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg==} - 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'} @@ -12608,10 +11665,6 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} - type-is@2.0.1: - resolution: {integrity: sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==} - engines: {node: '>= 0.6'} - typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} @@ -12670,9 +11723,6 @@ packages: undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} - undici-types@6.19.8: - resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} - undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -12707,10 +11757,6 @@ packages: resolution: {integrity: sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg==} engines: {node: '>=0.10.0'} - unpipe@1.0.0: - resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} - engines: {node: '>= 0.8'} - unstorage@1.16.1: resolution: {integrity: sha512-gdpZ3guLDhz+zWIlYP1UwQ259tG5T5vYRzDaHMkQ1bBY1SQPutvZnrRjTFaWUUpseErJIgAZS51h6NOcZVZiqQ==} peerDependencies: @@ -12852,10 +11898,6 @@ packages: util@0.12.5: resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} - utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - uuid-parse@1.1.0: resolution: {integrity: sha512-OdmXxA8rDsQ7YpNVbKSJkNzTw2I+S5WsbMDnCtIWSQaosNAcWtFuI/YK1TjzUI6nbkgiqEyh8gWngfcv8Asd9A==} @@ -12895,10 +11937,6 @@ packages: resolution: {integrity: sha512-Z6Uz+TYwEqE7ZN50gwn+1LCVo9ZVrpxRPOhOLnncYkY1ZzOYtrX8Fwf/rFktZ8R5mJms6EZf5TqNOMeZmnPq9Q==} engines: {node: '>=12'} - vary@1.1.2: - resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} - engines: {node: '>= 0.8'} - victory-vendor@36.9.2: resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} @@ -13008,10 +12046,6 @@ packages: jsdom: optional: true - vizion@2.2.1: - resolution: {integrity: sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww==} - engines: {node: '>=4.0'} - vm-browserify@1.1.2: resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} @@ -13115,14 +12149,6 @@ packages: engines: {node: '>=8'} hasBin: true - winston-transport@4.9.0: - resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} - engines: {node: '>= 12.0.0'} - - winston@3.13.0: - resolution: {integrity: sha512-rwidmA1w3SE4j0E5MuIufFhyJPBDG7Nu71RkZor1p2+qHvJSZ9GYDA81AyleQcZbh/+V6HjeBdfnTZJm9rSeQQ==} - engines: {node: '>= 12.0.0'} - wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} @@ -13210,9 +12236,6 @@ packages: xstate@5.0.0-beta.54: resolution: {integrity: sha512-BTnCPBQ2iTKe4uCnHEe1hNx6VTbXU+5mQGybSQHOjTLiBi4Ryi+tL9T6N1tmqagvM8rfl4XRfvndogfWCWcdpw==} - xstate@5.20.2: - resolution: {integrity: sha512-GZmLmc+WPKfFRxuTDAxCg0cUhS/ZnWaRD86DO8MKizeK4a050jd5k7UNnIQ2jJDWRig2/r0tmVXeezUNIhoz5Q==} - xstream@11.14.0: resolution: {integrity: sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==} @@ -13233,9 +12256,6 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - yallist@5.0.0: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} @@ -13288,10 +12308,6 @@ packages: yup@1.6.1: resolution: {integrity: sha512-JED8pB50qbA4FOkDol0bYF/p60qSEDQqBD0/qeIrUCG1KbPBIQ776fCUNb9ldbPcSTxA69g/47XTo4TqWiuXOA==} - zip-stream@4.1.1: - resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} - engines: {node: '>= 10'} - zod-validation-error@3.0.0: resolution: {integrity: sha512-x+agsJJG9rvC7axF0xqTEdZhJkLHyIZkdOAWDJSmwGPzxNHMHwtU6w2yDOAAP6yuSfTAUhAMJRBfhVGY64ySEQ==} engines: {node: '>=18.0.0'} @@ -14451,8 +13467,6 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@balena/dockerignore@1.0.2': {} - '@bcoe/v8-coverage@0.2.3': {} '@biomejs/biome@1.9.4': @@ -14498,11 +13512,11 @@ snapshots: lodash.mergewith: 4.6.2 react: 18.2.0 - '@chialab/esbuild-plugin-postcss@0.18.0(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))': + '@chialab/esbuild-plugin-postcss@0.18.0(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))': dependencies: '@chialab/esbuild-rna': 0.18.2 postcss: 8.4.35 - postcss-load-config: 4.0.2(postcss@8.4.35)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + postcss-load-config: 4.0.2(postcss@8.4.35)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) postcss-preset-env: 9.6.0(postcss@8.4.35) transitivePeerDependencies: - ts-node @@ -14544,8 +13558,6 @@ snapshots: '@colors/colors@1.5.0': optional: true - '@colors/colors@1.6.0': {} - '@confio/ics23@0.6.8': dependencies: '@noble/hashes': 1.8.0 @@ -14632,7 +13644,7 @@ snapshots: '@cosmjs/socket': 0.32.4(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@cosmjs/stream': 0.32.4 '@cosmjs/utils': 0.32.4 - axios: 1.15.0 + axios: 1.15.0(debug@4.4.1) readonly-date: 1.0.0 xstream: 11.14.0 transitivePeerDependencies: @@ -14644,7 +13656,7 @@ snapshots: '@cosmology/lcd@0.13.4': dependencies: - axios: 1.15.0 + axios: 1.15.0(debug@4.4.1) transitivePeerDependencies: - debug @@ -14890,23 +13902,17 @@ snapshots: dependencies: postcss: 8.4.35 - '@dabh/diagnostics@2.0.3': - dependencies: - colorspace: 1.1.4 - enabled: 2.0.0 - kuler: 2.0.0 - '@depay/solana-web3.js@1.98.3': dependencies: bs58: 5.0.0 '@depay/web3-blockchains@9.8.6': {} - '@depay/web3-client@10.18.6(@depay/solana-web3.js@1.98.3)(@depay/web3-blockchains@9.8.6)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@depay/web3-client@10.18.6(@depay/solana-web3.js@1.98.3)(@depay/web3-blockchains@9.8.6)(ethers@6.11.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@depay/solana-web3.js': 1.98.3 '@depay/web3-blockchains': 9.8.6 - ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ethers: 6.11.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@depay/web3-mock-evm@14.19.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: @@ -14960,16 +13966,6 @@ snapshots: '@whatwg-node/promise-helpers': 1.3.2 tslib: 2.8.1 - '@esbuild-kit/core-utils@3.3.2': - dependencies: - esbuild: 0.25.3 - source-map-support: 0.5.21 - - '@esbuild-kit/esm-loader@2.6.5': - dependencies: - '@esbuild-kit/core-utils': 3.3.2 - get-tsconfig: 4.7.2 - '@esbuild/aix-ppc64@0.25.3': optional: true @@ -15489,13 +14485,13 @@ snapshots: - debug - utf-8-validate - '@fuel-ts/abi-coder@0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/abi-coder@0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/crypto': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/crypto': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/errors': 0.100.0 - '@fuel-ts/hasher': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/hasher': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/math': 0.100.0 - '@fuel-ts/utils': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) type-fest: 4.34.1 transitivePeerDependencies: - vitest @@ -15511,24 +14507,13 @@ snapshots: transitivePeerDependencies: - vitest - '@fuel-ts/abi-coder@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': - dependencies: - '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/errors': 0.103.0 - '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/math': 0.103.0 - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - type-fest: 4.34.1 - transitivePeerDependencies: - - vitest - - '@fuel-ts/abi-coder@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/abi-coder@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/errors': 0.103.0 - '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/math': 0.103.0 - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) type-fest: 4.34.1 transitivePeerDependencies: - vitest @@ -15557,24 +14542,10 @@ snapshots: transitivePeerDependencies: - vitest - '@fuel-ts/abi-typegen@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': - dependencies: - '@fuel-ts/errors': 0.103.0 - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/versions': 0.103.0 - commander: 13.1.0 - glob: 10.4.5 - handlebars: 4.7.9 - mkdirp: 3.0.1 - ramda: 0.30.1 - rimraf: 5.0.10 - transitivePeerDependencies: - - vitest - - '@fuel-ts/abi-typegen@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/abi-typegen@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: '@fuel-ts/errors': 0.103.0 - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/versions': 0.103.0 commander: 13.1.0 glob: 10.4.5 @@ -15598,17 +14569,17 @@ snapshots: ramda: 0.30.1 rimraf: 5.0.10 - '@fuel-ts/account@0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/account@0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/abi-coder': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/address': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/crypto': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/abi-coder': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/address': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/crypto': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/errors': 0.100.0 - '@fuel-ts/hasher': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/hasher': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/math': 0.100.0 - '@fuel-ts/merkle': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/transactions': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/utils': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/merkle': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/transactions': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/versions': 0.100.0 '@fuels/vm-asm': 0.59.1 '@noble/curves': 1.8.1 @@ -15644,40 +14615,17 @@ snapshots: - encoding - vitest - '@fuel-ts/account@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': - dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/errors': 0.103.0 - '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/math': 0.103.0 - '@fuel-ts/merkle': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/versions': 0.103.0 - '@fuels/vm-asm': 0.62.0 - '@noble/curves': 1.8.1 - events: 3.3.0 - graphql: 16.10.0 - graphql-request: 6.1.0(graphql@16.10.0) - graphql-tag: 2.12.6(graphql@16.10.0) - ramda: 0.30.1 - transitivePeerDependencies: - - encoding - - vitest - - '@fuel-ts/account@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/account@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/errors': 0.103.0 - '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/math': 0.103.0 - '@fuel-ts/merkle': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/merkle': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/versions': 0.103.0 '@fuels/vm-asm': 0.62.0 '@noble/curves': 1.8.1 @@ -15713,11 +14661,11 @@ snapshots: transitivePeerDependencies: - encoding - '@fuel-ts/address@0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/address@0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/crypto': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/crypto': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/errors': 0.100.0 - '@fuel-ts/utils': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@noble/hashes': 1.7.1 transitivePeerDependencies: - vitest @@ -15731,20 +14679,11 @@ snapshots: transitivePeerDependencies: - vitest - '@fuel-ts/address@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': - dependencies: - '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/errors': 0.103.0 - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@noble/hashes': 1.7.1 - transitivePeerDependencies: - - vitest - - '@fuel-ts/address@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/address@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/errors': 0.103.0 - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@noble/hashes': 1.7.1 transitivePeerDependencies: - vitest @@ -15776,36 +14715,18 @@ snapshots: - encoding - vitest - '@fuel-ts/contract@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': - dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/errors': 0.103.0 - '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/math': 0.103.0 - '@fuel-ts/merkle': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/program': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuels/vm-asm': 0.62.0 - ramda: 0.30.1 - transitivePeerDependencies: - - encoding - - vitest - - '@fuel-ts/contract@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/contract@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/errors': 0.103.0 - '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/math': 0.103.0 - '@fuel-ts/merkle': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/program': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/merkle': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/program': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuels/vm-asm': 0.62.0 ramda: 0.30.1 transitivePeerDependencies: @@ -15831,10 +14752,10 @@ snapshots: transitivePeerDependencies: - encoding - '@fuel-ts/crypto@0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/crypto@0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: '@fuel-ts/errors': 0.100.0 - '@fuel-ts/utils': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@noble/hashes': 1.7.1 transitivePeerDependencies: - vitest @@ -15847,18 +14768,10 @@ snapshots: transitivePeerDependencies: - vitest - '@fuel-ts/crypto@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': - dependencies: - '@fuel-ts/errors': 0.103.0 - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@noble/hashes': 1.7.1 - transitivePeerDependencies: - - vitest - - '@fuel-ts/crypto@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/crypto@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: '@fuel-ts/errors': 0.103.0 - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@noble/hashes': 1.7.1 transitivePeerDependencies: - vitest @@ -15883,10 +14796,10 @@ snapshots: dependencies: '@fuel-ts/versions': 0.96.1 - '@fuel-ts/hasher@0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/hasher@0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/crypto': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/utils': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/crypto': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@noble/hashes': 1.7.1 transitivePeerDependencies: - vitest @@ -15899,18 +14812,10 @@ snapshots: transitivePeerDependencies: - vitest - '@fuel-ts/hasher@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': - dependencies: - '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@noble/hashes': 1.7.1 - transitivePeerDependencies: - - vitest - - '@fuel-ts/hasher@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/hasher@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@noble/hashes': 1.7.1 transitivePeerDependencies: - vitest @@ -15942,9 +14847,9 @@ snapshots: '@types/bn.js': 5.2.0 bn.js: 5.2.2 - '@fuel-ts/merkle@0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/merkle@0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/hasher': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/hasher': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/math': 0.100.0 transitivePeerDependencies: - vitest @@ -15956,16 +14861,9 @@ snapshots: transitivePeerDependencies: - vitest - '@fuel-ts/merkle@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': - dependencies: - '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/math': 0.103.0 - transitivePeerDependencies: - - vitest - - '@fuel-ts/merkle@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/merkle@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/math': 0.103.0 transitivePeerDependencies: - vitest @@ -15990,30 +14888,15 @@ snapshots: - encoding - vitest - '@fuel-ts/program@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': - dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/errors': 0.103.0 - '@fuel-ts/math': 0.103.0 - '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuels/vm-asm': 0.62.0 - ramda: 0.30.1 - transitivePeerDependencies: - - encoding - - vitest - - '@fuel-ts/program@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/program@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/errors': 0.103.0 '@fuel-ts/math': 0.103.0 - '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuels/vm-asm': 0.62.0 ramda: 0.30.1 transitivePeerDependencies: @@ -16049,35 +14932,21 @@ snapshots: - encoding - vitest - '@fuel-ts/recipes@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': + '@fuel-ts/recipes@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/abi-typegen': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/contract': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/program': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) + '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/abi-typegen': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/contract': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/program': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) transitivePeerDependencies: - encoding - vitest - '@fuel-ts/recipes@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': - dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/abi-typegen': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/contract': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/program': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - transitivePeerDependencies: - - encoding - - vitest - - '@fuel-ts/script@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': + '@fuel-ts/script@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': dependencies: '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) @@ -16090,28 +14959,15 @@ snapshots: - encoding - vitest - '@fuel-ts/script@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': - dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/errors': 0.103.0 - '@fuel-ts/math': 0.103.0 - '@fuel-ts/program': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - transitivePeerDependencies: - - encoding - - vitest - - '@fuel-ts/script@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/script@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/errors': 0.103.0 '@fuel-ts/math': 0.103.0 - '@fuel-ts/program': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/program': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) transitivePeerDependencies: - encoding - vitest @@ -16130,14 +14986,14 @@ snapshots: transitivePeerDependencies: - encoding - '@fuel-ts/transactions@0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/transactions@0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/abi-coder': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/address': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/abi-coder': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/address': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/errors': 0.100.0 - '@fuel-ts/hasher': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/hasher': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/math': 0.100.0 - '@fuel-ts/utils': 0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) transitivePeerDependencies: - vitest @@ -16152,25 +15008,14 @@ snapshots: transitivePeerDependencies: - vitest - '@fuel-ts/transactions@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': - dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/errors': 0.103.0 - '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/math': 0.103.0 - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - transitivePeerDependencies: - - vitest - - '@fuel-ts/transactions@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/transactions@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/errors': 0.103.0 - '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/math': 0.103.0 - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) transitivePeerDependencies: - vitest @@ -16184,13 +15029,13 @@ snapshots: '@fuel-ts/math': 0.96.1 '@fuel-ts/utils': 0.96.1 - '@fuel-ts/utils@0.100.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/utils@0.100.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: '@fuel-ts/errors': 0.100.0 '@fuel-ts/math': 0.100.0 '@fuel-ts/versions': 0.100.0 fflate: 0.8.2 - vitest: 4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) + vitest: 4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) '@fuel-ts/utils@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': dependencies: @@ -16200,21 +15045,13 @@ snapshots: fflate: 0.8.2 vitest: 4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) - '@fuel-ts/utils@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': - dependencies: - '@fuel-ts/errors': 0.103.0 - '@fuel-ts/math': 0.103.0 - '@fuel-ts/versions': 0.103.0 - fflate: 0.8.2 - vitest: 4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) - - '@fuel-ts/utils@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuel-ts/utils@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: '@fuel-ts/errors': 0.103.0 '@fuel-ts/math': 0.103.0 '@fuel-ts/versions': 0.103.0 fflate: 0.8.2 - vitest: 4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) + vitest: 4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) '@fuel-ts/utils@0.96.1': dependencies: @@ -16239,7 +15076,7 @@ snapshots: chalk: 4.1.2 cli-table: 0.3.11 - '@fuels/connectors@0.45.0(@tanstack/query-core@5.56.2)(@types/react@18.2.54)(@wagmi/connectors@5.1.7(@types/react@18.2.54)(@wagmi/core@2.13.4(@tanstack/query-core@5.56.2)(@types/react@18.2.54)(react@18.2.0)(typescript@5.4.5)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.9)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.46.2)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8))(bufferutil@4.0.9)(fuels@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8)': + '@fuels/connectors@0.45.0(@tanstack/query-core@5.56.2)(@types/react@18.2.54)(@wagmi/connectors@5.1.7(@types/react@18.2.54)(@wagmi/core@2.13.4(@tanstack/query-core@5.56.2)(@types/react@18.2.54)(react@18.2.0)(typescript@5.4.5)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.9)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.46.2)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8))(bufferutil@4.0.9)(fuels@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8)': dependencies: '@ethereumjs/util': 9.0.3 '@ethersproject/bytes': 5.7.0 @@ -16249,7 +15086,7 @@ snapshots: '@web3modal/scaffold': 5.0.0(@types/react@18.2.54)(react@18.2.0) '@web3modal/solana': 5.0.0(@types/react@18.2.54)(bufferutil@4.0.9)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8) '@web3modal/wagmi': 5.0.0(@types/react@18.2.54)(@wagmi/connectors@5.1.7(@types/react@18.2.54)(@wagmi/core@2.13.4(@tanstack/query-core@5.56.2)(@types/react@18.2.54)(react@18.2.0)(typescript@5.4.5)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.9)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.46.2)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8))(zod@3.23.8))(@wagmi/core@2.13.4(@tanstack/query-core@5.56.2)(@types/react@18.2.54)(react@18.2.0)(typescript@5.4.5)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8)))(bufferutil@4.0.9)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(utf-8-validate@5.0.10)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8)) - fuels: 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + fuels: 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) rpc-websockets: 7.11.0 socket.io-client: 4.7.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) viem: 2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.23.8) @@ -16286,19 +15123,19 @@ snapshots: - vue - zod - '@fuels/jest@0.20.0(@jest/globals@29.7.0)(@types/jest@29.5.12)(bufferutil@4.0.9)(jest@29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)))(utf-8-validate@5.0.10)(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@fuels/jest@0.20.0(@jest/globals@29.7.0)(@types/jest@29.5.12)(bufferutil@4.0.9)(jest@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)))(utf-8-validate@5.0.10)(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: '@ariakit/test': 0.2.5(@testing-library/dom@9.3.4)(@testing-library/react@14.3.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0) '@chakra-ui/utils': 2.2.2(react@18.2.0) '@testing-library/dom': 9.3.4 - '@testing-library/jest-dom': 6.4.2(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)))(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@testing-library/jest-dom': 6.4.2(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)))(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@testing-library/react': 14.3.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@testing-library/user-event': 14.6.1(@testing-library/dom@9.3.4) '@types/react': 18.2.54 '@types/react-dom': 18.2.22 dotenv: 16.4.5 identity-obj-proxy: 3.0.0 - jest: 29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + jest: 29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) jest-axe: 8.0.0 jest-environment-jsdom: 29.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) jest-fail-on-console: 3.3.1 @@ -16319,13 +15156,13 @@ snapshots: '@fuels/local-storage@0.23.0': {} - '@fuels/playwright-utils@0.57.1(@playwright/test@1.48.2)(fuels@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)))': + '@fuels/playwright-utils@0.57.1(@playwright/test@1.48.2)(fuels@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)))': dependencies: '@playwright/test': 1.48.2 adm-zip: 0.5.16 - fuels: 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) + fuels: 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuels/react-xstore@0.23.0(@babel/core@7.28.0)(@babel/template@7.27.2)(@types/react@18.2.54)(@types/ws@8.18.1)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@fuels/react-xstore@0.23.0(@babel/core@7.28.0)(@babel/template@7.27.2)(@types/react@18.2.54)(@types/ws@8.18.1)(@xstate/react@3.2.2(@types/react@18.2.54)(react@18.2.0)(xstate@4.38.3))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(xstate@4.38.3)': dependencies: '@fuels/local-storage': 0.23.0 '@xstate/inspect': 0.8.0(@types/ws@8.18.1)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(xstate@4.38.3) @@ -16341,15 +15178,32 @@ snapshots: - '@babel/template' - '@types/react' - '@types/ws' - - '@xstate/fsm' - ws - '@fuels/react@0.44.1(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react-dom@18.2.22)(@types/react@18.2.54)(fuels@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@fuels/react-xstore@0.23.0(@babel/core@7.28.0)(@babel/template@7.27.2)(@types/react@18.2.54)(@types/ws@8.18.1)(@xstate/react@3.2.2(@types/react@18.2.54)(react@18.2.0)(xstate@5.0.0-beta.54))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(xstate@5.0.0-beta.54)': + dependencies: + '@fuels/local-storage': 0.23.0 + '@xstate/inspect': 0.8.0(@types/ws@8.18.1)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(xstate@5.0.0-beta.54) + '@xstate/react': 3.2.2(@types/react@18.2.54)(react@18.2.0)(xstate@5.0.0-beta.54) + fast-equals: 5.2.2 + jotai: 2.13.1(@babel/core@7.28.0)(@babel/template@7.27.2)(@types/react@18.2.54)(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + uuid: 9.0.1 + xstate: 5.0.0-beta.54 + transitivePeerDependencies: + - '@babel/core' + - '@babel/template' + - '@types/react' + - '@types/ws' + - ws + + '@fuels/react@0.44.1(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react-dom@18.2.22)(@types/react@18.2.54)(fuels@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@radix-ui/react-dialog': 1.1.1(@types/react-dom@18.2.22)(@types/react@18.2.54)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@tanstack/react-query': 5.56.2(react@18.2.0) events: 3.3.0 - fuels: 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + fuels: 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) react: 18.2.0 transitivePeerDependencies: - '@types/react' @@ -16364,12 +15218,12 @@ snapshots: dependencies: typescript: 5.9.2 - '@fuels/tsup-config@0.26.0(tsup@8.0.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5))': + '@fuels/tsup-config@0.26.0(tsup@8.0.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.4.5))': dependencies: dotenv: 16.4.5 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - tsup: 8.0.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5) + tsup: 8.0.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.4.5) '@fuels/vm-asm@0.58.0': {} @@ -16383,7 +15237,7 @@ snapshots: graphql: 16.10.0 tslib: 2.6.3 - '@graphql-codegen/cli@5.0.7(@types/node@20.19.10)(bufferutil@4.0.9)(crossws@0.3.5)(enquirer@2.3.6)(graphql@16.10.0)(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@graphql-codegen/cli@5.0.7(@types/node@20.19.10)(bufferutil@4.0.9)(crossws@0.3.5)(graphql@16.10.0)(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: '@babel/generator': 7.28.0 '@babel/template': 7.27.2 @@ -16412,7 +15266,7 @@ snapshots: is-glob: 4.0.3 jiti: 1.21.7 json-to-pretty-yaml: 1.2.2 - listr2: 4.0.5(enquirer@2.3.6) + listr2: 4.0.5 log-symbols: 4.1.0 micromatch: 4.0.8 shell-quote: 1.9.0 @@ -16608,15 +15462,6 @@ snapshots: sync-fetch: 0.6.0-2 tslib: 2.8.1 - '@graphql-tools/batch-delegate@9.0.41(graphql@16.10.0)': - dependencies: - '@graphql-tools/delegate': 10.2.23(graphql@16.10.0) - '@graphql-tools/utils': 10.9.1(graphql@16.10.0) - '@whatwg-node/promise-helpers': 1.3.2 - dataloader: 2.2.3 - graphql: 16.10.0 - tslib: 2.8.1 - '@graphql-tools/batch-execute@9.0.19(graphql@16.10.0)': dependencies: '@graphql-tools/utils': 10.9.1(graphql@16.10.0) @@ -16916,19 +15761,6 @@ snapshots: tslib: 2.8.1 value-or-promise: 1.0.12 - '@graphql-tools/stitch@9.4.28(graphql@16.10.0)': - dependencies: - '@graphql-tools/batch-delegate': 9.0.41(graphql@16.10.0) - '@graphql-tools/delegate': 10.2.23(graphql@16.10.0) - '@graphql-tools/executor': 1.4.9(graphql@16.10.0) - '@graphql-tools/merge': 9.1.1(graphql@16.10.0) - '@graphql-tools/schema': 10.0.25(graphql@16.10.0) - '@graphql-tools/utils': 10.9.1(graphql@16.10.0) - '@graphql-tools/wrap': 10.1.4(graphql@16.10.0) - '@whatwg-node/promise-helpers': 1.3.2 - graphql: 16.10.0 - tslib: 2.8.1 - '@graphql-tools/url-loader@8.0.33(@types/node@20.19.10)(bufferutil@4.0.9)(crossws@0.3.5)(graphql@16.10.0)(utf-8-validate@5.0.10)': dependencies: '@graphql-tools/executor-graphql-ws': 2.0.7(bufferutil@4.0.9)(crossws@0.3.5)(graphql@16.10.0)(utf-8-validate@5.0.10) @@ -17109,42 +15941,7 @@ snapshots: - supports-color - ts-node - '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(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': 20.19.10 - 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@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(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/core@29.7.0(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))': + '@jest/core@29.7.0(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))': dependencies: '@jest/console': 29.7.0 '@jest/reporters': 29.7.0 @@ -17158,7 +15955,7 @@ snapshots: exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -17684,7 +16481,7 @@ snapshots: - debug - encoding - '@openzeppelin/hardhat-upgrades@3.9.1(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + '@openzeppelin/hardhat-upgrades@3.9.1(ethers@6.11.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@openzeppelin/defender-sdk-base-client': 2.7.0 '@openzeppelin/defender-sdk-deploy-client': 2.7.0(debug@4.4.1) @@ -17693,7 +16490,7 @@ snapshots: chalk: 4.1.2 debug: 4.4.1 ethereumjs-util: 7.1.5 - ethers: 6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + ethers: 6.11.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) proper-lockfile: 4.1.2 undici: 6.21.3 transitivePeerDependencies: @@ -17728,57 +16525,6 @@ snapshots: dependencies: playwright: 1.48.2 - '@pm2/agent@2.0.4(bufferutil@4.0.9)(utf-8-validate@5.0.10)': - dependencies: - async: 3.2.6 - chalk: 3.0.0 - dayjs: 1.8.36 - debug: 4.3.7 - eventemitter2: 5.0.1 - fast-json-patch: 3.1.1 - fclone: 1.0.11 - nssocket: 0.6.0 - pm2-axon: 4.0.1 - pm2-axon-rpc: 0.7.1 - proxy-agent: 6.3.1 - semver: 7.5.4 - ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - '@pm2/io@6.0.1': - dependencies: - async: 2.6.4 - debug: 4.3.7 - eventemitter2: 6.4.9 - require-in-the-middle: 5.2.0 - semver: 7.5.4 - shimmer: 1.2.1 - signal-exit: 3.0.7 - tslib: 1.9.3 - transitivePeerDependencies: - - supports-color - - '@pm2/js-api@0.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': - dependencies: - async: 2.6.4 - debug: 4.3.7 - eventemitter2: 6.4.9 - extrareqp2: 1.0.0(debug@4.3.7) - ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - '@pm2/pm2-version-check@1.0.4': - dependencies: - debug: 4.4.3(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - '@protobufjs/aspromise@1.1.2': {} '@protobufjs/base64@1.1.2': {} @@ -20610,9 +19356,9 @@ snapshots: dependencies: '@swc/counter': 0.1.3 - '@synthetixio/ethereum-wallet-mock@0.0.12(@depay/solana-web3.js@1.98.3)(@depay/web3-blockchains@9.8.6)(@playwright/test@1.48.2)(bufferutil@4.0.9)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.23.8)': + '@synthetixio/ethereum-wallet-mock@0.0.12(@depay/solana-web3.js@1.98.3)(@depay/web3-blockchains@9.8.6)(@playwright/test@1.48.2)(bufferutil@4.0.9)(ethers@6.11.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.23.8)': dependencies: - '@depay/web3-client': 10.18.6(@depay/solana-web3.js@1.98.3)(@depay/web3-blockchains@9.8.6)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@depay/web3-client': 10.18.6(@depay/solana-web3.js@1.98.3)(@depay/web3-blockchains@9.8.6)(ethers@6.11.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@depay/web3-mock': 14.19.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@depay/web3-mock-evm': 14.19.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@playwright/test': 1.48.2 @@ -20627,9 +19373,9 @@ snapshots: - utf-8-validate - zod - '@synthetixio/synpress-cache@0.0.12(@swc/core@1.13.3(@swc/helpers@0.5.17))(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.9.2)': + '@synthetixio/synpress-cache@0.0.12(@swc/core@1.13.3(@swc/helpers@0.5.17))(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.9.2)': dependencies: - axios: 1.15.0 + axios: 1.15.0(debug@4.4.1) chalk: 5.3.0 commander: 12.0.0 esbuild: 0.27.2 @@ -20638,7 +19384,7 @@ snapshots: gradient-string: 2.0.2 playwright-core: 1.48.2 progress: 2.0.3 - tsup: 8.0.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.9.2) + tsup: 8.0.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.9.2) unzip-crx-3: 0.2.0 unzipper: 0.10.14 zod: 3.22.4 @@ -20655,10 +19401,10 @@ snapshots: dependencies: '@playwright/test': 1.48.2 - '@synthetixio/synpress-metamask@0.0.12(@playwright/test@1.48.2)(@swc/core@1.13.3(@swc/helpers@0.5.17))(bufferutil@4.0.9)(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@synthetixio/synpress-metamask@0.0.12(@playwright/test@1.48.2)(@swc/core@1.13.3(@swc/helpers@0.5.17))(bufferutil@4.0.9)(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: '@playwright/test': 1.48.2 - '@synthetixio/synpress-cache': 0.0.12(@swc/core@1.13.3(@swc/helpers@0.5.17))(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.9.2) + '@synthetixio/synpress-cache': 0.0.12(@swc/core@1.13.3(@swc/helpers@0.5.17))(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.9.2) '@synthetixio/synpress-core': 0.0.12(@playwright/test@1.48.2) '@viem/anvil': 0.0.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) fs-extra: 11.2.0 @@ -20675,10 +19421,10 @@ snapshots: - typescript - utf-8-validate - '@synthetixio/synpress-phantom@0.0.12(@playwright/test@1.48.2)(@swc/core@1.13.3(@swc/helpers@0.5.17))(bufferutil@4.0.9)(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.9.2)(utf-8-validate@5.0.10)': + '@synthetixio/synpress-phantom@0.0.12(@playwright/test@1.48.2)(@swc/core@1.13.3(@swc/helpers@0.5.17))(bufferutil@4.0.9)(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.9.2)(utf-8-validate@5.0.10)': dependencies: '@playwright/test': 1.48.2 - '@synthetixio/synpress-cache': 0.0.12(@swc/core@1.13.3(@swc/helpers@0.5.17))(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.9.2) + '@synthetixio/synpress-cache': 0.0.12(@swc/core@1.13.3(@swc/helpers@0.5.17))(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.9.2) '@synthetixio/synpress-core': 0.0.12(@playwright/test@1.48.2) '@viem/anvil': 0.0.7(bufferutil@4.0.9)(utf-8-validate@5.0.10) fs-extra: 11.2.0 @@ -20695,14 +19441,14 @@ snapshots: - typescript - utf-8-validate - '@synthetixio/synpress@4.1.0(@depay/solana-web3.js@1.98.3)(@depay/web3-blockchains@9.8.6)(@playwright/test@1.48.2)(@swc/core@1.13.3(@swc/helpers@0.5.17))(bufferutil@4.0.9)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.23.8)': + '@synthetixio/synpress@4.1.0(@depay/solana-web3.js@1.98.3)(@depay/web3-blockchains@9.8.6)(@playwright/test@1.48.2)(@swc/core@1.13.3(@swc/helpers@0.5.17))(bufferutil@4.0.9)(ethers@6.11.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.23.8)': dependencies: '@playwright/test': 1.48.2 - '@synthetixio/ethereum-wallet-mock': 0.0.12(@depay/solana-web3.js@1.98.3)(@depay/web3-blockchains@9.8.6)(@playwright/test@1.48.2)(bufferutil@4.0.9)(ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.23.8) - '@synthetixio/synpress-cache': 0.0.12(@swc/core@1.13.3(@swc/helpers@0.5.17))(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.9.2) + '@synthetixio/ethereum-wallet-mock': 0.0.12(@depay/solana-web3.js@1.98.3)(@depay/web3-blockchains@9.8.6)(@playwright/test@1.48.2)(bufferutil@4.0.9)(ethers@6.11.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(typescript@5.9.2)(utf-8-validate@5.0.10)(zod@3.23.8) + '@synthetixio/synpress-cache': 0.0.12(@swc/core@1.13.3(@swc/helpers@0.5.17))(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.9.2) '@synthetixio/synpress-core': 0.0.12(@playwright/test@1.48.2) - '@synthetixio/synpress-metamask': 0.0.12(@playwright/test@1.48.2)(@swc/core@1.13.3(@swc/helpers@0.5.17))(bufferutil@4.0.9)(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.9.2)(utf-8-validate@5.0.10) - '@synthetixio/synpress-phantom': 0.0.12(@playwright/test@1.48.2)(@swc/core@1.13.3(@swc/helpers@0.5.17))(bufferutil@4.0.9)(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.9.2)(utf-8-validate@5.0.10) + '@synthetixio/synpress-metamask': 0.0.12(@playwright/test@1.48.2)(@swc/core@1.13.3(@swc/helpers@0.5.17))(bufferutil@4.0.9)(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.9.2)(utf-8-validate@5.0.10) + '@synthetixio/synpress-phantom': 0.0.12(@playwright/test@1.48.2)(@swc/core@1.13.3(@swc/helpers@0.5.17))(bufferutil@4.0.9)(playwright-core@1.48.2)(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.9.2)(utf-8-validate@5.0.10) transitivePeerDependencies: - '@depay/solana-web3.js' - '@depay/web3-blockchains' @@ -20791,20 +19537,20 @@ snapshots: '@tailwindcss/oxide-win32-arm64-msvc': 4.1.11 '@tailwindcss/oxide-win32-x64-msvc': 4.1.11 - '@tailwindcss/typography@0.5.10(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)))': + '@tailwindcss/typography@0.5.10(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)))': dependencies: lodash.castarray: 4.4.0 lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 postcss-selector-parser: 6.0.10 - tailwindcss: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + tailwindcss: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) - '@tailwindcss/vite@4.1.11(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': + '@tailwindcss/vite@4.1.11(vite@6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': dependencies: '@tailwindcss/node': 4.1.11 '@tailwindcss/oxide': 4.1.11 tailwindcss: 4.1.11 - vite: 6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) + vite: 6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) '@tanstack/query-core@5.56.2': {} @@ -20836,14 +19582,6 @@ snapshots: '@tanstack/query-core': 5.56.2 react: 18.2.0 - '@testcontainers/postgresql@10.10.0': - dependencies: - testcontainers: 10.10.0 - transitivePeerDependencies: - - bare-buffer - - encoding - - supports-color - '@testing-library/dom@9.3.4': dependencies: '@babel/code-frame': 7.27.1 @@ -20855,7 +19593,7 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.4.2(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)))(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@testing-library/jest-dom@6.4.2(@jest/globals@29.7.0)(@types/jest@29.5.12)(jest@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)))(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: '@adobe/css-tools': 4.4.4 '@babel/runtime': 7.28.2 @@ -20868,8 +19606,8 @@ snapshots: optionalDependencies: '@jest/globals': 29.7.0 '@types/jest': 29.5.12 - jest: 29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) - vitest: 4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) + jest: 29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) + vitest: 4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) '@testing-library/react@14.3.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: @@ -20885,8 +19623,6 @@ snapshots: '@tootallnate/once@2.0.0': {} - '@tootallnate/quickjs-emscripten@0.23.0': {} - '@tsconfig/node10@1.0.11': {} '@tsconfig/node12@1.0.11': {} @@ -20939,10 +19675,6 @@ snapshots: dependencies: '@types/node': 20.19.10 - '@types/cors@2.8.19': - dependencies: - '@types/node': 20.19.10 - '@types/d3-array@3.2.1': {} '@types/d3-color@3.1.3': {} @@ -20973,17 +19705,6 @@ snapshots: '@types/deep-eql@4.0.2': {} - '@types/docker-modem@3.0.6': - dependencies: - '@types/node': 20.19.10 - '@types/ssh2': 1.15.5 - - '@types/dockerode@3.3.42': - dependencies: - '@types/docker-modem': 3.0.6 - '@types/node': 20.19.10 - '@types/ssh2': 1.15.5 - '@types/dom-screen-wake-lock@1.0.3': {} '@types/estree@1.0.8': {} @@ -21058,20 +19779,10 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@22.7.5': - dependencies: - undici-types: 6.19.8 - '@types/pbkdf2@3.1.2': dependencies: '@types/node': 20.19.10 - '@types/pg@8.15.5': - dependencies: - '@types/node': 20.19.10 - pg-protocol: 1.10.3 - pg-types: 2.2.0 - '@types/prop-types@15.7.15': {} '@types/react-dom@18.2.22': @@ -21094,27 +19805,12 @@ snapshots: dependencies: '@types/node': 20.19.10 - '@types/ssh2-streams@0.1.12': - dependencies: - '@types/node': 20.19.10 - - '@types/ssh2@0.5.52': - dependencies: - '@types/node': 20.19.10 - '@types/ssh2-streams': 0.1.12 - - '@types/ssh2@1.15.5': - dependencies: - '@types/node': 18.19.122 - '@types/stack-utils@2.0.3': {} '@types/tinycolor2@1.4.6': {} '@types/tough-cookie@4.0.5': {} - '@types/triple-beam@1.3.5': {} - '@types/trusted-types@2.0.7': {} '@types/uuid@8.3.4': {} @@ -21152,11 +19848,11 @@ snapshots: - debug - utf-8-validate - '@vitejs/plugin-react-swc@3.11.0(@swc/helpers@0.5.17)(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': + '@vitejs/plugin-react-swc@3.11.0(@swc/helpers@0.5.17)(vite@6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.27 '@swc/core': 1.13.3(@swc/helpers@0.5.17) - vite: 6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) + vite: 6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) transitivePeerDependencies: - '@swc/helpers' @@ -21188,21 +19884,13 @@ snapshots: optionalDependencies: vite: 6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) - '@vitest/mocker@4.1.9(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1))': - dependencies: - '@vitest/spy': 4.1.9 - estree-walker: 3.0.3 - magic-string: 0.30.21 - optionalDependencies: - vite: 6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) - - '@vitest/mocker@4.1.9(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': + '@vitest/mocker@4.1.9(vite@6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1))': dependencies: '@vitest/spy': 4.1.9 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) + vite: 6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) '@vitest/pretty-format@4.1.9': dependencies: @@ -22671,6 +21359,14 @@ snapshots: optionalDependencies: '@types/ws': 8.18.1 + '@xstate/inspect@0.8.0(@types/ws@8.18.1)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(xstate@5.0.0-beta.54)': + dependencies: + fast-safe-stringify: 2.1.1 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + xstate: 5.0.0-beta.54 + optionalDependencies: + '@types/ws': 8.18.1 + '@xstate/machine-extractor@0.16.0(xstate@4.38.3)': dependencies: '@babel/parser': 7.28.0 @@ -22691,6 +21387,16 @@ snapshots: transitivePeerDependencies: - '@types/react' + '@xstate/react@3.2.2(@types/react@18.2.54)(react@18.2.0)(xstate@5.0.0-beta.54)': + dependencies: + react: 18.2.0 + use-isomorphic-layout-effect: 1.2.1(@types/react@18.2.54)(react@18.2.0) + use-sync-external-store: 1.5.0(react@18.2.0) + optionalDependencies: + xstate: 5.0.0-beta.54 + transitivePeerDependencies: + - '@types/react' + '@xstate/store@3.0.1(react@18.2.0)': optionalDependencies: react: 18.2.0 @@ -22724,11 +21430,6 @@ snapshots: dependencies: event-target-shim: 5.0.1 - accepts@2.0.0: - dependencies: - mime-types: 3.0.1 - negotiator: 1.0.0 - acorn-globals@7.0.1: dependencies: acorn: 8.15.0 @@ -22780,14 +21481,6 @@ snapshots: transitivePeerDependencies: - encoding - amp-message@0.1.2: - dependencies: - amp: 0.3.1 - - amp@0.3.1: {} - - ansi-colors@4.1.3: {} - ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 @@ -22821,42 +21514,6 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 - archiver-utils@2.1.0: - dependencies: - glob: 7.2.3 - graceful-fs: 4.2.11 - lazystream: 1.0.1 - lodash.defaults: 4.2.0 - lodash.difference: 4.5.0 - lodash.flatten: 4.4.0 - lodash.isplainobject: 4.0.6 - lodash.union: 4.6.0 - normalize-path: 3.0.0 - readable-stream: 2.3.8 - - archiver-utils@3.0.4: - dependencies: - glob: 7.2.3 - graceful-fs: 4.2.11 - lazystream: 1.0.1 - lodash.defaults: 4.2.0 - lodash.difference: 4.5.0 - lodash.flatten: 4.4.0 - lodash.isplainobject: 4.0.6 - lodash.union: 4.6.0 - normalize-path: 3.0.0 - readable-stream: 3.6.2 - - archiver@5.3.2: - dependencies: - archiver-utils: 2.1.0 - async: 3.2.6 - buffer-crc32: 0.2.13 - readable-stream: 3.6.2 - readdir-glob: 1.1.3 - tar-stream: 2.2.0 - zip-stream: 4.1.1 - arg@4.1.3: {} arg@5.0.2: {} @@ -22902,12 +21559,6 @@ snapshots: inherits: 2.0.4 minimalistic-assert: 1.0.1 - asn1@0.2.6: - dependencies: - safer-buffer: 2.1.2 - - assert-options@0.8.1: {} - assert@2.1.0: dependencies: call-bind: 1.0.8 @@ -22918,10 +21569,6 @@ snapshots: assertion-error@2.0.1: {} - ast-types@0.13.4: - dependencies: - tslib: 2.8.1 - ast-types@0.16.1: dependencies: tslib: 2.8.1 @@ -22930,8 +21577,6 @@ snapshots: async-function@1.0.0: {} - async-lock@1.4.1: {} - async-mutex@0.2.6: dependencies: tslib: 2.8.1 @@ -22944,8 +21589,6 @@ snapshots: dependencies: lodash: 4.17.21 - async@3.2.6: {} - asynckit@0.4.0: {} atomic-sleep@1.0.0: {} @@ -23024,14 +21667,6 @@ snapshots: axe-core@4.7.2: {} - axios@1.15.0: - dependencies: - follow-redirects: 1.15.11(debug@4.3.7) - form-data: 4.0.5 - proxy-from-env: 2.1.0 - transitivePeerDependencies: - - debug - axios@1.15.0(debug@4.4.1): dependencies: follow-redirects: 1.15.11(debug@4.4.1) @@ -23040,8 +21675,6 @@ snapshots: transitivePeerDependencies: - debug - b4a@1.6.7: {} - babel-jest@29.7.0(@babel/core@7.28.0): dependencies: '@babel/core': 7.28.0 @@ -23146,31 +21779,6 @@ snapshots: balanced-match@1.0.2: {} - bare-events@2.6.1: - optional: true - - bare-fs@4.2.0: - dependencies: - bare-events: 2.6.1 - bare-path: 3.0.0 - bare-stream: 2.7.0(bare-events@2.6.1) - optional: true - - bare-os@3.6.1: - optional: true - - bare-path@3.0.0: - dependencies: - bare-os: 3.6.1 - optional: true - - bare-stream@2.7.0(bare-events@2.6.1): - dependencies: - streamx: 2.22.1 - optionalDependencies: - bare-events: 2.6.1 - optional: true - base-x@3.0.11: dependencies: safe-buffer: 5.2.1 @@ -23181,12 +21789,6 @@ snapshots: base64-js@1.5.1: {} - basic-ftp@5.2.0: {} - - bcrypt-pbkdf@1.0.2: - dependencies: - tweetnacl: 0.14.5 - bech32@1.1.4: {} bech32@2.0.0: {} @@ -23223,8 +21825,6 @@ snapshots: blakejs@1.2.1: {} - blessed@0.1.81: {} - bluebird@3.4.7: {} bn.js@4.12.2: {} @@ -23233,22 +21833,6 @@ snapshots: bn.js@5.2.2: {} - bodec@0.1.0: {} - - body-parser@2.2.0: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 4.4.3(supports-color@5.5.0) - http-errors: 2.0.0 - iconv-lite: 0.6.3 - on-finished: 2.4.1 - qs: 6.14.0 - raw-body: 3.0.0 - type-is: 2.0.1 - transitivePeerDependencies: - - supports-color - borsh@0.7.0: dependencies: bn.js: 5.2.2 @@ -23361,8 +21945,6 @@ snapshots: buffer-alloc-unsafe: 1.1.0 buffer-fill: 1.0.0 - buffer-crc32@0.2.13: {} - buffer-fill@1.0.0: {} buffer-from@1.1.2: {} @@ -23393,9 +21975,6 @@ snapshots: dependencies: node-gyp-build: 4.8.4 - buildcheck@0.0.6: - optional: true - builtin-status-codes@3.0.0: {} bundle-require@4.2.1(esbuild@0.25.3): @@ -23422,10 +22001,6 @@ snapshots: dependencies: streamsearch: 1.1.0 - byline@5.0.0: {} - - bytes@3.1.2: {} - cac@6.7.14: {} call-bind-apply-helpers@1.0.2: @@ -23554,8 +22129,6 @@ snapshots: chardet@2.1.0: {} - charm@0.1.2: {} - chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -23609,10 +22182,6 @@ snapshots: dependencies: colors: 1.0.3 - cli-tableau@2.0.1: - dependencies: - chalk: 3.0.0 - cli-truncate@2.1.0: dependencies: slice-ansi: 3.0.0 @@ -23672,12 +22241,7 @@ snapshots: color-support@1.1.3: {} - color@3.2.1: - dependencies: - color-convert: 1.9.3 - color-string: 1.9.1 - - color@4.2.3: + color@4.2.3: dependencies: color-convert: 2.0.1 color-string: 1.9.1 @@ -23686,11 +22250,6 @@ snapshots: colors@1.0.3: {} - colorspace@1.1.4: - dependencies: - color: 3.2.1 - text-hex: 1.0.0 - combined-stream@1.0.8: dependencies: delayed-stream: 1.0.0 @@ -23705,8 +22264,6 @@ snapshots: commander@14.0.2: {} - commander@2.15.1: {} - commander@2.20.3: {} commander@4.1.1: {} @@ -23717,13 +22274,6 @@ snapshots: compare-versions@6.1.1: {} - compress-commons@4.1.2: - dependencies: - buffer-crc32: 0.2.13 - crc32-stream: 4.0.3 - normalize-path: 3.0.0 - readable-stream: 3.6.2 - concat-map@0.0.1: {} connectkit@1.8.2(@babel/core@7.28.0)(@tanstack/react-query@5.56.2(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react-is@18.3.1)(react@18.2.0)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.22.4))(wagmi@2.12.7(@tanstack/query-core@5.56.2)(@tanstack/react-query@5.56.2(react@18.2.0))(@types/react@18.2.54)(bufferutil@4.0.9)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(rollup@4.46.2)(typescript@5.4.5)(utf-8-validate@5.0.10)(viem@2.23.2(bufferutil@4.0.9)(typescript@5.4.5)(utf-8-validate@5.0.10)(zod@3.22.4))(zod@3.22.4)): @@ -23774,31 +22324,16 @@ snapshots: constants-browserify@1.0.0: {} - content-disposition@1.0.0: - dependencies: - safe-buffer: 5.2.1 - - content-type@1.0.5: {} - convert-source-map@2.0.0: {} cookie-es@1.2.2: {} - cookie-signature@1.2.2: {} - - cookie@0.7.1: {} - copy-to-clipboard@3.3.3: dependencies: toggle-selection: 1.0.6 core-util-is@1.0.3: {} - cors@2.8.5: - dependencies: - object-assign: 4.1.1 - vary: 1.1.2 - cosmiconfig@8.3.6(typescript@5.4.5): dependencies: import-fresh: 3.3.1 @@ -23819,19 +22354,8 @@ snapshots: cosmjs-types@0.9.0: {} - cpu-features@0.0.10: - dependencies: - buildcheck: 0.0.6 - nan: 2.23.0 - optional: true - crc-32@1.2.2: {} - crc32-stream@4.0.3: - dependencies: - crc-32: 1.2.2 - readable-stream: 3.6.2 - create-ecdh@4.0.4: dependencies: bn.js: 4.12.2 @@ -23876,28 +22400,13 @@ snapshots: - supports-color - ts-node - create-jest@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(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@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)) - jest-util: 29.7.0 - prompts: 2.4.2 - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - create-jest@29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)): + create-jest@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)): 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.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -23908,12 +22417,6 @@ snapshots: create-require@1.1.1: {} - cron-parser@4.9.0: - dependencies: - luxon: 3.7.1 - - croner@4.1.97: {} - cross-argv@2.0.0: {} cross-fetch@3.2.0: @@ -24014,8 +22517,6 @@ snapshots: csstype@3.1.3: {} - culvert@0.1.2: {} - d3-array@3.2.4: dependencies: internmap: 2.0.3 @@ -24056,8 +22557,6 @@ snapshots: data-uri-to-buffer@4.0.1: {} - data-uri-to-buffer@6.0.2: {} - data-urls@3.0.2: dependencies: abab: 2.0.6 @@ -24088,14 +22587,10 @@ snapshots: dependencies: '@babel/runtime': 7.28.2 - dateformat@4.6.3: {} - dayjs@1.11.10: {} dayjs@1.11.11: {} - dayjs@1.8.36: {} - debounce@1.2.1: {} debug@3.2.7: @@ -24106,10 +22601,6 @@ snapshots: dependencies: ms: 2.1.2 - debug@4.3.6: - dependencies: - ms: 2.1.2 - debug@4.3.7: dependencies: ms: 2.1.3 @@ -24183,18 +22674,10 @@ snapshots: defu@6.1.4: {} - degenerator@5.0.1: - dependencies: - ast-types: 0.13.4 - escodegen: 2.1.0 - esprima: 4.0.1 - delay@5.0.0: {} delayed-stream@1.0.0: {} - depd@2.0.0: {} - dependency-graph@0.11.0: {} des.js@1.1.0: @@ -24240,27 +22723,6 @@ snapshots: dlv@1.1.3: {} - docker-compose@0.24.8: - dependencies: - yaml: 2.8.1 - - docker-modem@3.0.8: - dependencies: - debug: 4.4.3(supports-color@5.5.0) - readable-stream: 3.6.2 - split-ca: 1.0.1 - ssh2: 1.16.0 - transitivePeerDependencies: - - supports-color - - dockerode@3.3.5: - dependencies: - '@balena/dockerignore': 1.0.2 - docker-modem: 3.0.8 - tar-fs: 2.0.1 - transitivePeerDependencies: - - supports-color - dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.6.3: {} @@ -24285,21 +22747,11 @@ snapshots: dotenv@16.4.5: {} - drizzle-kit@0.22.8: - dependencies: - '@esbuild-kit/esm-loader': 2.6.5 - esbuild: 0.25.3 - esbuild-register: 3.6.0(esbuild@0.25.3) - transitivePeerDependencies: - - supports-color - - drizzle-orm@0.31.4(@types/better-sqlite3@7.6.11)(@types/pg@8.15.5)(@types/react@18.2.54)(better-sqlite3@11.3.0)(pg@8.16.3)(react@18.2.0): + drizzle-orm@0.31.4(@types/better-sqlite3@7.6.11)(@types/react@18.2.54)(better-sqlite3@11.3.0)(react@18.2.0): optionalDependencies: '@types/better-sqlite3': 7.6.11 - '@types/pg': 8.15.5 '@types/react': 18.2.54 better-sqlite3: 11.3.0 - pg: 8.16.3 react: 18.2.0 dset@3.1.4: {} @@ -24328,8 +22780,6 @@ snapshots: futoin-hkdf: 1.5.3 secp256k1: 5.0.1 - ee-first@1.1.1: {} - electron-to-chromium@1.5.200: {} elliptic@6.6.1: @@ -24364,12 +22814,8 @@ snapshots: emoji-regex@9.2.2: {} - enabled@2.0.0: {} - encode-utf8@1.0.3: {} - encodeurl@2.0.0: {} - end-of-stream@1.4.5: dependencies: once: 1.4.0 @@ -24405,10 +22851,6 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.2.2 - enquirer@2.3.6: - dependencies: - ansi-colors: 4.1.3 - entities@4.5.0: {} entities@6.0.1: {} @@ -24523,13 +22965,6 @@ snapshots: dependencies: es6-promise: 4.2.8 - esbuild-register@3.6.0(esbuild@0.25.3): - dependencies: - debug: 4.4.1 - esbuild: 0.25.3 - transitivePeerDependencies: - - supports-color - esbuild@0.25.3: optionalDependencies: '@esbuild/aix-ppc64': 0.25.3 @@ -24589,14 +23024,10 @@ snapshots: escalade@3.2.0: {} - escape-html@1.0.3: {} - escape-string-regexp@1.0.5: {} escape-string-regexp@2.0.0: {} - escape-string-regexp@4.0.0: {} - escodegen@2.1.0: dependencies: esprima: 4.0.1 @@ -24617,8 +23048,6 @@ snapshots: esutils@2.0.3: {} - etag@1.8.1: {} - eth-block-tracker@7.1.0: dependencies: '@metamask/eth-json-rpc-provider': 1.0.1 @@ -24728,25 +23157,8 @@ snapshots: - bufferutil - utf-8-validate - ethers@6.15.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): - dependencies: - '@adraffy/ens-normalize': 1.10.1 - '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.2 - '@types/node': 22.7.5 - aes-js: 4.0.0-beta.5 - tslib: 2.7.0 - ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - bufferutil - - utf-8-validate - event-target-shim@5.0.1: {} - eventemitter2@0.4.14: {} - - eventemitter2@5.0.1: {} - eventemitter2@6.4.9: {} eventemitter3@4.0.7: {} @@ -24814,43 +23226,6 @@ snapshots: jest-message-util: 29.7.0 jest-util: 29.7.0 - express@5.0.0: - dependencies: - accepts: 2.0.0 - body-parser: 2.2.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.1.0 - fresh: 2.0.0 - http-errors: 2.0.0 - merge-descriptors: 2.0.0 - methods: 1.1.2 - mime-types: 3.0.1 - 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.2.0 - safe-buffer: 5.2.1 - send: 1.2.0 - serve-static: 2.2.0 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 2.0.1 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color - extension-port-stream@3.0.0: dependencies: readable-stream: 4.7.0 @@ -24858,26 +23233,16 @@ snapshots: extract-files@9.0.0: {} - extrareqp2@1.0.0(debug@4.3.7): - dependencies: - follow-redirects: 1.15.11(debug@4.3.7) - transitivePeerDependencies: - - debug - eyes@0.1.8: {} fast-base64-decode@1.0.0: {} - fast-copy@3.0.2: {} - fast-decode-uri-component@1.0.1: {} fast-deep-equal@3.1.3: {} fast-equals@5.2.2: {} - fast-fifo@1.3.2: {} - fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -24886,8 +23251,6 @@ snapshots: merge2: 1.4.1 micromatch: 4.0.8 - fast-json-patch@3.1.1: {} - fast-json-stable-stringify@2.1.0: {} fast-querystring@1.1.2: @@ -24932,8 +23295,6 @@ snapshots: transitivePeerDependencies: - encoding - fclone@1.0.11: {} - fdir@6.5.0(picomatch@4.0.3): optionalDependencies: picomatch: 4.0.3 @@ -24942,8 +23303,6 @@ snapshots: optionalDependencies: picomatch: 4.0.5 - fecha@4.2.3: {} - fetch-blob@3.2.0: dependencies: node-domexception: 1.0.0 @@ -24963,17 +23322,6 @@ snapshots: filter-obj@1.1.0: {} - finalhandler@2.1.0: - dependencies: - debug: 4.4.3(supports-color@5.5.0) - encodeurl: 2.0.0 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - find-up@3.0.0: dependencies: locate-path: 3.0.0 @@ -24988,12 +23336,6 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - fn.name@1.1.0: {} - - follow-redirects@1.15.11(debug@4.3.7): - optionalDependencies: - debug: 4.3.7 - follow-redirects@1.15.11(debug@4.4.1): optionalDependencies: debug: 4.4.1 @@ -25019,8 +23361,6 @@ snapshots: dependencies: fetch-blob: 3.2.0 - forwarded@0.2.0: {} - fraction.js@4.3.7: {} framer-motion@11.0.3(react-dom@18.2.0(react@18.2.0))(react@18.2.0): @@ -25056,8 +23396,6 @@ snapshots: dependencies: tslib: 2.8.1 - fresh@2.0.0: {} - fs-constants@1.0.0: {} fs-extra@11.2.0: @@ -25123,58 +23461,22 @@ snapshots: - supports-color - vitest - fuels@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)): - dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/abi-typegen': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/contract': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/errors': 0.103.0 - '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/math': 0.103.0 - '@fuel-ts/program': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/recipes': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/script': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) - '@fuel-ts/versions': 0.103.0 - '@fuels/vm-asm': 0.62.0 - bundle-require: 5.1.0(esbuild@0.25.3) - chalk: 4.1.2 - chokidar: 3.6.0 - commander: 13.1.0 - esbuild: 0.25.3 - glob: 10.4.5 - handlebars: 4.7.9 - joycon: 3.1.1 - lodash.camelcase: 4.3.0 - portfinder: 1.0.32 - toml: 3.0.0 - uglify-js: 3.19.3 - yup: 1.6.1 - transitivePeerDependencies: - - encoding - - supports-color - - vitest - - fuels@0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)): + fuels@0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)): dependencies: - '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/abi-typegen': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/contract': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/abi-coder': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/abi-typegen': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/account': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/address': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/contract': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/crypto': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/errors': 0.103.0 - '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/hasher': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/math': 0.103.0 - '@fuel-ts/program': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/recipes': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/script': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/program': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/recipes': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/script': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/transactions': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) + '@fuel-ts/utils': 0.103.0(vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@fuel-ts/versions': 0.103.0 '@fuels/vm-asm': 0.62.0 bundle-require: 5.1.0(esbuild@0.25.3) @@ -25272,8 +23574,6 @@ snapshots: get-package-type@0.1.0: {} - get-port@5.1.1: {} - get-port@6.1.2: {} get-proto@1.0.1: @@ -25299,20 +23599,6 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 - get-uri@6.0.5: - dependencies: - basic-ftp: 5.2.0 - data-uri-to-buffer: 6.0.2 - debug: 4.4.3(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - git-node-fs@1.0.0(js-git@0.7.8): - optionalDependencies: - js-git: 0.7.8 - - git-sha1@0.1.2: {} - github-from-package@0.0.0: {} glob-parent@5.1.2: @@ -25633,8 +23919,6 @@ snapshots: capital-case: 1.0.4 tslib: 2.8.1 - help-me@5.0.0: {} - hey-listen@1.0.8: {} hmac-drbg@1.0.1: @@ -25655,14 +23939,6 @@ snapshots: html-escaper@2.0.2: {} - 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 - http-parser-js@0.5.10: {} http-proxy-agent@5.0.0: @@ -25683,7 +23959,7 @@ snapshots: http-proxy@1.18.1: dependencies: eventemitter3: 4.0.7 - follow-redirects: 1.15.11(debug@4.3.7) + follow-redirects: 1.15.11(debug@4.4.1) requires-port: 1.0.0 transitivePeerDependencies: - debug @@ -25732,10 +24008,6 @@ snapshots: dependencies: '@babel/runtime': 7.28.2 - iconv-lite@0.4.24: - dependencies: - safer-buffer: 2.1.2 - iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -25824,10 +24096,6 @@ snapshots: dependencies: loose-envify: 1.4.0 - ip-address@10.0.1: {} - - ipaddr.js@1.9.1: {} - iron-webcrypto@1.2.1: {} is-absolute@1.0.0: @@ -25943,8 +24211,6 @@ snapshots: is-potential-custom-element-name@1.0.1: {} - is-promise@4.0.0: {} - is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -26171,35 +24437,16 @@ snapshots: - supports-color - ts-node - jest-cli@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(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@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)) - exit: 0.1.2 - import-local: 3.2.0 - jest-config: 29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(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-cli@29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)): + jest-cli@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + create-jest: 29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) exit: 0.1.2 import-local: 3.2.0 - jest-config: 29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) jest-util: 29.7.0 jest-validate: 29.7.0 yargs: 17.7.2 @@ -26240,38 +24487,7 @@ snapshots: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)): - dependencies: - '@babel/core': 7.28.0 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.28.0) - 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': 20.19.10 - ts-node: 10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-config@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)): + jest-config@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)): dependencies: '@babel/core': 7.28.0 '@jest/test-sequencer': 29.7.0 @@ -26297,38 +24513,7 @@ snapshots: strip-json-comments: 3.1.1 optionalDependencies: '@types/node': 20.19.10 - ts-node: 10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-config@29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)): - dependencies: - '@babel/core': 7.28.0 - '@jest/test-sequencer': 29.7.0 - '@jest/types': 29.6.3 - babel-jest: 29.7.0(@babel/core@7.28.0) - 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.7.5 - ts-node: 10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5) + ts-node: 10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -26586,24 +24771,12 @@ snapshots: - supports-color - ts-node - jest@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)): - dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)) - '@jest/types': 29.6.3 - import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)) - transitivePeerDependencies: - - '@types/node' - - babel-plugin-macros - - supports-color - - ts-node - - jest@29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)): + jest@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)): dependencies: - '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + '@jest/core': 29.7.0(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) '@jest/types': 29.6.3 import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + jest-cli: 29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -26629,13 +24802,6 @@ snapshots: js-cookies@1.0.4: {} - js-git@0.7.8: - dependencies: - bodec: 0.1.0 - culvert: 0.1.2 - git-sha1: 0.1.2 - pako: 0.2.9 - js-sha3@0.8.0: {} js-tokens@4.0.0: {} @@ -26727,8 +24893,6 @@ snapshots: just-unique@4.2.0: {} - kafkajs@2.2.4: {} - keccak@3.0.4: dependencies: node-addon-api: 2.0.2 @@ -26739,19 +24903,11 @@ snapshots: kleur@3.0.3: {} - kuler@2.0.0: {} + leven@3.1.0: {} - lazy@1.0.11: {} + libsodium-sumo@0.7.15: {} - lazystream@1.0.1: - dependencies: - readable-stream: 2.3.8 - - leven@3.1.0: {} - - libsodium-sumo@0.7.15: {} - - libsodium-wrappers-sumo@0.7.15: + libsodium-wrappers-sumo@0.7.15: dependencies: libsodium-sumo: 0.7.15 @@ -26829,7 +24985,7 @@ snapshots: listenercount@1.0.1: {} - listr2@4.0.5(enquirer@2.3.6): + listr2@4.0.5: dependencies: cli-truncate: 2.1.0 colorette: 2.0.20 @@ -26839,8 +24995,6 @@ snapshots: rxjs: 7.8.2 through: 2.3.8 wrap-ansi: 7.0.0 - optionalDependencies: - enquirer: 2.3.6 listr2@8.0.1: dependencies: @@ -26913,12 +25067,6 @@ snapshots: lodash.clonedeep@4.5.0: {} - lodash.debounce@4.0.8: {} - - lodash.defaults@4.2.0: {} - - lodash.difference@4.5.0: {} - lodash.flatten@4.4.0: {} lodash.isequal@4.5.0: {} @@ -26935,8 +25083,6 @@ snapshots: lodash.truncate@4.4.2: {} - lodash.union@4.6.0: {} - lodash@4.17.21: {} log-symbols@4.1.0: @@ -26959,15 +25105,6 @@ snapshots: strip-ansi: 7.1.0 wrap-ansi: 9.0.0 - logform@2.7.0: - dependencies: - '@colors/colors': 1.6.0 - '@types/triple-beam': 1.3.5 - fecha: 4.2.3 - ms: 2.1.3 - safe-stable-stringify: 2.5.0 - triple-beam: 1.4.1 - long@4.0.0: {} long@5.3.2: {} @@ -26990,14 +25127,6 @@ snapshots: dependencies: yallist: 3.1.1 - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - - lru-cache@7.18.3: {} - - luxon@3.7.1: {} - lz-string@1.5.0: {} magic-string@0.30.17: @@ -27032,14 +25161,10 @@ snapshots: mdn-data@2.0.14: {} - media-typer@1.1.0: {} - memoize-one@5.2.1: {} memorystream@0.3.1: {} - merge-descriptors@2.0.0: {} - merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -27050,8 +25175,6 @@ snapshots: mersenne-twister@1.1.0: {} - methods@1.1.2: {} - micro-ftch@0.3.1: {} micromatch@4.0.5: @@ -27071,16 +25194,10 @@ snapshots: mime-db@1.52.0: {} - mime-db@1.54.0: {} - mime-types@2.1.35: dependencies: mime-db: 1.52.0 - mime-types@3.0.1: - dependencies: - mime-db: 1.54.0 - mimic-fn@2.1.0: {} mimic-fn@4.0.0: {} @@ -27103,10 +25220,6 @@ snapshots: dependencies: brace-expansion: 1.1.12 - minimatch@5.1.6: - dependencies: - brace-expansion: 2.0.2 - minimatch@9.0.5: dependencies: brace-expansion: 2.0.2 @@ -27129,14 +25242,10 @@ snapshots: dependencies: minimist: 1.2.8 - mkdirp@1.0.4: {} - mkdirp@3.0.1: {} modern-normalize@2.0.0: {} - module-details-from-path@1.0.4: {} - moment@2.30.1: {} motion@10.16.2: @@ -27162,9 +25271,6 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - nan@2.23.0: - optional: true - nano-css@5.6.2(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -27184,20 +25290,8 @@ snapshots: natural-compare@1.4.0: {} - needle@2.4.0: - dependencies: - debug: 3.2.7 - iconv-lite: 0.4.24 - sax: 1.4.1 - transitivePeerDependencies: - - supports-color - - negotiator@1.0.0: {} - neo-async@2.6.2: {} - netmask@2.0.2: {} - nice-try@1.0.5: {} no-case@3.0.4: @@ -27302,11 +25396,6 @@ snapshots: dependencies: path-key: 4.0.0 - nssocket@0.6.0: - dependencies: - eventemitter2: 0.4.14 - lazy: 1.0.11 - nullthrows@1.1.1: {} nwsapi@2.2.21: {} @@ -27349,22 +25438,12 @@ snapshots: on-exit-leak-free@0.2.0: {} - on-exit-leak-free@2.1.2: {} - - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - on-net-listen@1.1.2: {} once@1.4.0: dependencies: wrappy: 1.0.2 - one-time@1.0.0: - dependencies: - fn.name: 1.1.0 - onetime@5.1.2: dependencies: mimic-fn: 2.1.0 @@ -27471,28 +25550,8 @@ snapshots: p-try@2.2.0: {} - pac-proxy-agent@7.2.0: - dependencies: - '@tootallnate/quickjs-emscripten': 0.23.0 - agent-base: 7.1.4 - debug: 4.4.3(supports-color@5.5.0) - get-uri: 6.0.5 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - pac-resolver: 7.0.1 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - - pac-resolver@7.0.1: - dependencies: - degenerator: 5.0.1 - netmask: 2.0.2 - package-json-from-dist@1.0.1: {} - pako@0.2.9: {} - pako@1.0.11: {} param-case@3.0.4: @@ -27535,8 +25594,6 @@ snapshots: dependencies: entities: 6.0.1 - parseurl@1.3.3: {} - pascal-case@3.1.2: dependencies: no-case: 3.0.4 @@ -27574,8 +25631,6 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 - path-to-regexp@8.2.0: {} - path-type@3.0.0: dependencies: pify: 3.0.0 @@ -27595,78 +25650,6 @@ snapshots: sha.js: 2.4.12 to-buffer: 1.2.1 - pg-boss@9.0.3: - dependencies: - cron-parser: 4.9.0 - delay: 5.0.0 - lodash.debounce: 4.0.8 - p-map: 4.0.0 - pg: 8.16.3 - serialize-error: 8.1.0 - uuid: 9.0.1 - transitivePeerDependencies: - - pg-native - - pg-cloudflare@1.2.7: - optional: true - - pg-connection-string@2.9.1: {} - - pg-int8@1.0.1: {} - - pg-minify@1.6.5: {} - - pg-pool@3.10.1(pg@8.12.0): - dependencies: - pg: 8.12.0 - - pg-pool@3.10.1(pg@8.16.3): - dependencies: - pg: 8.16.3 - - pg-promise@11.9.1: - dependencies: - assert-options: 0.8.1 - pg: 8.12.0 - pg-minify: 1.6.5 - spex: 3.3.0 - transitivePeerDependencies: - - pg-native - - pg-protocol@1.10.3: {} - - 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.12.0: - dependencies: - pg-connection-string: 2.9.1 - pg-pool: 3.10.1(pg@8.12.0) - pg-protocol: 1.10.3 - pg-types: 2.2.0 - pgpass: 1.0.5 - optionalDependencies: - pg-cloudflare: 1.2.7 - - pg@8.16.3: - dependencies: - pg-connection-string: 2.9.1 - pg-pool: 3.10.1(pg@8.16.3) - pg-protocol: 1.10.3 - pg-types: 2.2.0 - pgpass: 1.0.5 - optionalDependencies: - pg-cloudflare: 1.2.7 - - pgpass@1.0.5: - dependencies: - split2: 4.2.0 - picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -27679,15 +25662,6 @@ snapshots: pidtree@0.6.0: {} - pidusage@2.0.21: - dependencies: - safe-buffer: 5.2.1 - optional: true - - pidusage@3.0.2: - dependencies: - safe-buffer: 5.2.1 - pify@2.3.0: {} pify@3.0.0: {} @@ -27699,32 +25673,8 @@ snapshots: duplexify: 4.1.3 split2: 4.2.0 - pino-abstract-transport@1.2.0: - dependencies: - readable-stream: 4.7.0 - split2: 4.2.0 - - pino-pretty@11.2.1: - 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: 1.2.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@4.0.0: {} - pino-std-serializers@7.0.0: {} - pino@7.11.0: dependencies: atomic-sleep: 1.0.0 @@ -27739,20 +25689,6 @@ snapshots: sonic-boom: 2.8.0 thread-stream: 0.15.2 - pino@9.2.0: - dependencies: - atomic-sleep: 1.0.0 - fast-redact: 3.5.0 - on-exit-leak-free: 2.1.2 - pino-abstract-transport: 1.2.0 - pino-std-serializers: 7.0.0 - process-warning: 3.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: {} pkg-dir@4.2.0: @@ -27771,79 +25707,6 @@ snapshots: optionalDependencies: fsevents: 2.3.2 - pm2-axon-rpc@0.7.1: - dependencies: - debug: 4.4.3(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - pm2-axon@4.0.1: - dependencies: - amp: 0.3.1 - amp-message: 0.1.2 - debug: 4.4.3(supports-color@5.5.0) - escape-string-regexp: 4.0.0 - transitivePeerDependencies: - - supports-color - - pm2-deploy@1.0.2: - dependencies: - run-series: 1.1.9 - tv4: 1.3.0 - - pm2-multimeter@0.1.2: - dependencies: - charm: 0.1.2 - - pm2-sysmonit@1.2.8: - dependencies: - async: 3.2.6 - debug: 4.4.3(supports-color@5.5.0) - pidusage: 2.0.21 - systeminformation: 5.27.7 - tx2: 1.0.5 - transitivePeerDependencies: - - supports-color - optional: true - - pm2@5.4.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): - dependencies: - '@pm2/agent': 2.0.4(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@pm2/io': 6.0.1 - '@pm2/js-api': 0.8.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@pm2/pm2-version-check': 1.0.4 - async: 3.2.6 - blessed: 0.1.81 - chalk: 3.0.0 - chokidar: 3.6.0 - cli-tableau: 2.0.1 - commander: 2.15.1 - croner: 4.1.97 - dayjs: 1.11.11 - debug: 4.4.1 - enquirer: 2.3.6 - eventemitter2: 5.0.1 - fclone: 1.0.11 - js-yaml: 4.1.0 - mkdirp: 1.0.4 - needle: 2.4.0 - pidusage: 3.0.2 - pm2-axon: 4.0.1 - pm2-axon-rpc: 0.7.1 - pm2-deploy: 1.0.2 - pm2-multimeter: 0.1.2 - promptly: 2.2.0 - semver: 7.7.2 - source-map-support: 0.5.21 - sprintf-js: 1.1.2 - vizion: 2.2.1 - optionalDependencies: - pm2-sysmonit: 1.2.8 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - pngjs@3.4.0: {} pngjs@5.0.0: {} @@ -28009,45 +25872,37 @@ snapshots: postcss: 8.4.35 ts-node: 10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@18.19.122)(typescript@5.4.5) - postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)): + postcss-load-config@4.0.2(postcss@8.4.35)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)): dependencies: lilconfig: 3.1.3 yaml: 2.8.1 optionalDependencies: postcss: 8.4.35 - ts-node: 10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5) - - postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)): - dependencies: - lilconfig: 3.1.3 - yaml: 2.8.1 - optionalDependencies: - postcss: 8.5.6 - ts-node: 10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2) + ts-node: 10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5) - postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)): + postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)): dependencies: lilconfig: 3.1.3 yaml: 2.8.1 optionalDependencies: postcss: 8.5.6 - ts-node: 10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5) + ts-node: 10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5) - postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)): + postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)): dependencies: lilconfig: 3.1.3 yaml: 2.8.1 optionalDependencies: postcss: 8.5.6 - ts-node: 10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2) + ts-node: 10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2) - postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)): + postcss-load-config@4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)): dependencies: lilconfig: 3.1.3 yaml: 2.8.1 optionalDependencies: postcss: 8.5.6 - ts-node: 10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5) + ts-node: 10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5) postcss-logical@7.0.1(postcss@8.4.35): dependencies: @@ -28199,16 +26054,6 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 - 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 - preact@10.27.0: {} preact@10.28.2: {} @@ -28250,8 +26095,6 @@ snapshots: process-warning@1.0.0: {} - process-warning@3.0.0: {} - process@0.11.10: {} progress@2.0.3: {} @@ -28260,10 +26103,6 @@ snapshots: dependencies: asap: 2.0.6 - promptly@2.2.0: - dependencies: - read: 1.0.7 - prompts@2.4.2: dependencies: kleur: 3.0.3 @@ -28281,10 +26120,6 @@ snapshots: retry: 0.12.0 signal-exit: 3.0.7 - properties-reader@2.3.0: - dependencies: - mkdirp: 1.0.4 - property-expr@2.0.6: {} protobufjs@8.0.1: @@ -28302,28 +26137,8 @@ snapshots: '@types/node': 20.19.10 long: 5.3.2 - proxy-addr@2.0.7: - dependencies: - forwarded: 0.2.0 - ipaddr.js: 1.9.1 - - proxy-agent@6.3.1: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3(supports-color@5.5.0) - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6 - lru-cache: 7.18.3 - pac-proxy-agent: 7.2.0 - proxy-from-env: 1.1.0 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - proxy-compare@2.5.1: {} - proxy-from-env@1.1.0: {} - proxy-from-env@2.1.0: {} psl@1.15.0: @@ -28381,10 +26196,6 @@ snapshots: pngjs: 5.0.0 yargs: 15.4.1 - qs@6.13.0: - dependencies: - side-channel: 1.1.0 - qs@6.14.0: dependencies: side-channel: 1.1.0 @@ -28417,15 +26228,6 @@ snapshots: 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 @@ -28687,10 +26489,6 @@ snapshots: normalize-package-data: 2.5.0 path-type: 3.0.0 - read@1.0.7: - dependencies: - mute-stream: 0.0.8 - readable-stream@2.3.8: dependencies: core-util-is: 1.0.3 @@ -28715,10 +26513,6 @@ snapshots: process: 0.11.10 string_decoder: 1.3.0 - readdir-glob@1.1.3: - dependencies: - minimatch: 5.1.6 - readdirp@3.6.0: dependencies: picomatch: 2.3.1 @@ -28729,8 +26523,6 @@ snapshots: real-require@0.1.0: {} - real-require@0.2.0: {} - recast@0.23.11: dependencies: ast-types: 0.16.1 @@ -28801,14 +26593,6 @@ snapshots: require-from-string@2.0.2: {} - require-in-the-middle@5.2.0: - dependencies: - debug: 4.4.3(supports-color@5.5.0) - module-details-from-path: 1.0.4 - resolve: 1.22.10 - transitivePeerDependencies: - - supports-color - require-main-filename@2.0.0: {} requires-port@1.0.0: {} @@ -28910,16 +26694,6 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.46.2 fsevents: 2.3.3 - router@2.2.0: - dependencies: - debug: 4.4.3(supports-color@5.5.0) - depd: 2.0.0 - is-promise: 4.0.0 - parseurl: 1.3.3 - path-to-regexp: 8.2.0 - transitivePeerDependencies: - - supports-color - rpc-websockets@7.11.0: dependencies: eventemitter3: 4.0.7 @@ -28952,8 +26726,6 @@ snapshots: dependencies: queue-microtask: 1.2.3 - run-series@1.1.9: {} - rxjs@7.8.2: dependencies: tslib: 2.8.1 @@ -28985,8 +26757,6 @@ snapshots: safer-buffer@2.1.2: {} - sax@1.4.1: {} - saxes@6.0.0: dependencies: xmlchars: 2.2.0 @@ -29013,55 +26783,20 @@ snapshots: node-addon-api: 5.1.0 node-gyp-build: 4.8.4 - secure-json-parse@2.7.0: {} - semver@5.7.2: {} semver@6.3.1: {} - semver@7.5.4: - dependencies: - lru-cache: 6.0.0 - semver@7.7.2: {} semver@7.7.3: {} - send@1.2.0: - dependencies: - debug: 4.4.3(supports-color@5.5.0) - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 2.0.0 - http-errors: 2.0.0 - mime-types: 3.0.1 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - sentence-case@3.0.4: dependencies: no-case: 3.0.4 tslib: 2.8.1 upper-case-first: 2.0.2 - serialize-error@8.1.0: - dependencies: - type-fest: 0.20.2 - - serve-static@2.2.0: - dependencies: - encodeurl: 2.0.0 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 1.2.0 - transitivePeerDependencies: - - supports-color - set-blocking@2.0.0: {} set-function-length@1.2.2: @@ -29090,8 +26825,6 @@ snapshots: setimmediate@1.0.5: {} - setprototypeof@1.2.0: {} - sha.js@2.4.12: dependencies: inherits: 2.0.4 @@ -29116,8 +26849,6 @@ snapshots: shell-quote@1.9.0: {} - shimmer@1.2.1: {} - side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -29194,8 +26925,6 @@ snapshots: ansi-styles: 6.2.1 is-fullwidth-code-point: 5.0.0 - smart-buffer@4.2.0: {} - snake-case@3.0.4: dependencies: dot-case: 3.0.4 @@ -29230,29 +26959,12 @@ snapshots: transitivePeerDependencies: - supports-color - socks-proxy-agent@8.0.5: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3(supports-color@5.5.0) - socks: 2.8.7 - transitivePeerDependencies: - - supports-color - - socks@2.8.7: - dependencies: - ip-address: 10.0.1 - smart-buffer: 4.2.0 - solidity-ast@0.4.60: {} sonic-boom@2.8.0: dependencies: atomic-sleep: 1.0.0 - sonic-boom@4.2.0: - dependencies: - atomic-sleep: 1.0.0 - source-map-js@1.2.1: {} source-map-support@0.5.13: @@ -29260,11 +26972,6 @@ snapshots: 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.5.6: {} source-map@0.6.1: {} @@ -29289,10 +26996,6 @@ snapshots: spdx-license-ids@3.0.22: {} - spex@3.3.0: {} - - split-ca@1.0.1: {} - split-on-first@1.1.0: {} split2@4.2.0: {} @@ -29303,27 +27006,10 @@ snapshots: sprintf-js@1.0.3: {} - sprintf-js@1.1.2: {} - - ssh-remote-port-forward@1.0.4: - dependencies: - '@types/ssh2': 0.5.52 - ssh2: 1.16.0 - - ssh2@1.16.0: - dependencies: - asn1: 0.2.6 - bcrypt-pbkdf: 1.0.2 - optionalDependencies: - cpu-features: 0.0.10 - nan: 2.23.0 - stack-generator@2.0.10: dependencies: stackframe: 1.3.4 - stack-trace@0.0.10: {} - stack-utils@2.0.6: dependencies: escape-string-regexp: 2.0.0 @@ -29343,8 +27029,6 @@ snapshots: stack-generator: 2.0.10 stacktrace-gps: 3.1.2 - statuses@2.0.1: {} - std-env@4.1.0: {} stop-iteration-iterator@1.1.0: @@ -29374,13 +27058,6 @@ snapshots: streamsearch@1.1.0: {} - streamx@2.22.1: - dependencies: - fast-fifo: 1.3.2 - text-decoder: 1.2.3 - optionalDependencies: - bare-events: 2.6.1 - strict-uri-encode@2.0.0: {} string-argv@0.3.2: {} @@ -29559,9 +27236,6 @@ snapshots: timeout-signal: 2.0.0 whatwg-mimetype: 4.0.0 - systeminformation@5.27.7: - optional: true - table@6.9.0: dependencies: ajv: 8.17.1 @@ -29583,10 +27257,10 @@ snapshots: tailwind-merge: 1.14.0 tailwindcss: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@18.19.122)(typescript@5.4.5)) - tailwind-variants@0.1.20(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))): + tailwind-variants@0.1.20(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))): dependencies: tailwind-merge: 1.14.0 - tailwindcss: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + tailwindcss: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) tailwind-variants@0.1.20(tailwindcss@4.1.11): dependencies: @@ -29597,19 +27271,19 @@ snapshots: dependencies: tailwindcss: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@18.19.122)(typescript@5.4.5)) - tailwindcss-animate@1.0.7(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))): + tailwindcss-animate@1.0.7(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))): dependencies: - tailwindcss: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + tailwindcss: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) tailwindcss-radix@3.0.3: {} - tailwindcss-themer@4.0.0(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))): + tailwindcss-themer@4.0.0(tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))): dependencies: color: 4.2.3 just-unique: 4.2.0 lodash.merge: 4.6.2 lodash.mergewith: 4.6.2 - tailwindcss: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + tailwindcss: 3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@18.19.122)(typescript@5.4.5)): dependencies: @@ -29638,7 +27312,7 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)): + tailwindcss@3.4.4(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)): dependencies: '@alloc/quick-lru': 5.2.0 arg: 5.0.2 @@ -29657,7 +27331,7 @@ snapshots: postcss: 8.4.35 postcss-import: 15.1.0(postcss@8.4.35) postcss-js: 4.0.1(postcss@8.4.35) - postcss-load-config: 4.0.2(postcss@8.4.35)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + postcss-load-config: 4.0.2(postcss@8.4.35)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) postcss-nested: 6.2.0(postcss@8.4.35) postcss-selector-parser: 6.1.2 resolve: 1.22.10 @@ -29676,16 +27350,6 @@ snapshots: pump: 3.0.3 tar-stream: 2.2.0 - tar-fs@3.1.0: - dependencies: - pump: 3.0.3 - tar-stream: 3.1.7 - optionalDependencies: - bare-fs: 4.2.0 - bare-path: 3.0.0 - transitivePeerDependencies: - - bare-buffer - tar-stream@2.2.0: dependencies: bl: 4.1.0 @@ -29694,12 +27358,6 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - tar-stream@3.1.7: - dependencies: - b4a: 1.6.7 - fast-fifo: 1.3.2 - streamx: 2.22.1 - tar@7.4.3: dependencies: '@isaacs/fs-minipass': 4.0.1 @@ -29715,36 +27373,8 @@ snapshots: glob: 7.2.3 minimatch: 3.1.2 - testcontainers@10.10.0: - dependencies: - '@balena/dockerignore': 1.0.2 - '@types/dockerode': 3.3.42 - archiver: 5.3.2 - async-lock: 1.4.1 - byline: 5.0.0 - debug: 4.4.1 - docker-compose: 0.24.8 - dockerode: 3.3.5 - get-port: 5.1.1 - node-fetch: 2.7.0 - proper-lockfile: 4.1.2 - properties-reader: 2.3.0 - ssh-remote-port-forward: 1.0.4 - tar-fs: 3.1.0 - tmp: 0.2.5 - transitivePeerDependencies: - - bare-buffer - - encoding - - supports-color - - text-decoder@1.2.3: - dependencies: - b4a: 1.6.7 - text-encoding-utf-8@1.0.2: {} - text-hex@1.0.0: {} - thenify-all@1.6.0: dependencies: thenify: 3.3.1 @@ -29757,10 +27387,6 @@ snapshots: dependencies: real-require: 0.1.0 - thread-stream@3.1.0: - dependencies: - real-require: 0.2.0 - throttle-debounce@3.0.1: {} through@2.3.8: {} @@ -29804,8 +27430,6 @@ snapshots: dependencies: tslib: 2.8.1 - tmp@0.2.5: {} - tmpl@1.0.5: {} to-buffer@1.2.1: @@ -29820,8 +27444,6 @@ snapshots: toggle-selection@1.0.6: {} - toidentifier@1.0.1: {} - toml@3.0.0: {} toposort@2.0.2: {} @@ -29847,18 +27469,16 @@ snapshots: tree-kill@1.2.2: {} - triple-beam@1.4.1: {} - ts-easing@0.2.0: {} ts-interface-checker@0.1.13: {} - ts-jest@29.4.1(@babel/core@7.28.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)))(typescript@5.4.5): + ts-jest@29.4.1(@babel/core@7.28.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.28.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)))(typescript@5.4.5): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 handlebars: 4.7.9 - jest: 29.7.0(@types/node@22.7.5)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + jest: 29.7.0(@types/node@20.19.10)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 @@ -29896,7 +27516,7 @@ snapshots: '@swc/core': 1.13.3(@swc/helpers@0.5.17) optional: true - ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2): + ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -29910,34 +27530,13 @@ snapshots: 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 - optionalDependencies: - '@swc/core': 1.13.3(@swc/helpers@0.5.17) - optional: true - - ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5): - 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.7.5 - acorn: 8.15.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.4.5 v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: '@swc/core': 1.13.3(@swc/helpers@0.5.17) - ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2): + ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2): dependencies: '@cspotcode/source-map-support': 0.8.1 '@tsconfig/node10': 1.0.11 @@ -29955,17 +27554,17 @@ snapshots: v8-compile-cache-lib: 3.0.1 yn: 3.1.1 optionalDependencies: - '@swc/core': 1.4.1(@swc/helpers@0.5.17) + '@swc/core': 1.13.3(@swc/helpers@0.5.17) optional: true - ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5): + ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5): 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.7.5 + '@types/node': 20.19.10 acorn: 8.15.0 acorn-walk: 8.3.4 arg: 4.1.3 @@ -29997,19 +27596,15 @@ snapshots: tslib@1.14.1: {} - tslib@1.9.3: {} - tslib@2.4.0: {} tslib@2.4.1: {} tslib@2.6.3: {} - tslib@2.7.0: {} - tslib@2.8.1: {} - tsup@8.0.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.9.2): + tsup@8.0.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.9.2): dependencies: bundle-require: 4.2.1(esbuild@0.25.3) cac: 6.7.14 @@ -30019,7 +27614,7 @@ snapshots: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) resolve-from: 5.0.0 rollup: 4.46.2 source-map: 0.8.0-beta.0 @@ -30033,7 +27628,7 @@ snapshots: - supports-color - ts-node - tsup@8.0.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5): + tsup@8.0.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.4.5): dependencies: bundle-require: 4.2.1(esbuild@0.25.3) cac: 6.7.14 @@ -30043,7 +27638,7 @@ snapshots: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) resolve-from: 5.0.0 rollup: 4.46.2 source-map: 0.8.0-beta.0 @@ -30057,31 +27652,7 @@ snapshots: - supports-color - ts-node - tsup@8.1.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2))(typescript@5.9.2): - dependencies: - bundle-require: 4.2.1(esbuild@0.27.2) - cac: 6.7.14 - chokidar: 3.6.0 - debug: 4.4.3(supports-color@5.5.0) - esbuild: 0.27.2 - execa: 5.1.1 - globby: 11.1.0 - joycon: 3.1.1 - postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)) - resolve-from: 5.0.0 - rollup: 4.46.2 - source-map: 0.8.0-beta.0 - sucrase: 3.35.0 - tree-kill: 1.2.2 - optionalDependencies: - '@swc/core': 1.13.3(@swc/helpers@0.5.17) - postcss: 8.5.6 - typescript: 5.9.2 - transitivePeerDependencies: - - supports-color - - ts-node - - tsup@8.1.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5))(typescript@5.4.5): + tsup@8.1.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5))(typescript@5.4.5): dependencies: bundle-require: 4.2.1(esbuild@0.27.2) cac: 6.7.14 @@ -30091,7 +27662,7 @@ snapshots: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.7.5)(typescript@5.4.5)) + postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.4.5)) resolve-from: 5.0.0 rollup: 4.46.2 source-map: 0.8.0-beta.0 @@ -30105,7 +27676,7 @@ snapshots: - supports-color - ts-node - tsup@8.1.0(@swc/core@1.4.1(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2))(typescript@5.9.2): + tsup@8.1.0(@swc/core@1.13.3(@swc/helpers@0.5.17))(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2))(typescript@5.9.2): dependencies: bundle-require: 4.2.1(esbuild@0.27.2) cac: 6.7.14 @@ -30115,14 +27686,14 @@ snapshots: execa: 5.1.1 globby: 11.1.0 joycon: 3.1.1 - postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.4.1(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)) + postcss-load-config: 4.0.2(postcss@8.5.6)(ts-node@10.9.2(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@20.19.10)(typescript@5.9.2)) resolve-from: 5.0.0 rollup: 4.46.2 source-map: 0.8.0-beta.0 sucrase: 3.35.0 tree-kill: 1.2.2 optionalDependencies: - '@swc/core': 1.4.1(@swc/helpers@0.5.17) + '@swc/core': 1.13.3(@swc/helpers@0.5.17) postcss: 8.5.6 typescript: 5.9.2 transitivePeerDependencies: @@ -30176,19 +27747,8 @@ snapshots: turbo-windows-64: 2.3.3 turbo-windows-arm64: 2.3.3 - tv4@1.3.0: {} - - tweetnacl@0.14.5: {} - - tx2@1.0.5: - dependencies: - json-stringify-safe: 5.0.1 - optional: true - type-detect@4.0.8: {} - type-fest@0.20.2: {} - type-fest@0.21.3: {} type-fest@2.19.0: {} @@ -30197,12 +27757,6 @@ snapshots: type-fest@4.41.0: {} - type-is@2.0.1: - dependencies: - content-type: 1.0.5 - media-typer: 1.1.0 - mime-types: 3.0.1 - typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 @@ -30267,8 +27821,6 @@ snapshots: undici-types@5.26.5: {} - undici-types@6.19.8: {} - undici-types@6.21.0: {} undici@5.29.0: @@ -30291,8 +27843,6 @@ snapshots: dependencies: normalize-path: 2.1.1 - unpipe@1.0.0: {} - unstorage@1.16.1(idb-keyval@6.2.2): dependencies: anymatch: 3.1.3 @@ -30396,8 +27946,6 @@ snapshots: is-typed-array: 1.1.15 which-typed-array: 1.1.19 - utils-merge@1.0.1: {} - uuid-parse@1.1.0: {} uuid@8.3.2: {} @@ -30427,8 +27975,6 @@ snapshots: value-or-promise@1.0.12: {} - vary@1.1.2: {} - victory-vendor@36.9.2: dependencies: '@types/d3-array': 3.2.1 @@ -30497,32 +28043,32 @@ snapshots: - utf-8-validate - zod - vite-plugin-node-polyfills@0.24.0(rollup@4.46.2)(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)): + vite-plugin-node-polyfills@0.24.0(rollup@4.46.2)(vite@6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)): dependencies: '@rollup/plugin-inject': 5.0.5(rollup@4.46.2) node-stdlib-browser: 1.3.1 - vite: 6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) + vite: 6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) transitivePeerDependencies: - rollup - vite-plugin-svgr@4.2.0(rollup@4.46.2)(typescript@5.4.5)(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)): + vite-plugin-svgr@4.2.0(rollup@4.46.2)(typescript@5.4.5)(vite@6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)): dependencies: '@rollup/pluginutils': 5.2.0(rollup@4.46.2) '@svgr/core': 8.1.0(typescript@5.4.5) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.4.5)) - vite: 6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) + vite: 6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) transitivePeerDependencies: - rollup - supports-color - typescript - vite-tsconfig-paths@4.3.2(typescript@5.4.5)(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)): + vite-tsconfig-paths@4.3.2(typescript@5.4.5)(vite@6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)): dependencies: debug: 4.4.1 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.4.5) optionalDependencies: - vite: 6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) + vite: 6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) transitivePeerDependencies: - supports-color - typescript @@ -30559,23 +28105,7 @@ snapshots: tsx: 4.16.0 yaml: 2.8.1 - vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1): - dependencies: - esbuild: 0.25.3 - fdir: 6.5.0(picomatch@4.0.3) - picomatch: 4.0.3 - postcss: 8.5.6 - rollup: 4.46.2 - tinyglobby: 0.2.14 - optionalDependencies: - '@types/node': 22.7.5 - fsevents: 2.3.3 - jiti: 2.5.1 - lightningcss: 1.30.1 - tsx: 4.16.0 - yaml: 2.8.1 - - vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1): + vite@6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1): dependencies: esbuild: 0.25.3 fdir: 6.5.0(picomatch@4.0.3) @@ -30584,7 +28114,7 @@ snapshots: rollup: 4.46.2 tinyglobby: 0.2.14 optionalDependencies: - '@types/node': 22.7.5 + '@types/node': 20.19.10 fsevents: 2.3.3 jiti: 2.5.1 lightningcss: 1.30.1 @@ -30629,10 +28159,10 @@ snapshots: - tsx - yaml - vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1): + vitest@4.1.9(@types/node@20.19.10)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1): dependencies: '@vitest/expect': 4.1.9 - '@vitest/mocker': 4.1.9(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1)) + '@vitest/mocker': 4.1.9(vite@6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) '@vitest/pretty-format': 4.1.9 '@vitest/runner': 4.1.9 '@vitest/snapshot': 4.1.9 @@ -30649,48 +28179,10 @@ snapshots: tinyexec: 1.2.4 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.16.0)(yaml@2.8.1) + vite: 6.3.5(@types/node@20.19.10)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.7.5 - jsdom: 20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) - transitivePeerDependencies: - - jiti - - less - - lightningcss - - msw - - sass - - sass-embedded - - stylus - - sugarss - - terser - - tsx - - yaml - - vitest@4.1.9(@types/node@22.7.5)(jiti@2.5.1)(jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1): - dependencies: - '@vitest/expect': 4.1.9 - '@vitest/mocker': 4.1.9(vite@6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1)) - '@vitest/pretty-format': 4.1.9 - '@vitest/runner': 4.1.9 - '@vitest/snapshot': 4.1.9 - '@vitest/spy': 4.1.9 - '@vitest/utils': 4.1.9 - es-module-lexer: 2.3.0 - expect-type: 1.4.0 - magic-string: 0.30.21 - obug: 2.1.3 - pathe: 2.0.3 - picomatch: 4.0.3 - std-env: 4.1.0 - tinybench: 2.9.0 - tinyexec: 1.2.4 - tinyglobby: 0.2.17 - tinyrainbow: 3.1.0 - vite: 6.3.5(@types/node@22.7.5)(jiti@2.5.1)(lightningcss@1.30.1)(tsx@4.7.1)(yaml@2.8.1) - why-is-node-running: 2.3.0 - optionalDependencies: - '@types/node': 22.7.5 + '@types/node': 20.19.10 jsdom: 20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - jiti @@ -30705,13 +28197,6 @@ snapshots: - tsx - yaml - vizion@2.2.1: - dependencies: - async: 2.6.4 - git-node-fs: 1.0.0(js-git@0.7.8) - ini: 1.3.8 - js-git: 0.7.8 - vm-browserify@1.1.2: {} w3c-xmlserializer@4.0.0: @@ -30906,26 +28391,6 @@ snapshots: siginfo: 2.0.0 stackback: 0.0.2 - winston-transport@4.9.0: - dependencies: - logform: 2.7.0 - readable-stream: 3.6.2 - triple-beam: 1.4.1 - - winston@3.13.0: - dependencies: - '@colors/colors': 1.6.0 - '@dabh/diagnostics': 2.0.3 - async: 3.2.6 - is-stream: 2.0.1 - logform: 2.7.0 - one-time: 1.0.0 - readable-stream: 3.6.2 - safe-stable-stringify: 2.5.0 - stack-trace: 0.0.10 - triple-beam: 1.4.1 - winston-transport: 4.9.0 - wordwrap@1.0.0: {} wrap-ansi@5.1.0: @@ -30992,8 +28457,6 @@ snapshots: xstate@5.0.0-beta.54: {} - xstate@5.20.2: {} - xstream@11.14.0: dependencies: globalthis: 1.0.4 @@ -31009,8 +28472,6 @@ snapshots: yallist@3.1.1: {} - yallist@4.0.0: {} - yallist@5.0.0: {} yaml-ast-parser@0.0.43: {} @@ -31086,12 +28547,6 @@ snapshots: toposort: 2.0.2 type-fest: 2.19.0 - zip-stream@4.1.1: - dependencies: - archiver-utils: 3.0.4 - compress-commons: 4.1.2 - readable-stream: 3.6.2 - zod-validation-error@3.0.0(zod@3.22.4): dependencies: zod: 3.22.4 diff --git a/scripts/run-backend.sh b/scripts/run-backend.sh deleted file mode 100755 index 21e4e819f..000000000 --- a/scripts/run-backend.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -# run backend -cd packages/graphql -npx tsx src/app.ts diff --git a/scripts/setup-backend.sh b/scripts/setup-backend.sh deleted file mode 100755 index 649eedcc0..000000000 --- a/scripts/setup-backend.sh +++ /dev/null @@ -1,223 +0,0 @@ -#!/bin/bash - -check_var () { - cd packages/graphql - echo "" - echo "Checking the .env file" - sleep .5 - if [ ! -f .env ]; then - echo "Fail! .env file is missing, please copy from .env.example" - exit 1 - else - echo "Done! .env file found successfully" - fi - echo "Loading the .env file variables..." - sleep 2 - export $(grep -v '^#' .env | xargs) - env_vars=( - FUEL_PROVIDER - SERVER_PORT - SERVER_API_KEY - DB_HOST - DB_PORT - DB_USER - DB_PASS - DB_NAME - RABBITMQ_HOST - RABBITMQ_PORT - RABBITMQ_USER - RABBITMQ_PASS - QUEUE_CONCURRENCY - SSL - DEBUG - ) - echo "Checking .env file variables..." - for env_var in "${env_vars[@]}"; do - if [[ -z "${!env_var}" ]]; then - echo $env_var not found, please set the variable on .env file - exit 1 - else - echo "$env_var = ${!env_var}" - fi - done - sleep 1 - echo "Done! .env file was configured successfully" - echo "" - cd ../.. -} - -start_database () { - echo "" - export PGPASSWORD='postgres' - pg_isready -h localhost -U postgres -d postgres -p 5435 > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "Database is already started" - echo "" - return - fi - echo "Starting database using docker compose..." - export PROFILE=indexer-local - pnpm node:start &> /dev/null 2>&1 - status=1 - limit=0 - while [ $status -gt 0 ]; do - if [ $limit -eq 20 ]; then - echo "Could not start PostgreSQL, please check your environment" - echo "" - return - fi - sleep 1 - echo "Waiting PostgreSQL connection..." - pg_isready -h localhost -U postgres -d postgres -p 5435 > /dev/null 2>&1 - status=$? - limit=$((limit+1)) - done - echo "Done! PostgreSQL is ready and accepting connections." - echo "" -} - -apply_migrations () { - cd packages/graphql - echo "Checking psql installation..." - if command -v psql &> /dev/null 2>&1 - then - echo "Done! psql is installed" - else - echo "Fail! psql is not installed, to install psql use: brew install libpq" - exit 1 - fi - export PGPASSWORD='postgres' - pg_isready -h localhost -U postgres -d postgres -p 5435 > /dev/null 2>&1 - sleep 2 - if [ $? -eq 0 ]; then - echo "Done! PostgreSQL is ready and accepting connections successfully" - else - echo "Fail! PostgreSQL is not running" - exit 1 - fi - for sql_file in `/bin/ls database/*.sql`; do - psql -h localhost -U postgres -d postgres -p 5435 -f $sql_file > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "Done! Successfully applied $sql_file" - else - echo "Fail! Error applying $sql_file" - exit 1 - fi - done - echo "Done! Database has the schema migrations" - echo "" - cd ../.. -} - -update_migrations () { - cd packages/graphql - echo "Checking psql installation..." - if command -v psql &> /dev/null 2>&1 - then - echo "Done! psql is installed" - else - echo "Fail! psql is not installed, to install psql use: brew install libpq" - exit 1 - fi - export PGPASSWORD='postgres' - pg_isready -h localhost -U postgres -d postgres -p 5435 > /dev/null 2>&1 - sleep 2 - if [ $? -eq 0 ]; then - echo "Done! PostgreSQL is ready and accepting connections successfully" - else - echo "Fail! PostgreSQL is not running" - exit 1 - fi - # get actual version - version=`psql -t -X -h localhost -U postgres -d postgres -p 5435 -c "select version from indexer.migration;"` - for sql_file in `/bin/ls database/*.sql`; do - file_version=$(echo "$sql_file" | grep -o -E '[0-9]+') - if (($file_version > $version)); then - psql -h localhost -U postgres -d postgres -p 5435 -f $sql_file > /dev/null 2>&1 - if [ $? -eq 0 ]; then - echo "Done! Successfully applied $sql_file" - else - echo "Fail! Error applying $sql_file" - exit 1 - fi - fi - done - echo "Done! Database has the schema migrations" - echo "" - cd ../.. -} - -sync_blocks () { - cd packages/graphql - echo "Sync block range (max interval is 10)..." - read -p "From: " from - read -p "To: " to - echo "Syncing blocks from ${from} to ${to}" - npx tsx src/sync-block-range.ts $from $to > /dev/null 2>&1 - echo "Done! Setup finished successfully, backend is ready to use" - echo "" - cd ../.. -} - -init () { -echo " - ______ _ - | ____| | | - | |__ __ ___ __ | | ___ _ __ ___ _ __ - | __| \ \/ / '_ \| |/ _ \| '__/ _ \ '__| - | |____ > <| |_) | | (_) | | | __/ | - |______/_/\_\ .__/|_|\___/|_| \___|_| - | | - |_| - " - echo "" - echo "Welcome to Explorer Setup Tool" - sleep 2 - echo "" -} - -menu () { - COLUMNS=0 - PS3="Please enter your choice: " - select choice_main in "Execute complete setup (from scratch)" "Check .env variables" "Start database" "Apply database migrations (all)" "Update database schema (diff)" "Sync blocks" "Exit" - do - case $choice_main in - "Execute complete setup (from scratch)" ) - check_var - start_database - apply_migrations - sync_blocks - echo "Done! Type pnpm run:backend to run the backend" - exit 0 - ;; - "Check .env variables" ) - check_var - menu - ;; - "Start database" ) - start_database - menu - ;; - "Apply database migrations (all)" ) - start_database - apply_migrations - menu - ;; - "Update database schema (diff)" ) - start_database - update_migrations - menu - ;; - "Sync blocks" ) - sync_blocks - menu - ;; - "Exit" ) - exit 0 - ;; - esac - done -} - -init -menu From 9005043f473c345231f3c598585609a265bf6280 Mon Sep 17 00:00:00 2001 From: Nelito Junior Date: Thu, 3 Sep 2026 18:46:57 -0300 Subject: [PATCH 2/2] chore(api-lite): drop committed block fixtures from the repo Parity stays opt-in via `pnpm --filter api-lite fixture `; the multi-MB fuel-core JSON dumps were not a CI gate and bloated the PR diff. --- .gitignore | 4 + .../scripts/measure-heap-multiplier.ts | 40 +- packages/api-lite/src/store/BlockStore.ts | 4 +- .../api-lite/test/fixtures/blocks/.gitkeep | 0 .../test/fixtures/blocks/62724773.bin | Bin 497823 -> 0 bytes .../fixtures/blocks/62724773.fuelcore.json | 80728 ---------------- .../test/fixtures/blocks/62724775.bin | Bin 353486 -> 0 bytes .../fixtures/blocks/62724775.fuelcore.json | 57287 ----------- 8 files changed, 39 insertions(+), 138024 deletions(-) create mode 100644 packages/api-lite/test/fixtures/blocks/.gitkeep delete mode 100644 packages/api-lite/test/fixtures/blocks/62724773.bin delete mode 100644 packages/api-lite/test/fixtures/blocks/62724773.fuelcore.json delete mode 100644 packages/api-lite/test/fixtures/blocks/62724775.bin delete mode 100644 packages/api-lite/test/fixtures/blocks/62724775.fuelcore.json diff --git a/.gitignore b/.gitignore index df7ecada8..0d2173daa 100644 --- a/.gitignore +++ b/.gitignore @@ -105,3 +105,7 @@ CLAUDE.md # agent scratch .superpowers/ + +# api-lite parity fixtures (fetch locally; do not commit) +packages/api-lite/test/fixtures/blocks/*.bin +packages/api-lite/test/fixtures/blocks/*.fuelcore.json diff --git a/packages/api-lite/scripts/measure-heap-multiplier.ts b/packages/api-lite/scripts/measure-heap-multiplier.ts index 7a2a9a370..87faf1f3c 100644 --- a/packages/api-lite/scripts/measure-heap-multiplier.ts +++ b/packages/api-lite/scripts/measure-heap-multiplier.ts @@ -4,8 +4,10 @@ // GQLBlock and update that constant if the multiplier moves. Run with // --expose-gc for accurate deltas. // -// npx tsx --expose-gc scripts/measure-heap-multiplier.ts -import { readFileSync } from 'node:fs'; +// Fixtures are not committed. Fetch first, then measure: +// pnpm --filter api-lite fixture +// npx tsx --expose-gc scripts/measure-heap-multiplier.ts [height...] +import { existsSync, readFileSync, readdirSync } from 'node:fs'; import { join } from 'node:path'; import { decodeBlock } from '../src/decoder/block'; @@ -20,11 +22,19 @@ const fee = { }, }; +const fixturesDir = join(__dirname, '../test/fixtures/blocks'); + function decodeFixture(height: number) { - const bytes = readFileSync( - join(__dirname, '../test/fixtures/blocks', `${height}.bin`), - ); - return decodeBlock(new Uint8Array(bytes), { chainId: 9889, fee }); + const path = join(fixturesDir, `${height}.bin`); + if (!existsSync(path)) { + throw new Error( + `missing ${path}; run: pnpm --filter api-lite fixture ${height}`, + ); + } + return decodeBlock(new Uint8Array(readFileSync(path)), { + chainId: 9889, + fee, + }); } function measure(height: number) { @@ -48,7 +58,23 @@ function measure(height: number) { return multiplier; } -const heights = [62724773, 62724775]; +const fromArgs = process.argv + .slice(2) + .map(Number) + .filter((n) => Number.isInteger(n)); +const fromDisk = existsSync(fixturesDir) + ? readdirSync(fixturesDir) + .filter((f) => f.endsWith('.bin')) + .map((f) => Number(f.replace('.bin', ''))) + : []; +const heights = fromArgs.length ? fromArgs : fromDisk; +if (!heights.length) { + console.error( + 'no block fixtures; fetch one first:\n pnpm --filter api-lite fixture \n npx tsx --expose-gc scripts/measure-heap-multiplier.ts [height...]', + ); + process.exit(1); +} + const multipliers = heights.map(measure); const avg = multipliers.reduce((a, b) => a + b, 0) / multipliers.length; console.log(`\naverage multiplier: ${avg.toFixed(2)}x`); diff --git a/packages/api-lite/src/store/BlockStore.ts b/packages/api-lite/src/store/BlockStore.ts index bd5d9c21c..fff3592f6 100644 --- a/packages/api-lite/src/store/BlockStore.ts +++ b/packages/api-lite/src/store/BlockStore.ts @@ -26,8 +26,8 @@ type Opts = { // A decoded GQLBlock's real V8 heap footprint (nested objects/arrays/strings // for every tx, input, output, receipt) runs well above its // JSON.stringify() byte length -- measured empirically at ~2.25x via -// scripts/measure-heap-multiplier.ts against two real mainnet block fixtures -// (test/fixtures/blocks/62724773.bin, 62724775.bin; 200 held copies each, +// scripts/measure-heap-multiplier.ts against real mainnet blocks fetched with +// `pnpm --filter api-lite fixture ` (200 held copies each, // process.memoryUsage().heapUsed delta with --expose-gc). Rounded up to 2.5x // for headroom. Without this, the LRU's `memoryBytes` budget bounds only the // serialized size, not the real heap it costs to hold those objects, so a diff --git a/packages/api-lite/test/fixtures/blocks/.gitkeep b/packages/api-lite/test/fixtures/blocks/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/packages/api-lite/test/fixtures/blocks/62724773.bin b/packages/api-lite/test/fixtures/blocks/62724773.bin deleted file mode 100644 index d247244cf167e662ac545f56c396caa88eab3e39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 497823 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

Cl$S;x7D=We3oxYdCDa5#;HgxT87 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.Q0#1`c!44V!FsBkIMB{WabJeNMbkoT? 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

{JWEU7E&DC2n(91fL&Y|+htmFiWe7^ukL9AS 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 RL*`>0i3eTd1nH1QK~lN|q#J1vrMr=M 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

)@lM9j~e?wax~%E&-@kd{t(;&Fy02hjW^mg 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 jYNw#MySiKM8?WOBNAjW{D?;Z*AT|DbUX*u