From 3dd1264e5a4d3721b73fae475e1227b07aa9263a Mon Sep 17 00:00:00 2001 From: Pooya Raki Date: Tue, 2 Sep 2025 11:08:30 +0200 Subject: [PATCH] refactor: Replaced all instances of 0x${string} with Address. --- .../__tests__/00001_accounts.spec.ts | 3 +- .../00003_account-data-settings.spec.ts | 3 +- .../00004_counterfactual-safes.spec.ts | 13 +- .../__tests__/00005_notifications.spec.ts | 5 +- .../__tests__/00011_address-books.spec.ts | 3 +- src/config/entities/blocklist.config.ts | 3 +- .../accounts/accounts.datasource.ts | 11 +- .../counterfactual-safes.datasource.ts | 9 +- .../balances-api/balances-api.manager.ts | 6 +- .../balances-api/safe-balances-api.service.ts | 11 +- .../zerion-balances-api.service.ts | 10 +- .../bridge-api/lifi-api.service.spec.ts | 5 +- .../bridge-api/lifi-api.service.ts | 3 +- src/datasources/cache/cache.router.ts | 112 +++++++++--------- .../data-decoder-api.service.spec.ts | 6 +- .../data-decoder-api.service.ts | 7 +- .../locking-api/locking-api.service.ts | 9 +- .../notification-subscription.entity.db.ts | 10 +- .../zerion-positions-api.service.ts | 6 +- .../relay-api/gelato-api.service.ts | 7 +- .../entities/address-book-item.entity.db.ts | 7 +- .../spaces/entities/space-safes.entity.db.ts | 3 +- .../defi-morpho-extra-reward.entity.spec.ts | 3 +- .../__tests__/defi-vault-stake.entity.spec.ts | 3 +- .../__tests__/defi-vault-stats.entity.spec.ts | 5 +- .../__tests__/deployment.entity.spec.ts | 3 +- .../pooled-staking-stats.entity.spec.ts | 6 +- .../__tests__/stake.entity.builder.ts | 3 +- .../transaction-status.entity.builder.ts | 7 +- .../transaction-status.entity.spec.ts | 5 +- .../staking-api/kiln-api.service.spec.ts | 10 +- .../staking-api/kiln-api.service.ts | 29 ++--- .../swaps-api/cowswap-api.service.ts | 3 +- .../__tests__/outreach-file.entity.spec.ts | 3 +- .../entities/submission.entity.ts | 6 +- .../entities/targeted-safe.entity.ts | 6 +- .../outreach-file-processor.spec.ts | 4 +- .../targeted-messaging.datasource.ts | 7 +- .../transaction-api.service.spec.ts | 14 +-- .../transaction-api.service.ts | 103 ++++++++-------- .../users/entities/member.entity.db.ts | 3 +- .../wallets/entities/wallets.entity.db.ts | 3 +- .../accounts/accounts.repository.interface.ts | 9 +- src/domain/accounts/accounts.repository.ts | 9 +- .../address-books.repository.interface.ts | 9 +- .../address-books/address-books.repository.ts | 11 +- .../create-address-book-item.dto.entity.ts | 3 +- .../update-address-book.item.dto.entity.ts | 3 +- ...unterfactual-safes.repository.interface.ts | 17 ++- .../counterfactual-safes.repository.ts | 17 +-- .../create-counterfactual-safe.dto.entity.ts | 9 +- .../entities/create-account.dto.entity.ts | 3 +- src/domain/alerts/alerts.repository.ts | 2 +- .../delay-modifier-encoder.builder.ts | 20 ++-- .../alerts/entities/alerts-deletion.entity.ts | 4 +- .../entities/alerts-registration.entity.ts | 4 +- .../__tests__/auth-payload.entity.spec.ts | 12 +- .../auth/entities/auth-payload.entity.ts | 5 +- .../balances/balances.repository.interface.ts | 8 +- src/domain/balances/balances.repository.ts | 5 +- .../balances/entities/balance.entity.spec.ts | 4 +- .../bridge/bridge.repository.interface.ts | 5 +- src/domain/bridge/bridge.repository.ts | 5 +- .../__tests__/across-v3-encoder.builder.ts | 11 +- .../__tests__/bridge-status.builder.ts | 12 +- .../entities/bridge-chain.entity.spec.ts | 6 +- .../entities/bridge-status.entity.spec.ts | 4 +- .../bridge/entities/token.entity.spec.ts | 4 +- .../entities/__tests__/chain.builder.ts | 6 +- .../schemas/__tests__/chain.schema.spec.ts | 7 +- .../__tests__/singleton.schema.spec.ts | 4 +- .../collectibles.repository.interface.ts | 5 +- .../collectibles/collectibles.repository.ts | 5 +- .../__tests__/collectible.schema.spec.ts | 4 +- .../common/entities/safe-signature.spec.ts | 51 ++++---- src/domain/common/entities/safe-signature.ts | 28 ++--- .../databaseAddress.transformer.ts | 5 +- .../nullableDatabaseAddress.transformer.ts | 5 +- .../common/utils/__tests__/safe.spec.ts | 6 +- .../utils/__tests__/signatures.builder.ts | 27 +++-- .../common/utils/__tests__/signatures.spec.ts | 49 ++++---- src/domain/common/utils/deployments.ts | 35 +++--- src/domain/common/utils/safe.ts | 5 +- src/domain/common/utils/signatures.ts | 9 +- src/domain/common/utils/utils.ts | 12 +- .../community.repository.interface.ts | 9 +- src/domain/community/community.repository.ts | 9 +- .../__tests__/locking-event.builder.ts | 9 +- .../campaign-activity.schema.spec.ts | 5 +- .../__tests__/campaign-rank.schema.spec.ts | 4 +- .../__tests__/locking-event.schema.spec.ts | 10 +- .../__tests__/locking-rank.schema.spec.ts | 4 +- .../contracts.repository.interface.ts | 5 +- src/domain/contracts/contracts.repository.ts | 9 +- .../schemas/__tests__/contract.schema.spec.ts | 4 +- .../v1/data-decoded.repository.interface.ts | 5 +- .../v1/data-decoded.repository.ts | 5 +- .../v2/data-decoder.repository.interface.ts | 5 +- .../v2/data-decoder.repository.ts | 9 +- .../v2/entities/__tests__/contract.builder.ts | 3 +- .../__tests__/data-decoded.builder.ts | 4 +- .../v2/entities/contract.entity.spec.ts | 6 +- .../v2/entities/data-decoded.entity.spec.ts | 6 +- .../v2/entities/data-decoded.entity.ts | 5 +- .../delegate/delegate.repository.interface.ts | 21 ++-- src/domain/delegate/delegate.repository.ts | 21 ++-- .../schemas/__tests__/delegate.schema.spec.ts | 4 +- .../v2/delegates.v2.repository.interface.ts | 13 +- .../delegate/v2/delegates.v2.repository.ts | 21 ++-- src/domain/earn/earn.repository.ts | 21 ++-- .../entities/get-estimation.dto.entity.ts | 9 +- .../estimations.repository.interface.ts | 3 +- .../estimations/estimations.repository.ts | 3 +- .../helpers/event-notifications.helper.ts | 15 +-- .../human-description-template.entity.ts | 3 +- .../entities/human-description.entity.ts | 3 +- .../human-description.repository.ts | 3 +- .../accounts.datasource.interface.ts | 11 +- .../interfaces/balances-api.interface.ts | 12 +- .../balances-api.manager.interface.ts | 3 +- src/domain/interfaces/bridge-api.inferface.ts | 3 +- ...unterfactual-safes.datasource.interface.ts | 9 +- .../interfaces/data-decoder-api.interface.ts | 7 +- .../interfaces/locking-api.interface.ts | 9 +- .../notifications.datasource.interface.ts | 13 +- .../interfaces/positions-api.interface.ts | 5 +- src/domain/interfaces/relay-api.interface.ts | 10 +- .../interfaces/staking-api.interface.ts | 21 ++-- src/domain/interfaces/swaps-api.interface.ts | 3 +- ...targeted-messaging.datasource.interface.ts | 7 +- .../interfaces/transaction-api.interface.ts | 103 ++++++++-------- .../__tests__/message-confirmation.builder.ts | 7 +- .../entities/__tests__/message.builder.ts | 14 ++- .../entities/__tests__/message.entity.spec.ts | 6 +- .../__tests__/typed-data.entity.spec.ts | 6 +- .../message-confirmation.entity.spec.ts | 6 +- .../messages/entities/message.entity.spec.ts | 6 +- .../helpers/message-verifier.helper.spec.ts | 12 +- .../helpers/message-verifier.helper.ts | 33 +++--- .../messages/messages.repository.interface.ts | 9 +- src/domain/messages/messages.repository.ts | 15 +-- ...elete-all-subscriptions.dto.entity.spec.ts | 10 +- .../upsert-subscriptions-dto.entity.spec.ts | 4 +- .../v2/notifications.repository.interface.ts | 13 +- .../v2/notifications.repository.spec.ts | 18 +-- .../v2/notifications.repository.ts | 21 ++-- .../positions.repository.interface.ts | 5 +- src/domain/positions/positions.repository.ts | 5 +- .../encoders/erc20-encoder.builder.ts | 15 +-- .../encoders/proxy-factory-encoder.builder.ts | 8 +- .../__tests__/erc20-decoder.helper.spec.ts | 3 +- .../proxy-factory-decoder.helper.spec.ts | 3 +- .../relay/errors/relay-limit-reached.error.ts | 3 +- src/domain/relay/limit-addresses.mapper.ts | 64 +++++----- src/domain/relay/relay.repository.ts | 11 +- .../__tests__/creation-transaction.builder.ts | 6 +- .../__tests__/erc20-transfer.builder.ts | 4 +- .../__tests__/erc721-transfer.builder.ts | 4 +- .../__tests__/ethereum-transaction.builder.ts | 6 +- .../__tests__/module-transaction.builder.ts | 6 +- ...ltisig-transaction-confirmation.builder.ts | 7 +- .../__tests__/multisig-transaction.builder.ts | 10 +- .../multisig-transaction.entity.spec.ts | 6 +- .../native-token-transfer.builder.ts | 4 +- .../creation-transaction.schema.spec.ts | 8 +- .../__tests__/erc20-transfer.schema.spec.ts | 6 +- .../__tests__/erc721-transfer.schema.spec.ts | 6 +- .../module-transaction.schema.spec.ts | 6 +- .../native-token-transfer.schema.spec.ts | 6 +- .../schemas/__tests__/safe.schema.spec.ts | 6 +- src/domain/safe/safe.repository.interface.ts | 55 ++++----- src/domain/safe/safe.repository.ts | 72 +++++------ src/domain/siwe/siwe.repository.interface.ts | 3 +- src/domain/siwe/siwe.repository.ts | 3 +- ...-book-items.repository.integration.spec.ts | 22 ++-- .../entities/address-book-item.db.entity.ts | 13 +- .../spaces/entities/space-safe.entity.ts | 3 +- .../encoders/kiln-encoder.builder.ts | 35 +++--- .../__tests__/kiln-decoder.helper.spec.ts | 23 ++-- .../contracts/decoders/kiln-decoder.helper.ts | 31 ++--- .../staking/staking.repository.interface.ts | 26 ++-- src/domain/staking/staking.repository.ts | 23 ++-- .../composable-cow-encoder.builder.ts | 30 ++--- .../encoders/gp-v2-encoder.builder.ts | 3 +- .../decoders/composable-cow-decoder.helper.ts | 15 +-- .../decoders/gp-v2-decoder.helper.ts | 21 ++-- .../swaps/entities/__tests__/order.builder.ts | 6 +- .../swaps/entities/order.entity.spec.ts | 4 +- src/domain/swaps/swaps.repository.e2e-spec.ts | 3 +- src/domain/swaps/swaps.repository.ts | 12 +- .../create-targeted-safes.dto.entity.ts | 3 +- ...targeted-messaging.repository.interface.ts | 9 +- .../targeted-messaging.repository.ts | 9 +- .../entities/__tests__/token.entity.spec.ts | 4 +- .../tokens/token.repository.interface.ts | 3 +- src/domain/tokens/token.repository.ts | 6 +- .../entities/add-confirmation.dto.entity.ts | 3 +- .../propose-transaction.dto.entity.ts | 15 +-- src/domain/users/entities/member.entity.ts | 5 +- .../members.repository.integration.spec.ts | 21 ++-- .../users/members.repository.interface.ts | 3 +- src/domain/users/members.repository.ts | 8 +- .../users.repository.integration.spec.ts | 12 +- .../users/users.repository.interface.ts | 9 +- src/domain/users/users.repository.ts | 17 ++- src/domain/wallets/entities/wallet.entity.ts | 3 +- .../wallets.repository.integration.spec.ts | 16 ++- .../wallets/wallets.repository.interface.ts | 9 +- src/domain/wallets/wallets.repository.ts | 9 +- .../csv-export/v1/csv-export.controller.ts | 3 +- .../csv-export/v1/csv-export.service.spec.ts | 7 +- .../csv-export/v1/csv-export.service.ts | 11 +- .../v1/datasources/export-api.interface.ts | 3 +- .../v1/datasources/export-api.service.ts | 3 +- .../__tests__/transaction-export.builder.ts | 4 +- .../v1/entities/csv-export-job-data.entity.ts | 3 +- .../transaction-export.entity.spec.ts | 18 +-- src/routes/accounts/accounts.controller.ts | 9 +- src/routes/accounts/accounts.service.ts | 9 +- .../address-books/address-books.controller.ts | 9 +- .../address-books/address-books.service.ts | 9 +- .../entities/address-book.entity.ts | 5 +- .../create-address-book-item.dto.entity.ts | 3 +- .../counterfactual-safes.controller.ts | 15 +-- .../counterfactual-safes.service.ts | 15 +-- .../entities/counterfactual-safe.entity.ts | 21 ++-- .../create-counterfactual-safe.dto.entity.ts | 9 +- .../accounts/entities/account.entity.ts | 5 +- .../entities/create-account.dto.entity.ts | 3 +- .../entities/__tests__/alerts.builder.ts | 6 +- .../alerts/entities/alert.dto.entity.ts | 11 +- .../schemas/__tests__/alerts.schema.spec.ts | 11 +- src/routes/auth/entities/siwe.dto.entity.ts | 3 +- src/routes/balances/balances.controller.ts | 3 +- src/routes/balances/balances.service.ts | 3 +- src/routes/balances/entities/token.entity.ts | 3 +- src/routes/chains/entities/chain.entity.ts | 5 +- .../entities/contract-addresses.entity.ts | 19 +-- .../collectibles/collectibles.controller.ts | 3 +- .../collectibles/collectibles.service.ts | 3 +- .../entities/collectible.entity.ts | 3 +- src/routes/common/__tests__/constants.ts | 6 +- .../address-info/address-info.helper.ts | 9 +- .../entities/transaction-data.dto.entity.ts | 7 +- .../route-logger.interceptor.spec.ts | 3 +- src/routes/community/community.controller.ts | 9 +- src/routes/community/community.service.ts | 9 +- .../entities/campaign-activity.entity.ts | 3 +- .../entities/campaign-rank.entity.ts | 3 +- .../entities/locking-event.page.entity.ts | 13 +- .../community/entities/locking-rank.entity.ts | 3 +- src/routes/contracts/contracts.controller.ts | 3 +- src/routes/contracts/contracts.service.ts | 3 +- .../contracts/entities/contract.entity.ts | 3 +- .../__tests__/transaction-data.dto.builder.ts | 4 +- .../entities/data-decoded.entity.ts | 5 +- .../transaction-data.dto.schema.spec.ts | 6 +- src/routes/delegates/delegates.controller.ts | 3 +- src/routes/delegates/delegates.service.ts | 3 +- .../delete-safe-delegate.dto.builder.ts | 7 +- .../entities/create-delegate.dto.entity.ts | 7 +- .../entities/delete-delegate.dto.entity.ts | 5 +- .../delete-safe-delegate.dto.entity.ts | 7 +- .../entities/get-delegate.dto.entity.ts | 13 +- .../create-delegate.dto.schema.spec.ts | 4 +- .../delete-delegate.dto.schema.spec.ts | 4 +- .../delete-safe-delegate.dto.schema.spec.ts | 6 +- .../__tests__/get-delegate.dto.schema.spec.ts | 4 +- .../delegates/v2/delegates.v2.controller.ts | 3 +- .../delegates/v2/delegates.v2.service.ts | 9 +- .../delete-delegate.v2.dto.builder.ts | 7 +- .../entities/delete-delegate.v2.dto.entity.ts | 5 +- .../__tests__/get-estimation.dto.builder.ts | 4 +- .../entities/get-estimation.dto.entity.ts | 5 +- .../get-estimation.dto.schema.spec.ts | 8 +- .../estimations/estimations.controller.ts | 3 +- src/routes/estimations/estimations.service.ts | 3 +- .../__tests__/executed-transaction.builder.ts | 11 +- .../__tests__/pending-transaction.builder.ts | 7 +- .../__tests__/delegate-events.schema.spec.ts | 4 +- ...eleted-multisig-transaction.schema.spec.ts | 6 +- .../executed-transaction.schema.spec.ts | 8 +- .../__tests__/incoming-ether.schema.spec.ts | 6 +- .../__tests__/incoming-token.schema.spec.ts | 6 +- .../__tests__/message-created.schema.spec.ts | 6 +- .../module-transaction.schema.spec.ts | 6 +- .../__tests__/new-confirmation.schema.spec.ts | 6 +- .../new-message-confirmation.schema.spec.ts | 6 +- .../__tests__/outgoing-ether.schema.spec.ts | 6 +- .../__tests__/outgoing-token.schema.spec.ts | 6 +- .../pending-transaction.schema.spec.ts | 6 +- .../__tests__/safe-created.schema.spec.ts | 4 +- src/routes/hooks/hooks-notifications.spec.ts | 36 +++--- .../__tests__/create-message.dto.builder.ts | 3 +- .../entities/__tests__/typed-data.builder.ts | 4 +- .../update-message-signature.dto.builder.ts | 3 +- .../entities/create-message.dto.entity.ts | 3 +- .../entities/message-confirmation.entity.ts | 5 +- .../messages/entities/message.entity.ts | 9 +- .../create-message.dto.schema.spec.ts | 3 +- .../update-message.dto.schema.spec.ts | 8 +- .../messages/entities/typed-data.entity.ts | 5 +- .../update-message-signature.entity.ts | 3 +- .../messages/messages.controller.spec.ts | 4 +- src/routes/messages/messages.controller.ts | 9 +- src/routes/messages/messages.service.ts | 9 +- .../create-registration-v2.dto.builder.ts | 11 +- .../__tests__/create-signature.builder.ts | 3 +- .../v1/notifications.controller.ts | 25 ++-- .../delete-all-subscriptions.dto.entity.ts | 5 +- .../upsert-subscriptions.dto.entity.ts | 3 +- .../v2/notifications.controller.ts | 5 +- .../notifications/v2/notifications.service.ts | 7 +- .../owners/entities/safe-list.entity.ts | 3 +- src/routes/owners/owners.controller.v1.ts | 5 +- src/routes/owners/owners.controller.v2.ts | 3 +- src/routes/owners/owners.service.ts | 7 +- src/routes/positions/positions.controller.ts | 3 +- .../positions/positions.service.spec.ts | 17 +-- src/routes/positions/positions.service.ts | 3 +- .../add-recovery-module.dto.entity.ts | 3 +- .../add-recovery-module.dto.schema.spec.ts | 4 +- src/routes/recovery/recovery.controller.ts | 7 +- src/routes/recovery/recovery.service.ts | 7 +- src/routes/relay/entities/relay.dto.entity.ts | 5 +- src/routes/relay/relay.controller.ts | 3 +- src/routes/relay/relay.service.ts | 3 +- src/routes/safes/safes.controller.ts | 7 +- src/routes/safes/safes.service.ts | 15 +-- .../spaces/address-books.controller.spec.ts | 8 +- src/routes/spaces/address-books.controller.ts | 3 +- .../entities/invite-users.dto.entity.ts | 3 +- .../upsert-address-book-items.dto.entity.ts | 3 +- .../spaces/space-safes.controller.spec.ts | 8 +- src/routes/spaces/space-safes.service.ts | 7 +- src/routes/spaces/spaces.controller.spec.ts | 13 +- src/routes/spaces/spaces.service.ts | 5 +- .../entities/submission.entity.ts | 5 +- .../targeted-messaging.controller.ts | 11 +- .../targeted-messaging.service.ts | 13 +- ...firmations.transactions.controller.spec.ts | 8 +- ...tion-by-id.transactions.controller.spec.ts | 9 +- ...ns-by-safe.transactions.controller.spec.ts | 4 +- ...ns-by-safe.transactions.controller.spec.ts | 4 +- ...ction-kiln.transactions.controller.spec.ts | 31 ++--- ...ransaction.transactions.controller.spec.ts | 8 +- .../encoders/erc4262-encoder.builder.ts | 12 +- .../entities/add-confirmation.dto.builder.ts | 3 +- .../decoders/erc4262-decoder.helper.spec.ts | 3 +- .../preview-transaction.dto.builder.ts | 4 +- .../propose-transaction.dto.builder.ts | 14 +-- .../entities/add-confirmation.dto.ts | 3 +- .../entities/bridge/bridge-info.entity.ts | 3 +- .../entities/bridge/fees.entity.ts | 5 +- .../entities/creation-transaction.entity.ts | 21 ++-- .../entities/human-description.entity.ts | 3 +- .../preview-transaction.dto.entity.ts | 5 +- .../propose-transaction.dto.entity.ts | 15 +-- .../add-confirmation.dto.schema.spec.ts | 5 +- .../preview-transaction.dto.schema.spec.ts | 4 +- .../propose-transaction.dto.schema.spec.ts | 17 ++- .../native-staking-deposit-info.entity.ts | 5 +- ...ive-staking-validators-exit-info.entity.ts | 5 +- .../native-staking-withdraw-info.entity.ts | 5 +- .../entities/swaps/swap-order-info.entity.ts | 7 +- .../entities/swaps/token-info.entity.ts | 5 +- .../entities/swaps/twap-order-info.entity.ts | 19 +-- .../entities/transaction-data.entity.ts | 5 +- .../entities/transaction.entity.ts | 5 +- .../transfers/erc20-transfer.entity.ts | 5 +- .../transfers/erc721-transfer.entity.ts | 5 +- .../txs-creation-transaction.entity.ts | 21 ++-- .../txs-multisig-transaction.entity.ts | 45 +++---- .../entities/vaults/vault-info.entity.ts | 5 +- .../helpers/gp-v2-order.helper.ts | 7 +- .../kiln-native-staking.helper.spec.ts | 3 +- .../helpers/kiln-native-staking.helper.ts | 23 ++-- .../transactions/helpers/kiln-vault.helper.ts | 13 +- .../transactions/helpers/lifi-helper.ts | 20 ++-- .../helpers/swap-order.helper.spec.ts | 10 +- .../transactions/helpers/swap-order.helper.ts | 7 +- .../transaction-data-finder.helper.spec.ts | 4 +- .../helpers/transaction-finder.helper.ts | 10 +- .../transaction-verifier.helper.spec.ts | 24 ++-- .../helpers/transaction-verifier.helper.ts | 28 ++--- .../transactions/helpers/twap-order.helper.ts | 7 +- .../common/bridge-transaction.mapper.spec.ts | 63 +++++----- .../common/bridge-transaction.mapper.ts | 18 +-- .../common/data-decoded-param.helper.spec.ts | 18 +-- .../common/human-descriptions.mapper.spec.ts | 12 +- .../common/native-staking.mapper.spec.ts | 16 +-- .../mappers/common/native-staking.mapper.ts | 37 +++--- .../mappers/common/swap-order.mapper.ts | 5 +- .../common/transaction-data.mapper.spec.ts | 10 +- .../mappers/common/transaction-data.mapper.ts | 21 ++-- .../mappers/common/transaction-info.mapper.ts | 7 +- .../mappers/common/twap-order.mapper.ts | 11 +- .../common/vault-transaction.mapper.spec.ts | 18 +-- .../common/vault-transaction.mapper.ts | 15 +-- ...ultisig-transaction-details.mapper.spec.ts | 3 +- .../multisig-transaction-details.mapper.ts | 3 +- .../multisig-transaction.mapper.ts | 4 +- .../mappers/transactions-history.mapper.ts | 5 +- .../transfers/swap-transfer-info.mapper.ts | 4 +- .../mappers/transfers/transfer-info.mapper.ts | 5 +- .../swap-transfer-transaction-info.entity.ts | 5 +- ....imitation-transactions.controller.spec.ts | 8 +- .../transactions/transactions.controller.ts | 27 +++-- .../transactions/transactions.service.ts | 29 ++--- .../entities/user-with-wallets.entity.ts | 3 +- src/routes/users/users.controller.spec.ts | 12 +- src/routes/users/users.controller.ts | 3 +- src/routes/users/users.service.ts | 3 +- .../__tests__/event-topics.schema.spec.ts | 5 +- .../__tests__/signature.schema.spec.ts | 9 +- .../entities/schemas/hexbytes.schema.ts | 3 +- .../entities/schemas/signature.schema.ts | 3 +- 417 files changed, 2142 insertions(+), 1953 deletions(-) diff --git a/migrations/deprecated/__tests__/00001_accounts.spec.ts b/migrations/deprecated/__tests__/00001_accounts.spec.ts index bb643139f6..4e8dad3eb8 100644 --- a/migrations/deprecated/__tests__/00001_accounts.spec.ts +++ b/migrations/deprecated/__tests__/00001_accounts.spec.ts @@ -4,13 +4,14 @@ import { PostgresDatabaseMigrator } from '@/datasources/db/v1/postgres-database. import { faker } from '@faker-js/faker'; import type { Sql } from 'postgres'; import type postgres from 'postgres'; +import type { Address } from 'viem'; interface AccountRow { id: number; group_id: number; created_at: Date; updated_at: Date; - address: `0x${string}`; + address: Address; } describe('Migration 00001_accounts', () => { diff --git a/migrations/deprecated/__tests__/00003_account-data-settings.spec.ts b/migrations/deprecated/__tests__/00003_account-data-settings.spec.ts index 1400f462d1..7994b9b9c1 100644 --- a/migrations/deprecated/__tests__/00003_account-data-settings.spec.ts +++ b/migrations/deprecated/__tests__/00003_account-data-settings.spec.ts @@ -3,6 +3,7 @@ import { waitMilliseconds } from '@/__tests__/util/retry'; import { PostgresDatabaseMigrator } from '@/datasources/db/v1/postgres-database.migrator'; import { faker } from '@faker-js/faker'; import type postgres from 'postgres'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; interface AccountRow { @@ -10,7 +11,7 @@ interface AccountRow { group_id: number; created_at: Date; updated_at: Date; - address: `0x${string}`; + address: Address; } interface AccountDataTypeRow { diff --git a/migrations/deprecated/__tests__/00004_counterfactual-safes.spec.ts b/migrations/deprecated/__tests__/00004_counterfactual-safes.spec.ts index cd8ebd4242..ede3ab941e 100644 --- a/migrations/deprecated/__tests__/00004_counterfactual-safes.spec.ts +++ b/migrations/deprecated/__tests__/00004_counterfactual-safes.spec.ts @@ -3,6 +3,7 @@ import { waitMilliseconds } from '@/__tests__/util/retry'; import { PostgresDatabaseMigrator } from '@/datasources/db/v1/postgres-database.migrator'; import { faker } from '@faker-js/faker'; import type postgres from 'postgres'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; interface AccountRow { @@ -10,7 +11,7 @@ interface AccountRow { group_id: number; created_at: Date; updated_at: Date; - address: `0x${string}`; + address: Address; } interface CounterfactualSafesRow { @@ -18,12 +19,12 @@ interface CounterfactualSafesRow { updated_at: Date; id: number; chain_id: string; - creator: `0x${string}`; - fallback_handler: `0x${string}`; - owners: Array<`0x${string}`>; - predicted_address: `0x${string}`; + creator: Address; + fallback_handler: Address; + owners: Array
; + predicted_address: Address; salt_nonce: string; - singleton_address: `0x${string}`; + singleton_address: Address; threshold: number; account_id: number; } diff --git a/migrations/deprecated/__tests__/00005_notifications.spec.ts b/migrations/deprecated/__tests__/00005_notifications.spec.ts index f8abd7a629..c8f154f03f 100644 --- a/migrations/deprecated/__tests__/00005_notifications.spec.ts +++ b/migrations/deprecated/__tests__/00005_notifications.spec.ts @@ -4,6 +4,7 @@ import { DeviceType } from '@/domain/notifications/v2/entities/device-type.entit import type { UUID } from 'crypto'; import { faker } from '@faker-js/faker'; import type postgres from 'postgres'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; type PushNotificationDevicesRow = { @@ -29,10 +30,10 @@ type NotificationTypesRow = { type NotificationSubscriptionsRow = { id: number; - signer_address: `0x${string}` | null; + signer_address: Address | null; push_notification_device_id: PushNotificationDevicesRow['id']; chain_id: string; - safe_address: `0x${string}`; + safe_address: Address; created_at: Date; updated_at: Date; }; diff --git a/migrations/deprecated/__tests__/00011_address-books.spec.ts b/migrations/deprecated/__tests__/00011_address-books.spec.ts index fa858a2b0a..8ceb77a8bf 100644 --- a/migrations/deprecated/__tests__/00011_address-books.spec.ts +++ b/migrations/deprecated/__tests__/00011_address-books.spec.ts @@ -3,6 +3,7 @@ import { waitMilliseconds } from '@/__tests__/util/retry'; import { PostgresDatabaseMigrator } from '@/datasources/db/v1/postgres-database.migrator'; import { faker } from '@faker-js/faker'; import type postgres from 'postgres'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; interface AccountDataTypeRow { @@ -19,7 +20,7 @@ interface AccountRow { group_id: number; created_at: Date; updated_at: Date; - address: `0x${string}`; + address: Address; } interface AddressBooksRow { diff --git a/src/config/entities/blocklist.config.ts b/src/config/entities/blocklist.config.ts index 2296f32aa5..d49d76f9da 100644 --- a/src/config/entities/blocklist.config.ts +++ b/src/config/entities/blocklist.config.ts @@ -1,6 +1,7 @@ +import type { Address } from 'viem'; import { getAddress } from 'viem'; -export function getBlocklist(): Array<`0x${string}`> { +export function getBlocklist(): Array
{ // Addresses not allowed to interact with the service // List taken from https://www.ic3.gov/PSA/2025/PSA250226 return [ diff --git a/src/datasources/accounts/accounts.datasource.ts b/src/datasources/accounts/accounts.datasource.ts index 600b530703..800a221da0 100644 --- a/src/datasources/accounts/accounts.datasource.ts +++ b/src/datasources/accounts/accounts.datasource.ts @@ -28,6 +28,7 @@ import { import crypto from 'crypto'; import omit from 'lodash/omit'; import postgres from 'postgres'; +import type { Address } from 'viem'; @Injectable() export class AccountsDatasource implements IAccountsDatasource, OnModuleInit { @@ -112,7 +113,7 @@ export class AccountsDatasource implements IAccountsDatasource, OnModuleInit { return omit(await this.decryptAccountData(account), 'name_hash'); } - async getAccount(address: `0x${string}`): Promise { + async getAccount(address: Address): Promise { const cacheDir = CacheRouter.getAccountCacheDir(address); const [account] = await this.cachedQueryResolver.get>({ cacheDir, @@ -127,7 +128,7 @@ export class AccountsDatasource implements IAccountsDatasource, OnModuleInit { return this.decryptAccountData(account); } - async deleteAccount(address: `0x${string}`): Promise { + async deleteAccount(address: Address): Promise { try { const { count } = await this .sql`DELETE FROM accounts WHERE address = ${address}`; @@ -156,7 +157,7 @@ export class AccountsDatasource implements IAccountsDatasource, OnModuleInit { } async getAccountDataSettings( - address: `0x${string}`, + address: Address, ): Promise> { const account = await this.getAccount(address); const cacheDir = CacheRouter.getAccountDataSettingsCacheDir(address); @@ -182,7 +183,7 @@ export class AccountsDatasource implements IAccountsDatasource, OnModuleInit { * @returns {Array} inserted account data settings. */ async upsertAccountDataSettings(args: { - address: `0x${string}`; + address: Address; upsertAccountDataSettingsDto: UpsertAccountDataSettingsDto; }): Promise> { const { accountDataSettings } = args.upsertAccountDataSettingsDto; @@ -270,7 +271,7 @@ export class AccountsDatasource implements IAccountsDatasource, OnModuleInit { async encryptAccountData( createAccountDto: CreateAccountDto, - ): Promise<{ address: `0x${string}`; name: string; nameHash: string }> { + ): Promise<{ address: Address; name: string; nameHash: string }> { const hash = crypto.createHash('sha256'); hash.update(createAccountDto.name); const nameHash = hash.digest('hex'); diff --git a/src/datasources/accounts/counterfactual-safes/counterfactual-safes.datasource.ts b/src/datasources/accounts/counterfactual-safes/counterfactual-safes.datasource.ts index 94c0882b4a..8dbaf7d3f2 100644 --- a/src/datasources/accounts/counterfactual-safes/counterfactual-safes.datasource.ts +++ b/src/datasources/accounts/counterfactual-safes/counterfactual-safes.datasource.ts @@ -14,6 +14,7 @@ import { ICounterfactualSafesDatasource } from '@/domain/interfaces/counterfactu import { ILoggingService, LoggingService } from '@/logging/logging.interface'; import { Inject, Injectable, NotFoundException } from '@nestjs/common'; import postgres from 'postgres'; +import type { Address } from 'viem'; @Injectable() export class CounterfactualSafesDatasource @@ -67,9 +68,9 @@ export class CounterfactualSafesDatasource } async getCounterfactualSafe(args: { - address: `0x${string}`; + address: Address; chainId: string; - predictedAddress: `0x${string}`; + predictedAddress: Address; }): Promise { const cacheDir = CacheRouter.getCounterfactualSafeCacheDir( args.chainId, @@ -95,7 +96,7 @@ export class CounterfactualSafesDatasource } getCounterfactualSafesForAddress( - address: `0x${string}`, + address: Address, ): Promise> { const cacheDir = CacheRouter.getCounterfactualSafesCacheDir(address); return this.cachedQueryResolver.get>({ @@ -110,7 +111,7 @@ export class CounterfactualSafesDatasource async deleteCounterfactualSafe(args: { account: Account; chainId: string; - predictedAddress: `0x${string}`; + predictedAddress: Address; }): Promise { try { const { count } = await this diff --git a/src/datasources/balances-api/balances-api.manager.ts b/src/datasources/balances-api/balances-api.manager.ts index fdf633baaa..d82272460f 100644 --- a/src/datasources/balances-api/balances-api.manager.ts +++ b/src/datasources/balances-api/balances-api.manager.ts @@ -17,6 +17,7 @@ import { ITransactionApiManager } from '@/domain/interfaces/transaction-api.mana import { ChainSchema } from '@/domain/chains/entities/schemas/chain.schema'; import { z } from 'zod'; import { type Raw, rawify } from '@/validation/entities/raw.entity'; +import type { Address } from 'viem'; @Injectable() export class BalancesApiManager implements IBalancesApiManager { @@ -51,10 +52,7 @@ export class BalancesApiManager implements IBalancesApiManager { this.zerionBalancesApi = zerionBalancesApi; } - async getApi( - chainId: string, - safeAddress: `0x${string}`, - ): Promise { + async getApi(chainId: string, safeAddress: Address): Promise { if (this.zerionChainIds.includes(chainId)) { return this.zerionBalancesApi; } diff --git a/src/datasources/balances-api/safe-balances-api.service.ts b/src/datasources/balances-api/safe-balances-api.service.ts index d857e7e5dd..cdc50ec1ee 100644 --- a/src/datasources/balances-api/safe-balances-api.service.ts +++ b/src/datasources/balances-api/safe-balances-api.service.ts @@ -20,6 +20,7 @@ import { getAssetPricesSchema, } from '@/datasources/balances-api/entities/asset-price.entity'; import { ZodError } from 'zod'; +import type { Address } from 'viem'; @Injectable() export class SafeBalancesApi implements IBalancesApi { @@ -65,7 +66,7 @@ export class SafeBalancesApi implements IBalancesApi { } async getBalances(args: { - safeAddress: `0x${string}`; + safeAddress: Address; fiatCode: string; chain: Chain; trusted?: boolean; @@ -105,7 +106,7 @@ export class SafeBalancesApi implements IBalancesApi { } } - async clearBalances(args: { safeAddress: `0x${string}` }): Promise { + async clearBalances(args: { safeAddress: Address }): Promise { const key = CacheRouter.getBalancesCacheKey({ chainId: this.chainId, safeAddress: args.safeAddress, @@ -114,7 +115,7 @@ export class SafeBalancesApi implements IBalancesApi { } async getCollectibles(args: { - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; trusted?: boolean; @@ -145,7 +146,7 @@ export class SafeBalancesApi implements IBalancesApi { } } - async clearCollectibles(args: { safeAddress: `0x${string}` }): Promise { + async clearCollectibles(args: { safeAddress: Address }): Promise { const key = CacheRouter.getCollectiblesKey({ chainId: this.chainId, safeAddress: args.safeAddress, @@ -176,7 +177,7 @@ export class SafeBalancesApi implements IBalancesApi { }): Promise>> { const tokenAddresses = args.balances .map((balance) => balance.tokenAddress) - .filter((address): address is `0x${string}` => address !== null); + .filter((address): address is Address => address !== null); const lowerCaseFiatCode = args.fiatCode.toLowerCase(); const assetPrices = await this.coingeckoApi diff --git a/src/datasources/balances-api/zerion-balances-api.service.ts b/src/datasources/balances-api/zerion-balances-api.service.ts index 59de39f291..e3ed9cc318 100644 --- a/src/datasources/balances-api/zerion-balances-api.service.ts +++ b/src/datasources/balances-api/zerion-balances-api.service.ts @@ -38,7 +38,7 @@ import { IBalancesApi } from '@/domain/interfaces/balances-api.interface'; import { ILoggingService, LoggingService } from '@/logging/logging.interface'; import { rawify, type Raw } from '@/validation/entities/raw.entity'; import { Inject, Injectable } from '@nestjs/common'; -import { getAddress } from 'viem'; +import { Address, getAddress } from 'viem'; import { z, ZodError } from 'zod'; export const IZerionBalancesApi = Symbol('IZerionBalancesApi'); @@ -96,7 +96,7 @@ export class ZerionBalancesApi implements IBalancesApi { async getBalances(args: { chain: Chain; - safeAddress: `0x${string}`; + safeAddress: Address; fiatCode: string; }): Promise>> { if (!this.fiatCodes.includes(args.fiatCode.toUpperCase())) { @@ -166,7 +166,7 @@ export class ZerionBalancesApi implements IBalancesApi { */ async getCollectibles(args: { chain: Chain; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; }): Promise>> { @@ -221,7 +221,7 @@ export class ZerionBalancesApi implements IBalancesApi { async clearCollectibles(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const key = CacheRouter.getZerionCollectiblesCacheKey(args); await this.cacheService.deleteByKey(key); @@ -291,7 +291,7 @@ export class ZerionBalancesApi implements IBalancesApi { async clearBalances(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const key = CacheRouter.getZerionBalancesCacheKey(args); await this.cacheService.deleteByKey(key); diff --git a/src/datasources/bridge-api/lifi-api.service.spec.ts b/src/datasources/bridge-api/lifi-api.service.spec.ts index e0a401234e..942f224876 100644 --- a/src/datasources/bridge-api/lifi-api.service.spec.ts +++ b/src/datasources/bridge-api/lifi-api.service.spec.ts @@ -17,6 +17,7 @@ import { TestLoggingModule } from '@/logging/__tests__/test.logging.module'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { Test } from '@nestjs/testing'; import configuration from '@/config/entities/__tests__/configuration'; +import type { Hash } from 'viem'; const mockNetworkService = jest.mocked({ get: jest.fn(), @@ -99,7 +100,7 @@ describe('LifiBridgeApi', () => { describe('getStatus', () => { it('should return the status', async () => { const bridgeStatus = bridgeStatusBuilder().build(); - const txHash = faker.string.hexadecimal({ length: 64 }) as `0x${string}`; + const txHash = faker.string.hexadecimal({ length: 64 }) as Hash; const bridge = faker.helpers.arrayElement(BridgeNames); const toChain = faker.string.numeric(); mockNetworkService.get.mockResolvedValueOnce({ @@ -131,7 +132,7 @@ describe('LifiBridgeApi', () => { }); it('should forward errors', async () => { - const txHash = faker.string.hexadecimal({ length: 64 }) as `0x${string}`; + const txHash = faker.string.hexadecimal({ length: 64 }) as Hash; const bridge = faker.helpers.arrayElement(BridgeNames); const toChain = faker.string.numeric(); const status = faker.internet.httpStatusCode({ types: ['serverError'] }); diff --git a/src/datasources/bridge-api/lifi-api.service.ts b/src/datasources/bridge-api/lifi-api.service.ts index 9becc4471f..ed8f3a0e78 100644 --- a/src/datasources/bridge-api/lifi-api.service.ts +++ b/src/datasources/bridge-api/lifi-api.service.ts @@ -8,6 +8,7 @@ import type { CacheFirstDataSource } from '@/datasources/cache/cache.first.data. import type { IConfigurationService } from '@/config/configuration.service.interface'; import { CacheRouter } from '@/datasources/cache/cache.router'; import { type BridgeChainPage } from '@/domain/bridge/entities/bridge-chain.entity'; +import type { Hash } from 'viem'; export class LifiBridgeApi implements IBridgeApi { public static readonly LIFI_API_HEADER = 'x-lifi-api-key'; @@ -59,7 +60,7 @@ export class LifiBridgeApi implements IBridgeApi { } public async getStatus(args: { - txHash: `0x${string}`; + txHash: Hash; bridge?: BridgeName; toChain?: string; }): Promise> { diff --git a/src/datasources/cache/cache.router.ts b/src/datasources/cache/cache.router.ts index fa6d39d293..d5a992b023 100644 --- a/src/datasources/cache/cache.router.ts +++ b/src/datasources/cache/cache.router.ts @@ -1,5 +1,6 @@ import crypto from 'crypto'; import { CacheDir } from '@/datasources/cache/entities/cache-dir.entity'; +import type { Address, Hash } from 'viem'; export class CacheRouter { private static readonly ACCOUNT_DATA_SETTINGS_KEY = 'account_data_settings'; @@ -90,14 +91,14 @@ export class CacheRouter { static getBalancesCacheKey(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): string { return `${args.chainId}_${CacheRouter.SAFE_BALANCES_KEY}_${args.safeAddress}`; } static getBalancesCacheDir(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; trusted?: boolean; excludeSpam?: boolean; }): CacheDir { @@ -109,14 +110,14 @@ export class CacheRouter { static getZerionBalancesCacheKey(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): string { return `${args.chainId}_${CacheRouter.ZERION_BALANCES_KEY}_${args.safeAddress}`; } static getZerionBalancesCacheDir(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; fiatCode: string; }): CacheDir { return new CacheDir( @@ -127,14 +128,14 @@ export class CacheRouter { static getZerionCollectiblesCacheKey(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): string { return `${args.chainId}_${CacheRouter.ZERION_COLLECTIBLES_KEY}_${args.safeAddress}`; } static getZerionCollectiblesCacheDir(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; }): CacheDir { @@ -146,14 +147,14 @@ export class CacheRouter { static getZerionPositionsCacheKey(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): string { return `${args.chainId}_${CacheRouter.ZERION_POSITIONS_KEY}_${args.safeAddress}`; } static getZerionPositionsCacheDir(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; fiatCode: string; }): CacheDir { return new CacheDir( @@ -168,28 +169,28 @@ export class CacheRouter { static getSafeCacheDir(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): CacheDir { return new CacheDir(CacheRouter.getSafeCacheKey(args), ''); } static getSafeCacheKey(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): string { return `${args.chainId}_${CacheRouter.SAFE_KEY}_${args.safeAddress}`; } static getIsSafeCacheDir(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): CacheDir { return new CacheDir(CacheRouter.getIsSafeCacheKey(args), ''); } static getIsSafeCacheKey(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): string { return `${args.chainId}_${CacheRouter.SAFE_EXISTS_KEY}_${args.safeAddress}`; } @@ -204,7 +205,7 @@ export class CacheRouter { static getCollectiblesCacheDir(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; trusted?: boolean; @@ -218,23 +219,23 @@ export class CacheRouter { static getCollectiblesKey(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): string { return `${args.chainId}_${CacheRouter.SAFE_COLLECTIBLES_KEY}_${args.safeAddress}`; } static getDelegatesCacheKey(args: { chainId: string; - safeAddress?: `0x${string}`; + safeAddress?: Address; }): string { return `${args.chainId}_${CacheRouter.DELEGATES_KEY}_${args.safeAddress}`; } static getDelegatesCacheDir(args: { chainId: string; - safeAddress?: `0x${string}`; - delegate?: `0x${string}`; - delegator?: `0x${string}`; + safeAddress?: Address; + delegate?: Address; + delegator?: Address; label?: string; limit?: number; offset?: number; @@ -292,7 +293,7 @@ export class CacheRouter { static getModuleTransactionsCacheDir(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; to?: string; txHash?: string; module?: string; @@ -307,7 +308,7 @@ export class CacheRouter { static getModuleTransactionsCacheKey(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): string { return `${args.chainId}_${CacheRouter.MODULE_TRANSACTIONS_KEY}_${args.safeAddress}`; } @@ -385,7 +386,7 @@ export class CacheRouter { static getCreationTransactionCacheDir(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): CacheDir { return new CacheDir( `${args.chainId}_${CacheRouter.CREATION_TRANSACTION_KEY}_${args.safeAddress}`, @@ -395,30 +396,30 @@ export class CacheRouter { static getDecodedDataCacheKey(args: { chainId: string; - data: `0x${string}`; - to: `0x${string}`; + data: Address; + to: Address; }): string { return `${args.chainId}_${CacheRouter.DECODED_DATA_KEY}_${args.data}_${args.to}`; } static getDecodedDataCacheDir(args: { chainId: string; - data: `0x${string}`; - to: `0x${string}`; + data: Address; + to: Address; }): CacheDir { return new CacheDir(CacheRouter.getDecodedDataCacheKey(args), ''); } static getContractsCacheKey(args: { chainId: string; - address: `0x${string}`; + address: Address; }): string { return `${args.chainId}_${CacheRouter.CONTRACTS_KEY}_${args.address}`; } static getContractsCacheDir(args: { chainId: string; - address: `0x${string}`; + address: Address; }): CacheDir { return new CacheDir(CacheRouter.getContractsCacheKey(args), ''); } @@ -440,7 +441,7 @@ export class CacheRouter { static getAllTransactionsCacheDir(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; ordering?: string; executed?: boolean; queued?: boolean; @@ -455,7 +456,7 @@ export class CacheRouter { static getAllTransactionsKey(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): string { return `${args.chainId}_${CacheRouter.ALL_TRANSACTIONS_KEY}_${args.safeAddress}`; } @@ -487,7 +488,7 @@ export class CacheRouter { static getSafesByOwnerCacheDir(args: { chainId: string; - ownerAddress: `0x${string}`; + ownerAddress: Address; }): CacheDir { return new CacheDir( `${args.chainId}_${CacheRouter.OWNERS_SAFE_KEY}_${args.ownerAddress}`, @@ -511,14 +512,14 @@ export class CacheRouter { static getMessagesBySafeCacheKey(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): string { return `${args.chainId}_${CacheRouter.MESSAGES_KEY}_${args.safeAddress}`; } static getMessagesBySafeCacheDir(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; }): CacheDir { @@ -550,16 +551,13 @@ export class CacheRouter { return new CacheDir(CacheRouter.getChainCacheKey(chainId), ''); } - static getRelayKey(args: { - chainId: string; - address: `0x${string}`; - }): string { + static getRelayKey(args: { chainId: string; address: Address }): string { return `${args.chainId}_${CacheRouter.RELAY_KEY}_${args.address}`; } static getRelayCacheDir(args: { chainId: string; - address: `0x${string}`; + address: Address; }): CacheDir { return new CacheDir(CacheRouter.getRelayKey(args), ''); } @@ -605,7 +603,7 @@ export class CacheRouter { return new CacheDir(CacheRouter.SAFE_FIAT_CODES_KEY, ''); } - static getAccountCacheDir(address: `0x${string}`): CacheDir { + static getAccountCacheDir(address: Address): CacheDir { return new CacheDir(`${CacheRouter.ACCOUNT_KEY}_${address}`, ''); } @@ -613,7 +611,7 @@ export class CacheRouter { return new CacheDir(CacheRouter.ACCOUNT_DATA_TYPES_KEY, ''); } - static getAccountDataSettingsCacheDir(address: `0x${string}`): CacheDir { + static getAccountDataSettingsCacheDir(address: Address): CacheDir { return new CacheDir( `${CacheRouter.ACCOUNT_DATA_SETTINGS_KEY}_${address}`, '', @@ -622,7 +620,7 @@ export class CacheRouter { static getCounterfactualSafeCacheDir( chainId: string, - predictedAddress: `0x${string}`, + predictedAddress: Address, ): CacheDir { return new CacheDir( `${chainId}_${CacheRouter.COUNTERFACTUAL_SAFE_KEY}_${predictedAddress}`, @@ -630,7 +628,7 @@ export class CacheRouter { ); } - static getCounterfactualSafesCacheDir(address: `0x${string}`): CacheDir { + static getCounterfactualSafesCacheDir(address: Address): CacheDir { return new CacheDir( `${CacheRouter.COUNTERFACTUAL_SAFES_KEY}_${address}`, '', @@ -661,7 +659,7 @@ export class CacheRouter { static getStakingRewardsFeeCacheDir(args: { cacheType: 'earn' | 'staking'; chainId: string; - contract: `0x${string}`; + contract: Address; }): CacheDir { return new CacheDir( `${args.chainId}_${this.STAKING_REWARDS_FEE_KEY}_${args.contract}`, @@ -683,7 +681,7 @@ export class CacheRouter { static getStakingPooledStakingStatsCacheDir(args: { cacheType: 'earn' | 'staking'; - pool: `0x${string}`; + pool: Address; }): CacheDir { return new CacheDir( `${this.STAKING_POOLED_STAKING_STATS_KEY}_${args.pool}`, @@ -694,7 +692,7 @@ export class CacheRouter { static getStakingDefiVaultStatsCacheDir(args: { cacheType: 'earn' | 'staking'; chainId: string; - vault: `0x${string}`; + vault: Address; }): CacheDir { return new CacheDir( `${args.chainId}_${this.STAKING_DEFI_VAULT_STATS_KEY}_${args.vault}`, @@ -705,8 +703,8 @@ export class CacheRouter { static getStakingDefiVaultStakesCacheDir(args: { cacheType: 'earn' | 'staking'; chainId: string; - safeAddress: `0x${string}`; - vault: `0x${string}`; + safeAddress: Address; + vault: Address; }): CacheDir { return new CacheDir( `${args.chainId}_${this.STAKING_DEFI_VAULT_STAKES_KEY}_${args.safeAddress}_${args.vault}`, @@ -717,7 +715,7 @@ export class CacheRouter { static getStakingDefiMorphoExtraRewardsCacheDir(args: { cacheType: 'earn' | 'staking'; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): CacheDir { return new CacheDir( `${args.chainId}_${this.STAKING_DEFI_MORPHO_EXTRA_REWARDS_KEY}_${args.safeAddress}`, @@ -734,7 +732,7 @@ export class CacheRouter { */ static getStakingStakesCacheKey(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): string { return `${args.chainId}_${CacheRouter.STAKING_STAKES_KEY}_${args.safeAddress}`; } @@ -755,8 +753,8 @@ export class CacheRouter { static getStakingStakesCacheDir(args: { cacheType: 'earn' | 'staking'; chainId: string; - safeAddress: `0x${string}`; - validatorsPublicKeys: Array<`0x${string}`>; + safeAddress: Address; + validatorsPublicKeys: Array
; }): CacheDir { const hash = crypto.createHash('sha256'); hash.update(args.validatorsPublicKeys.join('_')); @@ -773,7 +771,7 @@ export class CacheRouter { static getStakingTransactionStatusCacheDir(args: { cacheType: 'earn' | 'staking'; chainId: string; - txHash: `0x${string}`; + txHash: Hash; }): CacheDir { return new CacheDir( `${args.chainId}_${CacheRouter.STAKING_TRANSACTION_STATUS_KEY}_${args.txHash}`, @@ -787,7 +785,7 @@ export class CacheRouter { static getTargetedSafeCacheDir(args: { outreachId: number; - safeAddress: `0x${string}`; + safeAddress: Address; }): CacheDir { return new CacheDir( CacheRouter.getTargetedSafeCacheKey(args.outreachId), @@ -801,8 +799,8 @@ export class CacheRouter { static getSubmissionCacheDir(args: { outreachId: number; - safeAddress: `0x${string}`; - signerAddress: `0x${string}`; + safeAddress: Address; + signerAddress: Address; }): CacheDir { return new CacheDir( CacheRouter.getSubmissionCacheKey(args.outreachId), @@ -824,14 +822,14 @@ export class CacheRouter { static getTransactionsExportCacheKey(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): string { return `${args.chainId}_${CacheRouter.TRANSACTIONS_EXPORT_KEY}_${args.safeAddress}`; } static getTransactionsExportCacheDir(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; executionDateGte?: string; executionDateLte?: string; limit?: number; @@ -862,7 +860,7 @@ export class CacheRouter { static getOrnCacheKey( prefix: string, chainId: string, - safeAddress: `0x${string}`, + safeAddress: Address, ): string { return `${CacheRouter.ORM_QUERY_CACHE_KEY}:${prefix}:${chainId}:${safeAddress}`; } diff --git a/src/datasources/data-decoder-api/data-decoder-api.service.spec.ts b/src/datasources/data-decoder-api/data-decoder-api.service.spec.ts index 4fb8d812ec..3e98678399 100644 --- a/src/datasources/data-decoder-api/data-decoder-api.service.spec.ts +++ b/src/datasources/data-decoder-api/data-decoder-api.service.spec.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { getAddress, type Hex } from 'viem'; import { DataDecoderApi } from '@/datasources/data-decoder-api/data-decoder-api.service'; import { HttpErrorFactory } from '@/datasources/errors/http-error-factory'; import { dataDecodedBuilder } from '@/domain/data-decoder/v2/entities/__tests__/data-decoded.builder'; @@ -57,7 +57,7 @@ describe('DataDecoderApi', () => { const dataDecoded = dataDecodedBuilder().build(); const to = getAddress(faker.finance.ethereumAddress()); const chainId = faker.string.numeric(); - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Hex; const getDataDecodedUrl = `${baseUrl}/api/v1/data-decoder`; mockCacheFirstDataSource.post.mockImplementation(({ url }) => { if (url === getDataDecodedUrl) { @@ -83,7 +83,7 @@ describe('DataDecoderApi', () => { it('should forward an error', async () => { const to = getAddress(faker.finance.ethereumAddress()); - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Hex; const chainId = faker.string.numeric(); const errorMessage = faker.word.words(); const statusCode = faker.internet.httpStatusCode({ diff --git a/src/datasources/data-decoder-api/data-decoder-api.service.ts b/src/datasources/data-decoder-api/data-decoder-api.service.ts index 26765cac0a..f779947e8a 100644 --- a/src/datasources/data-decoder-api/data-decoder-api.service.ts +++ b/src/datasources/data-decoder-api/data-decoder-api.service.ts @@ -8,6 +8,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { IConfigurationService } from '@/config/configuration.service.interface'; import { CacheFirstDataSource } from '@/datasources/cache/cache.first.data.source'; import { CacheRouter } from '@/datasources/cache/cache.router'; +import type { Address } from 'viem'; @Injectable() export class DataDecoderApi implements IDataDecoderApi { @@ -41,8 +42,8 @@ export class DataDecoderApi implements IDataDecoderApi { } public async getDecodedData(args: { - data: `0x${string}`; - to: `0x${string}`; + data: Address; + to: Address; chainId: string; }): Promise> { try { @@ -59,7 +60,7 @@ export class DataDecoderApi implements IDataDecoderApi { } public async getContracts(args: { - address: `0x${string}`; + address: Address; chainId: string; limit?: number; offset?: number; diff --git a/src/datasources/locking-api/locking-api.service.ts b/src/datasources/locking-api/locking-api.service.ts index e460d3aa6b..39a021866b 100644 --- a/src/datasources/locking-api/locking-api.service.ts +++ b/src/datasources/locking-api/locking-api.service.ts @@ -13,6 +13,7 @@ import { LockingEvent } from '@/domain/community/entities/locking-event.entity'; import { LockingRank } from '@/domain/community/entities/locking-rank.entity'; import { Inject } from '@nestjs/common'; import type { Raw } from '@/validation/entities/raw.entity'; +import type { Address } from 'viem'; export class LockingApi implements ILockingApi { private readonly baseUri: string; @@ -61,7 +62,7 @@ export class LockingApi implements ILockingApi { async getCampaignActivities(args: { resourceId: string; - holder?: `0x${string}`; + holder?: Address; limit?: number; offset?: number; }): Promise>> { @@ -87,7 +88,7 @@ export class LockingApi implements ILockingApi { async getCampaignRank(args: { resourceId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise> { try { const url = `${this.baseUri}/api/v1/campaigns/${args.resourceId}/leaderboard/${args.safeAddress}`; @@ -100,7 +101,7 @@ export class LockingApi implements ILockingApi { } } - async getLockingRank(safeAddress: `0x${string}`): Promise> { + async getLockingRank(safeAddress: Address): Promise> { try { const url = `${this.baseUri}/api/v1/leaderboard/${safeAddress}`; const { data } = await this.networkService.get({ url }); @@ -154,7 +155,7 @@ export class LockingApi implements ILockingApi { } async getLockingHistory(args: { - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; }): Promise>> { diff --git a/src/datasources/notifications/entities/notification-subscription.entity.db.ts b/src/datasources/notifications/entities/notification-subscription.entity.db.ts index 5d41853812..5b7641208c 100644 --- a/src/datasources/notifications/entities/notification-subscription.entity.db.ts +++ b/src/datasources/notifications/entities/notification-subscription.entity.db.ts @@ -15,7 +15,7 @@ import { OneToMany, JoinColumn, } from 'typeorm'; -import { getAddress } from 'viem'; +import { Address, getAddress } from 'viem'; import { z } from 'zod'; export const NotificationSubscriptionSchema = RowSchema.extend({ @@ -56,15 +56,15 @@ export class NotificationSubscription type: 'varchar', length: 42, transformer: { - from(value: string): `0x${string}` { + from(value: string): Address { return getAddress(value); }, - to(value: string): `0x${string}` { + to(value: string): Address { return getAddress(value); }, }, }) - safe_address!: `0x${string}`; + safe_address!: Address; @Column({ type: 'varchar', @@ -79,7 +79,7 @@ export class NotificationSubscription }, }, }) - signer_address!: `0x${string}` | null; + signer_address!: Address | null; @Column({ type: 'timestamp with time zone', diff --git a/src/datasources/positions-api/zerion-positions-api.service.ts b/src/datasources/positions-api/zerion-positions-api.service.ts index 08697d1bec..bf7d243c90 100644 --- a/src/datasources/positions-api/zerion-positions-api.service.ts +++ b/src/datasources/positions-api/zerion-positions-api.service.ts @@ -30,7 +30,7 @@ import { IPositionsApi } from '@/domain/interfaces/positions-api.interface'; import { ILoggingService, LoggingService } from '@/logging/logging.interface'; import { rawify, type Raw } from '@/validation/entities/raw.entity'; import { Inject, Injectable } from '@nestjs/common'; -import { getAddress } from 'viem'; +import { Address, getAddress } from 'viem'; import { z, ZodError } from 'zod'; import { Position } from '@/domain/positions/entities/position.entity'; @@ -70,7 +70,7 @@ export class ZerionPositionsApi implements IPositionsApi { async getPositions(args: { chain: Chain; - safeAddress: `0x${string}`; + safeAddress: Address; fiatCode: string; }): Promise>> { if (!this.fiatCodes.includes(args.fiatCode.toUpperCase())) { @@ -131,7 +131,7 @@ export class ZerionPositionsApi implements IPositionsApi { async clearPositions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const key = CacheRouter.getZerionPositionsCacheKey(args); await this.cacheService.deleteByKey(key); diff --git a/src/datasources/relay-api/gelato-api.service.ts b/src/datasources/relay-api/gelato-api.service.ts index b8dd1015a6..21b99c2709 100644 --- a/src/datasources/relay-api/gelato-api.service.ts +++ b/src/datasources/relay-api/gelato-api.service.ts @@ -13,6 +13,7 @@ import { } from '@/datasources/cache/cache.service.interface'; import type { Relay } from '@/domain/relay/entities/relay.entity'; import type { Raw } from '@/validation/entities/raw.entity'; +import type { Address } from 'viem'; @Injectable() export class GelatoApi implements IRelayApi { @@ -42,7 +43,7 @@ export class GelatoApi implements IRelayApi { async relay(args: { chainId: string; - to: `0x${string}`; + to: Address; data: string; gasLimit: bigint | null; }): Promise> { @@ -76,7 +77,7 @@ export class GelatoApi implements IRelayApi { async getRelayCount(args: { chainId: string; - address: `0x${string}`; + address: Address; // TODO: Change to Raw when cache service is migrated }): Promise { const cacheDir = CacheRouter.getRelayCacheDir(args); @@ -86,7 +87,7 @@ export class GelatoApi implements IRelayApi { async setRelayCount(args: { chainId: string; - address: `0x${string}`; + address: Address; count: number; }): Promise { const cacheDir = CacheRouter.getRelayCacheDir(args); diff --git a/src/datasources/spaces/entities/address-book-item.entity.db.ts b/src/datasources/spaces/entities/address-book-item.entity.db.ts index 8384434c10..f4264fe653 100644 --- a/src/datasources/spaces/entities/address-book-item.entity.db.ts +++ b/src/datasources/spaces/entities/address-book-item.entity.db.ts @@ -11,6 +11,7 @@ import { PrimaryGeneratedColumn, Unique, } from 'typeorm'; +import type { Address } from 'viem'; @Entity('space_address_book_items') @Unique('UQ_SABI_space_id_address', ['space', 'address']) @@ -47,7 +48,7 @@ export class AddressBookItem implements DomainAddressBookItem { nullable: false, transformer: databaseAddressTransformer, }) - address!: `0x${string}`; + address!: Address; @Column({ type: 'varchar', @@ -62,7 +63,7 @@ export class AddressBookItem implements DomainAddressBookItem { nullable: false, transformer: databaseAddressTransformer, }) - createdBy!: `0x${string}`; + createdBy!: Address; @Column({ name: 'last_updated_by', @@ -71,7 +72,7 @@ export class AddressBookItem implements DomainAddressBookItem { nullable: false, transformer: databaseAddressTransformer, }) - lastUpdatedBy!: `0x${string}`; + lastUpdatedBy!: Address; @Column({ name: 'created_at', diff --git a/src/datasources/spaces/entities/space-safes.entity.db.ts b/src/datasources/spaces/entities/space-safes.entity.db.ts index 3e6518e0a7..0ed0c400e1 100644 --- a/src/datasources/spaces/entities/space-safes.entity.db.ts +++ b/src/datasources/spaces/entities/space-safes.entity.db.ts @@ -10,6 +10,7 @@ import { PrimaryGeneratedColumn, Unique, } from 'typeorm'; +import type { Address } from 'viem'; @Entity('space_safes') @Unique('UQ_SS_chainId_address_space', ['chainId', 'address', 'space']) @@ -31,7 +32,7 @@ export class SpaceSafe implements DomainSpaceSafe { length: 42, transformer: databaseAddressTransformer, }) - public readonly address!: `0x${string}`; + public readonly address!: Address; @Column({ name: 'created_at', diff --git a/src/datasources/staking-api/entities/__tests__/defi-morpho-extra-reward.entity.spec.ts b/src/datasources/staking-api/entities/__tests__/defi-morpho-extra-reward.entity.spec.ts index dc1e51f66a..801d0eb588 100644 --- a/src/datasources/staking-api/entities/__tests__/defi-morpho-extra-reward.entity.spec.ts +++ b/src/datasources/staking-api/entities/__tests__/defi-morpho-extra-reward.entity.spec.ts @@ -1,4 +1,5 @@ import { faker } from '@faker-js/faker'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; import { defiMorphoExtraRewardBuilder } from '@/datasources/staking-api/entities/__tests__/defi-morpho-extra-reward.entity.builder'; @@ -16,7 +17,7 @@ describe('DefiMorphoExtraRewardSchema', () => { it('should checksum the asset address', () => { const lowerCaseAddress = faker.finance.ethereumAddress().toLowerCase(); const defiMorphoExtraReward = defiMorphoExtraRewardBuilder() - .with('asset', lowerCaseAddress as `0x${string}`) + .with('asset', lowerCaseAddress as Address) .build(); const result = DefiMorphoExtraRewardSchema.safeParse(defiMorphoExtraReward); diff --git a/src/datasources/staking-api/entities/__tests__/defi-vault-stake.entity.spec.ts b/src/datasources/staking-api/entities/__tests__/defi-vault-stake.entity.spec.ts index f2598742ac..7ec4a833a1 100644 --- a/src/datasources/staking-api/entities/__tests__/defi-vault-stake.entity.spec.ts +++ b/src/datasources/staking-api/entities/__tests__/defi-vault-stake.entity.spec.ts @@ -1,4 +1,5 @@ import { faker } from '@faker-js/faker'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; import { defiVaultStakeBuilder } from '@/datasources/staking-api/entities/__tests__/defi-vault-state.entity.builder'; import { DefiVaultStakeSchema } from '@/datasources/staking-api/entities/defi-vault-stake.entity'; @@ -17,7 +18,7 @@ describe('DefiVaultStakeSchema', () => { (field) => { const lowerCaseAddress = faker.finance.ethereumAddress().toLowerCase(); const defiVaultStake = defiVaultStakeBuilder() - .with(field, lowerCaseAddress as `0x${string}`) + .with(field, lowerCaseAddress as Address) .build(); const result = DefiVaultStakeSchema.safeParse(defiVaultStake); diff --git a/src/datasources/staking-api/entities/__tests__/defi-vault-stats.entity.spec.ts b/src/datasources/staking-api/entities/__tests__/defi-vault-stats.entity.spec.ts index 47aff9d7bc..08c5410ba8 100644 --- a/src/datasources/staking-api/entities/__tests__/defi-vault-stats.entity.spec.ts +++ b/src/datasources/staking-api/entities/__tests__/defi-vault-stats.entity.spec.ts @@ -7,6 +7,7 @@ import { DefiVaultStatsSchema, } from '@/datasources/staking-api/entities/defi-vault-stats.entity'; import { faker } from '@faker-js/faker'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; describe('DefiVaultStatsSchema', () => { @@ -25,7 +26,7 @@ describe('DefiVaultStatsSchema', () => { .ethereumAddress() .toLowerCase(); const defiVaultStats = defiVaultStatsBuilder() - .with(key, nonChecksummedAddress as `0x${string}`) + .with(key, nonChecksummedAddress as Address) .build(); const result = DefiVaultStatsSchema.safeParse(defiVaultStats); @@ -282,7 +283,7 @@ describe('DefiVaultStatsSchema', () => { it('should checksum an asset address', () => { const nonChecksummedAddress = faker.finance.ethereumAddress().toLowerCase(); const defiVaultStatsAdditionalReward = defiVaultAdditionalRewardBuilder() - .with('asset', nonChecksummedAddress as `0x${string}`) + .with('asset', nonChecksummedAddress as Address) .build(); const result = DefiVaultStatsAdditionalRewardSchema.safeParse( diff --git a/src/datasources/staking-api/entities/__tests__/deployment.entity.spec.ts b/src/datasources/staking-api/entities/__tests__/deployment.entity.spec.ts index f91cbef8cf..5a85f4f671 100644 --- a/src/datasources/staking-api/entities/__tests__/deployment.entity.spec.ts +++ b/src/datasources/staking-api/entities/__tests__/deployment.entity.spec.ts @@ -1,6 +1,7 @@ import { deploymentBuilder } from '@/datasources/staking-api/entities/__tests__/deployment.entity.builder'; import { DeploymentSchema } from '@/datasources/staking-api/entities/deployment.entity'; import { faker } from '@faker-js/faker'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; describe('DeploymentSchema', () => { @@ -64,7 +65,7 @@ describe('DeploymentSchema', () => { it('should checksum the address field', () => { const nonChecksummedAddress = faker.finance.ethereumAddress().toLowerCase(); const deployment = deploymentBuilder() - .with('address', nonChecksummedAddress as `0x${string}`) + .with('address', nonChecksummedAddress as Address) .build(); const result = DeploymentSchema.safeParse(deployment); diff --git a/src/datasources/staking-api/entities/__tests__/pooled-staking-stats.entity.spec.ts b/src/datasources/staking-api/entities/__tests__/pooled-staking-stats.entity.spec.ts index d5121ccfc7..a81725a4d0 100644 --- a/src/datasources/staking-api/entities/__tests__/pooled-staking-stats.entity.spec.ts +++ b/src/datasources/staking-api/entities/__tests__/pooled-staking-stats.entity.spec.ts @@ -2,7 +2,7 @@ import { pooledStakingStatsBuilder } from '@/datasources/staking-api/entities/__ import type { PooledStakingStats } from '@/datasources/staking-api/entities/pooled-staking-stats.entity'; import { PooledStakingStatsSchema } from '@/datasources/staking-api/entities/pooled-staking-stats.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; describe('PooledStakingSchema', () => { it('should validate a PooledStakingStats object', () => { @@ -16,7 +16,7 @@ describe('PooledStakingSchema', () => { it('should checksum the address', () => { const nonChecksummedAddress = faker.finance.ethereumAddress().toLowerCase(); const pooledStakingStats = pooledStakingStatsBuilder() - .with('address', nonChecksummedAddress as `0x${string}`) + .with('address', nonChecksummedAddress as Address) .build(); const result = PooledStakingStatsSchema.safeParse(pooledStakingStats); @@ -65,7 +65,7 @@ describe('PooledStakingSchema', () => { ])('should checksum the pools[number]%s', (key) => { const nonChecksummedAddress = faker.finance.ethereumAddress().toLowerCase(); const pooledStakingStats = pooledStakingStatsBuilder().build(); - pooledStakingStats.pools[0][key] = nonChecksummedAddress as `0x${string}`; + pooledStakingStats.pools[0][key] = nonChecksummedAddress as Address; const result = PooledStakingStatsSchema.safeParse(pooledStakingStats); diff --git a/src/datasources/staking-api/entities/__tests__/stake.entity.builder.ts b/src/datasources/staking-api/entities/__tests__/stake.entity.builder.ts index ad7da5e37e..87a7668aa4 100644 --- a/src/datasources/staking-api/entities/__tests__/stake.entity.builder.ts +++ b/src/datasources/staking-api/entities/__tests__/stake.entity.builder.ts @@ -4,6 +4,7 @@ import type { Stake } from '@/datasources/staking-api/entities/stake.entity'; import { StakeState } from '@/datasources/staking-api/entities/stake.entity'; import { KilnDecoder } from '@/domain/staking/contracts/decoders/kiln-decoder.helper'; import { faker } from '@faker-js/faker'; +import type { Address } from 'viem'; export function stakeBuilder(): IBuilder { return new Builder() @@ -11,7 +12,7 @@ export function stakeBuilder(): IBuilder { 'validator_address', faker.string.hexadecimal({ length: KilnDecoder.KilnPublicKeyLength, - }) as `0x${string}`, + }) as Address, ) .with('state', faker.helpers.arrayElement(Object.values(StakeState))) .with('rewards', faker.string.numeric()) diff --git a/src/datasources/staking-api/entities/__tests__/transaction-status.entity.builder.ts b/src/datasources/staking-api/entities/__tests__/transaction-status.entity.builder.ts index ba7cc09e19..49c43c8a77 100644 --- a/src/datasources/staking-api/entities/__tests__/transaction-status.entity.builder.ts +++ b/src/datasources/staking-api/entities/__tests__/transaction-status.entity.builder.ts @@ -2,6 +2,7 @@ import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { TransactionStatus } from '@/datasources/staking-api/entities/transaction-status.entity'; import { faker } from '@faker-js/faker'; +import type { Address, Hex } from 'viem'; export function transactionStatusReceiptLogBuilder(): IBuilder< TransactionStatus['receipt']['logs'][number] @@ -10,14 +11,14 @@ export function transactionStatusReceiptLogBuilder(): IBuilder< .with( 'topics', Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, () => { - return faker.string.hexadecimal({ length: 64 }) as `0x${string}`; - }) as [`0x${string}`, ...Array<`0x${string}`>], + return faker.string.hexadecimal({ length: 64 }) as Hex; + }) as [Address, ...Array
], ) .with( 'data', faker.string.hexadecimal({ length: 64, - }) as `0x${string}`, + }) as Address, ); } diff --git a/src/datasources/staking-api/entities/__tests__/transaction-status.entity.spec.ts b/src/datasources/staking-api/entities/__tests__/transaction-status.entity.spec.ts index 8e36236501..f04e351c9e 100644 --- a/src/datasources/staking-api/entities/__tests__/transaction-status.entity.spec.ts +++ b/src/datasources/staking-api/entities/__tests__/transaction-status.entity.spec.ts @@ -8,6 +8,7 @@ import { TransactionStatusSchema, } from '@/datasources/staking-api/entities/transaction-status.entity'; import { faker } from '@faker-js/faker/.'; +import type { Address } from 'viem'; describe('TransactionStatus', () => { describe('TransactionStatusReceiptLogSchema', () => { @@ -24,7 +25,7 @@ describe('TransactionStatus', () => { it('should not allow non-hex topics', () => { const transactionStatusReceiptLog = transactionStatusReceiptLogBuilder() - .with('topics', [faker.string.alphanumeric() as `0x${string}`]) + .with('topics', [faker.string.alphanumeric() as Address]) .build(); const result = TransactionStatusReceiptLogSchema.safeParse( @@ -41,7 +42,7 @@ describe('TransactionStatus', () => { it('should not allow non-hex data', () => { const transactionStatusReceiptLog = transactionStatusReceiptLogBuilder() - .with('data', faker.string.alphanumeric() as `0x${string}`) + .with('data', faker.string.alphanumeric() as Address) .build(); const result = TransactionStatusReceiptLogSchema.safeParse( diff --git a/src/datasources/staking-api/kiln-api.service.spec.ts b/src/datasources/staking-api/kiln-api.service.spec.ts index 81d38162c4..981ce5879c 100644 --- a/src/datasources/staking-api/kiln-api.service.spec.ts +++ b/src/datasources/staking-api/kiln-api.service.spec.ts @@ -19,7 +19,7 @@ import { DataSourceError } from '@/domain/errors/data-source.error'; import { KilnDecoder } from '@/domain/staking/contracts/decoders/kiln-decoder.helper'; import { rawify } from '@/validation/entities/raw.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress, type Hash } from 'viem'; const dataSource = { get: jest.fn(), @@ -809,7 +809,7 @@ describe('KilnApi', () => { () => faker.string.hexadecimal({ length: KilnDecoder.KilnPublicKeyLength, - }) as `0x${string}`, + }) as Address, { count: { min: 1, max: 5 } }, ); const concatenatedValidatorsPublicKeys = validatorsPublicKeys.join(','); @@ -861,7 +861,7 @@ describe('KilnApi', () => { () => faker.string.hexadecimal({ length: KilnDecoder.KilnPublicKeyLength, - }) as `0x${string}`, + }) as Address, { count: { min: 1, max: 5 } }, ); const concatenatedValidatorsPublicKeys = validatorsPublicKeys.join(','); @@ -927,7 +927,7 @@ describe('KilnApi', () => { describe('getTransactionStatus', () => { it('should return the transaction status', async () => { - const txHash = faker.string.hexadecimal({ length: 64 }) as `0x${string}`; + const txHash = faker.string.hexadecimal({ length: 64 }) as Hash; const transactionStatus = transactionStatusBuilder().build(); const getTransactionStatusUrl = `${baseUrl}/v1/eth/transaction/status`; dataSource.get.mockResolvedValue( @@ -964,7 +964,7 @@ describe('KilnApi', () => { }); it('should forward errors', async () => { - const txHash = faker.string.hexadecimal({ length: 64 }) as `0x${string}`; + const txHash = faker.string.hexadecimal({ length: 64 }) as Hash; const getTransactionStatusUrl = `${baseUrl}/v1/eth/transaction/status`; const errorMessage = faker.lorem.sentence(); const statusCode = faker.internet.httpStatusCode({ diff --git a/src/datasources/staking-api/kiln-api.service.ts b/src/datasources/staking-api/kiln-api.service.ts index d717d8de7d..c418fbd77f 100644 --- a/src/datasources/staking-api/kiln-api.service.ts +++ b/src/datasources/staking-api/kiln-api.service.ts @@ -19,6 +19,7 @@ import type { TransactionStatus } from '@/datasources/staking-api/entities/trans import type { IStakingApi } from '@/domain/interfaces/staking-api.interface'; import type { Raw } from '@/validation/entities/raw.entity'; import { z, ZodError } from 'zod'; +import type { Address, Hash } from 'viem'; export class KilnApi implements IStakingApi { public static DefiVaultStatsChains: { @@ -77,7 +78,7 @@ export class KilnApi implements IStakingApi { // Important: there is no hook which invalidates this endpoint, // Therefore, this data will live in cache until [stakingExpirationTimeInSeconds] - async getRewardsFee(contract: `0x${string}`): Promise> { + async getRewardsFee(contract: Address): Promise> { const url = `${this.baseUrl}/v1/eth/onchain/v1/fee`; const cacheDir = CacheRouter.getStakingRewardsFeeCacheDir({ cacheType: this.cacheType, @@ -144,9 +145,7 @@ export class KilnApi implements IStakingApi { // Important: there is no hook which invalidates this endpoint, // Therefore, this data will live in cache until [stakingExpirationTimeInSeconds] - async getPooledStakingStats( - pool: `0x${string}`, - ): Promise> { + async getPooledStakingStats(pool: Address): Promise> { const url = `${this.baseUrl}/v1/eth/onchain/v2/network-stats`; const cacheDir = CacheRouter.getStakingPooledStakingStatsCacheDir({ cacheType: this.cacheType, @@ -172,9 +171,7 @@ export class KilnApi implements IStakingApi { // Important: there is no hook which invalidates this endpoint, // Therefore, this data will live in cache until [stakingExpirationTimeInSeconds] - async getDefiVaultStats( - vault: `0x${string}`, - ): Promise>> { + async getDefiVaultStats(vault: Address): Promise>> { const url = `${this.baseUrl}/v1/defi/network-stats`; const cacheDir = CacheRouter.getStakingDefiVaultStatsCacheDir({ cacheType: this.cacheType, @@ -202,8 +199,8 @@ export class KilnApi implements IStakingApi { // Important: there is no hook which invalidates this endpoint, // Therefore, this data will live in cache until [stakingExpirationTimeInSeconds] async getDefiVaultStakes(args: { - safeAddress: `0x${string}`; - vault: `0x${string}`; + safeAddress: Address; + vault: Address; }): Promise>> { const url = `${this.baseUrl}/v1/defi/stakes`; const cacheDir = CacheRouter.getStakingDefiVaultStakesCacheDir({ @@ -234,7 +231,7 @@ export class KilnApi implements IStakingApi { // Important: there is no hook which invalidates this endpoint, // Therefore, this data will live in cache until [stakingExpirationTimeInSeconds] async getDefiMorphoExtraRewards( - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise>> { const url = `${this.baseUrl}/v1/defi/extra-rewards/morpho`; const cacheDir = CacheRouter.getStakingDefiMorphoExtraRewardsCacheDir({ @@ -272,8 +269,8 @@ export class KilnApi implements IStakingApi { * @see https://docs.api.kiln.fi/reference/getethstakes */ async getStakes(args: { - safeAddress: `0x${string}`; - validatorsPublicKeys: Array<`0x${string}`>; + safeAddress: Address; + validatorsPublicKeys: Array
; }): Promise>> { const url = `${this.baseUrl}/v1/eth/stakes`; const cacheDir = CacheRouter.getStakingStakesCacheDir({ @@ -307,7 +304,7 @@ export class KilnApi implements IStakingApi { * * @param {string} safeAddress - Safe address */ - async clearStakes(safeAddress: `0x${string}`): Promise { + async clearStakes(safeAddress: Address): Promise { const key = CacheRouter.getStakingStakesCacheKey({ chainId: this.chainId, safeAddress, @@ -315,9 +312,7 @@ export class KilnApi implements IStakingApi { await this.cacheService.deleteByKey(key); } - async getTransactionStatus( - txHash: `0x${string}`, - ): Promise> { + async getTransactionStatus(txHash: Hash): Promise> { const url = `${this.baseUrl}/v1/eth/transaction/status`; const cacheDir = CacheRouter.getStakingTransactionStatusCacheDir({ cacheType: this.cacheType, @@ -374,7 +369,7 @@ export class KilnApi implements IStakingApi { * @returns array of DeFi vault identifiers - `chainIdentifier_vault`, e.g. `eth_0x123` * @see https://docs.api.kiln.fi/reference/getdefinetworkstats */ - private getDefiVaultIdentifier(vault: `0x${string}`): string { + private getDefiVaultIdentifier(vault: Address): string { const chain = Object.entries(KilnApi.DefiVaultStatsChains).find( ([, chainId]) => { return chainId === this.chainId; diff --git a/src/datasources/swaps-api/cowswap-api.service.ts b/src/datasources/swaps-api/cowswap-api.service.ts index a48e25f5ee..eb87d38e66 100644 --- a/src/datasources/swaps-api/cowswap-api.service.ts +++ b/src/datasources/swaps-api/cowswap-api.service.ts @@ -4,6 +4,7 @@ import type { ISwapsApi } from '@/domain/interfaces/swaps-api.interface'; import type { HttpErrorFactory } from '@/datasources/errors/http-error-factory'; import type { FullAppData } from '@/domain/swaps/entities/full-app-data.entity'; import type { Raw } from '@/validation/entities/raw.entity'; +import type { Hex } from 'viem'; export class CowSwapApi implements ISwapsApi { constructor( @@ -34,7 +35,7 @@ export class CowSwapApi implements ISwapsApi { } } - async getFullAppData(appDataHash: `0x${string}`): Promise> { + async getFullAppData(appDataHash: Hex): Promise> { try { const url = `${this.baseUrl}/api/v1/app_data/${appDataHash}`; const { data } = await this.networkService.get({ url }); diff --git a/src/datasources/targeted-messaging/entities/__tests__/outreach-file.entity.spec.ts b/src/datasources/targeted-messaging/entities/__tests__/outreach-file.entity.spec.ts index 12612c2c1a..310ec77be0 100644 --- a/src/datasources/targeted-messaging/entities/__tests__/outreach-file.entity.spec.ts +++ b/src/datasources/targeted-messaging/entities/__tests__/outreach-file.entity.spec.ts @@ -1,6 +1,7 @@ import { faker } from '@faker-js/faker'; import { outreachFileBuilder } from '@/datasources/targeted-messaging/entities/__tests__/outreach-file.builder'; import { OutreachFileSchema } from '@/datasources/targeted-messaging/entities/outreach-file.entity'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; describe('OutreachFileSchema', () => { @@ -52,7 +53,7 @@ describe('OutreachFileSchema', () => { { count: { min: 2, max: 5 } }, ); const outreachFile = outreachFileBuilder() - .with('safe_addresses', nonChecksummedAddresses as Array<`0x${string}`>) + .with('safe_addresses', nonChecksummedAddresses as Array
) .build(); const result = OutreachFileSchema.safeParse(outreachFile); diff --git a/src/datasources/targeted-messaging/entities/submission.entity.ts b/src/datasources/targeted-messaging/entities/submission.entity.ts index 3588c3fde2..cfa80e08cc 100644 --- a/src/datasources/targeted-messaging/entities/submission.entity.ts +++ b/src/datasources/targeted-messaging/entities/submission.entity.ts @@ -1,7 +1,9 @@ +import type { Address } from 'viem'; + export class Submission { id: number; targeted_safe_id: number; - signer_address: `0x${string}`; + signer_address: Address; completion_date: Date; created_at: Date; updated_at: Date; @@ -9,7 +11,7 @@ export class Submission { constructor( id: number, targeted_safe_id: number, - signer_address: `0x${string}`, + signer_address: Address, completion_date: Date, created_at: Date, updated_at: Date, diff --git a/src/datasources/targeted-messaging/entities/targeted-safe.entity.ts b/src/datasources/targeted-messaging/entities/targeted-safe.entity.ts index bd912cb99f..89ac7805a4 100644 --- a/src/datasources/targeted-messaging/entities/targeted-safe.entity.ts +++ b/src/datasources/targeted-messaging/entities/targeted-safe.entity.ts @@ -1,13 +1,15 @@ +import type { Address } from 'viem'; + export class TargetedSafe { id: number; - address: `0x${string}`; + address: Address; outreach_id: number; created_at: Date; updated_at: Date; constructor( id: number, - address: `0x${string}`, + address: Address, outreach_id: number, created_at: Date, updated_at: Date, diff --git a/src/datasources/targeted-messaging/outreach-file-processor.spec.ts b/src/datasources/targeted-messaging/outreach-file-processor.spec.ts index 32058f2de4..1287e24f86 100644 --- a/src/datasources/targeted-messaging/outreach-file-processor.spec.ts +++ b/src/datasources/targeted-messaging/outreach-file-processor.spec.ts @@ -16,7 +16,7 @@ import { createHash } from 'crypto'; import { mkdir, rm, writeFile } from 'fs/promises'; import path from 'path'; import type postgres from 'postgres'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { OutreachFileProcessor } from './outreach-file-processor'; import { SubmissionDbMapper } from '@/datasources/targeted-messaging/entities/submission.db.mapper'; import { TargetedSafeDbMapper } from '@/datasources/targeted-messaging/entities/targeted-safe.db.mapper'; @@ -303,7 +303,7 @@ describe('OutreachFileProcessor', () => { .with( 'safe_addresses', faker.helpers.multiple( - () => faker.finance.ethereumAddress().toLowerCase() as `0x${string}`, // not checksummed + () => faker.finance.ethereumAddress().toLowerCase() as Address, // not checksummed { count: { min: 10, max: 50 } }, ), ) diff --git a/src/datasources/targeted-messaging/targeted-messaging.datasource.ts b/src/datasources/targeted-messaging/targeted-messaging.datasource.ts index 1415d11832..d1052bc76d 100644 --- a/src/datasources/targeted-messaging/targeted-messaging.datasource.ts +++ b/src/datasources/targeted-messaging/targeted-messaging.datasource.ts @@ -30,6 +30,7 @@ import { UnprocessableEntityException, } from '@nestjs/common'; import postgres from 'postgres'; +import { type Address } from 'viem'; @Injectable() export class TargetedMessagingDatasource @@ -195,7 +196,7 @@ export class TargetedMessagingDatasource async getTargetedSafe(args: { outreachId: number; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const [dbTargetedSafe] = await this.cachedQueryResolver.get< Array @@ -216,7 +217,7 @@ export class TargetedMessagingDatasource async createSubmission(args: { targetedSafe: TargetedSafe; - signerAddress: `0x${string}`; + signerAddress: Address; }): Promise { const [dbSubmission] = await this.sql>` INSERT INTO submissions (targeted_safe_id, signer_address, completion_date) @@ -236,7 +237,7 @@ export class TargetedMessagingDatasource async getSubmission(args: { targetedSafe: TargetedSafe; - signerAddress: `0x${string}`; + signerAddress: Address; }): Promise { const [dbSubmission] = await this.cachedQueryResolver.get< Array diff --git a/src/datasources/transaction-api/transaction-api.service.spec.ts b/src/datasources/transaction-api/transaction-api.service.spec.ts index 215d07cfe3..002c5c81c9 100644 --- a/src/datasources/transaction-api/transaction-api.service.spec.ts +++ b/src/datasources/transaction-api/transaction-api.service.spec.ts @@ -21,7 +21,7 @@ import { tokenBuilder } from '@/domain/tokens/__tests__/token.builder'; import { messageBuilder } from '@/domain/messages/entities/__tests__/message.builder'; import { proposeTransactionDtoBuilder } from '@/routes/transactions/entities/__tests__/propose-transaction.dto.builder'; import { erc20TransferBuilder } from '@/domain/safe/entities/__tests__/erc20-transfer.builder'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import type { ILoggingService } from '@/logging/logging.interface'; import { indexingStatusBuilder } from '@/domain/chains/entities/__tests__/indexing-status.builder'; import { fakeJson } from '@/__tests__/faker'; @@ -110,7 +110,7 @@ describe('TransactionApi', () => { describe('getDataDecoded', () => { it('should return the decoded data', async () => { - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Address; const to = getAddress(faker.finance.ethereumAddress()); const getDataDecodedUrl = `${baseUrl}/api/v1/data-decoder/`; const decodedData = dataDecodedBuilder().build(); @@ -137,7 +137,7 @@ describe('TransactionApi', () => { ['Transaction Service', { nonFieldErrors: [errorMessage] }], ['standard', new Error(errorMessage)], ])(`should forward a %s error`, async (_, error) => { - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Address; const to = getAddress(faker.finance.ethereumAddress()); const getDataDecodedUrl = `${baseUrl}/api/v1/data-decoder/`; const statusCode = faker.internet.httpStatusCode({ @@ -1137,7 +1137,7 @@ describe('TransactionApi', () => { const safeTxHash = faker.string.hexadecimal(); const signature = faker.string.hexadecimal({ length: 130, - }) as `0x${string}`; + }) as Address; const postConfirmationUrl = `${baseUrl}/api/v1/multisig-transactions/${safeTxHash}/confirmations/`; networkService.post.mockResolvedValueOnce({ status: 200, @@ -1166,7 +1166,7 @@ describe('TransactionApi', () => { const safeTxHash = faker.string.hexadecimal(); const signature = faker.string.hexadecimal({ length: 130, - }) as `0x${string}`; + }) as Address; const postConfirmationUrl = `${baseUrl}/api/v1/multisig-transactions/${safeTxHash}/confirmations/`; const statusCode = faker.internet.httpStatusCode({ types: ['clientError', 'serverError'], @@ -2095,7 +2095,7 @@ describe('TransactionApi', () => { const safeAddress = getAddress(faker.finance.ethereumAddress()); const to = getAddress(faker.finance.ethereumAddress()); const value = faker.string.numeric(); - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Address; const operation = faker.helpers.arrayElement([0, 1] as const); const estimation = { safeTxGas: faker.string.numeric(), @@ -2132,7 +2132,7 @@ describe('TransactionApi', () => { const safeAddress = getAddress(faker.finance.ethereumAddress()); const to = getAddress(faker.finance.ethereumAddress()); const value = faker.string.numeric(); - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Address; const operation = faker.helpers.arrayElement([0, 1] as const); const getEstimationUrl = `${baseUrl}/api/v1/safes/${safeAddress}/multisig-transactions/estimations/`; const statusCode = faker.internet.httpStatusCode({ diff --git a/src/datasources/transaction-api/transaction-api.service.ts b/src/datasources/transaction-api/transaction-api.service.ts index d88c2c0b93..f44d7273ce 100644 --- a/src/datasources/transaction-api/transaction-api.service.ts +++ b/src/datasources/transaction-api/transaction-api.service.ts @@ -30,6 +30,7 @@ import type { ProposeTransactionDto } from '@/domain/transactions/entities/propo import type { ILoggingService } from '@/logging/logging.interface'; import type { Raw } from '@/validation/entities/raw.entity'; import get from 'lodash/get'; +import type { Address } from 'viem'; export class TransactionApi implements ITransactionApi { private static readonly ERROR_ARRAY_PATH = 'nonFieldErrors'; @@ -94,8 +95,8 @@ export class TransactionApi implements ITransactionApi { } async getDataDecoded(args: { - data: `0x${string}`; - to?: `0x${string}`; + data: Address; + to?: Address; }): Promise> { try { const url = `${this.baseUrl}/api/v1/data-decoder/`; @@ -163,7 +164,7 @@ export class TransactionApi implements ITransactionApi { } } - async getSafe(safeAddress: `0x${string}`): Promise> { + async getSafe(safeAddress: Address): Promise> { try { const cacheDir = CacheRouter.getSafeCacheDir({ chainId: this.chainId, @@ -181,7 +182,7 @@ export class TransactionApi implements ITransactionApi { } } - async clearSafe(safeAddress: `0x${string}`): Promise { + async clearSafe(safeAddress: Address): Promise { const key = CacheRouter.getSafeCacheKey({ chainId: this.chainId, safeAddress, @@ -192,7 +193,7 @@ export class TransactionApi implements ITransactionApi { // TODO: this replicates logic from the CacheFirstDataSource.get method to avoid // implementation of response remapping but we should refactor it to avoid duplication // TODO: Change to Raw when cache service is migrated - async isSafe(safeAddress: `0x${string}`): Promise { + async isSafe(safeAddress: Address): Promise { const cacheDir = CacheRouter.getIsSafeCacheDir({ chainId: this.chainId, safeAddress, @@ -244,7 +245,7 @@ export class TransactionApi implements ITransactionApi { return isSafe; } - async clearIsSafe(safeAddress: `0x${string}`): Promise { + async clearIsSafe(safeAddress: Address): Promise { const key = CacheRouter.getIsSafeCacheKey({ chainId: this.chainId, safeAddress, @@ -253,9 +254,9 @@ export class TransactionApi implements ITransactionApi { } async getDelegates(args: { - safeAddress?: `0x${string}`; - delegate?: `0x${string}`; - delegator?: `0x${string}`; + safeAddress?: Address; + delegate?: Address; + delegator?: Address; label?: string; limit?: number; offset?: number; @@ -287,9 +288,9 @@ export class TransactionApi implements ITransactionApi { } async getDelegatesV2(args: { - safeAddress?: `0x${string}`; - delegate?: `0x${string}`; - delegator?: `0x${string}`; + safeAddress?: Address; + delegate?: Address; + delegator?: Address; label?: string; limit?: number; offset?: number; @@ -320,7 +321,7 @@ export class TransactionApi implements ITransactionApi { } } - async clearDelegates(safeAddress?: `0x${string}`): Promise { + async clearDelegates(safeAddress?: Address): Promise { const cacheKey = CacheRouter.getDelegatesCacheKey({ chainId: this.chainId, safeAddress, @@ -329,9 +330,9 @@ export class TransactionApi implements ITransactionApi { } async postDelegate(args: { - safeAddress: `0x${string}` | null; - delegate: `0x${string}`; - delegator: `0x${string}`; + safeAddress: Address | null; + delegate: Address; + delegator: Address; signature: string; label: string; }): Promise { @@ -353,9 +354,9 @@ export class TransactionApi implements ITransactionApi { } async postDelegateV2(args: { - safeAddress: `0x${string}` | null; - delegate: `0x${string}`; - delegator: `0x${string}`; + safeAddress: Address | null; + delegate: Address; + delegator: Address; signature: string; label: string; }): Promise { @@ -377,8 +378,8 @@ export class TransactionApi implements ITransactionApi { } async deleteDelegate(args: { - delegate: `0x${string}`; - delegator: `0x${string}`; + delegate: Address; + delegator: Address; signature: string; }): Promise { try { @@ -397,8 +398,8 @@ export class TransactionApi implements ITransactionApi { } async deleteSafeDelegate(args: { - delegate: `0x${string}`; - safeAddress: `0x${string}`; + delegate: Address; + safeAddress: Address; signature: string; }): Promise { try { @@ -417,9 +418,9 @@ export class TransactionApi implements ITransactionApi { } async deleteDelegateV2(args: { - delegate: `0x${string}`; - delegator: `0x${string}`; - safeAddress: `0x${string}` | null; + delegate: Address; + delegator: Address; + safeAddress: Address | null; signature: string; }): Promise { try { @@ -458,7 +459,7 @@ export class TransactionApi implements ITransactionApi { } async getTransfers(args: { - safeAddress: `0x${string}`; + safeAddress: Address; onlyErc20: boolean; onlyErc721: boolean; limit?: number; @@ -489,7 +490,7 @@ export class TransactionApi implements ITransactionApi { } } - async clearTransfers(safeAddress: `0x${string}`): Promise { + async clearTransfers(safeAddress: Address): Promise { const key = CacheRouter.getTransfersCacheKey({ chainId: this.chainId, safeAddress, @@ -498,12 +499,12 @@ export class TransactionApi implements ITransactionApi { } async getIncomingTransfers(args: { - safeAddress: `0x${string}`; + safeAddress: Address; executionDateGte?: string; executionDateLte?: string; - to?: `0x${string}`; + to?: Address; value?: string; - tokenAddress?: `0x${string}`; + tokenAddress?: Address; txHash?: string; limit?: number; offset?: number; @@ -537,7 +538,7 @@ export class TransactionApi implements ITransactionApi { } } - async clearIncomingTransfers(safeAddress: `0x${string}`): Promise { + async clearIncomingTransfers(safeAddress: Address): Promise { const key = CacheRouter.getIncomingTransfersCacheKey({ chainId: this.chainId, safeAddress, @@ -562,7 +563,7 @@ export class TransactionApi implements ITransactionApi { } } - async getSafesByModule(moduleAddress: `0x${string}`): Promise> { + async getSafesByModule(moduleAddress: Address): Promise> { try { const url = `${this.baseUrl}/api/v1/modules/${moduleAddress}/safes/`; const { data } = await this.networkService.get({ url }); @@ -595,7 +596,7 @@ export class TransactionApi implements ITransactionApi { } async getModuleTransactions(args: { - safeAddress: `0x${string}`; + safeAddress: Address; to?: string; txHash?: string; module?: string; @@ -628,7 +629,7 @@ export class TransactionApi implements ITransactionApi { } } - async clearModuleTransactions(safeAddress: `0x${string}`): Promise { + async clearModuleTransactions(safeAddress: Address): Promise { const key = CacheRouter.getModuleTransactionsCacheKey({ chainId: this.chainId, safeAddress, @@ -637,13 +638,13 @@ export class TransactionApi implements ITransactionApi { } async getMultisigTransactions(args: { - safeAddress: `0x${string}`; + safeAddress: Address; ordering?: string; executed?: boolean; trusted?: boolean; executionDateGte?: string; executionDateLte?: string; - to?: `0x${string}`; + to?: Address; value?: string; nonce?: string; nonceGte?: number; @@ -687,7 +688,7 @@ export class TransactionApi implements ITransactionApi { safeAddress, ...params }: { - safeAddress: `0x${string}`; + safeAddress: Address; // Transaction Service parameters failed?: boolean; modified__lt?: string; @@ -732,7 +733,7 @@ export class TransactionApi implements ITransactionApi { } } - async clearMultisigTransactions(safeAddress: `0x${string}`): Promise { + async clearMultisigTransactions(safeAddress: Address): Promise { const key = CacheRouter.getMultisigTransactionsCacheKey({ chainId: this.chainId, safeAddress, @@ -802,7 +803,7 @@ export class TransactionApi implements ITransactionApi { // Important: there is no hook which invalidates this endpoint, // Therefore, this data will live in cache until [defaultExpirationTimeInSeconds] async getCreationTransaction( - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise> { try { const cacheDir = CacheRouter.getCreationTransactionCacheDir({ @@ -822,7 +823,7 @@ export class TransactionApi implements ITransactionApi { } async getCreationTransactionWithNoCache( - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise> { try { const url = `${this.baseUrl}/api/v1/safes/${safeAddress}/creation/`; @@ -836,7 +837,7 @@ export class TransactionApi implements ITransactionApi { } async getAllTransactions(args: { - safeAddress: `0x${string}`; + safeAddress: Address; ordering?: string; executed?: boolean; queued?: boolean; @@ -870,7 +871,7 @@ export class TransactionApi implements ITransactionApi { } } - async clearAllTransactions(safeAddress: `0x${string}`): Promise { + async clearAllTransactions(safeAddress: Address): Promise { const key = CacheRouter.getAllTransactionsKey({ chainId: this.chainId, safeAddress, @@ -880,7 +881,7 @@ export class TransactionApi implements ITransactionApi { // Important: there is no hook which invalidates this endpoint, // Therefore, this data will live in cache until [defaultExpirationTimeInSeconds] - async getToken(address: `0x${string}`): Promise> { + async getToken(address: Address): Promise> { try { const cacheDir = CacheRouter.getTokenCacheDir({ chainId: this.chainId, @@ -929,7 +930,7 @@ export class TransactionApi implements ITransactionApi { // Important: there is no hook which invalidates this endpoint, // Therefore, this data will live in cache until [ownersExpirationTimeSeconds] - async getSafesByOwner(ownerAddress: `0x${string}`): Promise> { + async getSafesByOwner(ownerAddress: Address): Promise> { try { const cacheDir = CacheRouter.getSafesByOwnerCacheDir({ chainId: this.chainId, @@ -948,7 +949,7 @@ export class TransactionApi implements ITransactionApi { } async getEstimation(args: { - address: `0x${string}`; + address: Address; getEstimationDto: GetEstimationDto; }): Promise> { try { @@ -989,7 +990,7 @@ export class TransactionApi implements ITransactionApi { } async getMessagesBySafe(args: { - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number | undefined; offset?: number | undefined; }): Promise>> { @@ -1017,7 +1018,7 @@ export class TransactionApi implements ITransactionApi { } async postMultisigTransaction(args: { - address: `0x${string}`; + address: Address; data: ProposeTransactionDto; }): Promise { try { @@ -1047,7 +1048,7 @@ export class TransactionApi implements ITransactionApi { } async postMessage(args: { - safeAddress: `0x${string}`; + safeAddress: Address; message: unknown; safeAppId: number | null; signature: string; @@ -1088,9 +1089,7 @@ export class TransactionApi implements ITransactionApi { } } - async clearMessagesBySafe(args: { - safeAddress: `0x${string}`; - }): Promise { + async clearMessagesBySafe(args: { safeAddress: Address }): Promise { const key = CacheRouter.getMessagesBySafeCacheKey({ chainId: this.chainId, safeAddress: args.safeAddress, diff --git a/src/datasources/users/entities/member.entity.db.ts b/src/datasources/users/entities/member.entity.db.ts index 7b40af7585..68873a9eeb 100644 --- a/src/datasources/users/entities/member.entity.db.ts +++ b/src/datasources/users/entities/member.entity.db.ts @@ -17,6 +17,7 @@ import { PrimaryGeneratedColumn, Unique, } from 'typeorm'; +import type { Address } from 'viem'; @Entity('members') @Unique('UQ_members', ['user', 'space']) @@ -75,7 +76,7 @@ export class Member implements DomainMember { nullable: true, transformer: nullableDatabaseAddressTransformer, }) - invitedBy!: `0x${string}` | null; + invitedBy!: Address | null; @Column({ name: 'created_at', diff --git a/src/datasources/wallets/entities/wallets.entity.db.ts b/src/datasources/wallets/entities/wallets.entity.db.ts index 233fed62ca..f33f9d775b 100644 --- a/src/datasources/wallets/entities/wallets.entity.db.ts +++ b/src/datasources/wallets/entities/wallets.entity.db.ts @@ -10,6 +10,7 @@ import { z } from 'zod'; import { User } from '@/datasources/users/entities/users.entity.db'; import { WalletSchema } from '@/domain/wallets/entities/wallet.entity'; import { databaseAddressTransformer } from '@/domain/common/transformers/databaseAddress.transformer'; +import type { Address } from 'viem'; @Entity('wallets') @Unique('UQ_wallet_address', ['address']) @@ -32,7 +33,7 @@ export class Wallet implements z.infer { length: 42, transformer: databaseAddressTransformer, }) - address!: `0x${string}`; + address!: Address; @Column({ name: 'created_at', diff --git a/src/domain/accounts/accounts.repository.interface.ts b/src/domain/accounts/accounts.repository.interface.ts index 3f1a50b079..769ef82a9c 100644 --- a/src/domain/accounts/accounts.repository.interface.ts +++ b/src/domain/accounts/accounts.repository.interface.ts @@ -8,6 +8,7 @@ import { UpsertAccountDataSettingsDto } from '@/domain/accounts/entities/upsert- import { AuthPayload } from '@/domain/auth/entities/auth-payload.entity'; import { Module } from '@nestjs/common'; import { Request } from 'express'; +import type { Address } from 'viem'; export const IAccountsRepository = Symbol('IAccountsRepository'); @@ -20,24 +21,24 @@ export interface IAccountsRepository { getAccount(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise; deleteAccount(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise; getDataTypes(): Promise>; getAccountDataSettings(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise>; upsertAccountDataSettings(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; upsertAccountDataSettingsDto: UpsertAccountDataSettingsDto; }): Promise>; } diff --git a/src/domain/accounts/accounts.repository.ts b/src/domain/accounts/accounts.repository.ts index def134a5c4..392605b567 100644 --- a/src/domain/accounts/accounts.repository.ts +++ b/src/domain/accounts/accounts.repository.ts @@ -11,6 +11,7 @@ import { AuthPayload } from '@/domain/auth/entities/auth-payload.entity'; import { IAccountsDatasource } from '@/domain/interfaces/accounts.datasource.interface'; import { Inject, Injectable, UnauthorizedException } from '@nestjs/common'; import { Request } from 'express'; +import type { Address } from 'viem'; @Injectable() export class AccountsRepository implements IAccountsRepository { @@ -39,7 +40,7 @@ export class AccountsRepository implements IAccountsRepository { async getAccount(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise { if (!args.authPayload.isForSigner(args.address)) { throw new UnauthorizedException(); @@ -50,7 +51,7 @@ export class AccountsRepository implements IAccountsRepository { async deleteAccount(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise { if (!args.authPayload.isForSigner(args.address)) { throw new UnauthorizedException(); @@ -64,7 +65,7 @@ export class AccountsRepository implements IAccountsRepository { async getAccountDataSettings(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise> { if (!args.authPayload.isForSigner(args.address)) { throw new UnauthorizedException(); @@ -75,7 +76,7 @@ export class AccountsRepository implements IAccountsRepository { async upsertAccountDataSettings(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; upsertAccountDataSettingsDto: UpsertAccountDataSettingsDto; }): Promise> { const { address, upsertAccountDataSettingsDto } = args; diff --git a/src/domain/accounts/address-books/address-books.repository.interface.ts b/src/domain/accounts/address-books/address-books.repository.interface.ts index 7e9c30aca3..b1724f1615 100644 --- a/src/domain/accounts/address-books/address-books.repository.interface.ts +++ b/src/domain/accounts/address-books/address-books.repository.interface.ts @@ -8,32 +8,33 @@ import type { import { CreateAddressBookItemDto } from '@/domain/accounts/address-books/entities/create-address-book-item.dto.entity'; import { AuthPayload } from '@/domain/auth/entities/auth-payload.entity'; import { Module } from '@nestjs/common'; +import type { Address } from 'viem'; export const IAddressBooksRepository = Symbol.for('IAddressBooksRepository'); export interface IAddressBooksRepository { getAddressBook(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; }): Promise; createAddressBookItem(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; createAddressBookItemDto: CreateAddressBookItemDto; }): Promise; deleteAddressBook(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; }): Promise; deleteAddressBookItem(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; addressBookItemId: number; }): Promise; diff --git a/src/domain/accounts/address-books/address-books.repository.ts b/src/domain/accounts/address-books/address-books.repository.ts index 265d7f05e4..0a5956f564 100644 --- a/src/domain/accounts/address-books/address-books.repository.ts +++ b/src/domain/accounts/address-books/address-books.repository.ts @@ -18,6 +18,7 @@ import { Injectable, UnauthorizedException, } from '@nestjs/common'; +import type { Address } from 'viem'; @Injectable() export class AddressBooksRepository implements IAddressBooksRepository { @@ -35,7 +36,7 @@ export class AddressBooksRepository implements IAddressBooksRepository { */ async getAddressBook(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; }): Promise { if (!args.authPayload.isForSigner(args.address)) { @@ -63,7 +64,7 @@ export class AddressBooksRepository implements IAddressBooksRepository { */ async createAddressBookItem(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; createAddressBookItemDto: CreateAddressBookItemDto; }): Promise { @@ -88,7 +89,7 @@ export class AddressBooksRepository implements IAddressBooksRepository { async deleteAddressBook(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; }): Promise { if (!args.authPayload.isForSigner(args.address)) { @@ -111,7 +112,7 @@ export class AddressBooksRepository implements IAddressBooksRepository { async deleteAddressBookItem(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; addressBookItemId: number; }): Promise { @@ -139,7 +140,7 @@ export class AddressBooksRepository implements IAddressBooksRepository { // TODO: Extract this functionality in AccountsRepository['checkIsEnabled(DataType, Account)'] private async checkAddressBooksIsEnabled(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise { const addressBookDataType = await this.checkAddressBookDataTypeIsActive(); const accountDataSettings = diff --git a/src/domain/accounts/address-books/entities/create-address-book-item.dto.entity.ts b/src/domain/accounts/address-books/entities/create-address-book-item.dto.entity.ts index f258844b22..0e13061571 100644 --- a/src/domain/accounts/address-books/entities/create-address-book-item.dto.entity.ts +++ b/src/domain/accounts/address-books/entities/create-address-book-item.dto.entity.ts @@ -1,6 +1,7 @@ import { NameSchema } from '@/domain/common/entities/name.schema'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { z } from 'zod'; +import type { Address } from 'viem'; export const CreateAddressBookItemDtoSchema = z.object({ name: NameSchema, @@ -11,7 +12,7 @@ export class CreateAddressBookItemDto implements z.infer { name: string; - address: `0x${string}`; + address: Address; constructor(props: CreateAddressBookItemDto) { this.name = props.name; diff --git a/src/domain/accounts/address-books/entities/update-address-book.item.dto.entity.ts b/src/domain/accounts/address-books/entities/update-address-book.item.dto.entity.ts index 81a18e7fff..be59089c2d 100644 --- a/src/domain/accounts/address-books/entities/update-address-book.item.dto.entity.ts +++ b/src/domain/accounts/address-books/entities/update-address-book.item.dto.entity.ts @@ -1,4 +1,5 @@ import { z } from 'zod'; +import type { Address } from 'viem'; export const UpdateAddressBookItemDtoSchema = z.object({ id: z.number(), @@ -11,7 +12,7 @@ export class UpdateAddressBookItemDto { id: number; name: string; - address: `0x${string}`; + address: Address; constructor(props: UpdateAddressBookItemDto) { this.id = props.id; diff --git a/src/domain/accounts/counterfactual-safes/counterfactual-safes.repository.interface.ts b/src/domain/accounts/counterfactual-safes/counterfactual-safes.repository.interface.ts index ca95725c71..1cf1cf29ba 100644 --- a/src/domain/accounts/counterfactual-safes/counterfactual-safes.repository.interface.ts +++ b/src/domain/accounts/counterfactual-safes/counterfactual-safes.repository.interface.ts @@ -5,6 +5,7 @@ import { CounterfactualSafe } from '@/domain/accounts/counterfactual-safes/entit import { CreateCounterfactualSafeDto } from '@/domain/accounts/counterfactual-safes/entities/create-counterfactual-safe.dto.entity'; import { AuthPayload } from '@/domain/auth/entities/auth-payload.entity'; import { Module } from '@nestjs/common'; +import type { Address } from 'viem'; export const ICounterfactualSafesRepository = Symbol( 'ICounterfactualSafesRepository', @@ -12,31 +13,29 @@ export const ICounterfactualSafesRepository = Symbol( export interface ICounterfactualSafesRepository { getCounterfactualSafe(args: { - address: `0x${string}`; + address: Address; chainId: string; - predictedAddress: `0x${string}`; + predictedAddress: Address; }): Promise; - getCounterfactualSafes( - address: `0x${string}`, - ): Promise>; + getCounterfactualSafes(address: Address): Promise>; createCounterfactualSafe(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; createCounterfactualSafeDto: CreateCounterfactualSafeDto; }): Promise; deleteCounterfactualSafe(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; - predictedAddress: `0x${string}`; + predictedAddress: Address; }): Promise; deleteCounterfactualSafes(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise; } diff --git a/src/domain/accounts/counterfactual-safes/counterfactual-safes.repository.ts b/src/domain/accounts/counterfactual-safes/counterfactual-safes.repository.ts index 49e2759c4c..42e345a7b5 100644 --- a/src/domain/accounts/counterfactual-safes/counterfactual-safes.repository.ts +++ b/src/domain/accounts/counterfactual-safes/counterfactual-safes.repository.ts @@ -16,6 +16,7 @@ import { NotFoundException, UnauthorizedException, } from '@nestjs/common'; +import type { Address } from 'viem'; @Injectable() export class CounterfactualSafesRepository @@ -34,9 +35,9 @@ export class CounterfactualSafesRepository * Checks that the account has the CounterfactualSafes data setting enabled. */ async getCounterfactualSafe(args: { - address: `0x${string}`; + address: Address; chainId: string; - predictedAddress: `0x${string}`; + predictedAddress: Address; }): Promise { return this.datasource.getCounterfactualSafe(args); } @@ -46,7 +47,7 @@ export class CounterfactualSafesRepository * Checks that the account has the CounterfactualSafes data setting enabled. */ async getCounterfactualSafes( - address: `0x${string}`, + address: Address, ): Promise> { return this.datasource.getCounterfactualSafesForAddress(address); } @@ -60,7 +61,7 @@ export class CounterfactualSafesRepository */ async createCounterfactualSafe(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; createCounterfactualSafeDto: CreateCounterfactualSafeDto; }): Promise { if (!args.authPayload.isForSigner(args.address)) { @@ -98,9 +99,9 @@ export class CounterfactualSafesRepository */ async deleteCounterfactualSafe(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; - predictedAddress: `0x${string}`; + predictedAddress: Address; }): Promise { if (!args.authPayload.isForSigner(args.address)) { throw new UnauthorizedException(); @@ -126,7 +127,7 @@ export class CounterfactualSafesRepository */ async deleteCounterfactualSafes(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise { if (!args.authPayload.isForSigner(args.address)) { throw new UnauthorizedException(); @@ -145,7 +146,7 @@ export class CounterfactualSafesRepository // TODO: Extract this functionality in AccountsRepository['checkIsEnabled(DataType, Account)'] private async checkCounterfactualSafesIsEnabled(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise { const counterfactualSafeDataType = await this.checkCounterfactualSafeDataTypeIsActive(); diff --git a/src/domain/accounts/counterfactual-safes/entities/create-counterfactual-safe.dto.entity.ts b/src/domain/accounts/counterfactual-safes/entities/create-counterfactual-safe.dto.entity.ts index 1fcab93e03..3a523c47da 100644 --- a/src/domain/accounts/counterfactual-safes/entities/create-counterfactual-safe.dto.entity.ts +++ b/src/domain/accounts/counterfactual-safes/entities/create-counterfactual-safe.dto.entity.ts @@ -1,15 +1,16 @@ import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { z } from 'zod'; +import type { Address } from 'viem'; export class CreateCounterfactualSafeDto implements z.infer { chainId: string; - fallbackHandler: `0x${string}`; - owners: Array<`0x${string}`>; - predictedAddress: `0x${string}`; + fallbackHandler: Address; + owners: Array
; + predictedAddress: Address; saltNonce: string; - singletonAddress: `0x${string}`; + singletonAddress: Address; threshold: number; constructor(props: CreateCounterfactualSafeDto) { diff --git a/src/domain/accounts/entities/create-account.dto.entity.ts b/src/domain/accounts/entities/create-account.dto.entity.ts index 2c64aebc0f..a1c3587228 100644 --- a/src/domain/accounts/entities/create-account.dto.entity.ts +++ b/src/domain/accounts/entities/create-account.dto.entity.ts @@ -1,6 +1,7 @@ import { NameSchema } from '@/domain/common/entities/name.schema'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { z } from 'zod'; +import type { Address } from 'viem'; export const CreateAccountDtoSchema = z.object({ address: AddressSchema, @@ -10,7 +11,7 @@ export const CreateAccountDtoSchema = z.object({ export class CreateAccountDto implements z.infer { - address: `0x${string}`; + address: Address; name: string; constructor(props: CreateAccountDto) { diff --git a/src/domain/alerts/alerts.repository.ts b/src/domain/alerts/alerts.repository.ts index 4c1e78abfc..04065840fe 100644 --- a/src/domain/alerts/alerts.repository.ts +++ b/src/domain/alerts/alerts.repository.ts @@ -1,5 +1,5 @@ import { Inject, Injectable } from '@nestjs/common'; -import { Hex } from 'viem'; +import { type Hex } from 'viem'; import { IAlertsRepository } from '@/domain/alerts/alerts.repository.interface'; import { IAlertsApi } from '@/domain/interfaces/alerts-api.interface'; import { AlertsRegistration } from '@/domain/alerts/entities/alerts-registration.entity'; diff --git a/src/domain/alerts/contracts/__tests__/encoders/delay-modifier-encoder.builder.ts b/src/domain/alerts/contracts/__tests__/encoders/delay-modifier-encoder.builder.ts index d6eec777c6..916f3c0421 100644 --- a/src/domain/alerts/contracts/__tests__/encoders/delay-modifier-encoder.builder.ts +++ b/src/domain/alerts/contracts/__tests__/encoders/delay-modifier-encoder.builder.ts @@ -1,6 +1,6 @@ import type { IEncoder } from '@/__tests__/encoder-builder'; import { faker } from '@faker-js/faker'; -import type { Hex } from 'viem'; +import type { Address, Hash, Hex } from 'viem'; import { encodeAbiParameters, encodeEventTopics, @@ -17,7 +17,7 @@ import { DelayModifierAbi } from '@/domain/alerts/contracts/decoders/delay-modif type TransactionAddedEventArgs = { queueNonce: bigint; - txHash: Hex; + txHash: Hash; to: Hex; value: bigint; data: Hex; @@ -82,9 +82,9 @@ export function transactionAddedEventBuilder(): TransactionAddedEventBuilder extends Builder implements IEncoder { - encode(): `0x${string}` { + encode(): Address { const args = this.build(); return encodeFunctionData({ @@ -107,16 +107,16 @@ export function execTransactionFromModuleEncoder(): ExecTransactionFromModuleEnc return new ExecTransactionFromModuleEncoder() .with('to', getAddress(faker.finance.ethereumAddress())) .with('value', faker.number.bigInt()) - .with('data', faker.string.hexadecimal() as `0x${string}`) + .with('data', faker.string.hexadecimal() as Hex) .with('operation', faker.helpers.arrayElement([0, 1])); } // executeNextTx type ExecNextTxArgs = { - to: `0x${string}`; + to: Address; value: bigint; - data: `0x${string}`; + data: Address; operation: 0 | 1; }; @@ -124,7 +124,7 @@ class ExecNextTxEncoder extends Builder implements IEncoder { - encode(): `0x${string}` { + encode(): Address { const args = this.build(); return encodeFunctionData({ @@ -139,6 +139,6 @@ export function executeNextTxEncoder(): ExecNextTxEncoder { return new ExecNextTxEncoder() .with('to', getAddress(faker.finance.ethereumAddress())) .with('value', faker.number.bigInt()) - .with('data', faker.string.hexadecimal() as `0x${string}`) + .with('data', faker.string.hexadecimal() as Hex) .with('operation', faker.helpers.arrayElement([0, 1])); } diff --git a/src/domain/alerts/entities/alerts-deletion.entity.ts b/src/domain/alerts/entities/alerts-deletion.entity.ts index 4e24b7884e..11c4dfdbc6 100644 --- a/src/domain/alerts/entities/alerts-deletion.entity.ts +++ b/src/domain/alerts/entities/alerts-deletion.entity.ts @@ -1,4 +1,6 @@ +import type { Address } from 'viem'; + export type AlertsDeletion = { chainId: string; - address: `0x${string}`; + address: Address; }; diff --git a/src/domain/alerts/entities/alerts-registration.entity.ts b/src/domain/alerts/entities/alerts-registration.entity.ts index d211518098..d981c80d2d 100644 --- a/src/domain/alerts/entities/alerts-registration.entity.ts +++ b/src/domain/alerts/entities/alerts-registration.entity.ts @@ -1,5 +1,7 @@ +import type { Address } from 'viem'; + export type AlertsRegistration = { - address: `0x${string}`; + address: Address; chainId: string; // {chainId}:{safeAddress}:{moduleAddress} displayName?: `${string}:${string}:${string}`; diff --git a/src/domain/auth/entities/__tests__/auth-payload.entity.spec.ts b/src/domain/auth/entities/__tests__/auth-payload.entity.spec.ts index 16a77a23ba..7b2d79a7d8 100644 --- a/src/domain/auth/entities/__tests__/auth-payload.entity.spec.ts +++ b/src/domain/auth/entities/__tests__/auth-payload.entity.spec.ts @@ -4,7 +4,7 @@ import { } from '@/domain/auth/entities/auth-payload.entity'; import { authPayloadDtoBuilder } from '@/domain/auth/entities/__tests__/auth-payload-dto.entity.builder'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; describe('AuthPayload entity', () => { describe('AuthPayload', () => { @@ -51,7 +51,7 @@ describe('AuthPayload entity', () => { const authPayloadDto = authPayloadDtoBuilder() .with( 'signer_address', - faker.finance.ethereumAddress().toLowerCase() as `0x${string}`, + faker.finance.ethereumAddress().toLowerCase() as Address, ) .build(); const authPayload = new AuthPayload(authPayloadDto); @@ -66,7 +66,7 @@ describe('AuthPayload entity', () => { .with('signer_address', getAddress(faker.finance.ethereumAddress())) .build(); const signerAddress = - authPayloadDto.signer_address.toLowerCase() as `0x${string}`; + authPayloadDto.signer_address.toLowerCase() as Address; const authPayload = new AuthPayload(authPayloadDto); const result = authPayload.isForSigner(signerAddress); @@ -78,7 +78,7 @@ describe('AuthPayload entity', () => { const authPayloadDto = authPayloadDtoBuilder() .with( 'signer_address', - faker.finance.ethereumAddress().toLowerCase() as `0x${string}`, + faker.finance.ethereumAddress().toLowerCase() as Address, ) .build(); const signerAddress = getAddress(authPayloadDto.signer_address); @@ -119,7 +119,7 @@ describe('AuthPayload entity', () => { .ethereumAddress() .toLowerCase(); const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', nonChecksummedAddress as `0x${string}`) + .with('signer_address', nonChecksummedAddress as Address) .build(); const result = AuthPayloadDtoSchema.safeParse(authPayloadDto); @@ -148,7 +148,7 @@ describe('AuthPayload entity', () => { it('should not allow a non-address signer_address', () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', faker.lorem.word() as `0x${string}`) + .with('signer_address', faker.lorem.word() as Address) .build(); const result = AuthPayloadDtoSchema.safeParse(authPayloadDto); diff --git a/src/domain/auth/entities/auth-payload.entity.ts b/src/domain/auth/entities/auth-payload.entity.ts index f41089c338..4f6b2d3430 100644 --- a/src/domain/auth/entities/auth-payload.entity.ts +++ b/src/domain/auth/entities/auth-payload.entity.ts @@ -1,6 +1,7 @@ import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { NumericStringSchema } from '@/validation/entities/schemas/numeric-string.schema'; import { z } from 'zod'; +import type { Address } from 'viem'; export type AuthPayloadDto = z.infer; @@ -13,7 +14,7 @@ export const AuthPayloadDtoSchema = z.object({ // the `Auth` decorator, should there not be a payload export class AuthPayload implements Partial { chain_id?: string; - signer_address?: `0x${string}`; + signer_address?: Address; constructor(props?: AuthPayloadDto) { this.chain_id = props?.chain_id; @@ -24,7 +25,7 @@ export class AuthPayload implements Partial { return !!this.chain_id && this.chain_id === chainId; } - isForSigner(signerAddress: `0x${string}`): boolean { + isForSigner(signerAddress: Address): boolean { return ( !!this.signer_address && // Lowercase ensures a mixture of (non-)checksummed addresses are compared correctly diff --git a/src/domain/balances/balances.repository.interface.ts b/src/domain/balances/balances.repository.interface.ts index 71094f5976..8e2573a7a8 100644 --- a/src/domain/balances/balances.repository.interface.ts +++ b/src/domain/balances/balances.repository.interface.ts @@ -3,6 +3,7 @@ import { Module } from '@nestjs/common'; import { BalancesRepository } from '@/domain/balances/balances.repository'; import { BalancesApiModule } from '@/datasources/balances-api/balances-api.module'; import { Chain } from '@/domain/chains/entities/chain.entity'; +import type { Address } from 'viem'; export const IBalancesRepository = Symbol('IBalancesRepository'); @@ -13,7 +14,7 @@ export interface IBalancesRepository { */ getBalances(args: { chain: Chain; - safeAddress: `0x${string}`; + safeAddress: Address; fiatCode: string; trusted?: boolean; excludeSpam?: boolean; @@ -22,10 +23,7 @@ export interface IBalancesRepository { /** * Clears any stored local balance data of {@link safeAddress} on {@link chainId} */ - clearBalances(args: { - chainId: string; - safeAddress: `0x${string}`; - }): Promise; + clearBalances(args: { chainId: string; safeAddress: Address }): Promise; /** * Gets the list of supported fiat codes. diff --git a/src/domain/balances/balances.repository.ts b/src/domain/balances/balances.repository.ts index f26036091c..e91985fe64 100644 --- a/src/domain/balances/balances.repository.ts +++ b/src/domain/balances/balances.repository.ts @@ -7,6 +7,7 @@ import { import { IBalancesApiManager } from '@/domain/interfaces/balances-api.manager.interface'; import { Chain } from '@/domain/chains/entities/chain.entity'; import { z } from 'zod'; +import type { Address } from 'viem'; @Injectable() export class BalancesRepository implements IBalancesRepository { @@ -17,7 +18,7 @@ export class BalancesRepository implements IBalancesRepository { async getBalances(args: { chain: Chain; - safeAddress: `0x${string}`; + safeAddress: Address; fiatCode: string; trusted?: boolean; excludeSpam?: boolean; @@ -32,7 +33,7 @@ export class BalancesRepository implements IBalancesRepository { async clearBalances(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const api = await this.balancesApiManager.getApi( args.chainId, diff --git a/src/domain/balances/entities/balance.entity.spec.ts b/src/domain/balances/entities/balance.entity.spec.ts index 66353cd5bd..6344f39af9 100644 --- a/src/domain/balances/entities/balance.entity.spec.ts +++ b/src/domain/balances/entities/balance.entity.spec.ts @@ -5,7 +5,7 @@ import { NativeBalanceSchema, } from '@/domain/balances/entities/balance.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('Balance entity schemas', () => { @@ -65,7 +65,7 @@ describe('Balance entity schemas', () => { it('should checksum the tokenAddress', () => { const nonChecksummedTokenAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const erc20Balance = balanceBuilder() .with('tokenAddress', nonChecksummedTokenAddress) .build(); diff --git a/src/domain/bridge/bridge.repository.interface.ts b/src/domain/bridge/bridge.repository.interface.ts index 907f6f1766..67e7b2d3f5 100644 --- a/src/domain/bridge/bridge.repository.interface.ts +++ b/src/domain/bridge/bridge.repository.interface.ts @@ -1,14 +1,15 @@ import type { BridgeName } from '@/domain/bridge/entities/bridge-name.entity'; import type { BridgeStatus } from '@/domain/bridge/entities/bridge-status.entity'; +import type { Address, Hash } from 'viem'; export const IBridgeRepository = Symbol('IBridgeRepository'); export interface IBridgeRepository { - getDiamondAddress(chainId: string): Promise<`0x${string}`>; + getDiamondAddress(chainId: string): Promise
; getStatus(args: { fromChain: string; - txHash: `0x${string}`; + txHash: Hash; bridge?: BridgeName; toChain?: string; }): Promise; diff --git a/src/domain/bridge/bridge.repository.ts b/src/domain/bridge/bridge.repository.ts index c741b06874..4e05b1638c 100644 --- a/src/domain/bridge/bridge.repository.ts +++ b/src/domain/bridge/bridge.repository.ts @@ -7,6 +7,7 @@ import { import { IBridgeApiFactory } from '@/domain/interfaces/bridge-api.factory.interface'; import { BridgeName } from '@/domain/bridge/entities/bridge-name.entity'; import { BridgeChainPageSchema } from '@/domain/bridge/entities/bridge-chain.entity'; +import type { Address, Hash } from 'viem'; @Injectable() export class BridgeRepository implements IBridgeRepository { @@ -15,7 +16,7 @@ export class BridgeRepository implements IBridgeRepository { private readonly bridgeApiFactory: IBridgeApiFactory, ) {} - public async getDiamondAddress(chainId: string): Promise<`0x${string}`> { + public async getDiamondAddress(chainId: string): Promise
{ const api = await this.bridgeApiFactory.getApi(chainId); const result = await api.getChains(); const { chains } = BridgeChainPageSchema.parse(result); @@ -31,7 +32,7 @@ export class BridgeRepository implements IBridgeRepository { } async getStatus(args: { - txHash: `0x${string}`; + txHash: Hash; bridge?: BridgeName; fromChain: string; toChain?: string; diff --git a/src/domain/bridge/contracts/decoders/__tests__/across-v3-encoder.builder.ts b/src/domain/bridge/contracts/decoders/__tests__/across-v3-encoder.builder.ts index 3b0011988a..0d5b4f54a7 100644 --- a/src/domain/bridge/contracts/decoders/__tests__/across-v3-encoder.builder.ts +++ b/src/domain/bridge/contracts/decoders/__tests__/across-v3-encoder.builder.ts @@ -1,6 +1,11 @@ import { faker } from '@faker-js/faker'; import { encodeFunctionData, getAddress, parseAbi } from 'viem'; -import type { AbiParameter, AbiParameterToPrimitiveType, Hex } from 'viem'; +import type { + AbiParameter, + AbiParameterToPrimitiveType, + Address, + Hex, +} from 'viem'; import type { ParseStructs } from 'abitype/dist/types/human-readable/types/structs'; import { Builder } from '@/__tests__/builder'; @@ -181,10 +186,10 @@ export function swapAndStartBridgeTokensViaAcrossV3Encoder(): SwapAndStartBridge abi: LiFiDecoder.FeeCollectorAbi, functionName: 'collectTokenFees', args: [ - faker.finance.ethereumAddress() as `0x${string}`, + faker.finance.ethereumAddress() as Address, faker.number.bigInt(), faker.number.bigInt(), - faker.finance.ethereumAddress() as `0x${string}`, + faker.finance.ethereumAddress() as Address, ], }), ) diff --git a/src/domain/bridge/entities/__tests__/bridge-status.builder.ts b/src/domain/bridge/entities/__tests__/bridge-status.builder.ts index 4c617553c5..ef141af535 100644 --- a/src/domain/bridge/entities/__tests__/bridge-status.builder.ts +++ b/src/domain/bridge/entities/__tests__/bridge-status.builder.ts @@ -17,6 +17,7 @@ import type { TransferMetadata, } from '@/domain/bridge/entities/bridge-status.entity'; import { tokenBuilder } from '@/domain/bridge/entities/__tests__/token.builder'; +import type { Address, Hash, Hex } from 'viem'; export function baseStatusDataBuilder< T extends SuccessStatusData | FailedStatusData | PendingStatusData, @@ -37,7 +38,7 @@ export function baseTransactionInfoBuilder< T extends BaseTransactionInfo | ExtendedTransactionInfo = BaseTransactionInfo, >(): IBuilder { return new Builder() - .with('txHash', faker.string.hexadecimal({ length: 64 }) as `0x${string}`) + .with('txHash', faker.string.hexadecimal({ length: 64 }) as Hash) .with('chainId', faker.string.numeric()) .with('txLink', faker.internet.url({ appendSlash: false })); } @@ -75,14 +76,11 @@ export function successStatusDataBuilder< >(): IBuilder { return baseStatusDataBuilder() .with('status', 'DONE') - .with('toAddress', faker.finance.ethereumAddress() as `0x${string}`) - .with('fromAddress', faker.finance.ethereumAddress() as `0x${string}`) + .with('toAddress', faker.finance.ethereumAddress() as Address) + .with('fromAddress', faker.finance.ethereumAddress() as Address) .with('substatus', faker.helpers.arrayElement([...SubstatusesDone])) .with('receiving', extendedTransactionInfoBuilder().build()) - .with( - 'transactionId', - faker.string.hexadecimal({ length: 64 }) as `0x${string}`, - ) + .with('transactionId', faker.string.hexadecimal({ length: 64 }) as Hex) .with('metadata', transferMetadataBuilder().build()) .with('bridgeExplorerLink', faker.internet.url({ appendSlash: false })) .with('lifiExplorerLink', faker.internet.url({ appendSlash: false })); diff --git a/src/domain/bridge/entities/bridge-chain.entity.spec.ts b/src/domain/bridge/entities/bridge-chain.entity.spec.ts index ea8de3f1d0..fb606ad97c 100644 --- a/src/domain/bridge/entities/bridge-chain.entity.spec.ts +++ b/src/domain/bridge/entities/bridge-chain.entity.spec.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { bridgeChainBuilder } from '@/domain/bridge/entities/__tests__/bridge-chain.builder'; import { BridgeChainSchema } from '@/domain/bridge/entities/bridge-chain.entity'; @@ -26,7 +26,7 @@ describe('BridgeChainSchema', () => { it('should checksum diamondAddress', () => { const nonChecksummedAddress = faker.finance.ethereumAddress().toLowerCase(); const bridgeChain = bridgeChainBuilder() - .with('diamondAddress', nonChecksummedAddress as `0x${string}`) + .with('diamondAddress', nonChecksummedAddress as Address) .build(); const result = BridgeChainSchema.safeParse(bridgeChain); @@ -61,7 +61,7 @@ describe('BridgeChainSchema', () => { it('should reject invalid diamondAddress format', () => { const invalidAddress = 'invalid-address'; const bridgeChain = bridgeChainBuilder() - .with('diamondAddress', invalidAddress as `0x${string}`) + .with('diamondAddress', invalidAddress as Address) .build(); const result = BridgeChainSchema.safeParse(bridgeChain); diff --git a/src/domain/bridge/entities/bridge-status.entity.spec.ts b/src/domain/bridge/entities/bridge-status.entity.spec.ts index c64bde0892..2b2e85dc26 100644 --- a/src/domain/bridge/entities/bridge-status.entity.spec.ts +++ b/src/domain/bridge/entities/bridge-status.entity.spec.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { baseStatusDataBuilder, baseTransactionInfoBuilder, @@ -151,7 +151,7 @@ describe('BridgeStatusSchema', () => { .ethereumAddress() .toLowerCase(); const fullStatusData = successStatusDataBuilder() - .with(key, nonChecksummedAddress as `0x${string}`) + .with(key, nonChecksummedAddress as Address) .build(); const result = SuccessStatusDataSchema.safeParse(fullStatusData); diff --git a/src/domain/bridge/entities/token.entity.spec.ts b/src/domain/bridge/entities/token.entity.spec.ts index aeebe5a811..846f719ca8 100644 --- a/src/domain/bridge/entities/token.entity.spec.ts +++ b/src/domain/bridge/entities/token.entity.spec.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { tokenBuilder } from '@/domain/bridge/entities/__tests__/token.builder'; import { TokenSchema } from '@/domain/bridge/entities/token.entity'; @@ -26,7 +26,7 @@ describe('TokenSchema', () => { it('should checksum address', () => { const nonChecksummedAddress = faker.finance.ethereumAddress().toLowerCase(); const token = tokenBuilder() - .with('address', nonChecksummedAddress as `0x${string}`) + .with('address', nonChecksummedAddress as Address) .build(); const result = TokenSchema.safeParse(token); diff --git a/src/domain/chains/entities/__tests__/chain.builder.ts b/src/domain/chains/entities/__tests__/chain.builder.ts index b45e429de0..e36b1be891 100644 --- a/src/domain/chains/entities/__tests__/chain.builder.ts +++ b/src/domain/chains/entities/__tests__/chain.builder.ts @@ -13,6 +13,7 @@ import { pricesProviderBuilder } from '@/domain/chains/entities/__tests__/prices import { balancesProviderBuilder } from '@/domain/chains/entities/__tests__/balances-provider.builder'; import { contractAddressesBuilder } from '@/domain/chains/entities/__tests__/contract-addresses.builder'; import { beaconChainExplorerUriTemplateBuilder } from '@/domain/chains/entities/__tests__/beacon-chain-explorer-uri-template.builder'; +import type { Address } from 'viem'; export function chainBuilder(): IBuilder { return new Builder() @@ -44,10 +45,7 @@ export function chainBuilder(): IBuilder { gasPriceFixedEIP1559Builder().build(), gasPriceOracleBuilder().build(), ]) - .with( - 'ensRegistryAddress', - faker.finance.ethereumAddress() as `0x${string}`, - ) + .with('ensRegistryAddress', faker.finance.ethereumAddress() as Address) .with('disabledWallets', [faker.word.sample(), faker.word.sample()]) .with('features', [faker.word.sample(), faker.word.sample()]) .with('recommendedMasterCopyVersion', faker.system.semver()); diff --git a/src/domain/chains/entities/schemas/__tests__/chain.schema.spec.ts b/src/domain/chains/entities/schemas/__tests__/chain.schema.spec.ts index 5ea2db468c..a9137013b7 100644 --- a/src/domain/chains/entities/schemas/__tests__/chain.schema.spec.ts +++ b/src/domain/chains/entities/schemas/__tests__/chain.schema.spec.ts @@ -27,7 +27,7 @@ import { } from '@/domain/chains/entities/schemas/chain.schema'; import { pageBuilder } from '@/domain/entities/__tests__/page.builder'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('Chain schemas', () => { @@ -518,10 +518,7 @@ describe('Chain schemas', () => { ].forEach((field) => { it(`should checksum the ${field}`, () => { const contractAddresses = contractAddressesBuilder() - .with( - field, - faker.finance.ethereumAddress().toLowerCase() as `0x${string}`, - ) + .with(field, faker.finance.ethereumAddress().toLowerCase() as Address) .build(); const result = ContractAddressesSchema.safeParse(contractAddresses); diff --git a/src/domain/chains/entities/schemas/__tests__/singleton.schema.spec.ts b/src/domain/chains/entities/schemas/__tests__/singleton.schema.spec.ts index 61057f6bc4..9179528833 100644 --- a/src/domain/chains/entities/schemas/__tests__/singleton.schema.spec.ts +++ b/src/domain/chains/entities/schemas/__tests__/singleton.schema.spec.ts @@ -2,7 +2,7 @@ import { singletonBuilder } from '@/domain/chains/entities/__tests__/singleton.b import { SingletonSchema } from '@/domain/chains/entities/schemas/singleton.schema'; import type { Singleton } from '@/domain/chains/entities/singleton.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; describe('SingletonSchema', () => { it('should validate a singleton', () => { @@ -16,7 +16,7 @@ describe('SingletonSchema', () => { it.each(['address' as const])('should checksum %s', (key) => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const singleton = singletonBuilder() .with(key, nonChecksummedAddress) .build(); diff --git a/src/domain/collectibles/collectibles.repository.interface.ts b/src/domain/collectibles/collectibles.repository.interface.ts index dc9e7896c2..4fd07df83e 100644 --- a/src/domain/collectibles/collectibles.repository.interface.ts +++ b/src/domain/collectibles/collectibles.repository.interface.ts @@ -4,13 +4,14 @@ import { Module } from '@nestjs/common'; import { CollectiblesRepository } from '@/domain/collectibles/collectibles.repository'; import { BalancesApiModule } from '@/datasources/balances-api/balances-api.module'; import { Chain } from '@/domain/chains/entities/chain.entity'; +import type { Address } from 'viem'; export const ICollectiblesRepository = Symbol('ICollectiblesRepository'); export interface ICollectiblesRepository { getCollectibles(args: { chain: Chain; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; trusted?: boolean; @@ -19,7 +20,7 @@ export interface ICollectiblesRepository { clearCollectibles(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; } diff --git a/src/domain/collectibles/collectibles.repository.ts b/src/domain/collectibles/collectibles.repository.ts index e2e9c77e1e..aebb263d5a 100644 --- a/src/domain/collectibles/collectibles.repository.ts +++ b/src/domain/collectibles/collectibles.repository.ts @@ -5,6 +5,7 @@ import { Collectible } from '@/domain/collectibles/entities/collectible.entity'; import { Page } from '@/domain/entities/page.entity'; import { IBalancesApiManager } from '@/domain/interfaces/balances-api.manager.interface'; import { Chain } from '@/domain/chains/entities/chain.entity'; +import type { Address } from 'viem'; @Injectable() export class CollectiblesRepository implements ICollectiblesRepository { @@ -15,7 +16,7 @@ export class CollectiblesRepository implements ICollectiblesRepository { async getCollectibles(args: { chain: Chain; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; trusted?: boolean; @@ -31,7 +32,7 @@ export class CollectiblesRepository implements ICollectiblesRepository { async clearCollectibles(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const api = await this.balancesApiManager.getApi( args.chainId, diff --git a/src/domain/collectibles/entities/schemas/__tests__/collectible.schema.spec.ts b/src/domain/collectibles/entities/schemas/__tests__/collectible.schema.spec.ts index e7f01fc28d..9206da93db 100644 --- a/src/domain/collectibles/entities/schemas/__tests__/collectible.schema.spec.ts +++ b/src/domain/collectibles/entities/schemas/__tests__/collectible.schema.spec.ts @@ -1,7 +1,7 @@ import { collectibleBuilder } from '@/domain/collectibles/entities/__tests__/collectible.builder'; import { CollectibleSchema } from '@/domain/collectibles/entities/schemas/collectible.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('CollectibleSchema', () => { @@ -16,7 +16,7 @@ describe('CollectibleSchema', () => { it('should checksum the address', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const collectible = collectibleBuilder() .with('address', nonChecksummedAddress) .build(); diff --git a/src/domain/common/entities/safe-signature.spec.ts b/src/domain/common/entities/safe-signature.spec.ts index caaf41355c..b148e8196d 100644 --- a/src/domain/common/entities/safe-signature.spec.ts +++ b/src/domain/common/entities/safe-signature.spec.ts @@ -9,6 +9,7 @@ import { SIGNATURE_HEX_LENGTH, DYNAMIC_PART_LENGTH_FIELD_HEX_LENGTH, } from '@/domain/common/utils/signatures'; +import type { Hex, Hash } from 'viem'; describe('SafeSignature', () => { it('should create an instance', () => { @@ -25,8 +26,8 @@ describe('SafeSignature', () => { '1f', '20', ]); - const signature = `${baseSignature}${v}` as `0x${string}`; - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const signature = `${baseSignature}${v}` as Hex; + const hash = faker.string.hexadecimal({ length: 66 }) as Hex; expect(() => new SafeSignature({ signature, hash })).not.toThrow(); }); @@ -36,8 +37,8 @@ describe('SafeSignature', () => { .hexadecimal({ length: 130, }) - .slice(2) as `0x${string}`; - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + .slice(2) as Hex; + const hash = faker.string.hexadecimal({ length: 66 }) as Hex; expect(() => new SafeSignature({ signature, hash })).toThrow( new Error('Invalid "0x" notated signature'), @@ -47,8 +48,8 @@ describe('SafeSignature', () => { it('should throw an error if the signature length is not even', () => { const signature = faker.string.hexadecimal({ length: 129, - }) as `0x${string}`; - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + }) as Hex; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; expect(() => new SafeSignature({ signature, hash })).toThrow( new Error('Invalid hex bytes length'), @@ -58,8 +59,8 @@ describe('SafeSignature', () => { it('should throw if the signature length is less than 132', () => { const signature = faker.string.hexadecimal({ length: 128, - }) as `0x${string}`; - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + }) as Hex; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; expect(() => new SafeSignature({ signature, hash })).toThrow( new Error('Invalid signature length'), @@ -69,7 +70,7 @@ describe('SafeSignature', () => { it('should throw if a contract signature has insufficient bytes for the dynamic part length field', async () => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; const signature = await getSignature({ signer, hash, @@ -82,7 +83,7 @@ describe('SafeSignature', () => { signature: signature.slice( 0, SIGNATURE_HEX_LENGTH + DYNAMIC_PART_LENGTH_FIELD_HEX_LENGTH - 2, - ) as `0x${string}`, + ) as Hex, hash, }), ).toThrow(new Error('Insufficient length for dynamic part length field')); @@ -91,7 +92,7 @@ describe('SafeSignature', () => { it('should throw if a contract signature has insufficient bytes for the dynamic part', async () => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; const signature = await getSignature({ signer, hash, @@ -101,7 +102,7 @@ describe('SafeSignature', () => { expect( () => new SafeSignature({ - signature: signature.slice(0, -2) as `0x${string}`, + signature: signature.slice(0, -2) as Hex, hash, }), ).toThrow(new Error('Insufficient length for dynamic part')); @@ -110,7 +111,7 @@ describe('SafeSignature', () => { it('should throw if providing a concatenated signature', async () => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; const signatures = await Promise.all( shuffle(Object.values(SignatureType)).map((signatureType) => { return getSignature({ @@ -133,8 +134,8 @@ describe('SafeSignature', () => { it('should return the r value', () => { const signature = faker.string.hexadecimal({ length: 130, - }) as `0x${string}`; - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + }) as Hex; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; const safeSignature = new SafeSignature({ signature, @@ -147,8 +148,8 @@ describe('SafeSignature', () => { it('should return the s value', () => { const signature = faker.string.hexadecimal({ length: 130, - }) as `0x${string}`; - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + }) as Hex; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; const safeSignature = new SafeSignature({ signature, @@ -161,8 +162,8 @@ describe('SafeSignature', () => { it('should return the v value', () => { const signature = faker.string.hexadecimal({ length: 130, - }) as `0x${string}`; - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + }) as Hex; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; const safeSignature = new SafeSignature({ signature, @@ -174,7 +175,7 @@ describe('SafeSignature', () => { describe('signatureType', () => { it('should return ContractSignature if the v is 0', async () => { - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; const signature = await getSignature({ signer: privateKeyToAccount(generatePrivateKey()), hash, @@ -187,7 +188,7 @@ describe('SafeSignature', () => { }); it('should return ApprovedHash if the v is 1', async () => { - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; const signature = await getSignature({ signer: privateKeyToAccount(generatePrivateKey()), hash, @@ -200,7 +201,7 @@ describe('SafeSignature', () => { }); it('should return EthSign if the v is greater than 30', async () => { - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; const signature = await getSignature({ signer: privateKeyToAccount(generatePrivateKey()), hash, @@ -213,7 +214,7 @@ describe('SafeSignature', () => { }); it('should return Eoa if the v is not any of the above', async () => { - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; const signature = await getSignature({ signer: privateKeyToAccount(generatePrivateKey()), hash, @@ -232,7 +233,7 @@ describe('SafeSignature', () => { async (signatureType) => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; const signature = await getSignature({ signer, hash, @@ -250,7 +251,7 @@ describe('SafeSignature', () => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hash; // Recovered via getAddress const signatureType = faker.helpers.arrayElement([ SignatureType.ApprovedHash, diff --git a/src/domain/common/entities/safe-signature.ts b/src/domain/common/entities/safe-signature.ts index 183c12171e..50203ac34f 100644 --- a/src/domain/common/entities/safe-signature.ts +++ b/src/domain/common/entities/safe-signature.ts @@ -1,6 +1,6 @@ import { secp256k1 } from '@noble/curves/secp256k1'; import { memoize } from 'lodash'; -import { getAddress, hashMessage } from 'viem'; +import { Address, getAddress, hashMessage, Hex } from 'viem'; import { publicKeyToAddress } from 'viem/utils'; import { SignatureType } from '@/domain/common/entities/signature-type.entity'; import { @@ -15,10 +15,10 @@ import { Cron, CronExpression } from '@nestjs/schedule'; const ETH_SIGN_V_OFFSET = 4; export class SafeSignature { - public signature: `0x${string}`; - public hash: `0x${string}`; + public signature: Hex; + public hash: Hex; - constructor(args: { signature: `0x${string}`; hash: `0x${string}` }) { + constructor(args: { signature: Hex; hash: Hex }) { const signatures = parseSignaturesByType(args.signature); if (signatures.length !== 1) { @@ -33,11 +33,11 @@ export class SafeSignature { this.hash = args.hash; } - get r(): `0x${string}` { + get r(): Hex { return `0x${this.signature.slice(HEX_PREFIX_LENGTH, HEX_PREFIX_LENGTH + R_OR_S_HEX_LENGTH)}`; } - get s(): `0x${string}` { + get s(): Hex { const rOffset = HEX_PREFIX_LENGTH + R_OR_S_HEX_LENGTH; return `0x${this.signature.slice(rOffset, rOffset + R_OR_S_HEX_LENGTH)}`; } @@ -60,7 +60,7 @@ export class SafeSignature { return SignatureType.Eoa; } - get owner(): `0x${string}` { + get owner(): Address { return this._owner(); } @@ -75,7 +75,7 @@ export class SafeSignature { case SignatureType.EthSign: { // To differentiate signature types, eth_sign signatures have v value increased by 4 // @see https://docs.safe.global/advanced/smart-account-signatures#eth_sign-signature - const normalizedSignature: `0x${string}` = `${this.r}${this.s.slice(HEX_PREFIX_LENGTH)}${(this.v - ETH_SIGN_V_OFFSET).toString(16)}`; + const normalizedSignature: Hex = `${this.r}${this.s.slice(HEX_PREFIX_LENGTH)}${(this.v - ETH_SIGN_V_OFFSET).toString(16)}`; return recoverAddress({ hash: hashMessage({ raw: this.hash }), signature: normalizedSignature, @@ -107,18 +107,12 @@ export class SafeSignature { } } -function recoverAddress(args: { - hash: `0x${string}`; - signature: `0x${string}`; -}): `0x${string}` { +function recoverAddress(args: { hash: Hex; signature: Hex }): Address { const publicKey = recoverPublicKey(args); return publicKeyToAddress(publicKey); } -function recoverPublicKey(args: { - hash: `0x${string}`; - signature: `0x${string}`; -}): `0x${string}` { +function recoverPublicKey(args: { hash: Hex; signature: Hex }): Hex { const recoveryBit = toRecoveryBit(args.signature); const signature = secp256k1.Signature.fromCompact( args.signature.substring(HEX_PREFIX_LENGTH, SIGNATURE_HEX_LENGTH), @@ -131,7 +125,7 @@ function recoverPublicKey(args: { return `0x${publicKey}`; } -function toRecoveryBit(signature: `0x${string}`): number { +function toRecoveryBit(signature: Hex): number { const v = parseInt(signature.slice(V_HEX_LENGTH * -1), 16); if (v === 0 || v === 1) { return v; diff --git a/src/domain/common/transformers/databaseAddress.transformer.ts b/src/domain/common/transformers/databaseAddress.transformer.ts index 1b5dab6cc9..31f0a40f0e 100644 --- a/src/domain/common/transformers/databaseAddress.transformer.ts +++ b/src/domain/common/transformers/databaseAddress.transformer.ts @@ -1,12 +1,13 @@ import type { ValueTransformer } from 'typeorm'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; // TODO: add tests export const databaseAddressTransformer: ValueTransformer = { - to(value: string): `0x${string}` { + to(value: string): Address { return getAddress(value); }, - from(value: string): `0x${string}` { + from(value: string): Address { return getAddress(value); }, }; diff --git a/src/domain/common/transformers/nullableDatabaseAddress.transformer.ts b/src/domain/common/transformers/nullableDatabaseAddress.transformer.ts index 9637a490cb..60e0ac6ac4 100644 --- a/src/domain/common/transformers/nullableDatabaseAddress.transformer.ts +++ b/src/domain/common/transformers/nullableDatabaseAddress.transformer.ts @@ -1,11 +1,12 @@ import type { ValueTransformer } from 'typeorm'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; export const nullableDatabaseAddressTransformer: ValueTransformer = { - to(value: string | null | undefined): `0x${string}` | null { + to(value: string | null | undefined): Address | null { return value === null || value === undefined ? null : getAddress(value); }, - from(value: string | null): `0x${string}` | null { + from(value: string | null): Address | null { return value === null ? null : getAddress(value); }, }; diff --git a/src/domain/common/utils/__tests__/safe.spec.ts b/src/domain/common/utils/__tests__/safe.spec.ts index 37c34ec3b7..3ea1bc1587 100644 --- a/src/domain/common/utils/__tests__/safe.spec.ts +++ b/src/domain/common/utils/__tests__/safe.spec.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { getAddress, type Hex } from 'viem'; import { Builder } from '@/__tests__/builder'; import { multisigTransactionBuilder } from '@/domain/safe/entities/__tests__/multisig-transaction.builder'; import { Operation } from '@/domain/safe/entities/operation.entity'; @@ -39,7 +39,7 @@ function safeTxHashMultisigTransactionBuilder(): IBuilder() .with('to', getAddress(faker.finance.ethereumAddress())) .with('value', faker.string.numeric()) - .with('data', faker.string.hexadecimal() as `0x${string}`) + .with('data', faker.string.hexadecimal() as Hex) .with('operation', faker.helpers.enumValue(Operation)) .with('safeTxGas', faker.number.int()) .with('baseGas', faker.number.int()) @@ -502,7 +502,7 @@ describe('Safe', () => { const chainId = faker.string.numeric(); const safe = safeBuilder().build(); const transaction = safeTxHashMultisigTransactionBuilder() - .with('to', faker.string.numeric() as `0x${string}`) + .with('to', faker.string.numeric() as Hex) .build(); expect(() => getSafeTxHash({ chainId, transaction, safe })).toThrow( diff --git a/src/domain/common/utils/__tests__/signatures.builder.ts b/src/domain/common/utils/__tests__/signatures.builder.ts index f7e59e806b..e27690dfbd 100644 --- a/src/domain/common/utils/__tests__/signatures.builder.ts +++ b/src/domain/common/utils/__tests__/signatures.builder.ts @@ -1,13 +1,18 @@ import { faker } from '@faker-js/faker'; -import { isAddress, type PrivateKeyAccount } from 'viem'; +import { + type Hex, + type Address, + isAddress, + type PrivateKeyAccount, +} from 'viem'; import { SignatureType } from '@/domain/common/entities/signature-type.entity'; import { DYNAMIC_PART_LENGTH_FIELD_HEX_LENGTH } from '@/domain/common/utils/signatures'; export async function getSignature(args: { signer: PrivateKeyAccount; - hash: `0x${string}`; + hash: Hex; signatureType: SignatureType; -}): Promise<`0x${string}`> { +}): Promise { switch (args.signatureType) { case SignatureType.ContractSignature: { return getContractSignature(args.signer.address); @@ -30,11 +35,11 @@ export async function getSignature(args: { } } -export function getApprovedHashSignature(owner: `0x${string}`): `0x${string}` { +export function getApprovedHashSignature(owner: Address): Hex { return ('0x000000000000000000000000' + owner.slice(2) + '0000000000000000000000000000000000000000000000000000000000000000' + - '01') as `0x${string}`; + '01') as Hex; } /** @@ -45,7 +50,7 @@ export function getApprovedHashSignature(owner: `0x${string}`): `0x${string}` { * @param verifier - the verifier address as a 0x-prefixed hex string * @returns a mock contract signature as a lower-cased hex string */ -export function getContractSignature(verifier: `0x${string}`): `0x${string}` { +export function getContractSignature(verifier: Address): Hex { // For single-signature blob, the pointer is 65, left-padded to 32 bytes const DATA_POINTER = (65).toString(16).padStart(64, '0'); const CONTRACT_SIGNATURE_TYPE = '00'; @@ -75,15 +80,15 @@ export function getContractSignature(verifier: `0x${string}`): `0x${string}` { export async function getEoaSignature(args: { signer: PrivateKeyAccount; - hash: `0x${string}`; -}): Promise<`0x${string}`> { + hash: Hex; +}): Promise { return await args.signer.sign({ hash: args.hash }); } export async function getEthSignSignature(args: { signer: PrivateKeyAccount; - hash: `0x${string}`; -}): Promise<`0x${string}`> { + hash: Hex; +}): Promise { const signature = await args.signer.signMessage({ message: { raw: args.hash }, }); @@ -91,5 +96,5 @@ export async function getEthSignSignature(args: { // To differentiate signature types, eth_sign signatures have v value increased by 4 // @see https://docs.safe.global/advanced/smart-account-signatures#eth_sign-signature const v = parseInt(signature.slice(-2), 16); - return (signature.slice(0, 130) + (v + 4).toString(16)) as `0x${string}`; + return (signature.slice(0, 130) + (v + 4).toString(16)) as Hex; } diff --git a/src/domain/common/utils/__tests__/signatures.spec.ts b/src/domain/common/utils/__tests__/signatures.spec.ts index 76ddfe6729..bde91dabf1 100644 --- a/src/domain/common/utils/__tests__/signatures.spec.ts +++ b/src/domain/common/utils/__tests__/signatures.spec.ts @@ -1,5 +1,6 @@ import { faker } from '@faker-js/faker'; import { shuffle } from 'lodash'; +import type { Address, Hex } from 'viem'; import { concat } from 'viem'; import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'; import { SignatureType } from '@/domain/common/entities/signature-type.entity'; @@ -16,7 +17,7 @@ describe('parseSignaturesByType', () => { async (signatureType) => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hex; const signature = await getSignature({ signer, hash, @@ -32,7 +33,7 @@ describe('parseSignaturesByType', () => { it('should parse concatenated signatures', async () => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hex; const signatures = await Promise.all( shuffle(Object.values(SignatureType)).map((signatureType) => { return getSignature({ signer, hash, signatureType }); @@ -47,7 +48,7 @@ describe('parseSignaturesByType', () => { it('should throw if the signature does not start with 0x', async () => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hex; const signatureType = faker.helpers.enumValue(SignatureType); const signature = await getSignature({ signer, @@ -55,15 +56,15 @@ describe('parseSignaturesByType', () => { signatureType, }); - expect(() => - parseSignaturesByType(signature.slice(2) as `0x${string}`), - ).toThrow('Invalid "0x" notated signature'); + expect(() => parseSignaturesByType(signature.slice(2) as Hex)).toThrow( + 'Invalid "0x" notated signature', + ); }); it('should throw if the signature length is not even', async () => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hex; const signatureType = faker.helpers.enumValue(SignatureType); const signature = await getSignature({ signer, @@ -71,15 +72,15 @@ describe('parseSignaturesByType', () => { signatureType, }); - expect(() => - parseSignaturesByType((signature + '0') as `0x${string}`), - ).toThrow('Invalid hex bytes length'); + expect(() => parseSignaturesByType((signature + '0') as Hex)).toThrow( + 'Invalid hex bytes length', + ); }); it('should throw if the signature length is less than 65 bytes', async () => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hex; const signatureType = faker.helpers.arrayElement([ // Contract signature cannot be last to test static part length check SignatureType.ApprovedHash, @@ -93,14 +94,14 @@ describe('parseSignaturesByType', () => { }); expect(() => - parseSignaturesByType(signature.slice(0, -2) as `0x${string}`), + parseSignaturesByType(signature.slice(0, -2) as Address), ).toThrow('Invalid signature length'); }); it('should throw if a concatenated signature is less than 65 bytes', async () => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hex; const signatures = await Promise.all( [ // Contract signature cannot be last to test static part length check @@ -115,16 +116,14 @@ describe('parseSignaturesByType', () => { const concatenatedSignature = concat(signatures); expect(() => - parseSignaturesByType( - concatenatedSignature.slice(0, -2) as `0x${string}`, - ), + parseSignaturesByType(concatenatedSignature.slice(0, -2) as Address), ).toThrow('Insufficient length for static part'); }); it('should throw if a contract signature has insufficient bytes for the dynamic part length field', async () => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hex; const signature = await getSignature({ signer, hash, @@ -136,7 +135,7 @@ describe('parseSignaturesByType', () => { signature.slice( 0, SIGNATURE_HEX_LENGTH + DYNAMIC_PART_LENGTH_FIELD_HEX_LENGTH - 2, - ) as `0x${string}`, + ) as Hex, ), ).toThrow('Insufficient length for dynamic part length field'); }); @@ -144,7 +143,7 @@ describe('parseSignaturesByType', () => { it('should throw if a concatenated contract signature has insufficient bytes for the dynamic part length field', async () => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hex; const signature = await getSignature({ signer, hash, @@ -158,7 +157,7 @@ describe('parseSignaturesByType', () => { signature.slice( 0, SIGNATURE_HEX_LENGTH + DYNAMIC_PART_LENGTH_FIELD_HEX_LENGTH - 2, - ) as `0x${string}`, + ) as Hex, ]), ), ).toThrow('Insufficient length for dynamic part length field'); @@ -167,7 +166,7 @@ describe('parseSignaturesByType', () => { it('should throw if a contract signature has insufficient bytes for the dynamic part', async () => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hex; const signature = await getSignature({ signer, hash, @@ -175,14 +174,14 @@ describe('parseSignaturesByType', () => { }); expect(() => - parseSignaturesByType(signature.slice(0, -2) as `0x${string}`), + parseSignaturesByType(signature.slice(0, -2) as Address), ).toThrow('Insufficient length for dynamic part'); }); it('should throw if a concatenated contract signature has insufficient bytes for the dynamic part', async () => { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); - const hash = faker.string.hexadecimal({ length: 66 }) as `0x${string}`; + const hash = faker.string.hexadecimal({ length: 66 }) as Hex; const signature = await getSignature({ signer, hash, @@ -190,9 +189,7 @@ describe('parseSignaturesByType', () => { }); expect(() => - parseSignaturesByType( - concat([signature, signature]).slice(0, -2) as `0x${string}`, - ), + parseSignaturesByType(concat([signature, signature]).slice(0, -2) as Hex), ).toThrow('Insufficient length for dynamic part'); }); }); diff --git a/src/domain/common/utils/deployments.ts b/src/domain/common/utils/deployments.ts index a8ad6fe092..01f61d63c5 100644 --- a/src/domain/common/utils/deployments.ts +++ b/src/domain/common/utils/deployments.ts @@ -6,6 +6,7 @@ import { getSafeL2SingletonDeployments as _getSafeL2SingletonDeployments, getSafeSingletonDeployments as _getSafeSingletonDeployments, } from '@safe-global/safe-deployments'; +import type { Address } from 'viem'; type Filter = { chainId: string; @@ -18,9 +19,9 @@ type Filter = { * @param {string} args.chainId - the chain ID to filter deployments by * @param {string} args.version - the version to filter deployments by * - * @returns {Array<`0x${string}`>} - a list of checksummed ProxyFactory addresses + * @returns {Array
} - a list of checksummed ProxyFactory addresses */ -export function getProxyFactoryDeployments(args: Filter): Array<`0x${string}`> { +export function getProxyFactoryDeployments(args: Filter): Array
{ return formatDeployments(_getProxyFactoryDeployments, args); } @@ -30,11 +31,9 @@ export function getProxyFactoryDeployments(args: Filter): Array<`0x${string}`> { * @param {string} args.chainId - the chain ID to filter deployments by * @param {string} args.version - the version to filter deployments by * - * @returns {Array<`0x${string}`>} - a list of checksummed L1 singleton addresses + * @returns {Array
} - a list of checksummed L1 singleton addresses */ -export function getSafeSingletonDeployments( - args: Filter, -): Array<`0x${string}`> { +export function getSafeSingletonDeployments(args: Filter): Array
{ return formatDeployments(_getSafeSingletonDeployments, args); } @@ -44,11 +43,9 @@ export function getSafeSingletonDeployments( * @param {string} args.chainId - the chain ID to filter deployments by * @param {string} args.version - the version to filter deployments by * - * @returns {Array<`0x${string}`>} - a list of checksummed L2 singleton addresses + * @returns {Array
} - a list of checksummed L2 singleton addresses */ -export function getSafeL2SingletonDeployments( - args: Filter, -): Array<`0x${string}`> { +export function getSafeL2SingletonDeployments(args: Filter): Array
{ return formatDeployments(_getSafeL2SingletonDeployments, args); } @@ -58,11 +55,9 @@ export function getSafeL2SingletonDeployments( * @param {string} args.chainId - the chain ID to filter deployments by * @param {string} args.version - the version to filter deployments by * - * @returns {Array<`0x${string}`>} - a list of checksummed MultiSendCallOnly addresses + * @returns {Array
} - a list of checksummed MultiSendCallOnly addresses */ -export function getMultiSendCallOnlyDeployments( - args: Filter, -): Array<`0x${string}`> { +export function getMultiSendCallOnlyDeployments(args: Filter): Array
{ return formatDeployments(_getMultiSendCallOnlyDeployments, args); } @@ -72,9 +67,9 @@ export function getMultiSendCallOnlyDeployments( * @param {string} args.chainId - the chain ID to filter deployments by * @param {string} args.version - the version to filter deployments by * - * @returns {Array<`0x${string}`>} - a list of checksummed MultiSend addresses + * @returns {Array
} - a list of checksummed MultiSend addresses */ -export function getMultiSendDeployments(args: Filter): Array<`0x${string}`> { +export function getMultiSendDeployments(args: Filter): Array
{ return formatDeployments(_getMultiSendDeployments, args); } @@ -84,7 +79,7 @@ export function getMultiSendDeployments(args: Filter): Array<`0x${string}`> { * @param {Function} getDeployments - function to get deployments * @param {Filter} filter - filter to apply to deployments * - * @returns {Array<`0x${string}`>} - a list of checksummed addresses + * @returns {Array
} - a list of checksummed addresses */ function formatDeployments( getDeployments: @@ -94,7 +89,7 @@ function formatDeployments( | typeof _getMultiSendCallOnlyDeployments | typeof _getMultiSendDeployments, filter: Filter, -): Array<`0x${string}`> { +): Array
{ const deployments = getDeployments({ network: filter.chainId, version: filter.version, @@ -111,8 +106,8 @@ function formatDeployments( // Note: can cast as deployment are inherently checksummed if (!Array.isArray(chainDeployments)) { - return [chainDeployments as `0x${string}`]; + return [chainDeployments as Address]; } - return chainDeployments as Array<`0x${string}`>; + return chainDeployments as Array
; } diff --git a/src/domain/common/utils/safe.ts b/src/domain/common/utils/safe.ts index 0aa49e9c82..14e664ac3c 100644 --- a/src/domain/common/utils/safe.ts +++ b/src/domain/common/utils/safe.ts @@ -1,4 +1,5 @@ import semverSatisfies from 'semver/functions/satisfies'; +import type { Address } from 'viem'; import { hashMessage, hashTypedData, zeroAddress } from 'viem'; import { MessageSchema } from '@/domain/messages/entities/message.entity'; import type { MultisigTransaction } from '@/domain/safe/entities/multisig-transaction.entity'; @@ -14,7 +15,7 @@ export function getSafeMessageMessageHash(args: { chainId: string; safe: Safe; message: string | TypedData; -}): `0x${string}` { +}): Address { if (!args.safe.version) { throw new Error('Safe version is required'); } @@ -83,7 +84,7 @@ export function getSafeTxHash(args: { chainId: string; transaction: BaseMultisigTransaction; safe: Safe; -}): `0x${string}` { +}): Address { if (!args.safe.version) { throw new Error('Safe version is required'); } diff --git a/src/domain/common/utils/signatures.ts b/src/domain/common/utils/signatures.ts index 6e265d4d61..f27a76d744 100644 --- a/src/domain/common/utils/signatures.ts +++ b/src/domain/common/utils/signatures.ts @@ -1,6 +1,7 @@ import { HEX_BYTES_LENGTH, HEX_PREFIX_LENGTH } from '@/routes/common/constants'; import { isHexBytes } from '@/validation/entities/schemas/hexbytes.schema'; import { isSignatureLike } from '@/validation/entities/schemas/signature.schema'; +import type { Address, Hex } from 'viem'; export const R_OR_S_HEX_LENGTH = 32 * HEX_BYTES_LENGTH; // 32 bytes in hex export const V_HEX_LENGTH = 1 * HEX_BYTES_LENGTH; // 1 byte in hex @@ -14,9 +15,7 @@ export const DYNAMIC_PART_LENGTH_FIELD_HEX_LENGTH = 32 * HEX_BYTES_LENGTH; // 32 * @param signature - A 0x-prefixed hex string of a (concatenated) signature * @returns An array of 0x-prefixed signature type signatures */ -export function parseSignaturesByType( - signature: `0x${string}`, -): Array<`0x${string}`> { +export function parseSignaturesByType(signature: Hex): Array { // TODO: Replace with viem's isHex and update all tests accordingly if (!signature.startsWith('0x')) { throw new Error('Invalid "0x" notated signature'); @@ -30,7 +29,7 @@ export function parseSignaturesByType( throw new Error('Invalid signature length'); } - const signatures: Array<`0x${string}`> = []; + const signatures: Array
= []; let i = HEX_PREFIX_LENGTH; @@ -60,7 +59,7 @@ export function parseSignaturesByType( return signatures; } -function getStaticPart(signature: `0x${string}`, offset: number): string { +function getStaticPart(signature: Hex, offset: number): string { return signature.slice(offset, offset + SIGNATURE_HEX_LENGTH); } diff --git a/src/domain/common/utils/utils.ts b/src/domain/common/utils/utils.ts index 86b14e9a44..9e9c666b5f 100644 --- a/src/domain/common/utils/utils.ts +++ b/src/domain/common/utils/utils.ts @@ -1,5 +1,6 @@ import { createHash } from 'crypto'; import type { BinaryLike } from 'crypto'; +import type { Address } from 'viem'; // We use the maximum value in order to preserve all decimals // @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat#maximumfractiondigits @@ -18,15 +19,12 @@ export function getNumberString(value: number): string { /** * Truncates an address with a specific lengthed prefix and suffix - * @param {`0x${string}`} address to truncate + * @param {Address} address to truncate * @param {number} [length] of the prefix and suffix, minus hex prefix - * @returns {`0x${string}`} truncated address + * @returns {Address} truncated address */ -export function truncateAddress( - address: `0x${string}`, - length: number = 4, -): `0x${string}` { - return `${address.slice(0, length + 2)}...${address.slice(-length)}` as `0x${string}`; +export function truncateAddress(address: Address, length: number = 4): Address { + return `${address.slice(0, length + 2)}...${address.slice(-length)}` as Address; } export function hashSha1(value: BinaryLike): string { diff --git a/src/domain/community/community.repository.interface.ts b/src/domain/community/community.repository.interface.ts index 23cb8e25c6..6c9c1465e1 100644 --- a/src/domain/community/community.repository.interface.ts +++ b/src/domain/community/community.repository.interface.ts @@ -6,6 +6,7 @@ import type { LockingRank } from '@/domain/community/entities/locking-rank.entit import type { CampaignActivity } from '@/domain/community/entities/campaign-activity.entity'; import type { EligibilityRequest } from '@/domain/community/entities/eligibility-request.entity'; import type { Eligibility } from '@/domain/community/entities/eligibility.entity'; +import type { Address } from 'viem'; export const ICommunityRepository = Symbol('ICommunityRepository'); @@ -19,12 +20,12 @@ export interface ICommunityRepository { getCampaignActivities(args: { resourceId: string; - holder?: `0x${string}`; + holder?: Address; limit?: number; offset?: number; }): Promise>; - getLockingRank(safeAddress: `0x${string}`): Promise; + getLockingRank(safeAddress: Address): Promise; getLeaderboard(args: { limit?: number; @@ -39,11 +40,11 @@ export interface ICommunityRepository { getCampaignRank(args: { resourceId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; getLockingHistory(args: { - safeAddress: `0x${string}`; + safeAddress: Address; offset?: number; limit?: number; }): Promise>; diff --git a/src/domain/community/community.repository.ts b/src/domain/community/community.repository.ts index 04fb5c665f..d23ad95bb2 100644 --- a/src/domain/community/community.repository.ts +++ b/src/domain/community/community.repository.ts @@ -28,6 +28,7 @@ import { Eligibility } from '@/domain/community/entities/eligibility.entity'; import { asError } from '@/logging/utils'; import { LoggingService, ILoggingService } from '@/logging/logging.interface'; import { IIdentityApi } from '@/domain/interfaces/identity-api.interface'; +import type { Address } from 'viem'; @Injectable() export class CommunityRepository implements ICommunityRepository { @@ -54,7 +55,7 @@ export class CommunityRepository implements ICommunityRepository { async getCampaignActivities(args: { resourceId: string; - holder?: `0x${string}`; + holder?: Address; limit?: number; offset?: number; }): Promise> { @@ -62,7 +63,7 @@ export class CommunityRepository implements ICommunityRepository { return CampaignActivityPageSchema.parse(page); } - async getLockingRank(safeAddress: `0x${string}`): Promise { + async getLockingRank(safeAddress: Address): Promise { const lockingRank = await this.lockingApi.getLockingRank(safeAddress); return LockingRankSchema.parse(lockingRank); } @@ -86,14 +87,14 @@ export class CommunityRepository implements ICommunityRepository { async getCampaignRank(args: { resourceId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const campaignRank = await this.lockingApi.getCampaignRank(args); return CampaignRankSchema.parse(campaignRank); } async getLockingHistory(args: { - safeAddress: `0x${string}`; + safeAddress: Address; offset?: number; limit?: number; }): Promise> { diff --git a/src/domain/community/entities/__tests__/locking-event.builder.ts b/src/domain/community/entities/__tests__/locking-event.builder.ts index 85d2bf2f53..46eff5ea64 100644 --- a/src/domain/community/entities/__tests__/locking-event.builder.ts +++ b/src/domain/community/entities/__tests__/locking-event.builder.ts @@ -12,15 +12,14 @@ import type { } from '@/domain/community/entities/schemas/locking-event.schema'; import { LockingEventType } from '@/domain/community/entities/schemas/locking-event.schema'; import { faker } from '@faker-js/faker'; -import type { Hex } from 'viem'; -import { getAddress } from 'viem'; +import { getAddress, type Hash } from 'viem'; import type { z } from 'zod'; export function lockEventItemBuilder(): IBuilder { return new Builder>() .with('eventType', LockingEventType.LOCKED) .with('executionDate', faker.date.recent()) - .with('transactionHash', faker.string.hexadecimal({ length: 64 }) as Hex) + .with('transactionHash', faker.string.hexadecimal({ length: 64 }) as Hash) .with('holder', getAddress(faker.finance.ethereumAddress())) .with('amount', faker.finance.amount()) .with('logIndex', faker.string.numeric()); @@ -30,7 +29,7 @@ export function unlockEventItemBuilder(): IBuilder { return new Builder>() .with('eventType', LockingEventType.UNLOCKED) .with('executionDate', faker.date.recent()) - .with('transactionHash', faker.string.hexadecimal({ length: 64 }) as Hex) + .with('transactionHash', faker.string.hexadecimal({ length: 64 }) as Hash) .with('holder', getAddress(faker.finance.ethereumAddress())) .with('amount', faker.finance.amount()) .with('unlockIndex', faker.string.numeric()) @@ -41,7 +40,7 @@ export function withdrawEventItemBuilder(): IBuilder { return new Builder>() .with('eventType', LockingEventType.WITHDRAWN) .with('executionDate', faker.date.recent()) - .with('transactionHash', faker.string.hexadecimal({ length: 64 }) as Hex) + .with('transactionHash', faker.string.hexadecimal({ length: 64 }) as Hash) .with('holder', getAddress(faker.finance.ethereumAddress())) .with('amount', faker.finance.amount()) .with('unlockIndex', faker.string.numeric()) diff --git a/src/domain/community/entities/schemas/__tests__/campaign-activity.schema.spec.ts b/src/domain/community/entities/schemas/__tests__/campaign-activity.schema.spec.ts index dfcd0ec199..004db25521 100644 --- a/src/domain/community/entities/schemas/__tests__/campaign-activity.schema.spec.ts +++ b/src/domain/community/entities/schemas/__tests__/campaign-activity.schema.spec.ts @@ -1,7 +1,7 @@ import { campaignActivityBuilder } from '@/domain/community/entities/__tests__/campaign-activity.builder'; import { CampaignActivitySchema } from '@/domain/community/entities/campaign-activity.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('CampaignActivitySchema', () => { @@ -15,8 +15,7 @@ describe('CampaignActivitySchema', () => { it('should checksum the holder', () => { const campaignActivity = campaignActivityBuilder().build(); - campaignActivity.holder = - campaignActivity.holder.toLowerCase() as `0x${string}`; + campaignActivity.holder = campaignActivity.holder.toLowerCase() as Address; const result = CampaignActivitySchema.safeParse(campaignActivity); diff --git a/src/domain/community/entities/schemas/__tests__/campaign-rank.schema.spec.ts b/src/domain/community/entities/schemas/__tests__/campaign-rank.schema.spec.ts index 340530da07..826e083f38 100644 --- a/src/domain/community/entities/schemas/__tests__/campaign-rank.schema.spec.ts +++ b/src/domain/community/entities/schemas/__tests__/campaign-rank.schema.spec.ts @@ -1,7 +1,7 @@ import { campaignRankBuilder } from '@/domain/community/entities/__tests__/campaign-rank.builder'; import { CampaignRankSchema } from '@/domain/community/entities/campaign-rank.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('CampaignRankSchema', () => { @@ -16,7 +16,7 @@ describe('CampaignRankSchema', () => { it('should checksum the holder address', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const campaignRank = campaignRankBuilder() .with('holder', nonChecksummedAddress) .build(); diff --git a/src/domain/community/entities/schemas/__tests__/locking-event.schema.spec.ts b/src/domain/community/entities/schemas/__tests__/locking-event.schema.spec.ts index 3cf3d81447..ad3f13a1ae 100644 --- a/src/domain/community/entities/schemas/__tests__/locking-event.schema.spec.ts +++ b/src/domain/community/entities/schemas/__tests__/locking-event.schema.spec.ts @@ -12,7 +12,7 @@ import { WithdrawEventItemSchema, } from '@/domain/community/entities/schemas/locking-event.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('Locking event schemas', () => { @@ -58,7 +58,7 @@ describe('Locking event schemas', () => { it('should not allow non-hex transactionHash', () => { const transactionHash = faker.string.numeric(); const lockEventItem = lockEventItemBuilder() - .with('transactionHash', transactionHash as `0x${string}`) + .with('transactionHash', transactionHash as Address) .build(); const result = LockEventItemSchema.safeParse(lockEventItem); @@ -77,7 +77,7 @@ describe('Locking event schemas', () => { it('should checksum the holder', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const lockEventItem = lockEventItemBuilder() .with('holder', nonChecksummedAddress) .build(); @@ -204,7 +204,7 @@ describe('Locking event schemas', () => { it('should checksum the holder', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const unlockEventItem = unlockEventItemBuilder() .with('holder', nonChecksummedAddress) .build(); @@ -339,7 +339,7 @@ describe('Locking event schemas', () => { it('should checksum the holder', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const withdrawEventItem = withdrawEventItemBuilder() .with('holder', nonChecksummedAddress) .build(); diff --git a/src/domain/community/entities/schemas/__tests__/locking-rank.schema.spec.ts b/src/domain/community/entities/schemas/__tests__/locking-rank.schema.spec.ts index 9310c04ba8..d656e980c2 100644 --- a/src/domain/community/entities/schemas/__tests__/locking-rank.schema.spec.ts +++ b/src/domain/community/entities/schemas/__tests__/locking-rank.schema.spec.ts @@ -1,7 +1,7 @@ import { lockingRankBuilder } from '@/domain/community/entities/__tests__/locking-rank.builder'; import { LockingRankSchema } from '@/domain/community/entities/schemas/locking-rank.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('RankSchema', () => { @@ -16,7 +16,7 @@ describe('RankSchema', () => { it('should checksum the holder', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const lockingRank = lockingRankBuilder() .with('holder', nonChecksummedAddress) .build(); diff --git a/src/domain/contracts/contracts.repository.interface.ts b/src/domain/contracts/contracts.repository.interface.ts index 528448f943..c2f5715747 100644 --- a/src/domain/contracts/contracts.repository.interface.ts +++ b/src/domain/contracts/contracts.repository.interface.ts @@ -2,6 +2,7 @@ import { Module } from '@nestjs/common'; import { ContractsRepository } from '@/domain/contracts/contracts.repository'; import type { Contract } from '@/domain/data-decoder/v2/entities/contract.entity'; import { DataDecodedApiModule } from '@/datasources/data-decoder-api/data-decoder-api.module'; +import type { Address } from 'viem'; export const IContractsRepository = Symbol('IContractsRepository'); @@ -11,7 +12,7 @@ export interface IContractsRepository { */ getContract(args: { chainId: string; - contractAddress: `0x${string}`; + contractAddress: Address; }): Promise; /** @@ -19,7 +20,7 @@ export interface IContractsRepository { */ isTrustedForDelegateCall(args: { chainId: string; - contractAddress: `0x${string}`; + contractAddress: Address; }): Promise; } diff --git a/src/domain/contracts/contracts.repository.ts b/src/domain/contracts/contracts.repository.ts index 7417880ade..20103c20a1 100644 --- a/src/domain/contracts/contracts.repository.ts +++ b/src/domain/contracts/contracts.repository.ts @@ -1,5 +1,6 @@ import { Inject, Injectable, NotFoundException } from '@nestjs/common'; import { IContractsRepository } from '@/domain/contracts/contracts.repository.interface'; +import type { Address } from 'viem'; import { isAddressEqual } from 'viem'; import { IConfigurationService } from '@/config/configuration.service.interface'; import { PaginationData } from '@/routes/common/pagination/pagination.data'; @@ -34,7 +35,7 @@ export class ContractsRepository implements IContractsRepository { async getContract(args: { chainId: string; - contractAddress: `0x${string}`; + contractAddress: Address; }): Promise { const contracts = await this.dataDecoderApi.getContracts({ address: args.contractAddress, @@ -50,7 +51,7 @@ export class ContractsRepository implements IContractsRepository { async isTrustedForDelegateCall(args: { chainId: string; - contractAddress: `0x${string}`; + contractAddress: Address; }): Promise { return this.isTrustedForDelegateCallContractsListEnabled ? await this.isIncludedInTrustedForDelegateCallContractsList({ @@ -104,7 +105,7 @@ export class ContractsRepository implements IContractsRepository { private async isIncludedInTrustedForDelegateCallContractsList(args: { chainId: string; - contractAddress: `0x${string}`; + contractAddress: Address; }): Promise { const trustedContracts = await this.getTrustedForDelegateCallContracts( args.chainId, @@ -118,7 +119,7 @@ export class ContractsRepository implements IContractsRepository { private async isTrustedForDelegateCallContract(args: { chainId: string; - contractAddress: `0x${string}`; + contractAddress: Address; }): Promise { const contract = await this.getContract({ chainId: args.chainId, diff --git a/src/domain/contracts/entities/schemas/__tests__/contract.schema.spec.ts b/src/domain/contracts/entities/schemas/__tests__/contract.schema.spec.ts index 5daf20385f..a59394c775 100644 --- a/src/domain/contracts/entities/schemas/__tests__/contract.schema.spec.ts +++ b/src/domain/contracts/entities/schemas/__tests__/contract.schema.spec.ts @@ -1,7 +1,7 @@ import { contractBuilder } from '@/domain/contracts/entities/__tests__/contract.builder'; import { ContractSchema } from '@/domain/contracts/entities/schemas/contract.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('ContractSchema', () => { @@ -16,7 +16,7 @@ describe('ContractSchema', () => { it('should checksum the address', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const contract = contractBuilder() .with('address', nonChecksummedAddress) .build(); diff --git a/src/domain/data-decoder/v1/data-decoded.repository.interface.ts b/src/domain/data-decoder/v1/data-decoded.repository.interface.ts index c900b82bee..29edb6d299 100644 --- a/src/domain/data-decoder/v1/data-decoded.repository.interface.ts +++ b/src/domain/data-decoder/v1/data-decoded.repository.interface.ts @@ -2,6 +2,7 @@ import { DataDecoded } from '@/domain/data-decoder/v1/entities/data-decoded.enti import { Module } from '@nestjs/common'; import { DataDecodedRepository } from '@/domain/data-decoder/v1/data-decoded.repository'; import { TransactionApiManagerModule } from '@/domain/interfaces/transaction-api.manager.interface'; +import type { Address } from 'viem'; export const IDataDecodedRepository = Symbol('IDataDecodedRepository'); @@ -12,8 +13,8 @@ export interface IDataDecodedRepository { */ getDataDecoded(args: { chainId: string; - data: `0x${string}`; - to?: `0x${string}`; + data: Address; + to?: Address; }): Promise; } diff --git a/src/domain/data-decoder/v1/data-decoded.repository.ts b/src/domain/data-decoder/v1/data-decoded.repository.ts index cd3b900603..be34e3b460 100644 --- a/src/domain/data-decoder/v1/data-decoded.repository.ts +++ b/src/domain/data-decoder/v1/data-decoded.repository.ts @@ -3,6 +3,7 @@ import { IDataDecodedRepository } from '@/domain/data-decoder/v1/data-decoded.re import { DataDecoded } from '@/domain/data-decoder/v1/entities/data-decoded.entity'; import { ITransactionApiManager } from '@/domain/interfaces/transaction-api.manager.interface'; import { DataDecodedSchema } from '@/domain/data-decoder/v1/entities/schemas/data-decoded.schema'; +import type { Address } from 'viem'; @Injectable() export class DataDecodedRepository implements IDataDecodedRepository { @@ -13,8 +14,8 @@ export class DataDecodedRepository implements IDataDecodedRepository { async getDataDecoded(args: { chainId: string; - data: `0x${string}`; - to?: `0x${string}`; + data: Address; + to?: Address; }): Promise { const api = await this.transactionApiManager.getApi(args.chainId); const dataDecoded = await api.getDataDecoded({ diff --git a/src/domain/data-decoder/v2/data-decoder.repository.interface.ts b/src/domain/data-decoder/v2/data-decoder.repository.interface.ts index 0e608645b1..85a3ea51a9 100644 --- a/src/domain/data-decoder/v2/data-decoder.repository.interface.ts +++ b/src/domain/data-decoder/v2/data-decoder.repository.interface.ts @@ -1,13 +1,14 @@ import type { DataDecoded } from '@/domain/data-decoder/v2/entities/data-decoded.entity'; import type { Transaction } from '@/domain/safe/entities/transaction.entity'; +import type { Address } from 'viem'; export const IDataDecoderRepository = Symbol('IDataDecoderRepository'); export interface IDataDecoderRepository { getDecodedData(args: { chainId: string; - data: `0x${string}`; - to: `0x${string}`; + data: Address; + to: Address; }): Promise; getTransactionDataDecoded(args: { diff --git a/src/domain/data-decoder/v2/data-decoder.repository.ts b/src/domain/data-decoder/v2/data-decoder.repository.ts index 00fe9dcb8b..18cdb617c2 100644 --- a/src/domain/data-decoder/v2/data-decoder.repository.ts +++ b/src/domain/data-decoder/v2/data-decoder.repository.ts @@ -8,6 +8,7 @@ import { IDataDecoderApi } from '@/domain/interfaces/data-decoder-api.interface' import { Transaction } from '@/domain/safe/entities/transaction.entity'; import { ILoggingService, LoggingService } from '@/logging/logging.interface'; import { asError } from '@/logging/utils'; +import type { Address } from 'viem'; @Injectable() export class DataDecoderRepository implements IDataDecoderRepository { @@ -19,8 +20,8 @@ export class DataDecoderRepository implements IDataDecoderRepository { public async getDecodedData(args: { chainId: string; - data: `0x${string}`; - to: `0x${string}`; + data: Address; + to: Address; }): Promise { const dataDecoded = await this.dataDecoderApi.getDecodedData(args); return DataDecodedSchema.parse(dataDecoded); @@ -50,7 +51,7 @@ export class DataDecoderRepository implements IDataDecoderRepository { } } - private getDataDecodedData(transaction: Transaction): `0x${string}` | null { + private getDataDecodedData(transaction: Transaction): Address | null { // Multisig transaction if ('data' in transaction) { return transaction.data; @@ -63,7 +64,7 @@ export class DataDecoderRepository implements IDataDecoderRepository { throw Error('Unrecognized transaction type'); } - private getDataDecodedTo(transaction: Transaction): `0x${string}` { + private getDataDecodedTo(transaction: Transaction): Address { // Multisig transaction if ('to' in transaction) { return transaction.to; diff --git a/src/domain/data-decoder/v2/entities/__tests__/contract.builder.ts b/src/domain/data-decoder/v2/entities/__tests__/contract.builder.ts index 244788e81a..cc638281d6 100644 --- a/src/domain/data-decoder/v2/entities/__tests__/contract.builder.ts +++ b/src/domain/data-decoder/v2/entities/__tests__/contract.builder.ts @@ -1,4 +1,5 @@ import { faker } from '@faker-js/faker'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; import { fakeJson } from '@/__tests__/faker'; import { Builder } from '@/__tests__/builder'; @@ -14,7 +15,7 @@ export function projectBuilder(): IBuilder> { export function abiBuilder(): IBuilder> { return new Builder>() .with('abiJson', [JSON.parse(fakeJson()) as Record]) - .with('abiHash', faker.string.hexadecimal() as `0x${string}`) + .with('abiHash', faker.string.hexadecimal() as Address) .with('modified', faker.date.past()); } diff --git a/src/domain/data-decoder/v2/entities/__tests__/data-decoded.builder.ts b/src/domain/data-decoder/v2/entities/__tests__/data-decoded.builder.ts index fe73d10eaf..268cb4f155 100644 --- a/src/domain/data-decoder/v2/entities/__tests__/data-decoded.builder.ts +++ b/src/domain/data-decoder/v2/entities/__tests__/data-decoded.builder.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { getAddress, type Hex } from 'viem'; import { DataDecodedAccuracy } from '@/domain/data-decoder/v2/entities/data-decoded.entity'; import { Builder } from '@/__tests__/builder'; import type { IBuilder } from '@/__tests__/builder'; @@ -18,7 +18,7 @@ export function multisendBuilder(): IBuilder> { // No nested data to prevent call stack exceeded .with('dataDecoded', null) .with('to', getAddress(faker.finance.ethereumAddress())) - .with('data', faker.string.hexadecimal() as `0x${string}`) + .with('data', faker.string.hexadecimal() as Hex) ); } diff --git a/src/domain/data-decoder/v2/entities/contract.entity.spec.ts b/src/domain/data-decoder/v2/entities/contract.entity.spec.ts index 60772de930..ca5a5a61d1 100644 --- a/src/domain/data-decoder/v2/entities/contract.entity.spec.ts +++ b/src/domain/data-decoder/v2/entities/contract.entity.spec.ts @@ -9,7 +9,7 @@ import { ContractSchema, ProjectSchema, } from '@/domain/data-decoder/v2/entities/contract.entity'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; describe('Contract', () => { describe('ProjectSchema', () => { @@ -93,7 +93,7 @@ describe('Contract', () => { it('should require a valid hex string for abiHash', () => { const abi = abiBuilder() - .with('abiHash', faker.string.numeric() as `0x${string}`) + .with('abiHash', faker.string.numeric() as Address) .build(); const result = AbiSchema.safeParse(abi); @@ -161,7 +161,7 @@ describe('Contract', () => { .ethereumAddress() .toLowerCase(); const contract = contractBuilder() - .with('address', nonChecksummedAddress as `0x${string}`) + .with('address', nonChecksummedAddress as Address) .build(); const result = ContractSchema.safeParse(contract); diff --git a/src/domain/data-decoder/v2/entities/data-decoded.entity.spec.ts b/src/domain/data-decoder/v2/entities/data-decoded.entity.spec.ts index bb999fa17b..6f7f456997 100644 --- a/src/domain/data-decoder/v2/entities/data-decoded.entity.spec.ts +++ b/src/domain/data-decoder/v2/entities/data-decoded.entity.spec.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; import { baseDataDecodedBuilder, @@ -85,7 +85,7 @@ describe('DataDecoded', () => { .ethereumAddress() .toLowerCase(); const multisend = multisendBuilder() - .with('to', nonChecksummedAddress as `0x${string}`) + .with('to', nonChecksummedAddress as Address) .build(); const result = MultisendSchema.safeParse(multisend); @@ -97,7 +97,7 @@ describe('DataDecoded', () => { it('should expect hex data', () => { const multisend = multisendBuilder() - .with('data', faker.string.alpha() as `0x${string}`) + .with('data', faker.string.alpha() as Address) .build(); const result = MultisendSchema.safeParse(multisend); diff --git a/src/domain/data-decoder/v2/entities/data-decoded.entity.ts b/src/domain/data-decoder/v2/entities/data-decoded.entity.ts index 3ad8d90e12..cddd5a7405 100644 --- a/src/domain/data-decoder/v2/entities/data-decoded.entity.ts +++ b/src/domain/data-decoder/v2/entities/data-decoded.entity.ts @@ -3,10 +3,11 @@ import { AddressSchema as _AddressSchema } from '@/validation/entities/schemas/a import { HexSchema as _HexSchema } from '@/validation/entities/schemas/hex.schema'; import { NumericStringSchema } from '@/validation/entities/schemas/numeric-string.schema'; import { Operation } from '@/domain/safe/entities/operation.entity'; +import type { Address } from 'viem'; // ZodEffects cannot be recursively inferred and need be casted -const AddressSchema = _AddressSchema as z.ZodType<`0x${string}`>; -const HexSchema = _HexSchema as z.ZodType<`0x${string}`>; +const AddressSchema = _AddressSchema as z.ZodType
; +const HexSchema = _HexSchema as z.ZodType
; export const MultisendSchema = z.object({ operation: z.nativeEnum(Operation), diff --git a/src/domain/delegate/delegate.repository.interface.ts b/src/domain/delegate/delegate.repository.interface.ts index 2d68d70443..baa74387bd 100644 --- a/src/domain/delegate/delegate.repository.interface.ts +++ b/src/domain/delegate/delegate.repository.interface.ts @@ -3,15 +3,16 @@ import { Page } from '@/domain/entities/page.entity'; import { Module } from '@nestjs/common'; import { DelegateRepository } from '@/domain/delegate/delegate.repository'; import { TransactionApiManagerModule } from '@/domain/interfaces/transaction-api.manager.interface'; +import type { Address } from 'viem'; export const IDelegateRepository = Symbol('IDelegateRepository'); export interface IDelegateRepository { getDelegates(args: { chainId: string; - safeAddress?: `0x${string}`; - delegate?: `0x${string}`; - delegator?: `0x${string}`; + safeAddress?: Address; + delegate?: Address; + delegator?: Address; label?: string; limit?: number; offset?: number; @@ -19,24 +20,24 @@ export interface IDelegateRepository { postDelegate(args: { chainId: string; - safeAddress: `0x${string}` | null; - delegate: `0x${string}`; - delegator: `0x${string}`; + safeAddress: Address | null; + delegate: Address; + delegator: Address; signature: string; label: string; }): Promise; deleteDelegate(args: { chainId: string; - delegate: `0x${string}`; - delegator: `0x${string}`; + delegate: Address; + delegator: Address; signature: string; }): Promise; deleteSafeDelegate(args: { chainId: string; - delegate: `0x${string}`; - safeAddress: `0x${string}`; + delegate: Address; + safeAddress: Address; signature: string; }): Promise; } diff --git a/src/domain/delegate/delegate.repository.ts b/src/domain/delegate/delegate.repository.ts index 9bb43957f0..35d60745fc 100644 --- a/src/domain/delegate/delegate.repository.ts +++ b/src/domain/delegate/delegate.repository.ts @@ -4,6 +4,7 @@ import { Delegate } from '@/domain/delegate/entities/delegate.entity'; import { Page } from '@/domain/entities/page.entity'; import { ITransactionApiManager } from '@/domain/interfaces/transaction-api.manager.interface'; import { DelegatePageSchema } from '@/domain/delegate/entities/schemas/delegate.schema'; +import type { Address } from 'viem'; @Injectable() export class DelegateRepository implements IDelegateRepository { @@ -14,9 +15,9 @@ export class DelegateRepository implements IDelegateRepository { async getDelegates(args: { chainId: string; - safeAddress?: `0x${string}`; - delegate?: `0x${string}`; - delegator?: `0x${string}`; + safeAddress?: Address; + delegate?: Address; + delegator?: Address; label?: string; limit?: number; offset?: number; @@ -38,9 +39,9 @@ export class DelegateRepository implements IDelegateRepository { async postDelegate(args: { chainId: string; - safeAddress: `0x${string}` | null; - delegate: `0x${string}`; - delegator: `0x${string}`; + safeAddress: Address | null; + delegate: Address; + delegator: Address; signature: string; label: string; }): Promise { @@ -58,8 +59,8 @@ export class DelegateRepository implements IDelegateRepository { async deleteDelegate(args: { chainId: string; - delegate: `0x${string}`; - delegator: `0x${string}`; + delegate: Address; + delegator: Address; signature: string; }): Promise { const transactionService = await this.transactionApiManager.getApi( @@ -74,8 +75,8 @@ export class DelegateRepository implements IDelegateRepository { async deleteSafeDelegate(args: { chainId: string; - delegate: `0x${string}`; - safeAddress: `0x${string}`; + delegate: Address; + safeAddress: Address; signature: string; }): Promise { const transactionService = await this.transactionApiManager.getApi( diff --git a/src/domain/delegate/entities/schemas/__tests__/delegate.schema.spec.ts b/src/domain/delegate/entities/schemas/__tests__/delegate.schema.spec.ts index 8e7058c267..d9d7d21a8b 100644 --- a/src/domain/delegate/entities/schemas/__tests__/delegate.schema.spec.ts +++ b/src/domain/delegate/entities/schemas/__tests__/delegate.schema.spec.ts @@ -1,7 +1,7 @@ import { delegateBuilder } from '@/domain/delegate/entities/__tests__/delegate.builder'; import { DelegateSchema } from '@/domain/delegate/entities/schemas/delegate.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('DelegateSchema', () => { @@ -26,7 +26,7 @@ describe('DelegateSchema', () => { it('should checksum safe, delegate and delegator', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const delegate = delegateBuilder() .with('safe', nonChecksummedAddress) .with('delegate', nonChecksummedAddress) diff --git a/src/domain/delegate/v2/delegates.v2.repository.interface.ts b/src/domain/delegate/v2/delegates.v2.repository.interface.ts index 3564ecbb18..5839067301 100644 --- a/src/domain/delegate/v2/delegates.v2.repository.interface.ts +++ b/src/domain/delegate/v2/delegates.v2.repository.interface.ts @@ -3,6 +3,7 @@ import { DelegatesV2Repository } from '@/domain/delegate/v2/delegates.v2.reposit import { Page } from '@/domain/entities/page.entity'; import { TransactionApiManagerModule } from '@/domain/interfaces/transaction-api.manager.interface'; import { Module } from '@nestjs/common'; +import type { Address } from 'viem'; export const IDelegatesV2Repository = Symbol('IDelegatesV2Repository'); @@ -24,18 +25,18 @@ export interface IDelegatesV2Repository { postDelegate(args: { chainId: string; - safeAddress: `0x${string}` | null; - delegate: `0x${string}`; - delegator: `0x${string}`; + safeAddress: Address | null; + delegate: Address; + delegator: Address; signature: string; label: string; }): Promise; deleteDelegate(args: { chainId: string; - delegate: `0x${string}`; - delegator: `0x${string}`; - safeAddress: `0x${string}` | null; + delegate: Address; + delegator: Address; + safeAddress: Address | null; signature: string; }): Promise; } diff --git a/src/domain/delegate/v2/delegates.v2.repository.ts b/src/domain/delegate/v2/delegates.v2.repository.ts index 9d5c719391..bfa221e16b 100644 --- a/src/domain/delegate/v2/delegates.v2.repository.ts +++ b/src/domain/delegate/v2/delegates.v2.repository.ts @@ -4,6 +4,7 @@ import { IDelegatesV2Repository } from '@/domain/delegate/v2/delegates.v2.reposi import { Page } from '@/domain/entities/page.entity'; import { ITransactionApiManager } from '@/domain/interfaces/transaction-api.manager.interface'; import { Inject, Injectable } from '@nestjs/common'; +import type { Address } from 'viem'; @Injectable() export class DelegatesV2Repository implements IDelegatesV2Repository { @@ -14,9 +15,9 @@ export class DelegatesV2Repository implements IDelegatesV2Repository { async getDelegates(args: { chainId: string; - safeAddress?: `0x${string}`; - delegate?: `0x${string}`; - delegator?: `0x${string}`; + safeAddress?: Address; + delegate?: Address; + delegator?: Address; label?: string; limit?: number; offset?: number; @@ -38,7 +39,7 @@ export class DelegatesV2Repository implements IDelegatesV2Repository { async clearDelegates(args: { chainId: string; - safeAddress?: `0x${string}`; + safeAddress?: Address; }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, @@ -48,9 +49,9 @@ export class DelegatesV2Repository implements IDelegatesV2Repository { async postDelegate(args: { chainId: string; - safeAddress: `0x${string}` | null; - delegate: `0x${string}`; - delegator: `0x${string}`; + safeAddress: Address | null; + delegate: Address; + delegator: Address; signature: string; label: string; }): Promise { @@ -68,9 +69,9 @@ export class DelegatesV2Repository implements IDelegatesV2Repository { async deleteDelegate(args: { chainId: string; - delegate: `0x${string}`; - delegator: `0x${string}`; - safeAddress: `0x${string}` | null; + delegate: Address; + delegator: Address; + safeAddress: Address | null; signature: string; }): Promise { const transactionService = await this.transactionApiManager.getApi( diff --git a/src/domain/earn/earn.repository.ts b/src/domain/earn/earn.repository.ts index 1ffd310d40..5d45498b65 100644 --- a/src/domain/earn/earn.repository.ts +++ b/src/domain/earn/earn.repository.ts @@ -37,6 +37,7 @@ import { DefiMorphoExtraReward, DefiMorphoExtraRewardsSchema, } from '@/datasources/staking-api/entities/defi-morpho-extra-reward.entity'; +import type { Address, Hash } from 'viem'; // TODO: Deduplicate code with StakingRepository @@ -53,7 +54,7 @@ export class EarnRepository implements IStakingRepository { public async getDeployment(args: { chainId: string; - address: `0x${string}`; + address: Address; }): Promise { const deployments = await this.getDeployments(args.chainId); const deployment = deployments.find((deployment) => { @@ -91,7 +92,7 @@ export class EarnRepository implements IStakingRepository { public async getPooledStakingStats(args: { chainId: string; - pool: `0x${string}`; + pool: Address; }): Promise { const earnApi = await this.earnApiFactory.getApi(args.chainId); const pooledStaking = await earnApi.getPooledStakingStats(args.pool); @@ -100,7 +101,7 @@ export class EarnRepository implements IStakingRepository { public async getDefiVaultStats(args: { chainId: string; - vault: `0x${string}`; + vault: Address; }): Promise { const earnApi = await this.earnApiFactory.getApi(args.chainId); const defiStats = await earnApi.getDefiVaultStats(args.vault); @@ -110,8 +111,8 @@ export class EarnRepository implements IStakingRepository { public async getDefiVaultStake(args: { chainId: string; - safeAddress: `0x${string}`; - vault: `0x${string}`; + safeAddress: Address; + vault: Address; }): Promise { const earnApi = await this.earnApiFactory.getApi(args.chainId); const defiStakes = await earnApi.getDefiVaultStakes(args); @@ -121,7 +122,7 @@ export class EarnRepository implements IStakingRepository { public async getDefiMorphoExtraRewards(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise> { const earnApi = await this.earnApiFactory.getApi(args.chainId); const defiMorphoExtraRewards = await earnApi.getDefiMorphoExtraRewards( @@ -132,8 +133,8 @@ export class EarnRepository implements IStakingRepository { public async getStakes(args: { chainId: string; - safeAddress: `0x${string}`; - validatorsPublicKeys: Array<`0x${string}`>; + safeAddress: Address; + validatorsPublicKeys: Array
; }): Promise> { const earnApi = await this.earnApiFactory.getApi(args.chainId); const stakes = await earnApi.getStakes(args); @@ -142,7 +143,7 @@ export class EarnRepository implements IStakingRepository { public async clearStakes(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const earnApi = await this.earnApiFactory.getApi(args.chainId); await earnApi.clearStakes(args.safeAddress); @@ -150,7 +151,7 @@ export class EarnRepository implements IStakingRepository { public async getTransactionStatus(args: { chainId: string; - txHash: `0x${string}`; + txHash: Hash; }): Promise { const earnApi = await this.earnApiFactory.getApi(args.chainId); const txStatus = await earnApi.getTransactionStatus(args.txHash); diff --git a/src/domain/estimations/entities/get-estimation.dto.entity.ts b/src/domain/estimations/entities/get-estimation.dto.entity.ts index b598ab2a42..2e836cf6ed 100644 --- a/src/domain/estimations/entities/get-estimation.dto.entity.ts +++ b/src/domain/estimations/entities/get-estimation.dto.entity.ts @@ -1,19 +1,20 @@ import type { Operation } from '@/domain/safe/entities/operation.entity'; import type { GetEstimationDtoSchema } from '@/routes/estimations/entities/schemas/get-estimation.dto.schema'; import type { z } from 'zod'; +import type { Address, Hex } from 'viem'; export class GetEstimationDto implements z.infer { - to: `0x${string}`; + to: Address; value: string; - data: `0x${string}` | null; + data: Hex | null; operation: Operation; constructor( - to: `0x${string}`, + to: Address, value: string, - data: `0x${string}` | null, + data: Hex | null, operation: Operation, ) { this.to = to; diff --git a/src/domain/estimations/estimations.repository.interface.ts b/src/domain/estimations/estimations.repository.interface.ts index f39e32bdb3..2d8dffb2cf 100644 --- a/src/domain/estimations/estimations.repository.interface.ts +++ b/src/domain/estimations/estimations.repository.interface.ts @@ -3,13 +3,14 @@ import { GetEstimationDto } from '@/domain/estimations/entities/get-estimation.d import { Module } from '@nestjs/common'; import { EstimationsRepository } from '@/domain/estimations/estimations.repository'; import { TransactionApiManagerModule } from '@/domain/interfaces/transaction-api.manager.interface'; +import type { Address } from 'viem'; export const IEstimationsRepository = Symbol('IEstimationsRepository'); export interface IEstimationsRepository { getEstimation(args: { chainId: string; - address: `0x${string}`; + address: Address; getEstimationDto: GetEstimationDto; }): Promise; } diff --git a/src/domain/estimations/estimations.repository.ts b/src/domain/estimations/estimations.repository.ts index de5104dbde..076455078a 100644 --- a/src/domain/estimations/estimations.repository.ts +++ b/src/domain/estimations/estimations.repository.ts @@ -4,6 +4,7 @@ import { GetEstimationDto } from '@/domain/estimations/entities/get-estimation.d import { IEstimationsRepository } from '@/domain/estimations/estimations.repository.interface'; import { ITransactionApiManager } from '@/domain/interfaces/transaction-api.manager.interface'; import { EstimationSchema } from '@/domain/estimations/entities/schemas/estimation.schema'; +import type { Address } from 'viem'; @Injectable() export class EstimationsRepository implements IEstimationsRepository { @@ -14,7 +15,7 @@ export class EstimationsRepository implements IEstimationsRepository { async getEstimation(args: { chainId: string; - address: `0x${string}`; + address: Address; getEstimationDto: GetEstimationDto; }): Promise { const api = await this.transactionApiManager.getApi(args.chainId); diff --git a/src/domain/hooks/helpers/event-notifications.helper.ts b/src/domain/hooks/helpers/event-notifications.helper.ts index e2c9ff46fd..64a797ab68 100644 --- a/src/domain/hooks/helpers/event-notifications.helper.ts +++ b/src/domain/hooks/helpers/event-notifications.helper.ts @@ -40,6 +40,7 @@ import { Confirmation } from '@/domain/safe/entities/multisig-transaction.entity import { MessageConfirmation } from '@/domain/messages/entities/message-confirmation.entity'; import { LogType } from '@/domain/common/entities/log-type.entity'; import { asError } from '@/logging/utils'; +import type { Address } from 'viem'; type EventToNotify = | DeletedMultisigTransactionEvent @@ -176,7 +177,7 @@ export class EventNotificationsHelper { */ private async getRelevantSubscribers(event: EventToNotify): Promise< Array<{ - subscriber: `0x${string}` | null; + subscriber: Address | null; deviceUuid: UUID; cloudMessagingToken: string; }> @@ -236,8 +237,8 @@ export class EventNotificationsHelper { */ private async isOwnerOrDelegate(args: { chainId: string; - safeAddress: `0x${string}`; - subscriber: `0x${string}`; + safeAddress: Address; + subscriber: Address; }): Promise { // We don't use Promise.all avoid unnecessary calls for delegates const safe = await this.safeRepository.getSafe({ @@ -269,7 +270,7 @@ export class EventNotificationsHelper { */ private async mapEventNotification( event: EventToNotify, - subscriber: `0x${string}` | null, + subscriber: Address | null, ): Promise { if ( event.type === TransactionEventType.INCOMING_ETHER || @@ -341,7 +342,7 @@ export class EventNotificationsHelper { */ private async mapPendingMultisigTransactionEventNotification( event: PendingTransactionEvent, - subscriber: `0x${string}`, + subscriber: Address, ): Promise { const safe = await this.safeRepository.getSafe({ chainId: event.chainId, @@ -382,7 +383,7 @@ export class EventNotificationsHelper { private async hasSubscriberSigned( chainId: string, - subscriber: `0x${string}`, + subscriber: Address, confirmations: Array, ): Promise { // The owner can be a delegate key so we need to check whether the owner or the delegate key has signed the message. @@ -414,7 +415,7 @@ export class EventNotificationsHelper { */ private async mapMessageCreatedEventNotification( event: MessageCreatedEvent, - subscriber: `0x${string}`, + subscriber: Address, ): Promise { const safe = await this.safeRepository.getSafe({ chainId: event.chainId, diff --git a/src/domain/human-description/entities/human-description-template.entity.ts b/src/domain/human-description/entities/human-description-template.entity.ts index 649f1acd70..e23cbe30bf 100644 --- a/src/domain/human-description/entities/human-description-template.entity.ts +++ b/src/domain/human-description/entities/human-description-template.entity.ts @@ -4,6 +4,7 @@ import type { TextFragment, } from '@/domain/human-description/entities/human-description.entity'; import { ValueType } from '@/domain/human-description/entities/human-description.entity'; +import type { Address } from 'viem'; type SafeRegExpExecArray = RegExpExecArray & { groups: NonNullable; @@ -52,7 +53,7 @@ export class HumanDescriptionTemplate { * @param to - the target address of the transaction * @param data - the raw data of the transaction */ - parse(to: string, data: `0x${string}`): Array { + parse(to: string, data: Address): Array { const { args } = decodeFunctionData({ abi: this.functionAbi, data, diff --git a/src/domain/human-description/entities/human-description.entity.ts b/src/domain/human-description/entities/human-description.entity.ts index 0c343a3f60..0871d2c9ba 100644 --- a/src/domain/human-description/entities/human-description.entity.ts +++ b/src/domain/human-description/entities/human-description.entity.ts @@ -1,4 +1,5 @@ import type { Hex } from 'viem/types/misc'; +import type { Address } from 'viem'; export enum ValueType { Text = 'text', @@ -21,7 +22,7 @@ export interface TextFragment { export interface AddressFragment { type: ValueType.Address; - value: `0x${string}`; + value: Address; } export interface NumberFragment { diff --git a/src/domain/human-description/human-description.repository.ts b/src/domain/human-description/human-description.repository.ts index 995efaf80b..d5e4021e2f 100644 --- a/src/domain/human-description/human-description.repository.ts +++ b/src/domain/human-description/human-description.repository.ts @@ -7,6 +7,7 @@ import { } from '@/domain/human-description/entities/human-description.entity'; import { IHumanDescriptionRepository } from '@/domain/human-description/human-description.repository.interface'; import { IHumanDescriptionApi } from '@/domain/interfaces/human-description-api.interface'; +import type { Address } from 'viem'; @Injectable() export class HumanDescriptionRepository implements IHumanDescriptionRepository { @@ -33,7 +34,7 @@ export class HumanDescriptionRepository implements IHumanDescriptionRepository { getHumanDescription(args: { functionSignatureHash: FunctionSignatureHash; to: string; - data: `0x${string}`; + data: Address; }): Array { const template = this._getTemplate(args.functionSignatureHash); return template.parse(args.to, args.data); diff --git a/src/domain/interfaces/accounts.datasource.interface.ts b/src/domain/interfaces/accounts.datasource.interface.ts index 1c55e01ef3..2b43f1f67d 100644 --- a/src/domain/interfaces/accounts.datasource.interface.ts +++ b/src/domain/interfaces/accounts.datasource.interface.ts @@ -3,6 +3,7 @@ import type { AccountDataType } from '@/domain/accounts/entities/account-data-ty import type { Account } from '@/domain/accounts/entities/account.entity'; import type { CreateAccountDto } from '@/domain/accounts/entities/create-account.dto.entity'; import type { UpsertAccountDataSettingsDto } from '@/domain/accounts/entities/upsert-account-data-settings.dto.entity'; +import type { Address } from 'viem'; export const IAccountsDatasource = Symbol('IAccountsDatasource'); @@ -12,18 +13,16 @@ export interface IAccountsDatasource { clientIp: string; }): Promise; - getAccount(address: `0x${string}`): Promise; + getAccount(address: Address): Promise; - deleteAccount(address: `0x${string}`): Promise; + deleteAccount(address: Address): Promise; getDataTypes(): Promise>; - getAccountDataSettings( - address: `0x${string}`, - ): Promise>; + getAccountDataSettings(address: Address): Promise>; upsertAccountDataSettings(args: { - address: `0x${string}`; + address: Address; upsertAccountDataSettingsDto: UpsertAccountDataSettingsDto; }): Promise>; } diff --git a/src/domain/interfaces/balances-api.interface.ts b/src/domain/interfaces/balances-api.interface.ts index 319738d09a..9dc1146b09 100644 --- a/src/domain/interfaces/balances-api.interface.ts +++ b/src/domain/interfaces/balances-api.interface.ts @@ -3,23 +3,21 @@ import type { Chain } from '@/domain/chains/entities/chain.entity'; import type { Collectible } from '@/domain/collectibles/entities/collectible.entity'; import type { Page } from '@/domain/entities/page.entity'; import type { Raw } from '@/validation/entities/raw.entity'; +import type { Address } from 'viem'; export interface IBalancesApi { getBalances(args: { - safeAddress: `0x${string}`; + safeAddress: Address; fiatCode: string; chain: Chain; trusted?: boolean; excludeSpam?: boolean; }): Promise>>; - clearBalances(args: { - chainId: string; - safeAddress: `0x${string}`; - }): Promise; + clearBalances(args: { chainId: string; safeAddress: Address }): Promise; getCollectibles(args: { - safeAddress: `0x${string}`; + safeAddress: Address; chain: Chain; limit?: number; offset?: number; @@ -29,7 +27,7 @@ export interface IBalancesApi { clearCollectibles(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; getFiatCodes(): Promise>>; diff --git a/src/domain/interfaces/balances-api.manager.interface.ts b/src/domain/interfaces/balances-api.manager.interface.ts index 05a311dc2c..8217c3f79b 100644 --- a/src/domain/interfaces/balances-api.manager.interface.ts +++ b/src/domain/interfaces/balances-api.manager.interface.ts @@ -1,6 +1,7 @@ import type { IApiManager } from '@/domain/interfaces/api.manager.interface'; import type { IBalancesApi } from '@/domain/interfaces/balances-api.interface'; import type { Raw } from '@/validation/entities/raw.entity'; +import type { Address } from 'viem'; export const IBalancesApiManager = Symbol('IBalancesApiManager'); @@ -17,7 +18,7 @@ export interface IBalancesApiManager extends IApiManager { * @param safeAddress - the Safe address to check. * @returns {@link IBalancesApi} configured for the input chain ID. */ - getApi(chainId: string, safeAddress: `0x${string}`): Promise; + getApi(chainId: string, safeAddress: Address): Promise; /** * Gets the list of supported fiat codes. diff --git a/src/domain/interfaces/bridge-api.inferface.ts b/src/domain/interfaces/bridge-api.inferface.ts index 2700e3bb03..9fe586e8fc 100644 --- a/src/domain/interfaces/bridge-api.inferface.ts +++ b/src/domain/interfaces/bridge-api.inferface.ts @@ -3,6 +3,7 @@ import type { BridgeStatus } from '@/domain/bridge/entities/bridge-status.entity import type { Raw } from '@/validation/entities/raw.entity'; import type { BridgeChainPage } from '@/domain/bridge/entities/bridge-chain.entity'; +import type { Hash } from 'viem'; export const IBridgeApi = Symbol('IBridgeApi'); @@ -10,7 +11,7 @@ export interface IBridgeApi { getChains(): Promise>; getStatus(args: { - txHash: `0x${string}`; + txHash: Hash; bridge?: BridgeName; toChain?: string; }): Promise>; diff --git a/src/domain/interfaces/counterfactual-safes.datasource.interface.ts b/src/domain/interfaces/counterfactual-safes.datasource.interface.ts index 622ec668a8..fa33d441f1 100644 --- a/src/domain/interfaces/counterfactual-safes.datasource.interface.ts +++ b/src/domain/interfaces/counterfactual-safes.datasource.interface.ts @@ -1,6 +1,7 @@ import type { CounterfactualSafe } from '@/domain/accounts/counterfactual-safes/entities/counterfactual-safe.entity'; import type { CreateCounterfactualSafeDto } from '@/domain/accounts/counterfactual-safes/entities/create-counterfactual-safe.dto.entity'; import type { Account } from '@/domain/accounts/entities/account.entity'; +import type { Address } from 'viem'; export const ICounterfactualSafesDatasource = Symbol( 'ICounterfactualSafesDatasource', @@ -13,19 +14,19 @@ export interface ICounterfactualSafesDatasource { }): Promise; getCounterfactualSafe(args: { - address: `0x${string}`; + address: Address; chainId: string; - predictedAddress: `0x${string}`; + predictedAddress: Address; }): Promise; getCounterfactualSafesForAddress( - address: `0x${string}`, + address: Address, ): Promise>; deleteCounterfactualSafe(args: { account: Account; chainId: string; - predictedAddress: `0x${string}`; + predictedAddress: Address; }): Promise; deleteCounterfactualSafesForAccount(account: Account): Promise; diff --git a/src/domain/interfaces/data-decoder-api.interface.ts b/src/domain/interfaces/data-decoder-api.interface.ts index 0fb2a330ff..223360a832 100644 --- a/src/domain/interfaces/data-decoder-api.interface.ts +++ b/src/domain/interfaces/data-decoder-api.interface.ts @@ -2,17 +2,18 @@ import type { Contract } from '@/domain/data-decoder/v2/entities/contract.entity import type { DataDecoded } from '@/domain/data-decoder/v2/entities/data-decoded.entity'; import type { Page } from '@/domain/entities/page.entity'; import type { Raw } from '@/validation/entities/raw.entity'; +import type { Address } from 'viem'; export const IDataDecoderApi = Symbol('IDataDecoderApi'); export interface IDataDecoderApi { getDecodedData(args: { - data: `0x${string}`; - to: `0x${string}`; + data: Address; + to: Address; }): Promise>; getContracts(args: { - address: `0x${string}`; + address: Address; chainId: string; limit?: number; offset?: number; diff --git a/src/domain/interfaces/locking-api.interface.ts b/src/domain/interfaces/locking-api.interface.ts index 124e77e03b..3e2e7e7717 100644 --- a/src/domain/interfaces/locking-api.interface.ts +++ b/src/domain/interfaces/locking-api.interface.ts @@ -5,6 +5,7 @@ import type { CampaignRank } from '@/domain/community/entities/campaign-rank.ent import type { LockingEvent } from '@/domain/community/entities/locking-event.entity'; import type { LockingRank } from '@/domain/community/entities/locking-rank.entity'; import type { Raw } from '@/validation/entities/raw.entity'; +import type { Address } from 'viem'; export const ILockingApi = Symbol('ILockingApi'); @@ -18,12 +19,12 @@ export interface ILockingApi { getCampaignActivities(args: { resourceId: string; - holder?: `0x${string}`; + holder?: Address; limit?: number; offset?: number; }): Promise>>; - getLockingRank(safeAddress: `0x${string}`): Promise>; + getLockingRank(safeAddress: Address): Promise>; getLeaderboard(args: { limit?: number; @@ -38,11 +39,11 @@ export interface ILockingApi { getCampaignRank(args: { resourceId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise>; getLockingHistory(args: { - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; }): Promise>>; diff --git a/src/domain/interfaces/notifications.datasource.interface.ts b/src/domain/interfaces/notifications.datasource.interface.ts index da26d84d7b..1858952a88 100644 --- a/src/domain/interfaces/notifications.datasource.interface.ts +++ b/src/domain/interfaces/notifications.datasource.interface.ts @@ -1,30 +1,31 @@ import type { UpsertSubscriptionsDto } from '@/domain/notifications/v2/entities/upsert-subscriptions.dto.entity'; import type { NotificationType } from '@/domain/notifications/v2/entities/notification-type.entity'; import type { UUID } from 'crypto'; +import type { Address } from 'viem'; export const INotificationsDatasource = Symbol('INotificationsDatasource'); export interface INotificationsDatasource { upsertSubscriptions(args: { - signerAddress?: `0x${string}`; + signerAddress?: Address; upsertSubscriptionsDto: UpsertSubscriptionsDto; }): Promise<{ deviceUuid: UUID; }>; getSafeSubscription(args: { - signerAddress: `0x${string}`; + signerAddress: Address; deviceUuid: UUID; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise>; getSubscribersBySafe(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise< Array<{ - subscriber: `0x${string}` | null; + subscriber: Address | null; deviceUuid: UUID; cloudMessagingToken: string; }> @@ -33,7 +34,7 @@ export interface INotificationsDatasource { deleteSubscription(args: { deviceUuid: UUID; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; deleteDevice(deviceUuid: UUID): Promise; diff --git a/src/domain/interfaces/positions-api.interface.ts b/src/domain/interfaces/positions-api.interface.ts index e2d70c1034..67f73ddb36 100644 --- a/src/domain/interfaces/positions-api.interface.ts +++ b/src/domain/interfaces/positions-api.interface.ts @@ -1,19 +1,20 @@ import type { Position } from '@/domain/positions/entities/position.entity'; import type { Chain } from '@/domain/chains/entities/chain.entity'; import type { Raw } from '@/validation/entities/raw.entity'; +import type { Address } from 'viem'; export const IPositionsApi = Symbol('IPositionsApi'); export interface IPositionsApi { getPositions(args: { - safeAddress: `0x${string}`; + safeAddress: Address; fiatCode: string; chain: Chain; }): Promise>>; clearPositions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; getFiatCodes(): Promise>>; diff --git a/src/domain/interfaces/relay-api.interface.ts b/src/domain/interfaces/relay-api.interface.ts index 0f60100e58..893e95d5b9 100644 --- a/src/domain/interfaces/relay-api.interface.ts +++ b/src/domain/interfaces/relay-api.interface.ts @@ -1,24 +1,22 @@ import type { Relay } from '@/domain/relay/entities/relay.entity'; import type { Raw } from '@/validation/entities/raw.entity'; +import type { Address } from 'viem'; export const IRelayApi = Symbol('IRelayApi'); export interface IRelayApi { relay(args: { chainId: string; - to: `0x${string}`; + to: Address; data: string; gasLimit: bigint | null; }): Promise>; - getRelayCount(args: { - chainId: string; - address: `0x${string}`; - }): Promise; + getRelayCount(args: { chainId: string; address: Address }): Promise; setRelayCount(args: { chainId: string; - address: `0x${string}`; + address: Address; count: number; }): Promise; } diff --git a/src/domain/interfaces/staking-api.interface.ts b/src/domain/interfaces/staking-api.interface.ts index 1cda50f838..6b22fd7bcc 100644 --- a/src/domain/interfaces/staking-api.interface.ts +++ b/src/domain/interfaces/staking-api.interface.ts @@ -9,37 +9,38 @@ import type { Raw } from '@/validation/entities/raw.entity'; import type { DefiVaultStake } from '@/datasources/staking-api/entities/defi-vault-stake.entity'; import type { DefiMorphoExtraReward } from '@/datasources/staking-api/entities/defi-morpho-extra-reward.entity'; import type { RewardsFee } from '@/datasources/staking-api/entities/rewards-fee.entity'; +import type { Address, Hash } from 'viem'; export const IStakingApi = Symbol('IStakingApi'); export interface IStakingApi { getDeployments(): Promise>>; - getRewardsFee(contract: `0x${string}`): Promise>; + getRewardsFee(contract: Address): Promise>; getNetworkStats(): Promise>; getDedicatedStakingStats(): Promise>; - getPooledStakingStats(pool: `0x${string}`): Promise>; + getPooledStakingStats(pool: Address): Promise>; - getDefiVaultStats(vault: `0x${string}`): Promise>>; + getDefiVaultStats(vault: Address): Promise>>; getDefiVaultStakes(args: { - safeAddress: `0x${string}`; - vault: `0x${string}`; + safeAddress: Address; + vault: Address; }): Promise>>; getDefiMorphoExtraRewards( - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise>>; getStakes(args: { - safeAddress: `0x${string}`; - validatorsPublicKeys: Array<`0x${string}`>; + safeAddress: Address; + validatorsPublicKeys: Array
; }): Promise>>; - clearStakes(safeAddress: `0x${string}`): Promise; + clearStakes(safeAddress: Address): Promise; - getTransactionStatus(txHash: `0x${string}`): Promise>; + getTransactionStatus(txHash: Hash): Promise>; } diff --git a/src/domain/interfaces/swaps-api.interface.ts b/src/domain/interfaces/swaps-api.interface.ts index 9f76599bda..9fd1464164 100644 --- a/src/domain/interfaces/swaps-api.interface.ts +++ b/src/domain/interfaces/swaps-api.interface.ts @@ -1,11 +1,12 @@ import type { FullAppData } from '@/domain/swaps/entities/full-app-data.entity'; import type { Order } from '@/domain/swaps/entities/order.entity'; import type { Raw } from '@/validation/entities/raw.entity'; +import type { Hex } from 'viem'; export interface ISwapsApi { getOrder(uid: string): Promise>; getOrders(txHash: string): Promise>>; - getFullAppData(appDataHash: `0x${string}`): Promise>; + getFullAppData(appDataHash: Hex): Promise>; } diff --git a/src/domain/interfaces/targeted-messaging.datasource.interface.ts b/src/domain/interfaces/targeted-messaging.datasource.interface.ts index ea78f13518..304f1208b6 100644 --- a/src/domain/interfaces/targeted-messaging.datasource.interface.ts +++ b/src/domain/interfaces/targeted-messaging.datasource.interface.ts @@ -4,6 +4,7 @@ import type { Outreach } from '@/domain/targeted-messaging/entities/outreach.ent import type { Submission } from '@/domain/targeted-messaging/entities/submission.entity'; import type { TargetedSafe } from '@/domain/targeted-messaging/entities/targeted-safe.entity'; import type { UpdateOutreachDto } from '@/domain/targeted-messaging/entities/update-outreach.dto.entity'; +import type { Address } from 'viem'; export const ITargetedMessagingDatasource = Symbol( 'ITargetedMessagingDatasource', @@ -26,16 +27,16 @@ export interface ITargetedMessagingDatasource { getTargetedSafe(args: { outreachId: number; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; createSubmission(args: { targetedSafe: TargetedSafe; - signerAddress: `0x${string}`; + signerAddress: Address; }): Promise; getSubmission(args: { targetedSafe: TargetedSafe; - signerAddress: `0x${string}`; + signerAddress: Address; }): Promise; } diff --git a/src/domain/interfaces/transaction-api.interface.ts b/src/domain/interfaces/transaction-api.interface.ts index 1126286bd1..ea2480b459 100644 --- a/src/domain/interfaces/transaction-api.interface.ts +++ b/src/domain/interfaces/transaction-api.interface.ts @@ -18,11 +18,12 @@ import type { Token } from '@/domain/tokens/entities/token.entity'; import type { AddConfirmationDto } from '@/domain/transactions/entities/add-confirmation.dto.entity'; import type { ProposeTransactionDto } from '@/domain/transactions/entities/propose-transaction.dto.entity'; import type { Raw } from '@/validation/entities/raw.entity'; +import type { Address, Hex } from 'viem'; export interface ITransactionApi { getDataDecoded(args: { - data: `0x${string}`; - to?: `0x${string}`; + data: Address; + to?: Address; }): Promise>; getBackbone(): Promise>; @@ -31,108 +32,108 @@ export interface ITransactionApi { getIndexingStatus(): Promise>; - getSafe(safeAddress: `0x${string}`): Promise>; + getSafe(safeAddress: Address): Promise>; - clearSafe(address: `0x${string}`): Promise; + clearSafe(address: Address): Promise; - isSafe(address: `0x${string}`): Promise; + isSafe(address: Address): Promise; - clearIsSafe(address: `0x${string}`): Promise; + clearIsSafe(address: Address): Promise; getDelegates(args: { - safeAddress?: `0x${string}`; - delegate?: `0x${string}`; - delegator?: `0x${string}`; + safeAddress?: Address; + delegate?: Address; + delegator?: Address; label?: string; limit?: number; offset?: number; }): Promise>>; getDelegatesV2(args: { - safeAddress?: `0x${string}`; - delegate?: `0x${string}`; - delegator?: `0x${string}`; + safeAddress?: Address; + delegate?: Address; + delegator?: Address; label?: string; limit?: number; offset?: number; }): Promise>>; - clearDelegates(safeAddress?: `0x${string}`): Promise; + clearDelegates(safeAddress?: Address): Promise; postDelegate(args: { - safeAddress: `0x${string}` | null; - delegate: `0x${string}`; - delegator: `0x${string}`; + safeAddress: Address | null; + delegate: Address; + delegator: Address; signature: string; label: string; }): Promise; postDelegateV2(args: { - safeAddress: `0x${string}` | null; - delegate: `0x${string}`; - delegator: `0x${string}`; + safeAddress: Address | null; + delegate: Address; + delegator: Address; signature: string; label: string; }): Promise; deleteDelegate(args: { - delegate: `0x${string}`; - delegator: `0x${string}`; + delegate: Address; + delegator: Address; signature: string; }): Promise; deleteSafeDelegate(args: { - delegate: `0x${string}`; - safeAddress: `0x${string}`; + delegate: Address; + safeAddress: Address; signature: string; }): Promise; deleteDelegateV2(args: { - delegate: `0x${string}`; - delegator: `0x${string}`; - safeAddress: `0x${string}` | null; + delegate: Address; + delegator: Address; + safeAddress: Address | null; signature: string; }): Promise; getTransfer(transferId: string): Promise>; getTransfers(args: { - safeAddress: `0x${string}`; + safeAddress: Address; onlyErc20?: boolean; onlyErc721?: boolean; limit?: number; offset?: number; }): Promise>>; - clearTransfers(safeAddress: `0x${string}`): Promise; + clearTransfers(safeAddress: Address): Promise; getIncomingTransfers(args: { - safeAddress: `0x${string}`; + safeAddress: Address; executionDateGte?: string; executionDateLte?: string; - to?: `0x${string}`; + to?: Address; value?: string; - tokenAddress?: `0x${string}`; + tokenAddress?: Address; txHash?: string; limit?: number; offset?: number; }): Promise>>; - clearIncomingTransfers(safeAddress: `0x${string}`): Promise; + clearIncomingTransfers(safeAddress: Address): Promise; postConfirmation(args: { safeTxHash: string; addConfirmationDto: AddConfirmationDto; }): Promise; - getSafesByModule(moduleAddress: `0x${string}`): Promise>; + getSafesByModule(moduleAddress: Address): Promise>; getModuleTransaction( moduleTransactionId: string, ): Promise>; getModuleTransactions(args: { - safeAddress: `0x${string}`; + safeAddress: Address; to?: string; txHash?: string; module?: string; @@ -140,7 +141,7 @@ export interface ITransactionApi { offset?: number; }): Promise>>; - clearModuleTransactions(safeAddress: `0x${string}`): Promise; + clearModuleTransactions(safeAddress: Address): Promise; getMultisigTransaction( safeTransactionHash: string, @@ -158,13 +159,13 @@ export interface ITransactionApi { clearMultisigTransaction(safeTransactionHash: string): Promise; getMultisigTransactions(args: { - safeAddress: `0x${string}`; + safeAddress: Address; ordering?: string; executed?: boolean; trusted?: boolean; executionDateGte?: string; executionDateLte?: string; - to?: `0x${string}`; + to?: Address; value?: string; nonce?: string; nonceGte?: number; @@ -173,7 +174,7 @@ export interface ITransactionApi { }): Promise>>; getMultisigTransactionsWithNoCache(args: { - safeAddress: `0x${string}`; + safeAddress: Address; // Transaction Service parameters failed?: boolean; modified__lt?: string; @@ -203,18 +204,18 @@ export interface ITransactionApi { offset?: number; }): Promise>>; - clearMultisigTransactions(safeAddress: `0x${string}`): Promise; + clearMultisigTransactions(safeAddress: Address): Promise; getCreationTransaction( - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise>; getCreationTransactionWithNoCache( - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise>; getAllTransactions(args: { - safeAddress: `0x${string}`; + safeAddress: Address; ordering?: string; executed?: boolean; queued?: boolean; @@ -222,37 +223,37 @@ export interface ITransactionApi { offset?: number; }): Promise>>; - clearAllTransactions(safeAddress: `0x${string}`): Promise; + clearAllTransactions(safeAddress: Address): Promise; - getToken(address: `0x${string}`): Promise>; + getToken(address: Address): Promise>; getTokens(args: { limit?: number; offset?: number; }): Promise>>; - getSafesByOwner(ownerAddress: `0x${string}`): Promise>; + getSafesByOwner(ownerAddress: Address): Promise>; getEstimation(args: { - address: `0x${string}`; + address: Address; getEstimationDto: GetEstimationDto; }): Promise>; getMessageByHash(messageHash: string): Promise>; getMessagesBySafe(args: { - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; }): Promise>>; postMultisigTransaction(args: { - address: `0x${string}`; + address: Address; data: ProposeTransactionDto; }): Promise; postMessage(args: { - safeAddress: `0x${string}`; + safeAddress: Address; message: unknown; safeAppId: number | null; signature: string; @@ -261,10 +262,10 @@ export interface ITransactionApi { postMessageSignature(args: { messageHash: string; - signature: `0x${string}`; + signature: Hex; }): Promise; - clearMessagesBySafe(args: { safeAddress: `0x${string}` }): Promise; + clearMessagesBySafe(args: { safeAddress: Address }): Promise; clearMessagesByHash(args: { messageHash: string }): Promise; } diff --git a/src/domain/messages/entities/__tests__/message-confirmation.builder.ts b/src/domain/messages/entities/__tests__/message-confirmation.builder.ts index 3a1bcae477..82251a02c6 100644 --- a/src/domain/messages/entities/__tests__/message-confirmation.builder.ts +++ b/src/domain/messages/entities/__tests__/message-confirmation.builder.ts @@ -2,7 +2,7 @@ import { faker } from '@faker-js/faker'; import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { MessageConfirmation } from '@/domain/messages/entities/message-confirmation.entity'; -import { getAddress } from 'viem'; +import { type Hex, getAddress } from 'viem'; import { SignatureType } from '@/domain/common/entities/signature-type.entity'; export function messageConfirmationBuilder(): IBuilder { @@ -10,10 +10,7 @@ export function messageConfirmationBuilder(): IBuilder { .with('created', faker.date.recent()) .with('modified', faker.date.recent()) .with('owner', getAddress(faker.finance.ethereumAddress())) - .with( - 'signature', - faker.string.hexadecimal({ length: 130 }) as `0x${string}`, - ) + .with('signature', faker.string.hexadecimal({ length: 130 }) as Hex) .with('signatureType', faker.helpers.objectValue(SignatureType)); } diff --git a/src/domain/messages/entities/__tests__/message.builder.ts b/src/domain/messages/entities/__tests__/message.builder.ts index 635b6600b4..4ac1fd9776 100644 --- a/src/domain/messages/entities/__tests__/message.builder.ts +++ b/src/domain/messages/entities/__tests__/message.builder.ts @@ -5,7 +5,12 @@ import { messageConfirmationBuilder, toJson as messageConfirmationToJson, } from '@/domain/messages/entities/__tests__/message-confirmation.builder'; -import { getAddress, type PrivateKeyAccount } from 'viem'; +import { + type Address, + getAddress, + type Hash, + type PrivateKeyAccount, +} from 'viem'; import { fakeJson } from '@/__tests__/faker'; import { SignatureType } from '@/domain/common/entities/signature-type.entity'; import { getSafeMessageMessageHash } from '@/domain/common/utils/safe'; @@ -70,10 +75,7 @@ export function messageBuilder(): BuilderWithConfirmations { .with('modified', faker.date.recent()) .with('safe', getAddress(faker.finance.ethereumAddress())) .with('message', faker.word.words({ count: { min: 1, max: 5 } })) - .with( - 'messageHash', - faker.string.hexadecimal({ length: 32 }) as `0x${string}`, - ) + .with('messageHash', faker.string.hexadecimal({ length: 32 }) as Hash) .with('proposedBy', getAddress(faker.finance.ethereumAddress())) .with('safeAppId', faker.number.int()) .with( @@ -84,7 +86,7 @@ export function messageBuilder(): BuilderWithConfirmations { ) .with( 'preparedSignature', - faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + faker.string.hexadecimal({ length: 32 }) as Address, ) .with('origin', fakeJson()); } diff --git a/src/domain/messages/entities/__tests__/message.entity.spec.ts b/src/domain/messages/entities/__tests__/message.entity.spec.ts index b7b51c538e..1241bdc8cd 100644 --- a/src/domain/messages/entities/__tests__/message.entity.spec.ts +++ b/src/domain/messages/entities/__tests__/message.entity.spec.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { typedDataBuilder } from '@/routes/messages/entities/__tests__/typed-data.builder'; import { messageBuilder } from '@/domain/messages/entities/__tests__/message.builder'; import { MessageSchema } from '@/domain/messages/entities/message.entity'; @@ -54,7 +54,7 @@ describe('MessageSchema', () => { (key) => { const nonChecksummedAddress = faker.finance.ethereumAddress().toString(); const message = messageBuilder() - .with(key, nonChecksummedAddress as `0x${string}`) + .with(key, nonChecksummedAddress as Address) .build(); const result = MessageSchema.safeParse(message); @@ -69,7 +69,7 @@ describe('MessageSchema', () => { 'should not allow a non-hex messageHash', (key) => { const message = messageBuilder() - .with(key, faker.string.alphanumeric() as `0x${string}`) + .with(key, faker.string.alphanumeric() as Address) .build(); const result = MessageSchema.safeParse(message); diff --git a/src/domain/messages/entities/__tests__/typed-data.entity.spec.ts b/src/domain/messages/entities/__tests__/typed-data.entity.spec.ts index 9f50c017f7..88b11be358 100644 --- a/src/domain/messages/entities/__tests__/typed-data.entity.spec.ts +++ b/src/domain/messages/entities/__tests__/typed-data.entity.spec.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { _TypedDataDomainSchema, TypedDataSchema, @@ -88,7 +88,7 @@ describe('TypedDataSchema', () => { it('should require a hex salt', () => { const domain = typedDataDomainBuilder() - .with('salt', faker.string.alpha() as `0x${string}`) + .with('salt', faker.string.alpha() as Address) .build(); const result = _TypedDataDomainSchema.safeParse(domain); @@ -105,7 +105,7 @@ describe('TypedDataSchema', () => { it('should checksum the verifyingContract', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const domain = typedDataDomainBuilder() .with('verifyingContract', nonChecksummedAddress) .build(); diff --git a/src/domain/messages/entities/message-confirmation.entity.spec.ts b/src/domain/messages/entities/message-confirmation.entity.spec.ts index aa75b0afa2..c4af83af60 100644 --- a/src/domain/messages/entities/message-confirmation.entity.spec.ts +++ b/src/domain/messages/entities/message-confirmation.entity.spec.ts @@ -2,7 +2,7 @@ import type { SignatureType } from '@/domain/common/entities/signature-type.enti import { messageConfirmationBuilder } from '@/domain/messages/entities/__tests__/message-confirmation.builder'; import { MessageConfirmationSchema } from '@/domain/messages/entities/message-confirmation.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('MessageConfirmationSchema', () => { @@ -32,7 +32,7 @@ describe('MessageConfirmationSchema', () => { it('should checksum the owner', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const messageConfirmation = messageConfirmationBuilder() .with('owner', nonChecksummedAddress) .build(); @@ -46,7 +46,7 @@ describe('MessageConfirmationSchema', () => { it('should not allow non-hex signature', () => { const messageConfirmation = messageConfirmationBuilder() - .with('signature', faker.string.numeric() as `0x${string}`) + .with('signature', faker.string.numeric() as Address) .build(); const result = MessageConfirmationSchema.safeParse(messageConfirmation); diff --git a/src/domain/messages/entities/message.entity.spec.ts b/src/domain/messages/entities/message.entity.spec.ts index 16e17275bd..42e6a2e5a9 100644 --- a/src/domain/messages/entities/message.entity.spec.ts +++ b/src/domain/messages/entities/message.entity.spec.ts @@ -6,7 +6,7 @@ import { MessagePageSchema, } from '@/domain/messages/entities/message.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('Message entity schemas', () => { @@ -37,7 +37,7 @@ describe('Message entity schemas', () => { (key) => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const message = messageBuilder() .with(key, nonChecksummedAddress) .build(); @@ -54,7 +54,7 @@ describe('Message entity schemas', () => { 'should not allow non-hex %s', (key) => { const message = messageBuilder() - .with(key, faker.string.numeric() as `0x${string}`) + .with(key, faker.string.numeric() as Address) .build(); const result = MessageSchema.safeParse(message); diff --git a/src/domain/messages/helpers/message-verifier.helper.spec.ts b/src/domain/messages/helpers/message-verifier.helper.spec.ts index 78f09480b5..1ab6d6db4f 100644 --- a/src/domain/messages/helpers/message-verifier.helper.spec.ts +++ b/src/domain/messages/helpers/message-verifier.helper.spec.ts @@ -1,6 +1,6 @@ import { faker } from '@faker-js/faker'; import { get } from 'lodash'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'; import { MessageVerifierHelper } from '@/domain/messages/helpers/message-verifier.helper'; import { messageBuilder } from '@/domain/messages/entities/__tests__/message.builder'; @@ -203,7 +203,7 @@ describe('MessageVerifierHelper', () => { safe, }); message.confirmations[0].signature = - message.confirmations[0].signature.slice(0, 129) as `0x${string}`; + message.confirmations[0].signature.slice(0, 129) as Address; expect(() => { return target.verifyCreation({ @@ -243,7 +243,7 @@ describe('MessageVerifierHelper', () => { safe, }); message.confirmations[0].signature = - message.confirmations[0].signature.slice(0, 128) as `0x${string}`; + message.confirmations[0].signature.slice(0, 128) as Address; expect(() => { return target.verifyCreation({ @@ -502,7 +502,7 @@ describe('MessageVerifierHelper', () => { }); message.messageHash = faker.string.hexadecimal({ length: 64, - }) as `0x${string}`; + }) as Address; expect(() => { return target.verifyUpdate({ @@ -604,7 +604,7 @@ describe('MessageVerifierHelper', () => { safe, }); message.confirmations[0].signature = - message.confirmations[0].signature.slice(0, 129) as `0x${string}`; + message.confirmations[0].signature.slice(0, 129) as Address; expect(() => { return target.verifyUpdate({ @@ -645,7 +645,7 @@ describe('MessageVerifierHelper', () => { safe, }); message.confirmations[0].signature = - message.confirmations[0].signature.slice(0, 128) as `0x${string}`; + message.confirmations[0].signature.slice(0, 128) as Address; expect(() => { return target.verifyUpdate({ diff --git a/src/domain/messages/helpers/message-verifier.helper.ts b/src/domain/messages/helpers/message-verifier.helper.ts index 68de36303b..4623cc6f7b 100644 --- a/src/domain/messages/helpers/message-verifier.helper.ts +++ b/src/domain/messages/helpers/message-verifier.helper.ts @@ -9,6 +9,7 @@ import { Message } from '@/domain/messages/entities/message.entity'; import { Safe } from '@/domain/safe/entities/safe.entity'; import { LoggingService, ILoggingService } from '@/logging/logging.interface'; import { HttpStatus, Inject, Injectable } from '@nestjs/common'; +import type { Address, Hash, Hex } from 'viem'; import { isAddressEqual } from 'viem'; enum ErrorMessage { @@ -24,7 +25,7 @@ export class MessageVerifierHelper { private readonly isEthSignEnabled: boolean; private readonly isMessageVerificationEnabled: boolean; - private readonly blocklist: Array<`0x${string}`>; + private readonly blocklist: Array
; constructor( @Inject(IConfigurationService) @@ -46,7 +47,7 @@ export class MessageVerifierHelper { chainId: string; safe: Safe; message: Message['message']; - signature: `0x${string}`; + signature: Hex; }): void { if (!this.isMessageVerificationEnabled) { return; @@ -71,8 +72,8 @@ export class MessageVerifierHelper { chainId: string; safe: Safe; message: Message['message']; - messageHash: `0x${string}`; - signature: `0x${string}`; + messageHash: Hash; + signature: Hex; }): void { if (!this.isMessageVerificationEnabled) { return; @@ -98,7 +99,7 @@ export class MessageVerifierHelper { private verifyMessageHash(args: { chainId: string; safe: Safe; - expectedHash: `0x${string}`; + expectedHash: Hex; message: Message['message']; source: LogSource; }): void { @@ -121,8 +122,8 @@ export class MessageVerifierHelper { safe: Safe; message: Message['message']; source: LogSource; - }): `0x${string}` { - let calculatedHash: `0x${string}`; + }): Hash { + let calculatedHash: Hex; try { calculatedHash = getSafeMessageMessageHash(args); } catch { @@ -138,8 +139,8 @@ export class MessageVerifierHelper { private verifySignature(args: { safe: Safe; chainId: string; - messageHash: `0x${string}`; - signature: `0x${string}`; + messageHash: Hash; + signature: Hex; source: LogSource; }): void { const signature = new SafeSignature({ @@ -206,7 +207,7 @@ export class MessageVerifierHelper { private logMismatchMessageHash(args: { chainId: string; safe: Safe; - messageHash: `0x${string}`; + messageHash: Hash; message: Message['message']; source: LogSource; }): void { @@ -225,9 +226,9 @@ export class MessageVerifierHelper { private logBlockedAddress(args: { chainId: string; safe: Safe; - messageHash: `0x${string}`; - signature: `0x${string}`; - blockedAddress: `0x${string}`; + messageHash: Hash; + signature: Hex; + blockedAddress: Address; source: LogSource; }): void { this.loggingService.error({ @@ -246,9 +247,9 @@ export class MessageVerifierHelper { private logInvalidSignature(args: { chainId: string; safe: Safe; - messageHash: `0x${string}`; - signerAddress: `0x${string}`; - signature: `0x${string}`; + messageHash: Hash; + signerAddress: Address; + signature: Hex; source: LogSource; }): void { this.loggingService.error({ diff --git a/src/domain/messages/messages.repository.interface.ts b/src/domain/messages/messages.repository.interface.ts index d5dba66c8f..6555347f39 100644 --- a/src/domain/messages/messages.repository.interface.ts +++ b/src/domain/messages/messages.repository.interface.ts @@ -6,6 +6,7 @@ import { TransactionApiManagerModule } from '@/domain/interfaces/transaction-api import { SafeRepositoryModule } from '@/domain/safe/safe.repository.interface'; import { MessageVerifierHelper } from '@/domain/messages/helpers/message-verifier.helper'; import { TypedData } from '@/domain/messages/entities/typed-data.entity'; +import type { Address, Hex } from 'viem'; export const IMessagesRepository = Symbol('IMessagesRepository'); @@ -17,17 +18,17 @@ export interface IMessagesRepository { getMessagesBySafe(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; }): Promise>; createMessage(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; message: string | TypedData; safeAppId: number; - signature: `0x${string}`; + signature: Hex; origin: string | null; }): Promise; @@ -39,7 +40,7 @@ export interface IMessagesRepository { clearMessagesBySafe(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; clearMessagesByHash(args: { diff --git a/src/domain/messages/messages.repository.ts b/src/domain/messages/messages.repository.ts index ed8756e03c..78b1f5e55f 100644 --- a/src/domain/messages/messages.repository.ts +++ b/src/domain/messages/messages.repository.ts @@ -10,6 +10,7 @@ import { import { MessageVerifierHelper } from '@/domain/messages/helpers/message-verifier.helper'; import { ISafeRepository } from '@/domain/safe/safe.repository.interface'; import { TypedData } from '@/domain/messages/entities/typed-data.entity'; +import type { Address, Hash, Hex } from 'viem'; @Injectable() export class MessagesRepository implements IMessagesRepository { @@ -23,7 +24,7 @@ export class MessagesRepository implements IMessagesRepository { async getMessageByHash(args: { chainId: string; - messageHash: `0x${string}`; + messageHash: Hash; }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, @@ -34,7 +35,7 @@ export class MessagesRepository implements IMessagesRepository { async getMessagesBySafe(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number | undefined; offset?: number | undefined; }): Promise> { @@ -52,10 +53,10 @@ export class MessagesRepository implements IMessagesRepository { async createMessage(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; message: string | TypedData; safeAppId: number | null; - signature: `0x${string}`; + signature: Hex; origin: string | null; }): Promise { const safe = await this.safeRepository.getSafe({ @@ -82,8 +83,8 @@ export class MessagesRepository implements IMessagesRepository { async updateMessageSignature(args: { chainId: string; - messageHash: `0x${string}`; - signature: `0x${string}`; + messageHash: Hash; + signature: Hex; }): Promise { const message = await this.getMessageByHash({ chainId: args.chainId, @@ -109,7 +110,7 @@ export class MessagesRepository implements IMessagesRepository { async clearMessagesBySafe(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const api = await this.transactionApiManager.getApi(args.chainId); await api.clearMessagesBySafe(args); diff --git a/src/domain/notifications/v2/entities/__tests__/delete-all-subscriptions.dto.entity.spec.ts b/src/domain/notifications/v2/entities/__tests__/delete-all-subscriptions.dto.entity.spec.ts index 98267c6c5e..1861eb8964 100644 --- a/src/domain/notifications/v2/entities/__tests__/delete-all-subscriptions.dto.entity.spec.ts +++ b/src/domain/notifications/v2/entities/__tests__/delete-all-subscriptions.dto.entity.spec.ts @@ -2,7 +2,7 @@ import { DeleteAllSubscriptionsDtoSchema } from '@/domain/notifications/v2/entit import { deleteAllSubscriptionsDtoBuilder } from '@/domain/notifications/v2/entities/__tests__/delete-all-subscriptions.dto.builder'; import { faker } from '@faker-js/faker'; import type { UUID } from 'crypto'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; describe('DeleteAllSubscriptionsDtoSchema', () => { it('should validate a valid DeleteAllSubscriptionsDto', () => { @@ -93,7 +93,7 @@ describe('DeleteAllSubscriptionsDtoSchema', () => { { chainId: faker.string.numeric(), deviceUuid: faker.string.uuid() as UUID, - safeAddress: nonChecksummedAddress as `0x${string}`, + safeAddress: nonChecksummedAddress as Address, }, ], }; @@ -113,7 +113,7 @@ describe('DeleteAllSubscriptionsDtoSchema', () => { { chainId: faker.string.numeric(), deviceUuid: faker.string.uuid() as UUID, - safeAddress: 'not-an-address' as `0x${string}`, + safeAddress: 'not-an-address' as Address, }, ], }; @@ -253,7 +253,7 @@ describe('DeleteAllSubscriptionsDtoSchema', () => { chainId: faker.string.numeric(), deviceUuid: faker.string.uuid() as UUID, safeAddress: getAddress(faker.finance.ethereumAddress()), - signerAddress: nonChecksummedAddress as `0x${string}`, + signerAddress: nonChecksummedAddress as Address, }, ]) .build(); @@ -274,7 +274,7 @@ describe('DeleteAllSubscriptionsDtoSchema', () => { chainId: faker.string.numeric(), deviceUuid: faker.string.uuid() as UUID, safeAddress: getAddress(faker.finance.ethereumAddress()), - signerAddress: 'not-an-address' as `0x${string}`, + signerAddress: 'not-an-address' as Address, }, ]) .build(); diff --git a/src/domain/notifications/v2/entities/__tests__/upsert-subscriptions-dto.entity.spec.ts b/src/domain/notifications/v2/entities/__tests__/upsert-subscriptions-dto.entity.spec.ts index 89dc14860e..0eaec00f79 100644 --- a/src/domain/notifications/v2/entities/__tests__/upsert-subscriptions-dto.entity.spec.ts +++ b/src/domain/notifications/v2/entities/__tests__/upsert-subscriptions-dto.entity.spec.ts @@ -4,7 +4,7 @@ import { upsertSubscriptionsDtoBuilder } from '@/routes/notifications/v2/entitie import { UpsertSubscriptionsDtoSchema } from '@/domain/notifications/v2/entities/upsert-subscriptions.dto.entity'; import { faker } from '@faker-js/faker'; import type { UUID } from 'crypto'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; describe('UpsertSubscriptionsDtoSchema', () => { it('should validate a valid UpsertSubscriptionsDto', () => { @@ -131,7 +131,7 @@ describe('UpsertSubscriptionsDtoSchema', () => { .with('safes', [ { chainId: faker.string.numeric(), - address: nonChecksummedAddress as `0x${string}`, + address: nonChecksummedAddress as Address, notificationTypes: faker.helpers.arrayElements( Object.values(NotificationType), ), diff --git a/src/domain/notifications/v2/notifications.repository.interface.ts b/src/domain/notifications/v2/notifications.repository.interface.ts index 83c3de108c..a61b6e5fa1 100644 --- a/src/domain/notifications/v2/notifications.repository.interface.ts +++ b/src/domain/notifications/v2/notifications.repository.interface.ts @@ -3,6 +3,7 @@ import type { FirebaseNotification } from '@/datasources/push-notifications-api/ import type { UUID } from 'crypto'; import type { AuthPayload } from '@/domain/auth/entities/auth-payload.entity'; import type { NotificationType } from '@/datasources/notifications/entities/notification-type.entity.db'; +import type { Address } from 'viem'; export const INotificationsRepositoryV2 = Symbol('INotificationsRepositoryV2'); @@ -24,15 +25,15 @@ export interface INotificationsRepositoryV2 { authPayload: AuthPayload; deviceUuid: UUID; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise>; getSubscribersBySafe(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise< Array<{ - subscriber: `0x${string}` | null; + subscriber: Address | null; deviceUuid: UUID; cloudMessagingToken: string; }> @@ -42,15 +43,15 @@ export interface INotificationsRepositoryV2 { subscriptions: Array<{ chainId: string; deviceUuid: UUID; - safeAddress: `0x${string}`; - signerAddress?: `0x${string}` | null; + safeAddress: Address; + signerAddress?: Address | null; }>; }): Promise; deleteSubscription(args: { deviceUuid: UUID; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; deleteDevice(deviceUuid: UUID): Promise; diff --git a/src/domain/notifications/v2/notifications.repository.spec.ts b/src/domain/notifications/v2/notifications.repository.spec.ts index 4cd8d4dc13..d7bbbbd84b 100644 --- a/src/domain/notifications/v2/notifications.repository.spec.ts +++ b/src/domain/notifications/v2/notifications.repository.spec.ts @@ -16,7 +16,7 @@ import { NotificationDevice } from '@/datasources/notifications/entities/notific import { mockEntityManager } from '@/datasources/db/v2/__tests__/entity-manager.mock'; import { mockPostgresDatabaseService } from '@/datasources/db/v2/__tests__/postgresql-database.service.mock'; import { mockRepository } from '@/datasources/db/v2/__tests__/repository.mock'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { IsNull } from 'typeorm'; import { deleteAllSubscriptionsDtoBuilder } from '@/domain/notifications/v2/entities/__tests__/delete-all-subscriptions.dto.builder'; import type { ConfigService } from '@nestjs/config'; @@ -240,7 +240,7 @@ describe('NotificationsRepositoryV2', () => { authPayload: authPayload, deviceUuid: faker.string.uuid() as UUID, chainId: authPayload.chain_id as string, - safeAddress: faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + safeAddress: faker.string.hexadecimal({ length: 32 }) as Address, }; const result = await notificationsRepository.getSafeSubscription(args); @@ -263,7 +263,7 @@ describe('NotificationsRepositoryV2', () => { it('Should throw UnauthorizedException if signer_address is not passed', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', '' as `0x${string}`) + .with('signer_address', '' as Address) .build(); const authPayload = new AuthPayload(authPayloadDto); @@ -273,7 +273,7 @@ describe('NotificationsRepositoryV2', () => { chainId: authPayload.chain_id as string, safeAddress: faker.string.hexadecimal({ length: 32, - }) as `0x${string}`, + }) as Address, }; const result = notificationsRepository.getSafeSubscription(args); @@ -296,7 +296,7 @@ describe('NotificationsRepositoryV2', () => { chainId: authPayload.chain_id as string, safeAddress: faker.string.hexadecimal({ length: 32, - }) as `0x${string}`, + }) as Address, }; const result = await notificationsRepository.getSafeSubscription(args); @@ -333,7 +333,7 @@ describe('NotificationsRepositoryV2', () => { const result = await notificationsRepository.getSubscribersBySafe({ chainId: faker.number.int({ min: 1, max: 100 }).toString(), - safeAddress: faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + safeAddress: faker.string.hexadecimal({ length: 32 }) as Address, }); const output = mockSubscribers.map( @@ -358,7 +358,7 @@ describe('NotificationsRepositoryV2', () => { const result = await notificationsRepository.getSubscribersBySafe({ chainId: faker.number.int({ min: 1, max: 100 }).toString(), - safeAddress: faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + safeAddress: faker.string.hexadecimal({ length: 32 }) as Address, }); expect(result).toEqual([]); @@ -381,7 +381,7 @@ describe('NotificationsRepositoryV2', () => { const args = { deviceUuid: faker.string.uuid() as UUID, chainId: faker.number.int({ min: 0 }).toString(), - safeAddress: faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + safeAddress: faker.string.hexadecimal({ length: 32 }) as Address, }; await notificationsRepository.deleteSubscription(args); @@ -415,7 +415,7 @@ describe('NotificationsRepositoryV2', () => { const args = { deviceUuid: faker.string.uuid() as UUID, chainId: faker.number.int({ min: 0 }).toString(), - safeAddress: faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + safeAddress: faker.string.hexadecimal({ length: 32 }) as Address, }; const result = notificationsRepository.deleteSubscription(args); diff --git a/src/domain/notifications/v2/notifications.repository.ts b/src/domain/notifications/v2/notifications.repository.ts index 0bff8168b4..9f3cff5bbd 100644 --- a/src/domain/notifications/v2/notifications.repository.ts +++ b/src/domain/notifications/v2/notifications.repository.ts @@ -21,6 +21,7 @@ import { PostgresDatabaseService } from '@/datasources/db/v2/postgres-database.s import { NotificationSubscriptionNotificationType } from '@/datasources/notifications/entities/notification-subscription-notification-type.entity.db'; import { IConfigurationService } from '@/config/configuration.service.interface'; import { CacheRouter } from '@/datasources/cache/cache.router'; +import type { Address } from 'viem'; @Injectable() export class NotificationsRepositoryV2 implements INotificationsRepositoryV2 { @@ -167,7 +168,7 @@ export class NotificationsRepositoryV2 implements INotificationsRepositoryV2 { entityManager: EntityManager, args: { deviceId: number; - signerAddress?: `0x${string}`; + signerAddress?: Address; upsertSubscriptionsDto: UpsertSubscriptionsDto; }, ): Promise { @@ -314,7 +315,7 @@ export class NotificationsRepositoryV2 implements INotificationsRepositoryV2 { authPayload: AuthPayload; deviceUuid: UUID; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise> { if (!args.authPayload.signer_address) { throw new UnauthorizedException(); @@ -344,10 +345,10 @@ export class NotificationsRepositoryV2 implements INotificationsRepositoryV2 { public async getSubscribersBySafe(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise< Array<{ - subscriber: `0x${string}` | null; + subscriber: Address | null; deviceUuid: UUID; cloudMessagingToken: string; }> @@ -378,7 +379,7 @@ export class NotificationsRepositoryV2 implements INotificationsRepositoryV2 { }); const output: Array<{ - subscriber: `0x${string}` | null; + subscriber: Address | null; deviceUuid: UUID; cloudMessagingToken: string; }> = []; @@ -398,7 +399,7 @@ export class NotificationsRepositoryV2 implements INotificationsRepositoryV2 { public async deleteSubscription(args: { deviceUuid: UUID; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const notificationsSubscriptionsRepository = await this.postgresDatabaseService.getRepository( @@ -429,8 +430,8 @@ export class NotificationsRepositoryV2 implements INotificationsRepositoryV2 { subscriptions: Array<{ chainId: string; deviceUuid: UUID; - safeAddress: `0x${string}`; - signerAddress?: `0x${string}` | null; + safeAddress: Address; + signerAddress?: Address | null; }>; }): Promise { const notificationsSubscriptionsRepository = @@ -505,7 +506,7 @@ export class NotificationsRepositoryV2 implements INotificationsRepositoryV2 { private getSubscribersBySafeCacheKey(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): string { return CacheRouter.getOrnCacheKey( 'getSubscribersBySafe', @@ -516,7 +517,7 @@ export class NotificationsRepositoryV2 implements INotificationsRepositoryV2 { private async removeGetSubscribersBySafeCache(args: { entityManager: EntityManager; - safes: Array<{ chainId: string; address: `0x${string}` }>; + safes: Array<{ chainId: string; address: Address }>; }): Promise { for (const safe of args.safes) { const subscriptionsCacheKey = this.getSubscribersBySafeCacheKey({ diff --git a/src/domain/positions/positions.repository.interface.ts b/src/domain/positions/positions.repository.interface.ts index 864af784b4..5b398e042b 100644 --- a/src/domain/positions/positions.repository.interface.ts +++ b/src/domain/positions/positions.repository.interface.ts @@ -3,19 +3,20 @@ import { PositionsRepository } from '@/domain/positions/positions.repository'; import { PositionsApiModule } from '@/datasources/positions-api/positions-api.module'; import { Chain } from '@/domain/chains/entities/chain.entity'; import { Position } from '@/domain/positions/entities/position.entity'; +import type { Address } from 'viem'; export const IPositionsRepository = Symbol('IPositionsRepository'); export interface IPositionsRepository { getPositions(args: { chain: Chain; - safeAddress: `0x${string}`; + safeAddress: Address; fiatCode: string; }): Promise>; clearPositions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; getFiatCodes(): Promise>; diff --git a/src/domain/positions/positions.repository.ts b/src/domain/positions/positions.repository.ts index 1dd179d0f6..ab3dc7e04e 100644 --- a/src/domain/positions/positions.repository.ts +++ b/src/domain/positions/positions.repository.ts @@ -7,6 +7,7 @@ import { Position, PositionsSchema, } from '@/domain/positions/entities/position.entity'; +import type { Address } from 'viem'; @Injectable() export class PositionsRepository implements IPositionsRepository { @@ -16,7 +17,7 @@ export class PositionsRepository implements IPositionsRepository { async getPositions(args: { chain: Chain; - safeAddress: `0x${string}`; + safeAddress: Address; fiatCode: string; }): Promise> { const positions = await this.positionsApi.getPositions(args); @@ -25,7 +26,7 @@ export class PositionsRepository implements IPositionsRepository { async clearPositions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { await this.positionsApi.clearPositions(args); } diff --git a/src/domain/relay/contracts/__tests__/encoders/erc20-encoder.builder.ts b/src/domain/relay/contracts/__tests__/encoders/erc20-encoder.builder.ts index 852505ed3e..b31969d336 100644 --- a/src/domain/relay/contracts/__tests__/encoders/erc20-encoder.builder.ts +++ b/src/domain/relay/contracts/__tests__/encoders/erc20-encoder.builder.ts @@ -1,4 +1,5 @@ import { faker } from '@faker-js/faker'; +import type { Address } from 'viem'; import { encodeFunctionData, getAddress, erc20Abi } from 'viem'; import { Builder } from '@/__tests__/builder'; import type { IEncoder } from '@/__tests__/encoder-builder'; @@ -6,7 +7,7 @@ import type { IEncoder } from '@/__tests__/encoder-builder'; // transfer type Erc20TransferArgs = { - to: `0x${string}`; + to: Address; value: bigint; }; @@ -14,7 +15,7 @@ class Erc20TransferEncoder extends Builder implements IEncoder { - encode(): `0x${string}` { + encode(): Address { const args = this.build(); return encodeFunctionData({ @@ -34,8 +35,8 @@ export function erc20TransferEncoder(): Erc20TransferEncoder // transferFrom type Erc20TransferFromArgs = { - sender: `0x${string}`; - recipient: `0x${string}`; + sender: Address; + recipient: Address; amount: bigint; }; @@ -43,7 +44,7 @@ class Erc20TransferFromEncoder extends Builder implements IEncoder { - encode(): `0x${string}` { + encode(): Address { const args = this.build(); return encodeFunctionData({ @@ -64,7 +65,7 @@ export function erc20TransferFromEncoder(): Erc20TransferFromEncoder extends Builder implements IEncoder { - encode(): `0x${string}` { + encode(): Address { const args = this.build(); return encodeFunctionData({ diff --git a/src/domain/relay/contracts/__tests__/encoders/proxy-factory-encoder.builder.ts b/src/domain/relay/contracts/__tests__/encoders/proxy-factory-encoder.builder.ts index 2cabe64aa9..20b3caa8c6 100644 --- a/src/domain/relay/contracts/__tests__/encoders/proxy-factory-encoder.builder.ts +++ b/src/domain/relay/contracts/__tests__/encoders/proxy-factory-encoder.builder.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { encodeFunctionData, getAddress } from 'viem'; +import { type Address, encodeFunctionData, getAddress } from 'viem'; import ProxyFactory130 from '@/abis/safe/v1.3.0/GnosisSafeProxyFactory.abi'; import type { IEncoder } from '@/__tests__/encoder-builder'; import { Builder } from '@/__tests__/builder'; @@ -8,8 +8,8 @@ import { setupEncoder } from '@/domain/contracts/__tests__/encoders/safe-encoder // createProxyWithNonce type CreateProxyWithNonceArgs = { - singleton: `0x${string}`; - initializer: `0x${string}`; + singleton: Address; + initializer: Address; saltNonce: bigint; }; @@ -17,7 +17,7 @@ class SetupEncoder extends Builder implements IEncoder { - encode(): `0x${string}` { + encode(): Address { const args = this.build(); return encodeFunctionData({ diff --git a/src/domain/relay/contracts/decoders/__tests__/erc20-decoder.helper.spec.ts b/src/domain/relay/contracts/decoders/__tests__/erc20-decoder.helper.spec.ts index 9c3b2f53a4..020b414016 100644 --- a/src/domain/relay/contracts/decoders/__tests__/erc20-decoder.helper.spec.ts +++ b/src/domain/relay/contracts/decoders/__tests__/erc20-decoder.helper.spec.ts @@ -1,6 +1,7 @@ import { faker } from '@faker-js/faker'; import { Erc20Decoder } from '@/domain/relay/contracts/decoders/erc-20-decoder.helper'; import { erc20TransferEncoder } from '@/domain/relay/contracts/__tests__/encoders/erc20-encoder.builder'; +import type { Hex } from 'viem'; describe('Erc20Decoder', () => { let target: Erc20Decoder; @@ -22,7 +23,7 @@ describe('Erc20Decoder', () => { }); it('throws if the function call cannot be decoded', () => { - const data = faker.string.hexadecimal({ length: 138 }) as `0x${string}`; + const data = faker.string.hexadecimal({ length: 138 }) as Hex; expect(() => target.decodeFunctionData({ data })).toThrow(); }); diff --git a/src/domain/relay/contracts/decoders/__tests__/proxy-factory-decoder.helper.spec.ts b/src/domain/relay/contracts/decoders/__tests__/proxy-factory-decoder.helper.spec.ts index ec51849b9d..12069adf54 100644 --- a/src/domain/relay/contracts/decoders/__tests__/proxy-factory-decoder.helper.spec.ts +++ b/src/domain/relay/contracts/decoders/__tests__/proxy-factory-decoder.helper.spec.ts @@ -1,6 +1,7 @@ import { faker } from '@faker-js/faker'; import { ProxyFactoryDecoder } from '@/domain/relay/contracts/decoders/proxy-factory-decoder.helper'; import { createProxyWithNonceEncoder } from '@/domain/relay/contracts/__tests__/encoders/proxy-factory-encoder.builder'; +import type { Hex } from 'viem'; describe('ProxyFactoryDecoder', () => { let target: ProxyFactoryDecoder; @@ -26,7 +27,7 @@ describe('ProxyFactoryDecoder', () => { }); it('throws if the function call cannot be decoded', () => { - const data = faker.string.hexadecimal({ length: 138 }) as `0x${string}`; + const data = faker.string.hexadecimal({ length: 138 }) as Hex; expect(() => target.decodeFunctionData({ data })).toThrow(); }); diff --git a/src/domain/relay/errors/relay-limit-reached.error.ts b/src/domain/relay/errors/relay-limit-reached.error.ts index 05c158d3e4..f2db31d18c 100644 --- a/src/domain/relay/errors/relay-limit-reached.error.ts +++ b/src/domain/relay/errors/relay-limit-reached.error.ts @@ -1,8 +1,9 @@ import { HttpException, HttpStatus } from '@nestjs/common'; +import type { Address } from 'viem'; export class RelayLimitReachedError extends HttpException { constructor( - readonly address: `0x${string}`, + readonly address: Address, readonly current: number, readonly limit: number, ) { diff --git a/src/domain/relay/limit-addresses.mapper.ts b/src/domain/relay/limit-addresses.mapper.ts index 8e6fef4465..371c82b265 100644 --- a/src/domain/relay/limit-addresses.mapper.ts +++ b/src/domain/relay/limit-addresses.mapper.ts @@ -17,6 +17,7 @@ import { InvalidTransferError } from '@/domain/relay/errors/invalid-transfer.err import { InvalidMultiSendError } from '@/domain/relay/errors/invalid-multisend.error'; import { UnofficialProxyFactoryError } from '@/domain/relay/errors/unofficial-proxy-factory.error'; import { DelayModifierDecoder } from '@/domain/alerts/contracts/decoders/delay-modifier-decoder.helper'; +import type { Address } from 'viem'; @Injectable() export class LimitAddressesMapper { @@ -33,9 +34,9 @@ export class LimitAddressesMapper { async getLimitAddresses(args: { version: string; chainId: string; - to: `0x${string}`; - data: `0x${string}`; - }): Promise> { + to: Address; + data: Address; + }): Promise> { const safeBeingRecovered = await this.getSafeBeingRecovered(args); if (safeBeingRecovered) { return [safeBeingRecovered]; @@ -132,11 +133,11 @@ export class LimitAddressesMapper { private async getSafeBeingRecovered(args: { chainId: string; version: string; - to: `0x${string}`; - data: `0x${string}`; - }): Promise<`0x${string}` | null> { - let to: `0x${string}`; - let data: `0x${string}`; + to: Address; + data: Address; + }): Promise
{ + let to: Address; + let data: Address; try { const decoded = this.delayModifierDecoder.decodeFunctionData({ @@ -203,13 +204,13 @@ export class LimitAddressesMapper { * @returns {Array<{ to: string; data: string }>} - Array of transactions */ private decodeTransactions(args: { - address: `0x${string}`; + address: Address; version: string; chainId: string; - data: `0x${string}`; + data: Address; }): Array<{ - to: `0x${string}`; - data: `0x${string}`; + to: Address; + data: Address; }> { if ( this.isOfficialMultiSendDeployment(args) && @@ -226,7 +227,7 @@ export class LimitAddressesMapper { * @param {string} data - Data of the transaction * @returns {boolean} - Whether the data is of owner management */ - private isOwnerManagementTransaction(data: `0x${string}`): boolean { + private isOwnerManagementTransaction(data: Address): boolean { try { const decoded = this.safeDecoder.decodeFunctionData({ data, @@ -256,8 +257,8 @@ export class LimitAddressesMapper { } private isValidExecTransactionCall(args: { - to: `0x${string}`; - data: `0x${string}`; + to: Address; + data: Address; }): boolean { const execTransactionArgs = this.getExecTransactionArgs(args.data); // Not a valid execTransaction call @@ -298,10 +299,10 @@ export class LimitAddressesMapper { return isCancellation || this.safeDecoder.isCall(execTransactionArgs.data); } - private getExecTransactionArgs(data: `0x${string}`): { - to: `0x${string}`; + private getExecTransactionArgs(data: Address): { + to: Address; value: bigint; - data: `0x${string}`; + data: Address; } | null { try { const safeDecodedData = this.safeDecoder.decodeFunctionData({ @@ -322,10 +323,7 @@ export class LimitAddressesMapper { } } - private isValidErc20Transfer(args: { - to: `0x${string}`; - data: `0x${string}`; - }): boolean { + private isValidErc20Transfer(args: { to: Address; data: Address }): boolean { // Can throw but called after this.erc20Decoder.helpers.isTransfer const erc20DecodedData = this.erc20Decoder.decodeFunctionData({ data: args.data, @@ -341,8 +339,8 @@ export class LimitAddressesMapper { } private isValidErc20TransferFrom(args: { - to: `0x${string}`; - data: `0x${string}`; + to: Address; + data: Address; }): boolean { // Can throw but called after this.erc20Decoder.helpers.isTransferFrom const erc20DecodedData = this.erc20Decoder.decodeFunctionData({ @@ -360,7 +358,7 @@ export class LimitAddressesMapper { private async isOfficialMastercopy(args: { chainId: string; - address: `0x${string}`; + address: Address; }): Promise { try { await this.safeRepository.getSafe(args); @@ -373,7 +371,7 @@ export class LimitAddressesMapper { private isOfficialMultiSendDeployment(args: { version: string; chainId: string; - address: `0x${string}`; + address: Address; }): boolean { return ( getMultiSendCallOnlyDeployments(args).includes(args.address) || @@ -381,9 +379,7 @@ export class LimitAddressesMapper { ); } - private getSafeAddressFromMultiSend = ( - data: `0x${string}`, - ): `0x${string}` => { + private getSafeAddressFromMultiSend = (data: Address): Address => { // Decode transactions within MultiSend const transactions = this.multiSendDecoder.mapMultiSendTransactions(data); @@ -413,7 +409,7 @@ export class LimitAddressesMapper { private isOfficialProxyFactoryDeployment(args: { version: string; chainId: string; - address: `0x${string}`; + address: Address; }): boolean { const proxyFactoryDeployments = getProxyFactoryDeployments(args); return proxyFactoryDeployments.includes(args.address); @@ -422,9 +418,9 @@ export class LimitAddressesMapper { private isValidCreateProxyWithNonceCall(args: { version: string; chainId: string; - data: `0x${string}`; + data: Address; }): boolean { - let singleton: `0x${string}` | null = null; + let singleton: Address | null = null; try { const decoded = this.proxyFactoryDecoder.decodeFunctionData({ @@ -447,8 +443,8 @@ export class LimitAddressesMapper { } private getOwnersFromCreateProxyWithNonce( - data: `0x${string}`, - ): ReadonlyArray<`0x${string}`> { + data: Address, + ): ReadonlyArray
{ const decodedProxyFactory = this.proxyFactoryDecoder.decodeFunctionData({ data, }); diff --git a/src/domain/relay/relay.repository.ts b/src/domain/relay/relay.repository.ts index f81a2c379d..1e83c4fd87 100644 --- a/src/domain/relay/relay.repository.ts +++ b/src/domain/relay/relay.repository.ts @@ -5,6 +5,7 @@ import { IRelayApi } from '@/domain/interfaces/relay-api.interface'; import { LimitAddressesMapper } from '@/domain/relay/limit-addresses.mapper'; import { ILoggingService, LoggingService } from '@/logging/logging.interface'; import { Relay, RelaySchema } from '@/domain/relay/entities/relay.entity'; +import type { Address } from 'viem'; @Injectable() export class RelayRepository { @@ -24,8 +25,8 @@ export class RelayRepository { async relay(args: { version: string; chainId: string; - to: `0x${string}`; - data: `0x${string}`; + to: Address; + data: Address; gasLimit: bigint | null; }): Promise { const relayAddresses = @@ -67,14 +68,14 @@ export class RelayRepository { async getRelayCount(args: { chainId: string; - address: `0x${string}`; + address: Address; }): Promise { return this.relayApi.getRelayCount(args); } private async canRelay(args: { chainId: string; - address: `0x${string}`; + address: Address; }): Promise<{ result: boolean; currentCount: number }> { const currentCount = await this.getRelayCount(args); return { result: currentCount < this.limit, currentCount }; @@ -82,7 +83,7 @@ export class RelayRepository { private async incrementRelayCount(args: { chainId: string; - address: `0x${string}`; + address: Address; }): Promise { const currentCount = await this.getRelayCount(args); const incremented = currentCount + 1; diff --git a/src/domain/safe/entities/__tests__/creation-transaction.builder.ts b/src/domain/safe/entities/__tests__/creation-transaction.builder.ts index 41b2593468..cb84467a0f 100644 --- a/src/domain/safe/entities/__tests__/creation-transaction.builder.ts +++ b/src/domain/safe/entities/__tests__/creation-transaction.builder.ts @@ -2,16 +2,16 @@ import { faker } from '@faker-js/faker'; import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { CreationTransaction } from '@/domain/safe/entities/creation-transaction.entity'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; export function creationTransactionBuilder(): IBuilder { return new Builder() .with('created', faker.date.recent()) .with('creator', getAddress(faker.finance.ethereumAddress())) - .with('transactionHash', faker.string.hexadecimal() as `0x${string}`) + .with('transactionHash', faker.string.hexadecimal() as Address) .with('factoryAddress', getAddress(faker.finance.ethereumAddress())) .with('masterCopy', getAddress(faker.finance.ethereumAddress())) - .with('setupData', faker.string.hexadecimal() as `0x${string}`) + .with('setupData', faker.string.hexadecimal() as Address) .with('saltNonce', faker.string.numeric()); } diff --git a/src/domain/safe/entities/__tests__/erc20-transfer.builder.ts b/src/domain/safe/entities/__tests__/erc20-transfer.builder.ts index c0edda7d3b..6ea1e294a3 100644 --- a/src/domain/safe/entities/__tests__/erc20-transfer.builder.ts +++ b/src/domain/safe/entities/__tests__/erc20-transfer.builder.ts @@ -2,7 +2,7 @@ import { faker } from '@faker-js/faker'; import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { ERC20Transfer } from '@/domain/safe/entities/transfer.entity'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; export function erc20TransferBuilder(): IBuilder { return new Builder() @@ -11,7 +11,7 @@ export function erc20TransferBuilder(): IBuilder { .with('executionDate', faker.date.recent()) .with('from', getAddress(faker.finance.ethereumAddress())) .with('to', getAddress(faker.finance.ethereumAddress())) - .with('transactionHash', faker.string.hexadecimal() as `0x${string}`) + .with('transactionHash', faker.string.hexadecimal() as Address) .with('tokenAddress', getAddress(faker.finance.ethereumAddress())) .with('value', faker.string.numeric()) .with('transferId', faker.string.sample()); diff --git a/src/domain/safe/entities/__tests__/erc721-transfer.builder.ts b/src/domain/safe/entities/__tests__/erc721-transfer.builder.ts index db0c71594f..f713a4b774 100644 --- a/src/domain/safe/entities/__tests__/erc721-transfer.builder.ts +++ b/src/domain/safe/entities/__tests__/erc721-transfer.builder.ts @@ -2,7 +2,7 @@ import { faker } from '@faker-js/faker'; import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { ERC721Transfer } from '@/domain/safe/entities/transfer.entity'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; export function erc721TransferBuilder(): IBuilder { return new Builder() @@ -11,7 +11,7 @@ export function erc721TransferBuilder(): IBuilder { .with('executionDate', faker.date.recent()) .with('from', getAddress(faker.finance.ethereumAddress())) .with('to', getAddress(faker.finance.ethereumAddress())) - .with('transactionHash', faker.string.hexadecimal() as `0x${string}`) + .with('transactionHash', faker.string.hexadecimal() as Address) .with('tokenAddress', getAddress(faker.finance.ethereumAddress())) .with('tokenId', faker.string.sample()) .with('transferId', faker.string.sample()); diff --git a/src/domain/safe/entities/__tests__/ethereum-transaction.builder.ts b/src/domain/safe/entities/__tests__/ethereum-transaction.builder.ts index 121ebd1c54..7f6118d3cc 100644 --- a/src/domain/safe/entities/__tests__/ethereum-transaction.builder.ts +++ b/src/domain/safe/entities/__tests__/ethereum-transaction.builder.ts @@ -2,16 +2,16 @@ import { faker } from '@faker-js/faker'; import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { EthereumTransaction } from '@/domain/safe/entities/ethereum-transaction.entity'; -import { getAddress } from 'viem'; +import { getAddress, type Hash, type Hex } from 'viem'; export function ethereumTransactionBuilder(): IBuilder { return new Builder() .with('blockNumber', faker.number.int()) - .with('data', faker.string.hexadecimal() as `0x${string}`) + .with('data', faker.string.hexadecimal() as Hex) .with('executionDate', faker.date.recent()) .with('from', getAddress(faker.finance.ethereumAddress())) .with('transfers', []) - .with('txHash', faker.string.hexadecimal() as `0x${string}`); + .with('txHash', faker.string.hexadecimal() as Hash); } export function toJson(ethereumTransaction: EthereumTransaction): unknown { diff --git a/src/domain/safe/entities/__tests__/module-transaction.builder.ts b/src/domain/safe/entities/__tests__/module-transaction.builder.ts index df5e48e599..aa12c5f825 100644 --- a/src/domain/safe/entities/__tests__/module-transaction.builder.ts +++ b/src/domain/safe/entities/__tests__/module-transaction.builder.ts @@ -2,20 +2,20 @@ import { faker } from '@faker-js/faker'; import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { ModuleTransaction } from '@/domain/safe/entities/module-transaction.entity'; -import { getAddress } from 'viem'; +import { getAddress, type Hash, type Hex } from 'viem'; export function moduleTransactionBuilder(): IBuilder { return new Builder() .with('blockNumber', faker.number.int()) .with('created', faker.date.recent()) - .with('data', faker.string.hexadecimal() as `0x${string}`) + .with('data', faker.string.hexadecimal() as Hex) .with('executionDate', faker.date.recent()) .with('isSuccessful', faker.datatype.boolean()) .with('module', getAddress(faker.finance.ethereumAddress())) .with('operation', faker.helpers.arrayElement([0, 1])) .with('safe', getAddress(faker.finance.ethereumAddress())) .with('to', getAddress(faker.finance.ethereumAddress())) - .with('transactionHash', faker.string.hexadecimal() as `0x${string}`) + .with('transactionHash', faker.string.hexadecimal() as Hash) .with('value', faker.string.numeric()) .with('moduleTransactionId', faker.string.sample()); } diff --git a/src/domain/safe/entities/__tests__/multisig-transaction-confirmation.builder.ts b/src/domain/safe/entities/__tests__/multisig-transaction-confirmation.builder.ts index 461ea0ec7b..6156dd058b 100644 --- a/src/domain/safe/entities/__tests__/multisig-transaction-confirmation.builder.ts +++ b/src/domain/safe/entities/__tests__/multisig-transaction-confirmation.builder.ts @@ -3,7 +3,8 @@ import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { Confirmation } from '@/domain/safe/entities/multisig-transaction.entity'; import { SignatureType } from '@/domain/common/entities/signature-type.entity'; -import { getAddress } from 'viem'; +import type { Hash } from 'viem'; +import { type Hex, getAddress } from 'viem'; const HASH_LENGTH = 64; const SIGNATURE_LENGTH = 130; @@ -14,14 +15,14 @@ export function confirmationBuilder(): IBuilder { .with('owner', getAddress(faker.finance.ethereumAddress())) .with( 'signature', - faker.string.hexadecimal({ length: SIGNATURE_LENGTH }) as `0x${string}`, + faker.string.hexadecimal({ length: SIGNATURE_LENGTH }) as Hex, ) .with('signatureType', signatureType) .with('submissionDate', faker.date.recent()) .with( 'transactionHash', [SignatureType.Eoa, SignatureType.EthSign].includes(signatureType) - ? (faker.string.hexadecimal({ length: HASH_LENGTH }) as `0x${string}`) + ? (faker.string.hexadecimal({ length: HASH_LENGTH }) as Hash) : null, ); } diff --git a/src/domain/safe/entities/__tests__/multisig-transaction.builder.ts b/src/domain/safe/entities/__tests__/multisig-transaction.builder.ts index 271ff0290b..9d02837b85 100644 --- a/src/domain/safe/entities/__tests__/multisig-transaction.builder.ts +++ b/src/domain/safe/entities/__tests__/multisig-transaction.builder.ts @@ -12,7 +12,7 @@ import type { } from '@/domain/safe/entities/multisig-transaction.entity'; import type { Safe } from '@/domain/safe/entities/safe.entity'; import type { Operation } from '@/domain/safe/entities/operation.entity'; -import { getAddress, type PrivateKeyAccount } from 'viem'; +import { getAddress, type Hash, type Hex, type PrivateKeyAccount } from 'viem'; import { getSignature } from '@/domain/common/utils/__tests__/signatures.builder'; const HASH_LENGTH = 32; @@ -77,7 +77,7 @@ export function multisigTransactionBuilder(): BuilderWithConfirmations { @@ -98,7 +98,7 @@ describe('MultisigTransaction', () => { .ethereumAddress() .toLowerCase(); const multisigTransaction = multisigTransactionBuilder() - .with(key, nonChecksummedAddress as `0x${string}`) + .with(key, nonChecksummedAddress as Address) .build(); const result = MultisigTransactionSchema.safeParse(multisigTransaction); @@ -135,7 +135,7 @@ describe('MultisigTransaction', () => { 'safeTxHash' as const, ])('should require %s to be a hex string', (key) => { const multisigTransaction = multisigTransactionBuilder() - .with(key, faker.string.numeric() as `0x${string}`) + .with(key, faker.string.numeric() as Address) .build(); const result = MultisigTransactionSchema.safeParse(multisigTransaction); diff --git a/src/domain/safe/entities/__tests__/native-token-transfer.builder.ts b/src/domain/safe/entities/__tests__/native-token-transfer.builder.ts index d78acc1f79..3be05806bb 100644 --- a/src/domain/safe/entities/__tests__/native-token-transfer.builder.ts +++ b/src/domain/safe/entities/__tests__/native-token-transfer.builder.ts @@ -2,7 +2,7 @@ import { faker } from '@faker-js/faker'; import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { NativeTokenTransfer } from '@/domain/safe/entities/transfer.entity'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; export function nativeTokenTransferBuilder(): IBuilder { return new Builder() @@ -11,7 +11,7 @@ export function nativeTokenTransferBuilder(): IBuilder { .with('executionDate', faker.date.recent()) .with('from', getAddress(faker.finance.ethereumAddress())) .with('to', getAddress(faker.finance.ethereumAddress())) - .with('transactionHash', faker.string.hexadecimal() as `0x${string}`) + .with('transactionHash', faker.string.hexadecimal() as Address) .with('value', faker.string.hexadecimal()) .with('transferId', faker.string.sample()); } diff --git a/src/domain/safe/entities/schemas/__tests__/creation-transaction.schema.spec.ts b/src/domain/safe/entities/schemas/__tests__/creation-transaction.schema.spec.ts index c19447ad50..bbb3193c9f 100644 --- a/src/domain/safe/entities/schemas/__tests__/creation-transaction.schema.spec.ts +++ b/src/domain/safe/entities/schemas/__tests__/creation-transaction.schema.spec.ts @@ -2,7 +2,7 @@ import { creationTransactionBuilder } from '@/domain/safe/entities/__tests__/cre import type { CreationTransaction } from '@/domain/safe/entities/creation-transaction.entity'; import { CreationTransactionSchema } from '@/domain/safe/entities/schemas/creation-transaction.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; describe('CreationTransactionSchema', () => { it('should validate a valid creation transaction', () => { @@ -32,7 +32,7 @@ describe('CreationTransactionSchema', () => { ])('should checksum the %s', (field) => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const creationTransaction = creationTransactionBuilder() .with(field, nonChecksummedAddress) .build(); @@ -62,7 +62,7 @@ describe('CreationTransactionSchema', () => { 'masterCopy' as const, ])('should not allow non-address %s', (field) => { const creationTransaction = creationTransactionBuilder() - .with(field, 'not an address' as `0x${string}`) + .with(field, 'not an address' as Address) .build(); const result = CreationTransactionSchema.safeParse(creationTransaction); @@ -80,7 +80,7 @@ describe('CreationTransactionSchema', () => { 'should not allow non-hex %s', (field) => { const creationTransaction = creationTransactionBuilder() - .with(field, 'not a hex string' as `0x${string}`) + .with(field, 'not a hex string' as Address) .build(); const result = CreationTransactionSchema.safeParse(creationTransaction); diff --git a/src/domain/safe/entities/schemas/__tests__/erc20-transfer.schema.spec.ts b/src/domain/safe/entities/schemas/__tests__/erc20-transfer.schema.spec.ts index 694cd43cc6..b239c8b583 100644 --- a/src/domain/safe/entities/schemas/__tests__/erc20-transfer.schema.spec.ts +++ b/src/domain/safe/entities/schemas/__tests__/erc20-transfer.schema.spec.ts @@ -1,7 +1,7 @@ import { erc20TransferBuilder } from '@/domain/safe/entities/__tests__/erc20-transfer.builder'; import { Erc20TransferSchema } from '@/domain/safe/entities/schemas/erc20-transfer.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; describe('Erc20TransferSchema', () => { it('should validate a Erc20Transfer', () => { @@ -26,7 +26,7 @@ describe('Erc20TransferSchema', () => { it('should not allow non-hex transactionHash values', () => { const erc20Transfer = erc20TransferBuilder() - .with('transactionHash', faker.string.numeric() as `0x${string}`) + .with('transactionHash', faker.string.numeric() as Address) .build(); const result = Erc20TransferSchema.safeParse(erc20Transfer); @@ -41,7 +41,7 @@ describe('Erc20TransferSchema', () => { .ethereumAddress() .toLowerCase(); const erc20Transfer = erc20TransferBuilder() - .with(field, nonChecksummedAddress as `0x${string}`) + .with(field, nonChecksummedAddress as Address) .build(); const result = Erc20TransferSchema.safeParse(erc20Transfer); diff --git a/src/domain/safe/entities/schemas/__tests__/erc721-transfer.schema.spec.ts b/src/domain/safe/entities/schemas/__tests__/erc721-transfer.schema.spec.ts index 5b0a3c887c..c25f8af0f7 100644 --- a/src/domain/safe/entities/schemas/__tests__/erc721-transfer.schema.spec.ts +++ b/src/domain/safe/entities/schemas/__tests__/erc721-transfer.schema.spec.ts @@ -1,7 +1,7 @@ import { erc721TransferBuilder } from '@/domain/safe/entities/__tests__/erc721-transfer.builder'; import { Erc721TransferSchema } from '@/domain/safe/entities/schemas/erc721-transfer.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; describe('Erc721TransferSchema', () => { it('should validate a Erc721Transfer', () => { @@ -26,7 +26,7 @@ describe('Erc721TransferSchema', () => { it('should not allow non-hex transactionHash values', () => { const erc721Transfer = erc721TransferBuilder() - .with('transactionHash', faker.string.numeric() as `0x${string}`) + .with('transactionHash', faker.string.numeric() as Address) .build(); const result = Erc721TransferSchema.safeParse(erc721Transfer); @@ -41,7 +41,7 @@ describe('Erc721TransferSchema', () => { .ethereumAddress() .toLowerCase(); const erc20Transfer = erc721TransferBuilder() - .with(field, nonChecksummedAddress as `0x${string}`) + .with(field, nonChecksummedAddress as Address) .build(); const result = Erc721TransferSchema.safeParse(erc20Transfer); diff --git a/src/domain/safe/entities/schemas/__tests__/module-transaction.schema.spec.ts b/src/domain/safe/entities/schemas/__tests__/module-transaction.schema.spec.ts index 3f50a6236b..e968ecbb5f 100644 --- a/src/domain/safe/entities/schemas/__tests__/module-transaction.schema.spec.ts +++ b/src/domain/safe/entities/schemas/__tests__/module-transaction.schema.spec.ts @@ -7,7 +7,7 @@ import { ModuleTransactionSchema, } from '@/domain/safe/entities/module-transaction.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('ModuleTransaction schemas', () => { @@ -25,7 +25,7 @@ describe('ModuleTransaction schemas', () => { (key) => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const moduleTransaction = moduleTransactionBuilder() .with(key, nonChecksummedAddress) .build(); @@ -54,7 +54,7 @@ describe('ModuleTransaction schemas', () => { 'should not allow non-hex %s', (key) => { const moduleTransaction = moduleTransactionBuilder() - .with(key, faker.string.numeric() as `0x${string}`) + .with(key, faker.string.numeric() as Address) .build(); const result = ModuleTransactionSchema.safeParse(moduleTransaction); diff --git a/src/domain/safe/entities/schemas/__tests__/native-token-transfer.schema.spec.ts b/src/domain/safe/entities/schemas/__tests__/native-token-transfer.schema.spec.ts index 32b4e6cda5..fb06c1d74b 100644 --- a/src/domain/safe/entities/schemas/__tests__/native-token-transfer.schema.spec.ts +++ b/src/domain/safe/entities/schemas/__tests__/native-token-transfer.schema.spec.ts @@ -1,7 +1,7 @@ import { nativeTokenTransferBuilder } from '@/domain/safe/entities/__tests__/native-token-transfer.builder'; import { NativeTokenTransferSchema } from '@/domain/safe/entities/schemas/native-token-transfer.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; describe('NativeTokenTransferSchema', () => { it('should validate a NativeTokenTransfer', () => { @@ -26,7 +26,7 @@ describe('NativeTokenTransferSchema', () => { it('should not allow non-hex transactionHash values', () => { const nativeTokenTransfer = nativeTokenTransferBuilder() - .with('transactionHash', faker.string.numeric() as `0x${string}`) + .with('transactionHash', faker.string.numeric() as Address) .build(); const result = NativeTokenTransferSchema.safeParse(nativeTokenTransfer); @@ -41,7 +41,7 @@ describe('NativeTokenTransferSchema', () => { .ethereumAddress() .toLowerCase(); const nativeTokenTransfer = nativeTokenTransferBuilder() - .with(field, nonChecksummedAddress as `0x${string}`) + .with(field, nonChecksummedAddress as Address) .build(); const result = NativeTokenTransferSchema.safeParse(nativeTokenTransfer); diff --git a/src/domain/safe/entities/schemas/__tests__/safe.schema.spec.ts b/src/domain/safe/entities/schemas/__tests__/safe.schema.spec.ts index 8670e2f440..2970c56923 100644 --- a/src/domain/safe/entities/schemas/__tests__/safe.schema.spec.ts +++ b/src/domain/safe/entities/schemas/__tests__/safe.schema.spec.ts @@ -1,7 +1,7 @@ import { safeBuilder } from '@/domain/safe/entities/__tests__/safe.builder'; import { SafeSchema } from '@/domain/safe/entities/schemas/safe.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('SafeSchema', () => { @@ -31,7 +31,7 @@ describe('SafeSchema', () => { ])('should checksum %s', (field) => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const safe = safeBuilder().with(field, nonChecksummedAddress).build(); const result = SafeSchema.safeParse(safe); @@ -128,7 +128,7 @@ describe('SafeSchema', () => { 'should checksum the array of %s', (field) => { const nonChecksummedAddresses = faker.helpers.multiple( - () => faker.finance.ethereumAddress().toLowerCase() as `0x${string}`, + () => faker.finance.ethereumAddress().toLowerCase() as Address, { count: { min: 1, max: 5 }, }, diff --git a/src/domain/safe/safe.repository.interface.ts b/src/domain/safe/safe.repository.interface.ts index 09833e4bd4..9004a523eb 100644 --- a/src/domain/safe/safe.repository.interface.ts +++ b/src/domain/safe/safe.repository.interface.ts @@ -15,44 +15,45 @@ import { TransactionApiManagerModule } from '@/domain/interfaces/transaction-api import { TransactionVerifierHelper } from '@/routes/transactions/helpers/transaction-verifier.helper'; import { DelegatesV2RepositoryModule } from '@/domain/delegate/v2/delegates.v2.repository.interface'; import { ContractsRepositoryModule } from '@/domain/contracts/contracts.repository.interface'; +import type { Address } from 'viem'; export const ISafeRepository = Symbol('ISafeRepository'); export interface ISafeRepository { - getSafe(args: { chainId: string; address: `0x${string}` }): Promise; + getSafe(args: { chainId: string; address: Address }): Promise; - clearSafe(args: { chainId: string; address: `0x${string}` }): Promise; + clearSafe(args: { chainId: string; address: Address }): Promise; - isSafe(args: { chainId: string; address: `0x${string}` }): Promise; + isSafe(args: { chainId: string; address: Address }): Promise; - clearIsSafe(args: { chainId: string; address: `0x${string}` }): Promise; + clearIsSafe(args: { chainId: string; address: Address }): Promise; isOwner(args: { chainId: string; - safeAddress: `0x${string}`; - address: `0x${string}`; + safeAddress: Address; + address: Address; }): Promise; getCollectibleTransfers(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; }): Promise>; clearTransfers(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; getIncomingTransfers(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; executionDateGte?: string; executionDateLte?: string; - to?: `0x${string}`; + to?: Address; value?: string; - tokenAddress?: `0x${string}`; + tokenAddress?: Address; txHash?: string; limit?: number; offset?: number; @@ -60,7 +61,7 @@ export interface ISafeRepository { clearIncomingTransfers(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; addConfirmation(args: { @@ -76,7 +77,7 @@ export interface ISafeRepository { getModuleTransactions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; to?: string; txHash?: string; module?: string; @@ -86,7 +87,7 @@ export interface ISafeRepository { clearModuleTransactions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; /** @@ -116,12 +117,12 @@ export interface ISafeRepository { getCreationTransaction(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; getTransactionHistory(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; }): Promise>; @@ -133,7 +134,7 @@ export interface ISafeRepository { clearAllExecutedTransactions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; clearMultisigTransaction(args: { @@ -143,12 +144,12 @@ export interface ISafeRepository { clearMultisigTransactions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; getMultisigTransactions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; executed?: boolean; executionDateGte?: string; executionDateLte?: string; @@ -169,31 +170,31 @@ export interface ISafeRepository { getTransfers(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; }): Promise>; getSafesByOwner(args: { chainId: string; - ownerAddress: `0x${string}`; + ownerAddress: Address; }): Promise; deprecated__getAllSafesByOwner(args: { - ownerAddress: `0x${string}`; + ownerAddress: Address; }): Promise<{ [chainId: string]: Array }>; getAllSafesByOwner(args: { - ownerAddress: `0x${string}`; + ownerAddress: Address; }): Promise<{ [chainId: string]: Array | null }>; getLastTransactionSortedByNonce(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; proposeTransaction(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; proposeTransactionDto: ProposeTransactionDto; }): Promise; @@ -209,12 +210,12 @@ export interface ISafeRepository { */ getNonces(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise<{ currentNonce: number; recommendedNonce: number }>; getSafesByModule(args: { chainId: string; - moduleAddress: `0x${string}`; + moduleAddress: Address; }): Promise; } diff --git a/src/domain/safe/safe.repository.ts b/src/domain/safe/safe.repository.ts index a86dd865a6..852df381c0 100644 --- a/src/domain/safe/safe.repository.ts +++ b/src/domain/safe/safe.repository.ts @@ -32,6 +32,7 @@ import { CreationTransactionSchema } from '@/domain/safe/entities/schemas/creati import { SafeSchema } from '@/domain/safe/entities/schemas/safe.schema'; import { z } from 'zod'; import { TransactionVerifierHelper } from '@/routes/transactions/helpers/transaction-verifier.helper'; +import type { Address } from 'viem'; @Injectable() export class SafeRepository implements ISafeRepository { @@ -44,10 +45,7 @@ export class SafeRepository implements ISafeRepository { private readonly transactionVerifier: TransactionVerifierHelper, ) {} - async getSafe(args: { - chainId: string; - address: `0x${string}`; - }): Promise { + async getSafe(args: { chainId: string; address: Address }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, ); @@ -55,10 +53,7 @@ export class SafeRepository implements ISafeRepository { return SafeSchema.parse(safe); } - async isSafe(args: { - chainId: string; - address: `0x${string}`; - }): Promise { + async isSafe(args: { chainId: string; address: Address }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, ); @@ -68,7 +63,7 @@ export class SafeRepository implements ISafeRepository { async clearIsSafe(args: { chainId: string; - address: `0x${string}`; + address: Address; }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, @@ -76,10 +71,7 @@ export class SafeRepository implements ISafeRepository { return transactionService.clearIsSafe(args.address); } - async clearSafe(args: { - chainId: string; - address: `0x${string}`; - }): Promise { + async clearSafe(args: { chainId: string; address: Address }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, ); @@ -88,8 +80,8 @@ export class SafeRepository implements ISafeRepository { async isOwner(args: { chainId: string; - safeAddress: `0x${string}`; - address: `0x${string}`; + safeAddress: Address; + address: Address; }): Promise { const safe = await this.getSafe({ chainId: args.chainId, @@ -100,7 +92,7 @@ export class SafeRepository implements ISafeRepository { async getCollectibleTransfers(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; }): Promise> { @@ -117,7 +109,7 @@ export class SafeRepository implements ISafeRepository { async clearTransfers(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, @@ -128,12 +120,12 @@ export class SafeRepository implements ISafeRepository { async getIncomingTransfers(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; executionDateGte?: string; executionDateLte?: string; - to?: `0x${string}`; + to?: Address; value?: string; - tokenAddress?: `0x${string}`; + tokenAddress?: Address; txHash?: string; limit?: number; offset?: number; @@ -147,7 +139,7 @@ export class SafeRepository implements ISafeRepository { async clearIncomingTransfers(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, @@ -200,7 +192,7 @@ export class SafeRepository implements ISafeRepository { async getModuleTransactions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; to?: string; txHash?: string; module?: string; @@ -216,7 +208,7 @@ export class SafeRepository implements ISafeRepository { async clearModuleTransactions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, @@ -272,7 +264,7 @@ export class SafeRepository implements ISafeRepository { async getCreationTransaction(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, @@ -285,7 +277,7 @@ export class SafeRepository implements ISafeRepository { async getCreationTransactionWithNoCache(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, @@ -299,7 +291,7 @@ export class SafeRepository implements ISafeRepository { async getTransactionHistory(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number; offset?: number; }): Promise> { @@ -308,7 +300,7 @@ export class SafeRepository implements ISafeRepository { private async getAllExecutedTransactions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; ordering?: string; limit?: number; offset?: number; @@ -326,7 +318,7 @@ export class SafeRepository implements ISafeRepository { async clearAllExecutedTransactions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, @@ -413,7 +405,7 @@ export class SafeRepository implements ISafeRepository { async clearMultisigTransactions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, @@ -423,7 +415,7 @@ export class SafeRepository implements ISafeRepository { async getMultisigTransactionsWithNoCache(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; // Transaction Service parameters failed?: boolean; modified__lt?: string; @@ -475,11 +467,11 @@ export class SafeRepository implements ISafeRepository { async getMultisigTransactions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; executed?: boolean; executionDateGte?: string; executionDateLte?: string; - to?: `0x${string}`; + to?: Address; value?: string; nonce?: string; nonceGte?: number; @@ -510,7 +502,7 @@ export class SafeRepository implements ISafeRepository { async getTransfers(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; limit?: number | undefined; }): Promise> { const transactionService = await this.transactionApiManager.getApi( @@ -522,7 +514,7 @@ export class SafeRepository implements ISafeRepository { async getSafesByOwner(args: { chainId: string; - ownerAddress: `0x${string}`; + ownerAddress: Address; }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, @@ -537,7 +529,7 @@ export class SafeRepository implements ISafeRepository { // TODO: Remove with /owners/:ownerAddress/safes // @deprecated async deprecated__getAllSafesByOwner(args: { - ownerAddress: `0x${string}`; + ownerAddress: Address; }): Promise<{ [chainId: string]: Array }> { const chains = await this.chainsRepository.getAllChains(); const allSafeLists = await Promise.all( @@ -563,7 +555,7 @@ export class SafeRepository implements ISafeRepository { } async getAllSafesByOwner(args: { - ownerAddress: `0x${string}`; + ownerAddress: Address; }): Promise<{ [chainId: string]: Array | null }> { const chains = await this.chainsRepository.getAllChains(); const allSafeLists = await Promise.allSettled( @@ -600,7 +592,7 @@ export class SafeRepository implements ISafeRepository { async getLastTransactionSortedByNonce(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, @@ -618,7 +610,7 @@ export class SafeRepository implements ISafeRepository { async proposeTransaction(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; proposeTransactionDto: ProposeTransactionDto; }): Promise { const transactionService = await this.transactionApiManager.getApi( @@ -652,7 +644,7 @@ export class SafeRepository implements ISafeRepository { async getNonces(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise<{ currentNonce: number; recommendedNonce: number }> { const safe = await this.getSafe({ chainId: args.chainId, @@ -676,7 +668,7 @@ export class SafeRepository implements ISafeRepository { async getSafesByModule(args: { chainId: string; - moduleAddress: `0x${string}`; + moduleAddress: Address; }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, diff --git a/src/domain/siwe/siwe.repository.interface.ts b/src/domain/siwe/siwe.repository.interface.ts index 28d4d8edae..72d82926d5 100644 --- a/src/domain/siwe/siwe.repository.interface.ts +++ b/src/domain/siwe/siwe.repository.interface.ts @@ -2,6 +2,7 @@ import { SiweApiModule } from '@/datasources/siwe-api/siwe-api.module'; import { SiweRepository } from '@/domain/siwe/siwe.repository'; import { Module } from '@nestjs/common'; import type { SiweMessage } from 'viem/siwe'; +import type { Hex } from 'viem'; export const ISiweRepository = Symbol('ISiweRepository'); @@ -10,7 +11,7 @@ export interface ISiweRepository { getValidatedSiweMessage(args: { message: string; - signature: `0x${string}`; + signature: Hex; }): Promise; } diff --git a/src/domain/siwe/siwe.repository.ts b/src/domain/siwe/siwe.repository.ts index ddf73b5440..ccc3c639d5 100644 --- a/src/domain/siwe/siwe.repository.ts +++ b/src/domain/siwe/siwe.repository.ts @@ -4,6 +4,7 @@ import { Inject, Injectable, UnauthorizedException } from '@nestjs/common'; import { verifyMessage } from 'viem'; import { generateSiweNonce, SiweMessage } from 'viem/siwe'; import { SiweMessageSchema } from '@/domain/siwe/entities/siwe-message.entity'; +import type { Hex } from 'viem'; @Injectable() export class SiweRepository implements ISiweRepository { @@ -29,7 +30,7 @@ export class SiweRepository implements ISiweRepository { async getValidatedSiweMessage(args: { message: string; - signature: `0x${string}`; + signature: Hex; }): Promise { const result = SiweMessageSchema.safeParse(args.message); if (!result.success) { diff --git a/src/domain/spaces/address-books/address-book-items.repository.integration.spec.ts b/src/domain/spaces/address-books/address-book-items.repository.integration.spec.ts index bf55edeb46..bbfed24d18 100644 --- a/src/domain/spaces/address-books/address-book-items.repository.integration.spec.ts +++ b/src/domain/spaces/address-books/address-book-items.repository.integration.spec.ts @@ -26,7 +26,7 @@ import { BadRequestException, NotFoundException } from '@nestjs/common'; import type { ConfigService } from '@nestjs/config'; import { range } from 'lodash'; import { DataSource } from 'typeorm'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; const mockLoggingService = { debug: jest.fn(), @@ -255,8 +255,8 @@ describe('AddressBookItemsRepository', () => { () => addressBookItemBuilder() .with('space', spaceBuilder().with('id', spaceId).build()) - .with('createdBy', authPayload.signer_address as `0x${string}`) - .with('lastUpdatedBy', authPayload.signer_address as `0x${string}`) + .with('createdBy', authPayload.signer_address as Address) + .with('lastUpdatedBy', authPayload.signer_address as Address) .build(), { count: { min: 2, max: 5 } }, ); @@ -321,8 +321,8 @@ describe('AddressBookItemsRepository', () => { () => addressBookItemBuilder() .with('space', spaceBuilder().with('id', spaceId).build()) - .with('createdBy', authPayload.signer_address as `0x${string}`) - .with('lastUpdatedBy', authPayload.signer_address as `0x${string}`) + .with('createdBy', authPayload.signer_address as Address) + .with('lastUpdatedBy', authPayload.signer_address as Address) .build(), { count: limit - 1, @@ -385,8 +385,8 @@ describe('AddressBookItemsRepository', () => { const { spaceId, authPayload } = await createSpaceAsAdmin(); const addressBookItem = addressBookItemBuilder() .with('space', spaceBuilder().with('id', spaceId).build()) - .with('createdBy', authPayload.signer_address as `0x${string}`) - .with('lastUpdatedBy', authPayload.signer_address as `0x${string}`) + .with('createdBy', authPayload.signer_address as Address) + .with('lastUpdatedBy', authPayload.signer_address as Address) .build(); await dbAddressBookItemsRepository.insert(addressBookItem); @@ -412,14 +412,14 @@ describe('AddressBookItemsRepository', () => { const addressBookItem1 = addressBookItemBuilder() .with('address', address) .with('space', spaceBuilder().with('id', spaceId1).build()) - .with('createdBy', authPayload1.signer_address as `0x${string}`) - .with('lastUpdatedBy', authPayload1.signer_address as `0x${string}`) + .with('createdBy', authPayload1.signer_address as Address) + .with('lastUpdatedBy', authPayload1.signer_address as Address) .build(); const addressBookItem2 = addressBookItemBuilder() .with('address', address) .with('space', spaceBuilder().with('id', spaceId2).build()) - .with('createdBy', authPayload2.signer_address as `0x${string}`) - .with('lastUpdatedBy', authPayload2.signer_address as `0x${string}`) + .with('createdBy', authPayload2.signer_address as Address) + .with('lastUpdatedBy', authPayload2.signer_address as Address) .build(); await dbAddressBookItemsRepository.insert(addressBookItem1); await dbAddressBookItemsRepository.insert(addressBookItem2); diff --git a/src/domain/spaces/address-books/entities/address-book-item.db.entity.ts b/src/domain/spaces/address-books/entities/address-book-item.db.entity.ts index 14c97352c0..c7c13d73c4 100644 --- a/src/domain/spaces/address-books/entities/address-book-item.db.entity.ts +++ b/src/domain/spaces/address-books/entities/address-book-item.db.entity.ts @@ -5,24 +5,25 @@ import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { makeNameSchema } from '@/domain/common/entities/name.schema'; import { z } from 'zod'; import { ADDRESS_BOOK_NAME_MAX_LENGTH } from '@/domain/accounts/address-books/entities/address-book.entity'; +import type { Address } from 'viem'; // We need explicitly define ZodType due to recursion export const AddressBookDbItemSchema: z.ZodType< z.infer & { space: Space; chainIds: Array; - address: `0x${string}`; + address: Address; name: string; - createdBy: `0x${string}`; - lastUpdatedBy: `0x${string}`; + createdBy: Address; + lastUpdatedBy: Address; } > = RowSchema.extend({ space: z.lazy(() => SpaceSchema), chainIds: z.array(z.string()), - address: AddressSchema as z.ZodType<`0x${string}`>, + address: AddressSchema as z.ZodType
, name: makeNameSchema({ maxLength: ADDRESS_BOOK_NAME_MAX_LENGTH }), - createdBy: AddressSchema as z.ZodType<`0x${string}`>, - lastUpdatedBy: AddressSchema as z.ZodType<`0x${string}`>, + createdBy: AddressSchema as z.ZodType
, + lastUpdatedBy: AddressSchema as z.ZodType
, }); export type AddressBookDbItem = z.infer; diff --git a/src/domain/spaces/entities/space-safe.entity.ts b/src/domain/spaces/entities/space-safe.entity.ts index d5d3549a09..32f25541c9 100644 --- a/src/domain/spaces/entities/space-safe.entity.ts +++ b/src/domain/spaces/entities/space-safe.entity.ts @@ -4,6 +4,7 @@ import type { SpaceSafe as DbSpaceSafe } from '@/datasources/spaces/entities/spa import { SpaceSchema } from '@/domain/spaces/entities/space.entity'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { NumericStringSchema } from '@/validation/entities/schemas/numeric-string.schema'; +import type { Address } from 'viem'; export type SpaceSafe = z.infer; @@ -16,6 +17,6 @@ export const SpaceSafeSchema: z.ZodType< } > = RowSchema.extend({ chainId: NumericStringSchema, - address: AddressSchema as z.ZodType<`0x${string}`>, + address: AddressSchema as z.ZodType
, space: z.lazy(() => SpaceSchema).optional(), }); diff --git a/src/domain/staking/contracts/decoders/__tests__/encoders/kiln-encoder.builder.ts b/src/domain/staking/contracts/decoders/__tests__/encoders/kiln-encoder.builder.ts index 332e466ec9..96956b9035 100644 --- a/src/domain/staking/contracts/decoders/__tests__/encoders/kiln-encoder.builder.ts +++ b/src/domain/staking/contracts/decoders/__tests__/encoders/kiln-encoder.builder.ts @@ -15,6 +15,7 @@ import { getAbiItem, getAddress, } from 'viem'; +import type { Address, Hex } from 'viem'; // deposit @@ -24,7 +25,7 @@ class DepositEncoder extends Builder implements IEncoder { - encode(): `0x${string}` { + encode(): Address { return encodeFunctionData({ abi: KilnAbi, functionName: 'deposit', @@ -40,14 +41,14 @@ export function depositEncoder(): DepositEncoder { // requestValidatorsExit type RequestValidatorsExitArgs = { - _publicKeys: `0x${string}`; + _publicKeys: Address; }; class RequestValidatorsExitEncoder extends Builder implements IEncoder { - encode(): `0x${string}` { + encode(): Address { const args = this.build(); return encodeFunctionData({ @@ -72,14 +73,14 @@ export function requestValidatorsExitEncoder(): RequestValidatorsExitEncoder extends Builder implements IEncoder { - encode(): `0x${string}` { + encode(): Address { const args = this.build(); return encodeFunctionData({ @@ -104,16 +105,16 @@ export function batchWithdrawCLFeeEncoder(): BatchWithdrawCLFeeEncoder]; + data: Address; + topics: [signature: Hex, ...args: Array
]; }; class DepositEventBuilder @@ -175,17 +176,17 @@ export function depositEventEventBuilder(): DepositEventBuilder]; + data: Address; + topics: [signature: Hex, ...args: Array
]; }; class WithdrawalEventBuilder diff --git a/src/domain/staking/contracts/decoders/__tests__/kiln-decoder.helper.spec.ts b/src/domain/staking/contracts/decoders/__tests__/kiln-decoder.helper.spec.ts index 9b33043683..235492d566 100644 --- a/src/domain/staking/contracts/decoders/__tests__/kiln-decoder.helper.spec.ts +++ b/src/domain/staking/contracts/decoders/__tests__/kiln-decoder.helper.spec.ts @@ -8,6 +8,7 @@ import { import { KilnDecoder } from '@/domain/staking/contracts/decoders/kiln-decoder.helper'; import type { ILoggingService } from '@/logging/logging.interface'; import { faker } from '@faker-js/faker'; +import type { Address, Hex } from 'viem'; const mockLoggingService = { debug: jest.fn(), @@ -32,7 +33,7 @@ describe('KilnDecoder', () => { }); it('returns null if the data is not a requestValidatorsExit function call', () => { - const data = faker.string.hexadecimal({ length: 1 }) as `0x${string}`; + const data = faker.string.hexadecimal({ length: 1 }) as Address; expect(kilnDecoder.decodeValidatorsExit(data)).toBeNull(); }); @@ -51,7 +52,7 @@ describe('KilnDecoder', () => { }); it('returns null if the data is not a batchWithdrawCLFee function call', () => { - const data = faker.string.hexadecimal({ length: 1 }) as `0x${string}`; + const data = faker.string.hexadecimal({ length: 1 }) as Address; expect(kilnDecoder.decodeBatchWithdrawCLFee(data)).toBeNull(); }); @@ -81,10 +82,11 @@ describe('KilnDecoder', () => { }); it('returns null if the data is not a DepositEvent', () => { - const data = faker.string.hexadecimal({ length: 514 }) as `0x${string}`; - const topics = [ - faker.string.hexadecimal({ length: 64 }) as `0x${string}`, - ] as [signature: `0x${string}`, ...args: Array<`0x${string}`>]; + const data = faker.string.hexadecimal({ length: 514 }) as Hex; + const topics = [faker.string.hexadecimal({ length: 64 }) as Hex] as [ + signature: Hex, + ...args: Array
, + ]; expect(kilnDecoder.decodeDepositEvent({ data, topics })).toBe(null); }); @@ -110,10 +112,11 @@ describe('KilnDecoder', () => { }); it('returns null if the data is not a Withdrawal', () => { - const data = faker.string.hexadecimal({ length: 514 }) as `0x${string}`; - const topics = [ - faker.string.hexadecimal({ length: 64 }) as `0x${string}`, - ] as [signature: `0x${string}`, ...args: Array<`0x${string}`>]; + const data = faker.string.hexadecimal({ length: 514 }) as Hex; + const topics = [faker.string.hexadecimal({ length: 64 }) as Hex] as [ + signature: Hex, + ...args: Array
, + ]; expect(kilnDecoder.decodeWithdrawal({ data, topics })).toBe(null); }); diff --git a/src/domain/staking/contracts/decoders/kiln-decoder.helper.ts b/src/domain/staking/contracts/decoders/kiln-decoder.helper.ts index ea2e913f52..0bdc4b851a 100644 --- a/src/domain/staking/contracts/decoders/kiln-decoder.helper.ts +++ b/src/domain/staking/contracts/decoders/kiln-decoder.helper.ts @@ -2,6 +2,7 @@ import { AbiDecoder } from '@/domain/contracts/decoders/abi-decoder.helper'; import { LoggingService, ILoggingService } from '@/logging/logging.interface'; import { Inject, Injectable } from '@nestjs/common'; import { parseAbi } from 'viem'; +import type { Address, Hex } from 'viem'; export const KilnAbi = parseAbi([ 'event DepositEvent(bytes pubkey, bytes withdrawal_credentials, bytes amount, bytes signature, bytes index)', @@ -14,7 +15,7 @@ export const KilnAbi = parseAbi([ export type KilnRequestValidatorsExitParameters = { name: '_publicKeys'; type: 'bytes'; - value: `0x${string}`; + value: Address; valueDecoded: null; }; export type KilnBatchWithdrawCLFeeParameters = @@ -29,7 +30,7 @@ export class KilnDecoder extends AbiDecoder { super(KilnAbi); } - decodeValidatorsExit(data: `0x${string}`): `0x${string}` | null { + decodeValidatorsExit(data: Hex): Hex | null { if (!this.helpers.isRequestValidatorsExit(data)) { return null; } @@ -45,7 +46,7 @@ export class KilnDecoder extends AbiDecoder { } } - decodeBatchWithdrawCLFee(data: `0x${string}`): `0x${string}` | null { + decodeBatchWithdrawCLFee(data: Hex): Hex | null { if (!this.helpers.isBatchWithdrawCLFee(data)) { return null; } @@ -62,14 +63,14 @@ export class KilnDecoder extends AbiDecoder { } decodeDepositEvent(args: { - data: `0x${string}`; - topics: [signature: `0x${string}`, ...args: Array<`0x${string}`>]; + data: Address; + topics: [signature: Hex, ...args: Array
]; }): { - pubkey: `0x${string}`; - withdrawal_credentials: `0x${string}`; - amount: `0x${string}`; - signature: `0x${string}`; - index: `0x${string}`; + pubkey: Address; + withdrawal_credentials: Address; + amount: Address; + signature: Hex; + index: Address; } | null { try { const decoded = this.decodeEventLog(args); @@ -84,12 +85,12 @@ export class KilnDecoder extends AbiDecoder { } decodeWithdrawal(args: { - data: `0x${string}`; - topics: [signature: `0x${string}`, ...args: Array<`0x${string}`>]; + data: Address; + topics: [signature: Hex, ...args: Array
]; }): { - withdrawer: `0x${string}`; - feeRecipient: `0x${string}`; - pubKeyRoot: `0x${string}`; + withdrawer: Address; + feeRecipient: Address; + pubKeyRoot: Address; rewards: bigint; nodeOperatorFee: bigint; treasuryFee: bigint; diff --git a/src/domain/staking/staking.repository.interface.ts b/src/domain/staking/staking.repository.interface.ts index 3cb1d7bbc2..61229ca753 100644 --- a/src/domain/staking/staking.repository.interface.ts +++ b/src/domain/staking/staking.repository.interface.ts @@ -8,6 +8,7 @@ import type { TransactionStatus } from '@/datasources/staking-api/entities/trans import type { DefiVaultStake } from '@/datasources/staking-api/entities/defi-vault-stake.entity'; import type { DefiMorphoExtraReward } from '@/datasources/staking-api/entities/defi-morpho-extra-reward.entity'; import type { RewardsFee } from '@/datasources/staking-api/entities/rewards-fee.entity'; +import type { Address, Hash } from 'viem'; export const IStakingRepository = Symbol('IStakingRepository'); export const IStakingRepositoryWithRewardsFee = Symbol( @@ -17,7 +18,7 @@ export const IStakingRepositoryWithRewardsFee = Symbol( export interface IStakingRepository { getDeployment(args: { chainId: string; - address: `0x${string}`; + address: Address; }): Promise; getNetworkStats(chainId: string): Promise; @@ -26,39 +27,36 @@ export interface IStakingRepository { getPooledStakingStats(args: { chainId: string; - pool: `0x${string}`; + pool: Address; }): Promise; getDefiVaultStats(args: { chainId: string; - vault: `0x${string}`; + vault: Address; }): Promise; getDefiVaultStake(args: { chainId: string; - safeAddress: `0x${string}`; - vault: `0x${string}`; + safeAddress: Address; + vault: Address; }): Promise; getDefiMorphoExtraRewards(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise>; getStakes(args: { chainId: string; - safeAddress: `0x${string}`; - validatorsPublicKeys: Array<`0x${string}`>; + safeAddress: Address; + validatorsPublicKeys: Array
; }): Promise>; - clearStakes(args: { - chainId: string; - safeAddress: `0x${string}`; - }): Promise; + clearStakes(args: { chainId: string; safeAddress: Address }): Promise; getTransactionStatus(args: { chainId: string; - txHash: `0x${string}`; + txHash: Hash; }): Promise; clearApi(chainId: string): void; @@ -67,6 +65,6 @@ export interface IStakingRepository { export interface IStakingRepositoryWithRewardsFee extends IStakingRepository { getRewardsFee(args: { chainId: string; - address: `0x${string}`; + address: Address; }): Promise; } diff --git a/src/domain/staking/staking.repository.ts b/src/domain/staking/staking.repository.ts index f7854c1a1c..a438b02085 100644 --- a/src/domain/staking/staking.repository.ts +++ b/src/domain/staking/staking.repository.ts @@ -41,6 +41,7 @@ import { RewardsFee, RewardsFeeSchema, } from '@/datasources/staking-api/entities/rewards-fee.entity'; +import type { Address, Hash } from 'viem'; // TODO: Deduplicate code with EarnRepository @@ -53,7 +54,7 @@ export class StakingRepository implements IStakingRepositoryWithRewardsFee { public async getDeployment(args: { chainId: string; - address: `0x${string}`; + address: Address; }): Promise { const deployments = await this.getDeployments(args.chainId); const deployment = deployments.find((deployment) => { @@ -70,7 +71,7 @@ export class StakingRepository implements IStakingRepositoryWithRewardsFee { public async getRewardsFee(args: { chainId: string; - address: `0x${string}`; + address: Address; }): Promise { const stakingApi = await this.stakingApiFactory.getApi(args.chainId); const rewardsFee = await stakingApi.getRewardsFee(args.address); @@ -100,7 +101,7 @@ export class StakingRepository implements IStakingRepositoryWithRewardsFee { public async getPooledStakingStats(args: { chainId: string; - pool: `0x${string}`; + pool: Address; }): Promise { const stakingApi = await this.stakingApiFactory.getApi(args.chainId); const pooledStaking = await stakingApi.getPooledStakingStats(args.pool); @@ -109,7 +110,7 @@ export class StakingRepository implements IStakingRepositoryWithRewardsFee { public async getDefiVaultStats(args: { chainId: string; - vault: `0x${string}`; + vault: Address; }): Promise { const stakingApi = await this.stakingApiFactory.getApi(args.chainId); const defiStats = await stakingApi.getDefiVaultStats(args.vault); @@ -119,8 +120,8 @@ export class StakingRepository implements IStakingRepositoryWithRewardsFee { public async getDefiVaultStake(args: { chainId: string; - safeAddress: `0x${string}`; - vault: `0x${string}`; + safeAddress: Address; + vault: Address; }): Promise { const stakingApi = await this.stakingApiFactory.getApi(args.chainId); const defiStakes = await stakingApi.getDefiVaultStakes(args); @@ -130,7 +131,7 @@ export class StakingRepository implements IStakingRepositoryWithRewardsFee { public async getDefiMorphoExtraRewards(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise> { const stakingApi = await this.stakingApiFactory.getApi(args.chainId); const defiMorphoExtraRewards = await stakingApi.getDefiMorphoExtraRewards( @@ -141,8 +142,8 @@ export class StakingRepository implements IStakingRepositoryWithRewardsFee { public async getStakes(args: { chainId: string; - safeAddress: `0x${string}`; - validatorsPublicKeys: Array<`0x${string}`>; + safeAddress: Address; + validatorsPublicKeys: Array
; }): Promise> { const stakingApi = await this.stakingApiFactory.getApi(args.chainId); const stakes = await stakingApi.getStakes(args); @@ -151,7 +152,7 @@ export class StakingRepository implements IStakingRepositoryWithRewardsFee { public async clearStakes(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const stakingApi = await this.stakingApiFactory.getApi(args.chainId); await stakingApi.clearStakes(args.safeAddress); @@ -159,7 +160,7 @@ export class StakingRepository implements IStakingRepositoryWithRewardsFee { public async getTransactionStatus(args: { chainId: string; - txHash: `0x${string}`; + txHash: Hash; }): Promise { const stakingApi = await this.stakingApiFactory.getApi(args.chainId); const txStatus = await stakingApi.getTransactionStatus(args.txHash); diff --git a/src/domain/swaps/contracts/__tests__/encoders/composable-cow-encoder.builder.ts b/src/domain/swaps/contracts/__tests__/encoders/composable-cow-encoder.builder.ts index 2441b148d1..c0697d3988 100644 --- a/src/domain/swaps/contracts/__tests__/encoders/composable-cow-encoder.builder.ts +++ b/src/domain/swaps/contracts/__tests__/encoders/composable-cow-encoder.builder.ts @@ -4,7 +4,7 @@ import type { IEncoder } from '@/__tests__/encoder-builder'; import { fakeJson } from '@/__tests__/faker'; import { ComposableCowAbi } from '@/domain/swaps/contracts/decoders/composable-cow-decoder.helper'; import { faker } from '@faker-js/faker'; -import type { Hex } from 'viem'; +import type { Address, Hex } from 'viem'; import { encodeAbiParameters, encodeFunctionData, @@ -15,16 +15,16 @@ import { } from 'viem'; type StaticInputArgs = { - sellToken: `0x${string}`; - buyToken: `0x${string}`; - receiver: `0x${string}`; + sellToken: Address; + buyToken: Address; + receiver: Address; partSellAmount: bigint; minPartLimit: bigint; t0: bigint; n: bigint; t: bigint; span: bigint; - appData: `0x${string}`; + appData: Address; }; class StaticInputEncoder @@ -69,26 +69,26 @@ export function staticInputEncoder(): StaticInputEncoder { } type ConditionalOrderParamsArgs = { - handler: `0x${string}`; - salt: `0x${string}`; - staticInput: `0x${string}`; + handler: Address; + salt: Address; + staticInput: Address; }; export function conditionalOrderParamsBuilder(): IBuilder { return new Builder() .with('handler', getAddress(faker.finance.ethereumAddress())) - .with('salt', faker.string.hexadecimal({ length: 64 }) as `0x${string}`) + .with('salt', faker.string.hexadecimal({ length: 64 }) as Hex) .with('staticInput', staticInputEncoder().encode()); } type CreateWithContextArgs = { params: { - handler: `0x${string}`; - salt: `0x${string}`; - staticInput: `0x${string}`; + handler: Address; + salt: Address; + staticInput: Address; }; - factory: `0x${string}`; - calldata: `0x${string}`; + factory: Address; + calldata: Address; dispatch: boolean; }; @@ -111,6 +111,6 @@ export function createWithContextEncoder(): CreateWithContextEncoder { * @param data - transaction data to decode * @returns the decoded {@link TwapStruct} */ - decodeTwapStruct(data: `0x${string}`): TwapStruct { + decodeTwapStruct(data: Address): TwapStruct { const decoded = this.decodeCreateWithContext(data); if (!decoded) { @@ -671,7 +672,7 @@ export class ComposableCowDecoder extends AbiDecoder { */ // Use inferred return type // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - private decodeCreateWithContext(data: `0x${string}`) { + private decodeCreateWithContext(data: Address) { if (!this.helpers.isCreateWithContext(data)) { return null; } @@ -697,7 +698,7 @@ export class ComposableCowDecoder extends AbiDecoder { * @returns decoded `ConditionalOrderParams` as {@link TwapStruct} */ private decodeConditionalOrderParams( - staticInput: `0x${string}`, // IConditionalOrder.ConditionalOrderParams calldata + staticInput: Address, // IConditionalOrder.ConditionalOrderParams calldata ): TwapStruct { const [ sellToken, @@ -738,17 +739,17 @@ export type TwapStruct = { /** * which token to sell */ - readonly sellToken: `0x${string}`; + readonly sellToken: Address; /** * which token to buy */ - readonly buyToken: `0x${string}`; + readonly buyToken: Address; /** * who to send the tokens to */ - readonly receiver: `0x${string}`; + readonly receiver: Address; /** * Meta-data associated with the order. Normally would be the keccak256 hash of the document generated in http://github.com/cowprotocol/app-data @@ -756,7 +757,7 @@ export type TwapStruct = { * This hash should have been uploaded to the API https://api.cow.fi/docs/#/default/put_api_v1_app_data__app_data_hash_ and potentially to other data availability protocols like IPFS. * */ - readonly appData: `0x${string}`; + readonly appData: Address; /** * amount of sellToken to sell in each part diff --git a/src/domain/swaps/contracts/decoders/gp-v2-decoder.helper.ts b/src/domain/swaps/contracts/decoders/gp-v2-decoder.helper.ts index 39a89b3025..62aaec43e2 100644 --- a/src/domain/swaps/contracts/decoders/gp-v2-decoder.helper.ts +++ b/src/domain/swaps/contracts/decoders/gp-v2-decoder.helper.ts @@ -6,6 +6,7 @@ import { OrderKind, SellTokenBalance, } from '@/domain/swaps/entities/order.entity'; +import type { Address, Hex } from 'viem'; /** * Taken from CoW contracts: @@ -599,13 +600,13 @@ export const GPv2Abi = [ ] as const; export type GPv2OrderParameters = { - sellToken: `0x${string}`; - buyToken: `0x${string}`; - receiver: `0x${string}`; + sellToken: Address; + buyToken: Address; + receiver: Address; sellAmount: bigint; buyAmount: bigint; validTo: number; - appData: `0x${string}`; + appData: Address; feeAmount: bigint; kind: OrderKind; partiallyFillable: boolean; @@ -655,11 +656,9 @@ export class GPv2Decoder extends AbiDecoder { * Gets the Order UID associated with the provided transaction data. * * @param data - the transaction data for the setPreSignature call - * @returns {`0x${string}`} the order UID or null if the data does not represent a setPreSignature transaction + * @returns {Address} the order UID or null if the data does not represent a setPreSignature transaction */ - public getOrderUidFromSetPreSignature( - data: `0x${string}`, - ): `0x${string}` | null { + public getOrderUidFromSetPreSignature(data: Hex): Hex | null { if (!this.helpers.isSetPreSignature(data)) { return null; } @@ -685,9 +684,7 @@ export class GPv2Decoder extends AbiDecoder { * @param tokens The list of token addresses as they appear in the settlement. * @returns The decoded {@link GPv2OrderParameters} or null if the trade is invalid. */ - public decodeOrderFromSettle( - data: `0x${string}`, - ): GPv2OrderParameters | null { + public decodeOrderFromSettle(data: Hex): GPv2OrderParameters | null { const decoded = this.decodeSettle(data); if (!decoded) { @@ -721,7 +718,7 @@ export class GPv2Decoder extends AbiDecoder { // Use inferred return type // eslint-disable-next-line @typescript-eslint/explicit-function-return-type - private decodeSettle(data: `0x${string}`) { + private decodeSettle(data: Address) { if (!this.helpers.isSettle(data)) { return null; } diff --git a/src/domain/swaps/entities/__tests__/order.builder.ts b/src/domain/swaps/entities/__tests__/order.builder.ts index a7337a3e44..58f8a0f4c8 100644 --- a/src/domain/swaps/entities/__tests__/order.builder.ts +++ b/src/domain/swaps/entities/__tests__/order.builder.ts @@ -9,7 +9,7 @@ import { import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress, type Hex } from 'viem'; export function orderBuilder(): IBuilder { const executedFee = faker.number.bigInt({ min: 1 }); @@ -61,7 +61,7 @@ export function orderBuilder(): IBuilder { 'eip1271', ] as const), ) - .with('signature', faker.string.hexadecimal() as `0x${string}`) + .with('signature', faker.string.hexadecimal() as Hex) .with( 'from', faker.datatype.boolean() @@ -96,7 +96,7 @@ export function orderBuilder(): IBuilder { faker.datatype.boolean() ? { refundTxHash: faker.datatype.boolean() - ? (faker.string.hexadecimal() as `0x${string}`) + ? (faker.string.hexadecimal() as Address) : null, userValidTo: faker.date.future().getTime(), } diff --git a/src/domain/swaps/entities/order.entity.spec.ts b/src/domain/swaps/entities/order.entity.spec.ts index 0d37f4246c..8612f7d5f7 100644 --- a/src/domain/swaps/entities/order.entity.spec.ts +++ b/src/domain/swaps/entities/order.entity.spec.ts @@ -1,6 +1,6 @@ import { orderBuilder } from '@/domain/swaps/entities/__tests__/order.builder'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { getAddress, type Hex } from 'viem'; import type { Order } from '@/domain/swaps/entities/order.entity'; import { OrderSchema } from '@/domain/swaps/entities/order.entity'; @@ -15,7 +15,7 @@ describe('OrderSchema', () => { it('hexadecimal signature should be valid', () => { const order = orderBuilder() - .with('signature', faker.string.hexadecimal() as `0x${string}`) + .with('signature', faker.string.hexadecimal() as Hex) .build(); const result = OrderSchema.safeParse(order); diff --git a/src/domain/swaps/swaps.repository.e2e-spec.ts b/src/domain/swaps/swaps.repository.e2e-spec.ts index 152e5f1fa7..9a72db7bdd 100644 --- a/src/domain/swaps/swaps.repository.e2e-spec.ts +++ b/src/domain/swaps/swaps.repository.e2e-spec.ts @@ -10,6 +10,7 @@ import { ISwapsRepository } from '@/domain/swaps/swaps.repository'; import type { Order } from '@/domain/swaps/entities/order.entity'; import configuration from '@/config/entities/configuration'; import type { Server } from 'net'; +import type { Address } from 'viem'; const orderIds = { '1': { @@ -137,7 +138,7 @@ describe('CowSwap E2E tests', () => { it(`Transaction ID: ${orderId}`, async () => { const actual: Order = await repository.getOrder( chainId, - orderId as `0x${string}`, + orderId as Address, ); expect(actual).toEqual({ diff --git a/src/domain/swaps/swaps.repository.ts b/src/domain/swaps/swaps.repository.ts index be27cbce25..8faec41199 100644 --- a/src/domain/swaps/swaps.repository.ts +++ b/src/domain/swaps/swaps.repository.ts @@ -9,18 +9,16 @@ import { FullAppData, FullAppDataSchema, } from '@/domain/swaps/entities/full-app-data.entity'; +import type { Address, Hex } from 'viem'; export const ISwapsRepository = Symbol('ISwapsRepository'); export interface ISwapsRepository { - getOrder(chainId: string, orderUid: `0x${string}`): Promise; + getOrder(chainId: string, orderUid: Address): Promise; getOrders(chainId: string, txHash: string): Promise>; - getFullAppData( - chainId: string, - appDataHash: `0x${string}`, - ): Promise; + getFullAppData(chainId: string, appDataHash: Hex): Promise; } @Injectable() @@ -30,7 +28,7 @@ export class SwapsRepository implements ISwapsRepository { private readonly swapsApiFactory: ISwapsApiFactory, ) {} - async getOrder(chainId: string, orderUid: `0x${string}`): Promise { + async getOrder(chainId: string, orderUid: Address): Promise { const api = await this.swapsApiFactory.getApi(chainId); const order = await api.getOrder(orderUid); return OrderSchema.parse(order); @@ -44,7 +42,7 @@ export class SwapsRepository implements ISwapsRepository { async getFullAppData( chainId: string, - appDataHash: `0x${string}`, + appDataHash: Hex, ): Promise { const api = await this.swapsApiFactory.getApi(chainId); const fullAppData = await api.getFullAppData(appDataHash); diff --git a/src/domain/targeted-messaging/entities/create-targeted-safes.dto.entity.ts b/src/domain/targeted-messaging/entities/create-targeted-safes.dto.entity.ts index f01cc6a088..b81ce88911 100644 --- a/src/domain/targeted-messaging/entities/create-targeted-safes.dto.entity.ts +++ b/src/domain/targeted-messaging/entities/create-targeted-safes.dto.entity.ts @@ -1,5 +1,6 @@ import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { z } from 'zod'; +import type { Address } from 'viem'; export const CreateTargetedSafesDtoSchema = z.object({ outreachId: z.number(), @@ -10,7 +11,7 @@ export class CreateTargetedSafesDto implements z.infer { outreachId: number; - addresses: Array<`0x${string}`>; + addresses: Array
; constructor(props: CreateTargetedSafesDto) { this.outreachId = props.outreachId; diff --git a/src/domain/targeted-messaging/targeted-messaging.repository.interface.ts b/src/domain/targeted-messaging/targeted-messaging.repository.interface.ts index 1f5ecac9c9..3b97ba609e 100644 --- a/src/domain/targeted-messaging/targeted-messaging.repository.interface.ts +++ b/src/domain/targeted-messaging/targeted-messaging.repository.interface.ts @@ -5,6 +5,7 @@ import { Submission } from '@/domain/targeted-messaging/entities/submission.enti import { TargetedSafe } from '@/domain/targeted-messaging/entities/targeted-safe.entity'; import { TargetedMessagingRepository } from '@/domain/targeted-messaging/targeted-messaging.repository'; import { Module } from '@nestjs/common'; +import type { Address } from 'viem'; export const ITargetedMessagingRepository = Symbol( 'ITargetedMessagingRepository', @@ -13,12 +14,12 @@ export const ITargetedMessagingRepository = Symbol( export interface ITargetedMessagingRepository { getTargetedSafe(args: { outreachId: number; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise; addSafeToOutreach(args: { outreachId: number; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise>; getOutreachOrFail(outreachId: number): Promise; @@ -26,12 +27,12 @@ export interface ITargetedMessagingRepository { getSubmission(args: { chainId: string; targetedSafe: TargetedSafe; - signerAddress: `0x${string}`; + signerAddress: Address; }): Promise; createSubmission(args: { targetedSafe: TargetedSafe; - signerAddress: `0x${string}`; + signerAddress: Address; }): Promise; } diff --git a/src/domain/targeted-messaging/targeted-messaging.repository.ts b/src/domain/targeted-messaging/targeted-messaging.repository.ts index 1c3dae2c5a..2a4ad5f070 100644 --- a/src/domain/targeted-messaging/targeted-messaging.repository.ts +++ b/src/domain/targeted-messaging/targeted-messaging.repository.ts @@ -5,6 +5,7 @@ import { Submission } from '@/domain/targeted-messaging/entities/submission.enti import { TargetedSafe } from '@/domain/targeted-messaging/entities/targeted-safe.entity'; import { ITargetedMessagingRepository } from '@/domain/targeted-messaging/targeted-messaging.repository.interface'; import { BadRequestException, Inject, Injectable } from '@nestjs/common'; +import type { Address } from 'viem'; @Injectable() export class TargetedMessagingRepository @@ -19,14 +20,14 @@ export class TargetedMessagingRepository async getTargetedSafe(args: { outreachId: number; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { return this.datasource.getTargetedSafe(args); } async addSafeToOutreach(args: { outreachId: number; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise> { return this.datasource.createTargetedSafes({ outreachId: args.outreachId, @@ -37,7 +38,7 @@ export class TargetedMessagingRepository async getSubmission(args: { chainId: string; targetedSafe: TargetedSafe; - signerAddress: `0x${string}`; + signerAddress: Address; }): Promise { const isOwner = await this.safeRepository.isOwner({ chainId: args.chainId, @@ -52,7 +53,7 @@ export class TargetedMessagingRepository async createSubmission(args: { targetedSafe: TargetedSafe; - signerAddress: `0x${string}`; + signerAddress: Address; }): Promise { return this.datasource.createSubmission(args); } diff --git a/src/domain/tokens/entities/__tests__/token.entity.spec.ts b/src/domain/tokens/entities/__tests__/token.entity.spec.ts index bd6712b7f0..c033ab8858 100644 --- a/src/domain/tokens/entities/__tests__/token.entity.spec.ts +++ b/src/domain/tokens/entities/__tests__/token.entity.spec.ts @@ -7,7 +7,7 @@ import { import { TokenSchema } from '@/domain/tokens/entities/token.entity'; import type { Token } from '@/domain/tokens/entities/token.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; describe('Token', () => { it('should validate a token', () => { @@ -21,7 +21,7 @@ describe('Token', () => { it('should checksum address', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const token = tokenBuilder().with('address', nonChecksummedAddress).build(); const result = TokenSchema.safeParse(token); diff --git a/src/domain/tokens/token.repository.interface.ts b/src/domain/tokens/token.repository.interface.ts index fb5dd87a07..cb1a54dc73 100644 --- a/src/domain/tokens/token.repository.interface.ts +++ b/src/domain/tokens/token.repository.interface.ts @@ -3,11 +3,12 @@ import { Token } from '@/domain/tokens/entities/token.entity'; import { Module } from '@nestjs/common'; import { TokenRepository } from '@/domain/tokens/token.repository'; import { TransactionApiManagerModule } from '@/domain/interfaces/transaction-api.manager.interface'; +import type { Address } from 'viem'; export const ITokenRepository = Symbol('ITokenRepository'); export interface ITokenRepository { - getToken(args: { chainId: string; address: `0x${string}` }): Promise; + getToken(args: { chainId: string; address: Address }): Promise; getTokens(args: { chainId: string; diff --git a/src/domain/tokens/token.repository.ts b/src/domain/tokens/token.repository.ts index c9a7c4f077..f34d275a17 100644 --- a/src/domain/tokens/token.repository.ts +++ b/src/domain/tokens/token.repository.ts @@ -7,6 +7,7 @@ import { TokenPageSchema, TokenSchema, } from '@/domain/tokens/entities/token.entity'; +import type { Address } from 'viem'; @Injectable() export class TokenRepository implements ITokenRepository { @@ -15,10 +16,7 @@ export class TokenRepository implements ITokenRepository { private readonly transactionApiManager: ITransactionApiManager, ) {} - async getToken(args: { - chainId: string; - address: `0x${string}`; - }): Promise { + async getToken(args: { chainId: string; address: Address }): Promise { const transactionService = await this.transactionApiManager.getApi( args.chainId, ); diff --git a/src/domain/transactions/entities/add-confirmation.dto.entity.ts b/src/domain/transactions/entities/add-confirmation.dto.entity.ts index d277175bb4..b739e1ad7b 100644 --- a/src/domain/transactions/entities/add-confirmation.dto.entity.ts +++ b/src/domain/transactions/entities/add-confirmation.dto.entity.ts @@ -1,8 +1,9 @@ import type { AddConfirmationDtoSchema } from '@/routes/transactions/entities/schemas/add-confirmation.dto.schema'; import type { z } from 'zod'; +import type { Address } from 'viem'; export class AddConfirmationDto implements z.infer { - signature!: `0x${string}`; + signature!: Address; } diff --git a/src/domain/transactions/entities/propose-transaction.dto.entity.ts b/src/domain/transactions/entities/propose-transaction.dto.entity.ts index 38ec4666c4..a91838bf83 100644 --- a/src/domain/transactions/entities/propose-transaction.dto.entity.ts +++ b/src/domain/transactions/entities/propose-transaction.dto.entity.ts @@ -1,22 +1,23 @@ import type { Operation } from '@/domain/safe/entities/operation.entity'; import type { ProposeTransactionDtoSchema } from '@/routes/transactions/entities/schemas/propose-transaction.dto.schema'; import type { z } from 'zod'; +import type { Address, Hash, Hex } from 'viem'; export class ProposeTransactionDto implements z.infer { - to!: `0x${string}`; + to!: Address; value!: string; - data!: `0x${string}` | null; + data!: Hex | null; nonce!: string; operation!: Operation; safeTxGas!: string; baseGas!: string; gasPrice!: string; - gasToken!: `0x${string}`; - refundReceiver!: `0x${string}` | null; - safeTxHash!: `0x${string}`; - sender!: `0x${string}`; - signature!: `0x${string}` | null; + gasToken!: Address; + refundReceiver!: Address | null; + safeTxHash!: Hash; + sender!: Address; + signature!: Hex | null; origin!: string | null; } diff --git a/src/domain/users/entities/member.entity.ts b/src/domain/users/entities/member.entity.ts index 493046b174..0a83f81c0f 100644 --- a/src/domain/users/entities/member.entity.ts +++ b/src/domain/users/entities/member.entity.ts @@ -7,6 +7,7 @@ import type { Space } from '@/domain/spaces/entities/space.entity'; import type { User } from '@/domain/users/entities/user.entity'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { NameSchema } from '@/domain/common/entities/name.schema'; +import type { Address } from 'viem'; export enum MemberRole { ADMIN = 1, @@ -28,7 +29,7 @@ export const MemberSchema: z.ZodType< alias: string | null; role: keyof typeof MemberRole; status: keyof typeof MemberStatus; - invitedBy: `0x${string}` | null; + invitedBy: Address | null; } > = RowSchema.extend({ user: z.lazy(() => UserSchema), @@ -37,7 +38,7 @@ export const MemberSchema: z.ZodType< alias: NameSchema.nullable(), role: z.enum(getStringEnumKeys(MemberRole)), status: z.enum(getStringEnumKeys(MemberStatus)), - invitedBy: AddressSchema.nullable() as z.ZodType<`0x${string}` | null>, + invitedBy: AddressSchema.nullable() as z.ZodType
, }); export type Member = z.infer; diff --git a/src/domain/users/members.repository.integration.spec.ts b/src/domain/users/members.repository.integration.spec.ts index c3e5595a97..84ebaf903f 100644 --- a/src/domain/users/members.repository.integration.spec.ts +++ b/src/domain/users/members.repository.integration.spec.ts @@ -28,6 +28,7 @@ import { faker } from '@faker-js/faker'; import { UnauthorizedException } from '@nestjs/common'; import type { ConfigService } from '@nestjs/config'; import { DataSource, In } from 'typeorm'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; const mockLoggingService = { @@ -625,14 +626,14 @@ describe('MembersRepository', () => { it('should throw an error if the signer_address does not exist', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const spaceId = faker.number.int({ min: 69420, max: DB_MAX_SAFE_INTEGER, }); const users: Array<{ - address: `0x${string}`; + address: Address; role: keyof typeof MemberRole; name: string; }> = []; @@ -653,7 +654,7 @@ describe('MembersRepository', () => { max: DB_MAX_SAFE_INTEGER, }); const users: Array<{ - address: `0x${string}`; + address: Address; role: keyof typeof MemberRole; name: string; }> = []; @@ -773,7 +774,7 @@ describe('MembersRepository', () => { max: DB_MAX_SAFE_INTEGER, }); const users: Array<{ - address: `0x${string}`; + address: Address; role: keyof typeof MemberRole; name: string; }> = []; @@ -828,7 +829,7 @@ describe('MembersRepository', () => { invitedBy: getAddress(faker.finance.ethereumAddress()), }); const users: Array<{ - address: `0x${string}`; + address: Address; role: keyof typeof MemberRole; name: string; }> = []; @@ -1052,7 +1053,7 @@ describe('MembersRepository', () => { it('should throw an error if the signer_address does not exist', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const spaceId = faker.number.int({ min: 69420, @@ -1343,7 +1344,7 @@ describe('MembersRepository', () => { it('should throw an error if the signer_address does not exist', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const spaceId = faker.number.int({ min: 69420, @@ -1554,7 +1555,7 @@ describe('MembersRepository', () => { it('should throw an error if the signer_address does not exist', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const spaceId = faker.number.int({ min: 69420, @@ -1925,7 +1926,7 @@ describe('MembersRepository', () => { it('should throw an error if the signer_address does not exist', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const spaceId = faker.number.int({ min: 69420, @@ -2266,7 +2267,7 @@ describe('MembersRepository', () => { it('should throw an error if the signer_address does not exist', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const spaceId = faker.number.int({ min: 69420, diff --git a/src/domain/users/members.repository.interface.ts b/src/domain/users/members.repository.interface.ts index a648d0cf50..2710f0a6ed 100644 --- a/src/domain/users/members.repository.interface.ts +++ b/src/domain/users/members.repository.interface.ts @@ -9,6 +9,7 @@ import type { FindOptionsRelations, FindOptionsWhere, } from 'typeorm'; +import type { Address } from 'viem'; export const IMembersRepository = Symbol('IMembersRepository'); @@ -33,7 +34,7 @@ export interface IMembersRepository { authPayload: AuthPayload; spaceId: Space['id']; users: Array<{ - address: `0x${string}`; + address: Address; role: Member['role']; name: Member['name']; }>; diff --git a/src/domain/users/members.repository.ts b/src/domain/users/members.repository.ts index 638d4879c7..7cc077c902 100644 --- a/src/domain/users/members.repository.ts +++ b/src/domain/users/members.repository.ts @@ -5,7 +5,7 @@ import { NotFoundException, UnauthorizedException, } from '@nestjs/common'; -import { isAddressEqual } from 'viem'; +import { type Address, isAddressEqual } from 'viem'; import { PostgresDatabaseService } from '@/datasources/db/v2/postgres-database.service'; import { ISpacesRepository } from '@/domain/spaces/spaces.repository.interface'; import { AuthPayload } from '@/domain/auth/entities/auth-payload.entity'; @@ -91,7 +91,7 @@ export class MembersRepository implements IMembersRepository { spaceId: Space['id']; users: Array<{ name: Member['name']; - address: `0x${string}`; + address: Address; role: Member['role']; }>; }): Promise> { @@ -166,7 +166,7 @@ export class MembersRepository implements IMembersRepository { private async createUserAndWallet(args: { entityManager: EntityManager; - address: `0x${string}`; + address: Address; }): Promise { const { address, entityManager } = args; const userId = await this.usersRepository.create('PENDING', entityManager); @@ -388,7 +388,7 @@ export class MembersRepository implements IMembersRepository { private assertSignerAddress( authPayload: AuthPayload, - ): asserts authPayload is AuthPayload & { signer_address: `0x${string}` } { + ): asserts authPayload is AuthPayload & { signer_address: Address } { if (!authPayload.signer_address) { throw new UnauthorizedException('Signer address not provided.'); } diff --git a/src/domain/users/users.repository.integration.spec.ts b/src/domain/users/users.repository.integration.spec.ts index 1f0d090f62..75f8eda610 100644 --- a/src/domain/users/users.repository.integration.spec.ts +++ b/src/domain/users/users.repository.integration.spec.ts @@ -1,6 +1,6 @@ import { faker } from '@faker-js/faker'; import { DataSource } from 'typeorm'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import configuration from '@/config/entities/__tests__/configuration'; import { postgresConfig } from '@/config/entities/postgres.config'; import { PostgresDatabaseService } from '@/datasources/db/v2/postgres-database.service'; @@ -225,7 +225,7 @@ describe('UsersRepository', () => { length: { min: 41, max: 41 }, }); const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', signerAddress as `0x${string}`) + .with('signer_address', signerAddress as Address) .build(); const authPayload = new AuthPayload(authPayloadDto); const status = faker.helpers.arrayElement(UserStatusKeys); @@ -241,7 +241,7 @@ describe('UsersRepository', () => { .ethereumAddress() .toLowerCase(); const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', nonChecksummedAddress as `0x${string}`) + .with('signer_address', nonChecksummedAddress as Address) .build(); const authPayload = new AuthPayload(authPayloadDto); const status = faker.helpers.arrayElement(UserStatusKeys); @@ -346,7 +346,7 @@ describe('UsersRepository', () => { const dbUserRepository = dataSource.getRepository(User); const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const authPayloadDto = authPayloadDtoBuilder() .with('signer_address', nonChecksummedAddress) .build(); @@ -462,7 +462,7 @@ describe('UsersRepository', () => { await expect( usersRepository.addWalletToUser({ authPayload, - walletAddress: walletAddress as `0x${string}`, + walletAddress: walletAddress as Address, }), ).rejects.toThrow(new RegExp(`^Address "${walletAddress}" is invalid.`)); }); @@ -488,7 +488,7 @@ describe('UsersRepository', () => { await usersRepository.addWalletToUser({ authPayload, - walletAddress: nonChecksummedAddress as `0x${string}`, + walletAddress: nonChecksummedAddress as Address, }); const wallet = await dbWalletRepository.findOneOrFail({ diff --git a/src/domain/users/users.repository.interface.ts b/src/domain/users/users.repository.interface.ts index 5940dbb40d..6bbe59c725 100644 --- a/src/domain/users/users.repository.interface.ts +++ b/src/domain/users/users.repository.interface.ts @@ -2,6 +2,7 @@ import type { AuthPayload } from '@/domain/auth/entities/auth-payload.entity'; import type { User, UserStatus } from '@/domain/users/entities/user.entity'; import type { Wallet } from '@/datasources/wallets/entities/wallets.entity.db'; import type { EntityManager } from 'typeorm'; +import type { Address } from 'viem'; export const IUsersRepository = Symbol('IUsersRepository'); @@ -23,20 +24,20 @@ export interface IUsersRepository { }>; addWalletToUser(args: { - walletAddress: `0x${string}`; + walletAddress: Address; authPayload: AuthPayload; }): Promise>; delete(authPayload: AuthPayload): Promise; deleteWalletFromUser(args: { - walletAddress: `0x${string}`; + walletAddress: Address; authPayload: AuthPayload; }): Promise; - findByWalletAddressOrFail(address: `0x${string}`): Promise; + findByWalletAddressOrFail(address: Address): Promise; - findByWalletAddress(address: `0x${string}`): Promise; + findByWalletAddress(address: Address): Promise; update(args: { userId: User['id']; diff --git a/src/domain/users/users.repository.ts b/src/domain/users/users.repository.ts index f01414764b..8d5d07c98d 100644 --- a/src/domain/users/users.repository.ts +++ b/src/domain/users/users.repository.ts @@ -13,6 +13,7 @@ import { User as DbUser } from '@/datasources/users/entities/users.entity.db'; import { Wallet } from '@/datasources/wallets/entities/wallets.entity.db'; import { EntityManager } from 'typeorm'; import { IWalletsRepository } from '@/domain/wallets/wallets.repository.interface'; +import type { Address } from 'viem'; @Injectable() export class UsersRepository implements IUsersRepository { @@ -84,7 +85,7 @@ export class UsersRepository implements IUsersRepository { } async addWalletToUser(args: { - walletAddress: `0x${string}`; + walletAddress: Address; authPayload: AuthPayload; }): Promise> { this.assertSignerAddress(args.authPayload); @@ -126,7 +127,7 @@ export class UsersRepository implements IUsersRepository { } public async deleteWalletFromUser(args: { - walletAddress: `0x${string}`; + walletAddress: Address; authPayload: AuthPayload; }): Promise { this.assertSignerAddress(args.authPayload); @@ -144,9 +145,7 @@ export class UsersRepository implements IUsersRepository { await this.walletsRepository.deleteByAddress(wallet.address); } - public async findByWalletAddressOrFail( - address: `0x${string}`, - ): Promise { + public async findByWalletAddressOrFail(address: Address): Promise { const user = await this.findByWalletAddress(address); if (!user) { @@ -157,7 +156,7 @@ export class UsersRepository implements IUsersRepository { } public async findByWalletAddress( - address: `0x${string}`, + address: Address, ): Promise { const wallet = await this.walletsRepository.findOneByAddress(address, { user: true, @@ -191,7 +190,7 @@ export class UsersRepository implements IUsersRepository { private assertSignerAddress( authPayload: AuthPayload, - ): asserts authPayload is AuthPayload & { signer_address: `0x${string}` } { + ): asserts authPayload is AuthPayload & { signer_address: Address } { if (!authPayload.signer_address) { throw new UnauthorizedException('Signer address not provided'); } @@ -199,7 +198,7 @@ export class UsersRepository implements IUsersRepository { private assertWalletIsNotSigner(args: { authPayload: AuthPayload; - walletAddress: `0x${string}`; + walletAddress: Address; }): void { if (args.authPayload.isForSigner(args.walletAddress)) { throw new ConflictException('Cannot remove the current wallet'); @@ -207,7 +206,7 @@ export class UsersRepository implements IUsersRepository { } private async assertWalletDoesNotExist( - walletAddress: `0x${string}`, + walletAddress: Address, ): Promise { const wallet = await this.walletsRepository.findOneByAddress(walletAddress); diff --git a/src/domain/wallets/entities/wallet.entity.ts b/src/domain/wallets/entities/wallet.entity.ts index 31172ef952..c6851ebd14 100644 --- a/src/domain/wallets/entities/wallet.entity.ts +++ b/src/domain/wallets/entities/wallet.entity.ts @@ -2,11 +2,12 @@ import type { z } from 'zod'; import { RowSchema } from '@/datasources/db/v2/entities/row.entity'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { UserSchema } from '@/domain/users/entities/user.entity'; +import type { Address } from 'viem'; export type Wallet = z.infer; export const WalletSchema = RowSchema.extend({ // ZodEffects cannot be recursively inferred and need be casted - address: AddressSchema as z.ZodType<`0x${string}`>, + address: AddressSchema as z.ZodType
, user: UserSchema, }); diff --git a/src/domain/wallets/wallets.repository.integration.spec.ts b/src/domain/wallets/wallets.repository.integration.spec.ts index 2c10603dfc..546f97a1ae 100644 --- a/src/domain/wallets/wallets.repository.integration.spec.ts +++ b/src/domain/wallets/wallets.repository.integration.spec.ts @@ -1,6 +1,6 @@ import { faker } from '@faker-js/faker'; import { DataSource } from 'typeorm'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import configuration from '@/config/entities/__tests__/configuration'; import { postgresConfig } from '@/config/entities/postgres.config'; import { PostgresDatabaseService } from '@/datasources/db/v2/postgres-database.service'; @@ -374,7 +374,7 @@ describe('WalletsRepository', () => { const dbUserRepository = dataSource.getRepository(User); const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const user = await dbUserRepository.insert({ status: faker.helpers.arrayElement(UserStatusKeys), }); @@ -436,7 +436,7 @@ describe('WalletsRepository', () => { const dbUserRepository = dataSource.getRepository(User); const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const user = await dbUserRepository.insert({ status: faker.helpers.arrayElement(UserStatusKeys), }); @@ -570,7 +570,7 @@ describe('WalletsRepository', () => { await walletsRepository.create( { userId: user.identifiers[0].id as User['id'], - walletAddress: nonChecksummedAddress as `0x${string}`, + walletAddress: nonChecksummedAddress as Address, }, entityManager, ); @@ -651,7 +651,7 @@ describe('WalletsRepository', () => { await walletsRepository.create( { userId: user.identifiers[0].id as User['id'], - walletAddress: walletAddress as `0x${string}`, + walletAddress: walletAddress as Address, }, entityManager, ); @@ -697,9 +697,7 @@ describe('WalletsRepository', () => { }, }); - await walletsRepository.deleteByAddress( - nonChecksummedAddress as `0x${string}`, - ); + await walletsRepository.deleteByAddress(nonChecksummedAddress as Address); await expect(dbWalletRepository.find()).resolves.toEqual([]); }); @@ -710,7 +708,7 @@ describe('WalletsRepository', () => { }); await expect( - walletsRepository.deleteByAddress(walletAddress as `0x${string}`), + walletsRepository.deleteByAddress(walletAddress as Address), ).rejects.toThrow(new RegExp(`^Address "${walletAddress}" is invalid.`)); }); }); diff --git a/src/domain/wallets/wallets.repository.interface.ts b/src/domain/wallets/wallets.repository.interface.ts index c6e79a488e..46c190f8e7 100644 --- a/src/domain/wallets/wallets.repository.interface.ts +++ b/src/domain/wallets/wallets.repository.interface.ts @@ -8,6 +8,7 @@ import type { import { type Repository, type EntityManager } from 'typeorm'; import type { Wallet } from '@/datasources/wallets/entities/wallets.entity.db'; import type { User } from '@/domain/users/entities/user.entity'; +import type { Address } from 'viem'; export const IWalletsRepository = Symbol('IWalletsRepository'); @@ -35,12 +36,12 @@ export interface IWalletsRepository { }): Promise>; findOneByAddressOrFail( - address: `0x${string}`, + address: Address, relations?: FindOptionsRelations, ): Promise; findOneByAddress( - address: `0x${string}`, + address: Address, relations?: FindOptionsRelations, ): Promise; @@ -52,10 +53,10 @@ export interface IWalletsRepository { create( args: { userId: number; - walletAddress: `0x${string}`; + walletAddress: Address; }, entityManager: EntityManager | Repository, ): Promise; - deleteByAddress(address: `0x${string}`): Promise; + deleteByAddress(address: Address): Promise; } diff --git a/src/domain/wallets/wallets.repository.ts b/src/domain/wallets/wallets.repository.ts index 1b44b495dc..6073c5d503 100644 --- a/src/domain/wallets/wallets.repository.ts +++ b/src/domain/wallets/wallets.repository.ts @@ -11,6 +11,7 @@ import type { import type { User } from '@/domain/users/entities/user.entity'; import type { IWalletsRepository } from '@/domain/wallets/wallets.repository.interface'; import { PostgresDatabaseService } from '@/datasources/db/v2/postgres-database.service'; +import type { Address } from 'viem'; @Injectable() export class WalletsRepository implements IWalletsRepository { @@ -71,7 +72,7 @@ export class WalletsRepository implements IWalletsRepository { } public async findOneByAddressOrFail( - address: `0x${string}`, + address: Address, relations?: FindOptionsRelations, ): Promise { const wallet = await this.findOneByAddress(address, relations); @@ -84,7 +85,7 @@ export class WalletsRepository implements IWalletsRepository { } public async findOneByAddress( - address: `0x${string}`, + address: Address, relations?: FindOptionsRelations, ): Promise { return await this.findOne({ address }, relations); @@ -107,7 +108,7 @@ export class WalletsRepository implements IWalletsRepository { public async create( args: { userId: number; - walletAddress: `0x${string}`; + walletAddress: Address; }, entityManager: EntityManager, ): Promise { @@ -119,7 +120,7 @@ export class WalletsRepository implements IWalletsRepository { }); } - public async deleteByAddress(address: `0x${string}`): Promise { + public async deleteByAddress(address: Address): Promise { const walletRepository = await this.postgresDatabaseService.getRepository(Wallet); diff --git a/src/modules/csv-export/v1/csv-export.controller.ts b/src/modules/csv-export/v1/csv-export.controller.ts index 497486d545..2d8e65e93b 100644 --- a/src/modules/csv-export/v1/csv-export.controller.ts +++ b/src/modules/csv-export/v1/csv-export.controller.ts @@ -24,6 +24,7 @@ import { } from '@/routes/jobs/entities/job-status.dto'; import { TransactionExportDtoSchema } from '@/modules/csv-export/v1/entities/schemas/transaction-export.dto.schema'; import { TransactionExportDto } from '@/modules/csv-export/v1/entities/transaction-export-request'; +import type { Address } from 'viem'; @ApiTags('export') @Controller({ @@ -43,7 +44,7 @@ export class CsvExportController { async launchExport( @Param('chainId', new ValidationPipe(NumericStringSchema)) chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Body(new ValidationPipe(TransactionExportDtoSchema)) exportDto?: TransactionExportDto, ): Promise { diff --git a/src/modules/csv-export/v1/csv-export.service.spec.ts b/src/modules/csv-export/v1/csv-export.service.spec.ts index 0c471c7b66..28a1f39515 100644 --- a/src/modules/csv-export/v1/csv-export.service.spec.ts +++ b/src/modules/csv-export/v1/csv-export.service.spec.ts @@ -24,6 +24,7 @@ import { UnrecoverableError } from 'bullmq'; import type { TransactionExport } from '@/modules/csv-export/v1/entities/transaction-export.entity'; import type { CompleteMultipartUploadCommandOutput } from '@aws-sdk/client-s3'; import { pipeline } from 'stream/promises'; +import type { Address } from 'viem'; const exportApi = { export: jest.fn(), @@ -83,7 +84,7 @@ describe('CsvExportService', () => { const exportArgs = { chainId: faker.string.numeric(1), - safeAddress: faker.finance.ethereumAddress() as `0x${string}`, + safeAddress: faker.finance.ethereumAddress() as Address, timestamp: faker.date.recent().getTime(), executionDateGte: faker.date.past().toISOString().split('T')[0], executionDateLte: faker.date.recent().toISOString().split('T')[0], @@ -493,7 +494,7 @@ describe('CsvExportService', () => { it('should generate correct filename when dates are not provided', async () => { const exportArgsWithoutDates = { chainId: faker.string.numeric(1), - safeAddress: faker.finance.ethereumAddress() as `0x${string}`, + safeAddress: faker.finance.ethereumAddress() as Address, timestamp: faker.date.recent().getTime(), }; @@ -515,7 +516,7 @@ describe('CsvExportService', () => { it('should generate correct filename when only one date is provided', async () => { const exportArgsPartialDates = { chainId: faker.string.numeric(1), - safeAddress: faker.finance.ethereumAddress() as `0x${string}`, + safeAddress: faker.finance.ethereumAddress() as Address, timestamp: faker.date.recent().getTime(), executionDateGte: faker.date.past().toISOString().split('T')[0], }; diff --git a/src/modules/csv-export/v1/csv-export.service.ts b/src/modules/csv-export/v1/csv-export.service.ts index a6b0eae340..dcea864a09 100644 --- a/src/modules/csv-export/v1/csv-export.service.ts +++ b/src/modules/csv-export/v1/csv-export.service.ts @@ -27,6 +27,7 @@ import { asError } from '@/logging/utils'; import { DataSourceError } from '@/domain/errors/data-source.error'; import { CSV_OPTIONS } from '@/modules/csv-export/v1/entities/csv-export.options'; import { CompleteMultipartUploadCommandOutput } from '@aws-sdk/client-s3'; +import type { Address } from 'viem'; @Injectable() export class CsvExportService { @@ -70,7 +71,7 @@ export class CsvExportService { */ async registerExportJob(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; executionDateGte?: string; executionDateLte?: string; limit?: number; @@ -103,7 +104,7 @@ export class CsvExportService { async export( args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; timestamp: number; executionDateGte?: string; executionDateLte?: string; @@ -145,7 +146,7 @@ export class CsvExportService { private async *transactionPagesGenerator( args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; executionDateGte?: string; executionDateLte?: string; limit?: number; @@ -263,7 +264,7 @@ export class CsvExportService { private updatePaginationParams( nextUrl: string, chainId: string, - safeAddress: `0x${string}`, + safeAddress: Address, pageCount: number, currentLimit: number, currentOffset: number, @@ -307,7 +308,7 @@ export class CsvExportService { private generateFileName( chainId: string, - safeAddress: `0x${string}`, + safeAddress: Address, timestamp: number, ): string { return `${CsvExportService.FILE_NAME}_${chainId}_${safeAddress}_${timestamp}.csv`; diff --git a/src/modules/csv-export/v1/datasources/export-api.interface.ts b/src/modules/csv-export/v1/datasources/export-api.interface.ts index 2a7c1d853f..f90f4064ab 100644 --- a/src/modules/csv-export/v1/datasources/export-api.interface.ts +++ b/src/modules/csv-export/v1/datasources/export-api.interface.ts @@ -1,12 +1,13 @@ import type { Page } from '@/domain/entities/page.entity'; import type { TransactionExport } from '@/modules/csv-export/v1/entities/transaction-export.entity'; import type { Raw } from '@/validation/entities/raw.entity'; +import type { Address } from 'viem'; export const IExportApi = Symbol('IExportApi'); export interface IExportApi { export(args: { - safeAddress: `0x${string}`; + safeAddress: Address; executionDateGte?: string; executionDateLte?: string; limit?: number; diff --git a/src/modules/csv-export/v1/datasources/export-api.service.ts b/src/modules/csv-export/v1/datasources/export-api.service.ts index 80a1a289aa..f7e99734d2 100644 --- a/src/modules/csv-export/v1/datasources/export-api.service.ts +++ b/src/modules/csv-export/v1/datasources/export-api.service.ts @@ -7,6 +7,7 @@ import { IExportApi } from '@/modules/csv-export/v1/datasources/export-api.inter import { TransactionExport } from '@/modules/csv-export/v1/entities/transaction-export.entity'; import { Raw } from '@/validation/entities/raw.entity'; import { Inject, Injectable } from '@nestjs/common'; +import type { Address } from 'viem'; @Injectable() export class ExportApi implements IExportApi { @@ -32,7 +33,7 @@ export class ExportApi implements IExportApi { } async export(args: { - safeAddress: `0x${string}`; + safeAddress: Address; executionDateGte?: string; executionDateLte?: string; limit?: number; diff --git a/src/modules/csv-export/v1/entities/__tests__/transaction-export.builder.ts b/src/modules/csv-export/v1/entities/__tests__/transaction-export.builder.ts index 5b4b31a1f3..d7c5cc76b8 100644 --- a/src/modules/csv-export/v1/entities/__tests__/transaction-export.builder.ts +++ b/src/modules/csv-export/v1/entities/__tests__/transaction-export.builder.ts @@ -1,6 +1,6 @@ import { faker } from '@faker-js/faker'; import { formatUnits, getAddress } from 'viem'; -import type { Hex } from 'viem'; +import type { Hash } from 'viem'; import { Builder } from '@/__tests__/builder'; import type { IBuilder } from '@/__tests__/builder'; import type { TransactionExport } from '@/modules/csv-export/v1/entities/transaction-export.entity'; @@ -26,7 +26,7 @@ export function transactionExportBuilder(): IBuilder { .with('executorAddress', getAddress(faker.finance.ethereumAddress())) .with('executedAt', faker.date.recent()) .with('note', faker.lorem.sentence()) - .with('transactionHash', faker.string.hexadecimal({ length: 64 }) as Hex) + .with('transactionHash', faker.string.hexadecimal({ length: 64 }) as Hash) .with('contractAddress', getAddress(faker.finance.ethereumAddress())) .with('nonce', faker.number.int().toString()); } diff --git a/src/modules/csv-export/v1/entities/csv-export-job-data.entity.ts b/src/modules/csv-export/v1/entities/csv-export-job-data.entity.ts index 660e6c8f25..5df28407d1 100644 --- a/src/modules/csv-export/v1/entities/csv-export-job-data.entity.ts +++ b/src/modules/csv-export/v1/entities/csv-export-job-data.entity.ts @@ -2,10 +2,11 @@ import type { JobData, JobResponse, } from '@/datasources/job-queue/types/job-types'; +import type { Address } from 'viem'; export interface CsvExportJobData extends JobData { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; executionDateGte?: string; executionDateLte?: string; limit?: number; diff --git a/src/modules/csv-export/v1/entities/transaction-export.entity.spec.ts b/src/modules/csv-export/v1/entities/transaction-export.entity.spec.ts index 57d88b9259..1bd604858d 100644 --- a/src/modules/csv-export/v1/entities/transaction-export.entity.spec.ts +++ b/src/modules/csv-export/v1/entities/transaction-export.entity.spec.ts @@ -1,6 +1,6 @@ import { faker } from '@faker-js/faker'; import { getAddress } from 'viem'; -import type { Hex } from 'viem'; +import type { Address, Hex } from 'viem'; import { transactionExportBuilder } from '@/modules/csv-export/v1/entities/__tests__/transaction-export.builder'; import { TransactionExportSchema } from '@/modules/csv-export/v1/entities/transaction-export.entity'; @@ -22,13 +22,13 @@ describe('TransactionExportSchema', () => { const contractAddress = faker.finance.ethereumAddress().toLowerCase(); const transactionExportData = transactionExportBuilder() - .with('safe', safe as `0x${string}`) - .with('from', from as `0x${string}`) - .with('to', to as `0x${string}`) - .with('assetAddress', assetAddress as `0x${string}`) - .with('proposerAddress', proposerAddress as `0x${string}`) - .with('executorAddress', executorAddress as `0x${string}`) - .with('contractAddress', contractAddress as `0x${string}`) + .with('safe', safe as Address) + .with('from', from as Address) + .with('to', to as Address) + .with('assetAddress', assetAddress as Address) + .with('proposerAddress', proposerAddress as Address) + .with('executorAddress', executorAddress as Address) + .with('contractAddress', contractAddress as Address) .build(); const result = TransactionExportSchema.safeParse(transactionExportData); @@ -68,7 +68,7 @@ describe('TransactionExportSchema', () => { 'contractAddress', ] as const)('should validate %s as a valid address', (field) => { const transactionExportData = transactionExportBuilder() - .with(field, '0x123' as `0x${string}`) + .with(field, '0x123' as Address) .build(); const result = TransactionExportSchema.safeParse(transactionExportData); diff --git a/src/routes/accounts/accounts.controller.ts b/src/routes/accounts/accounts.controller.ts index 138ec0baf3..674f4b5943 100644 --- a/src/routes/accounts/accounts.controller.ts +++ b/src/routes/accounts/accounts.controller.ts @@ -36,6 +36,7 @@ import { ApiForbiddenResponse, } from '@nestjs/swagger'; import { Request } from 'express'; +import type { Address } from 'viem'; @ApiTags('accounts') @Controller({ path: 'accounts', version: '1' }) @@ -115,7 +116,7 @@ export class AccountsController { @UseGuards(AuthGuard) async getAccountDataSettings( @Auth() authPayload: AuthPayload, - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, ): Promise> { return this.accountsService.getAccountDataSettings({ authPayload, @@ -149,7 +150,7 @@ export class AccountsController { @UseGuards(AuthGuard) async upsertAccountDataSettings( @Auth() authPayload: AuthPayload, - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, @Body(new ValidationPipe(UpsertAccountDataSettingsDtoSchema)) upsertAccountDataSettingsDto: UpsertAccountDataSettingsDto, ): Promise> { @@ -180,7 +181,7 @@ export class AccountsController { @Get(':address') @UseGuards(AuthGuard) async getAccount( - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, @Auth() authPayload: AuthPayload, ): Promise { return this.accountsService.getAccount({ authPayload, address }); @@ -206,7 +207,7 @@ export class AccountsController { @UseGuards(AuthGuard) @HttpCode(HttpStatus.NO_CONTENT) async deleteAccount( - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, @Auth() authPayload: AuthPayload, ): Promise { return this.accountsService.deleteAccount({ authPayload, address }); diff --git a/src/routes/accounts/accounts.service.ts b/src/routes/accounts/accounts.service.ts index 46a38ae6c3..198152d7e5 100644 --- a/src/routes/accounts/accounts.service.ts +++ b/src/routes/accounts/accounts.service.ts @@ -10,6 +10,7 @@ import { CreateAccountDto } from '@/routes/accounts/entities/create-account.dto. import { UpsertAccountDataSettingsDto } from '@/routes/accounts/entities/upsert-account-data-settings.dto.entity'; import { Inject, Injectable } from '@nestjs/common'; import { Request } from 'express'; +import type { Address } from 'viem'; @Injectable() export class AccountsService { @@ -33,7 +34,7 @@ export class AccountsService { async getAccount(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise { const domainAccount = await this.accountsRepository.getAccount({ authPayload: args.authPayload, @@ -44,7 +45,7 @@ export class AccountsService { async deleteAccount(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise { await this.accountsRepository.deleteAccount({ authPayload: args.authPayload, @@ -61,7 +62,7 @@ export class AccountsService { async getAccountDataSettings(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise> { const [domainAccountDataSettings, dataTypes] = await Promise.all([ this.accountsRepository.getAccountDataSettings({ @@ -78,7 +79,7 @@ export class AccountsService { async upsertAccountDataSettings(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; upsertAccountDataSettingsDto: UpsertAccountDataSettingsDto; }): Promise> { const [domainAccountDataSettings, dataTypes] = await Promise.all([ diff --git a/src/routes/accounts/address-books/address-books.controller.ts b/src/routes/accounts/address-books/address-books.controller.ts index df434e5d6b..9d223636e1 100644 --- a/src/routes/accounts/address-books/address-books.controller.ts +++ b/src/routes/accounts/address-books/address-books.controller.ts @@ -23,6 +23,7 @@ import { UseGuards, } from '@nestjs/common'; import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; +import type { Address } from 'viem'; @ApiTags('accounts') @Controller({ path: 'accounts', version: '1' }) @@ -34,7 +35,7 @@ export class AddressBooksController { @UseGuards(AuthGuard) async getAddressBook( @Auth() authPayload: AuthPayload, - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, @Param('chainId', new ValidationPipe(NumericStringSchema)) chainId: string, ): Promise { return this.service.getAddressBook({ @@ -49,7 +50,7 @@ export class AddressBooksController { @UseGuards(AuthGuard) async createAddressBookItem( @Auth() authPayload: AuthPayload, - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, @Param('chainId', new ValidationPipe(NumericStringSchema)) chainId: string, @Body(new ValidationPipe(CreateAddressBookItemDtoSchema)) createAddressBookItemDto: CreateAddressBookItemDto, @@ -66,7 +67,7 @@ export class AddressBooksController { @UseGuards(AuthGuard) async deleteAddressBook( @Auth() authPayload: AuthPayload, - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, @Param('chainId', new ValidationPipe(NumericStringSchema)) chainId: string, ): Promise { return this.service.deleteAddressBook({ @@ -80,7 +81,7 @@ export class AddressBooksController { @UseGuards(AuthGuard) async deleteAddressBookItem( @Auth() authPayload: AuthPayload, - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, @Param('chainId', new ValidationPipe(NumericStringSchema)) chainId: string, @Param('addressBookItemId', new DefaultValuePipe(0), ParseIntPipe) addressBookItemId: number, diff --git a/src/routes/accounts/address-books/address-books.service.ts b/src/routes/accounts/address-books/address-books.service.ts index a5e572ffe2..251fddcda0 100644 --- a/src/routes/accounts/address-books/address-books.service.ts +++ b/src/routes/accounts/address-books/address-books.service.ts @@ -8,6 +8,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { IAddressBooksRepository } from '@/domain/accounts/address-books/address-books.repository.interface'; import { AuthPayload } from '@/domain/auth/entities/auth-payload.entity'; import { CreateAddressBookItemDto } from '@/domain/accounts/address-books/entities/create-address-book-item.dto.entity'; +import type { Address } from 'viem'; @Injectable() export class AddressBooksService { @@ -18,7 +19,7 @@ export class AddressBooksService { async getAddressBook(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; }): Promise { const domainAddressBook = await this.repository.getAddressBook(args); @@ -27,7 +28,7 @@ export class AddressBooksService { async createAddressBookItem(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; createAddressBookItemDto: CreateAddressBookItemDto; }): Promise { @@ -38,7 +39,7 @@ export class AddressBooksService { async deleteAddressBook(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; }): Promise { await this.repository.deleteAddressBook(args); @@ -46,7 +47,7 @@ export class AddressBooksService { async deleteAddressBookItem(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; addressBookItemId: number; }): Promise { diff --git a/src/routes/accounts/address-books/entities/address-book.entity.ts b/src/routes/accounts/address-books/entities/address-book.entity.ts index 7eb2cf0bfc..3bb643d67e 100644 --- a/src/routes/accounts/address-books/entities/address-book.entity.ts +++ b/src/routes/accounts/address-books/entities/address-book.entity.ts @@ -1,4 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class AddressBookItem { @ApiProperty() @@ -6,9 +7,9 @@ export class AddressBookItem { @ApiProperty() name: string; @ApiProperty() - address: `0x${string}`; + address: Address; - constructor(id: string, name: string, address: `0x${string}`) { + constructor(id: string, name: string, address: Address) { this.id = id; this.name = name; this.address = address; diff --git a/src/routes/accounts/address-books/entities/create-address-book-item.dto.entity.ts b/src/routes/accounts/address-books/entities/create-address-book-item.dto.entity.ts index f90e9ede6e..407716ace8 100644 --- a/src/routes/accounts/address-books/entities/create-address-book-item.dto.entity.ts +++ b/src/routes/accounts/address-books/entities/create-address-book-item.dto.entity.ts @@ -4,6 +4,7 @@ import { NAME_MIN_LENGTH, } from '@/domain/common/entities/name.schema'; import { ApiProperty } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class CreateAddressBookItemDto implements DomainCreateAddressBookItemDto @@ -11,5 +12,5 @@ export class CreateAddressBookItemDto @ApiProperty({ minLength: NAME_MIN_LENGTH, maxLength: NAME_MAX_LENGTH }) name!: string; @ApiProperty() - address!: `0x${string}`; + address!: Address; } diff --git a/src/routes/accounts/counterfactual-safes/counterfactual-safes.controller.ts b/src/routes/accounts/counterfactual-safes/counterfactual-safes.controller.ts index 8802d2025d..145c66ce4c 100644 --- a/src/routes/accounts/counterfactual-safes/counterfactual-safes.controller.ts +++ b/src/routes/accounts/counterfactual-safes/counterfactual-safes.controller.ts @@ -18,6 +18,7 @@ import { UseGuards, } from '@nestjs/common'; import { ApiOkResponse, ApiTags } from '@nestjs/swagger'; +import type { Address } from 'viem'; @ApiTags('accounts') @Controller({ path: 'accounts', version: '1' }) @@ -27,10 +28,10 @@ export class CounterfactualSafesController { @ApiOkResponse({ type: CounterfactualSafe }) @Get(':address/counterfactual-safes/:chainId/:predictedAddress') async getCounterfactualSafe( - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, @Param('chainId', new ValidationPipe(NumericStringSchema)) chainId: string, @Param('predictedAddress', new ValidationPipe(AddressSchema)) - predictedAddress: `0x${string}`, + predictedAddress: Address, ): Promise { return this.service.getCounterfactualSafe({ address, @@ -42,7 +43,7 @@ export class CounterfactualSafesController { @ApiOkResponse({ type: CounterfactualSafe, isArray: true }) @Get(':address/counterfactual-safes') async getCounterfactualSafes( - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, ): Promise> { return this.service.getCounterfactualSafes(address); } @@ -52,7 +53,7 @@ export class CounterfactualSafesController { @UseGuards(AuthGuard) async createCounterfactualSafe( @Auth() authPayload: AuthPayload, - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, @Body(new ValidationPipe(CreateCounterfactualSafeDtoSchema)) createCounterfactualSafeDto: CreateCounterfactualSafeDto, ): Promise { @@ -67,10 +68,10 @@ export class CounterfactualSafesController { @UseGuards(AuthGuard) async deleteCounterfactualSafe( @Auth() authPayload: AuthPayload, - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, @Param('chainId', new ValidationPipe(NumericStringSchema)) chainId: string, @Param('predictedAddress', new ValidationPipe(AddressSchema)) - predictedAddress: `0x${string}`, + predictedAddress: Address, ): Promise { return this.service.deleteCounterfactualSafe({ authPayload, @@ -84,7 +85,7 @@ export class CounterfactualSafesController { @UseGuards(AuthGuard) async deleteCounterfactualSafes( @Auth() authPayload: AuthPayload, - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, ): Promise { return this.service.deleteCounterfactualSafes({ authPayload, address }); } diff --git a/src/routes/accounts/counterfactual-safes/counterfactual-safes.service.ts b/src/routes/accounts/counterfactual-safes/counterfactual-safes.service.ts index 46a371f0dc..1b7adeb14b 100644 --- a/src/routes/accounts/counterfactual-safes/counterfactual-safes.service.ts +++ b/src/routes/accounts/counterfactual-safes/counterfactual-safes.service.ts @@ -4,6 +4,7 @@ import { CreateCounterfactualSafeDto } from '@/domain/accounts/counterfactual-sa import { AuthPayload } from '@/domain/auth/entities/auth-payload.entity'; import { CounterfactualSafe } from '@/routes/accounts/counterfactual-safes/entities/counterfactual-safe.entity'; import { Inject, Injectable } from '@nestjs/common'; +import type { Address } from 'viem'; @Injectable() export class CounterfactualSafesService { @@ -13,9 +14,9 @@ export class CounterfactualSafesService { ) {} async getCounterfactualSafe(args: { - address: `0x${string}`; + address: Address; chainId: string; - predictedAddress: `0x${string}`; + predictedAddress: Address; }): Promise { const domainCounterfactualSafe = await this.repository.getCounterfactualSafe(args); @@ -23,7 +24,7 @@ export class CounterfactualSafesService { } async getCounterfactualSafes( - address: `0x${string}`, + address: Address, ): Promise> { const domainCounterfactualSafes = await this.repository.getCounterfactualSafes(address); @@ -34,7 +35,7 @@ export class CounterfactualSafesService { async createCounterfactualSafe(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; createCounterfactualSafeDto: CreateCounterfactualSafeDto; }): Promise { const domainCounterfactualSafe = @@ -44,16 +45,16 @@ export class CounterfactualSafesService { async deleteCounterfactualSafe(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; chainId: string; - predictedAddress: `0x${string}`; + predictedAddress: Address; }): Promise { await this.repository.deleteCounterfactualSafe(args); } async deleteCounterfactualSafes(args: { authPayload: AuthPayload; - address: `0x${string}`; + address: Address; }): Promise { await this.repository.deleteCounterfactualSafes(args); } diff --git a/src/routes/accounts/counterfactual-safes/entities/counterfactual-safe.entity.ts b/src/routes/accounts/counterfactual-safes/entities/counterfactual-safe.entity.ts index e667264884..465e26f988 100644 --- a/src/routes/accounts/counterfactual-safes/entities/counterfactual-safe.entity.ts +++ b/src/routes/accounts/counterfactual-safes/entities/counterfactual-safe.entity.ts @@ -1,31 +1,32 @@ import { ApiProperty } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class CounterfactualSafe { @ApiProperty() chainId: string; @ApiProperty() - creator: `0x${string}`; + creator: Address; @ApiProperty() - fallbackHandler: `0x${string}`; + fallbackHandler: Address; @ApiProperty({ type: String, isArray: true }) - owners: Array<`0x${string}`>; + owners: Array
; @ApiProperty() - predictedAddress: `0x${string}`; + predictedAddress: Address; @ApiProperty() saltNonce: string; @ApiProperty() - singletonAddress: `0x${string}`; + singletonAddress: Address; @ApiProperty() threshold: number; constructor( chainId: string, - creator: `0x${string}`, - fallbackHandler: `0x${string}`, - owners: Array<`0x${string}`>, - predictedAddress: `0x${string}`, + creator: Address, + fallbackHandler: Address, + owners: Array
, + predictedAddress: Address, saltNonce: string, - singletonAddress: `0x${string}`, + singletonAddress: Address, threshold: number, ) { this.chainId = chainId; diff --git a/src/routes/accounts/counterfactual-safes/entities/create-counterfactual-safe.dto.entity.ts b/src/routes/accounts/counterfactual-safes/entities/create-counterfactual-safe.dto.entity.ts index 6cc6e77071..58f9921c19 100644 --- a/src/routes/accounts/counterfactual-safes/entities/create-counterfactual-safe.dto.entity.ts +++ b/src/routes/accounts/counterfactual-safes/entities/create-counterfactual-safe.dto.entity.ts @@ -1,5 +1,6 @@ import { CreateCounterfactualSafeDto as DomainCreateCounterfactualSafeDto } from '@/domain/accounts/counterfactual-safes/entities/create-counterfactual-safe.dto.entity'; import { ApiProperty } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class CreateCounterfactualSafeDto implements DomainCreateCounterfactualSafeDto @@ -7,15 +8,15 @@ export class CreateCounterfactualSafeDto @ApiProperty() chainId!: string; @ApiProperty() - fallbackHandler!: `0x${string}`; + fallbackHandler!: Address; @ApiProperty() - owners!: Array<`0x${string}`>; + owners!: Array
; @ApiProperty() - predictedAddress!: `0x${string}`; + predictedAddress!: Address; @ApiProperty() saltNonce!: string; @ApiProperty() - singletonAddress!: `0x${string}`; + singletonAddress!: Address; @ApiProperty() threshold!: number; } diff --git a/src/routes/accounts/entities/account.entity.ts b/src/routes/accounts/entities/account.entity.ts index aeb2b51321..212997c4e3 100644 --- a/src/routes/accounts/entities/account.entity.ts +++ b/src/routes/accounts/entities/account.entity.ts @@ -1,4 +1,5 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class Account { @ApiProperty() @@ -6,14 +7,14 @@ export class Account { @ApiPropertyOptional({ type: String, nullable: true }) groupId: string | null; @ApiProperty() - address: `0x${string}`; + address: Address; @ApiProperty() name: string; constructor( id: string, groupId: string | null, - address: `0x${string}`, + address: Address, name: string, ) { this.id = id; diff --git a/src/routes/accounts/entities/create-account.dto.entity.ts b/src/routes/accounts/entities/create-account.dto.entity.ts index a39f645cd9..8c23542e36 100644 --- a/src/routes/accounts/entities/create-account.dto.entity.ts +++ b/src/routes/accounts/entities/create-account.dto.entity.ts @@ -4,10 +4,11 @@ import { NAME_MIN_LENGTH, } from '@/domain/common/entities/name.schema'; import { ApiProperty } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class CreateAccountDto implements DomainCreateAccountDto { @ApiProperty({ minLength: NAME_MIN_LENGTH, maxLength: NAME_MAX_LENGTH }) - address!: `0x${string}`; + address!: Address; @ApiProperty() name!: string; } diff --git a/src/routes/alerts/entities/__tests__/alerts.builder.ts b/src/routes/alerts/entities/__tests__/alerts.builder.ts index b8a606e936..4d5c3f3f0a 100644 --- a/src/routes/alerts/entities/__tests__/alerts.builder.ts +++ b/src/routes/alerts/entities/__tests__/alerts.builder.ts @@ -7,7 +7,7 @@ import type { Alert, } from '@/routes/alerts/entities/alert.dto.entity'; import { EventType } from '@/routes/alerts/entities/alert.dto.entity'; -import { getAddress } from 'viem'; +import { type Address, getAddress, type Hash } from 'viem'; export function alertLogBuilder(): IBuilder { return new Builder() @@ -16,9 +16,9 @@ export function alertLogBuilder(): IBuilder { 'topics', Array.from({ length: faker.number.int({ min: 1, max: 10 }) }, () => faker.string.hexadecimal(), - ) as [`0x${string}`, ...Array<`0x${string}`>], + ) as [Address, ...Array
], ) - .with('data', faker.string.hexadecimal() as `0x${string}`); + .with('data', faker.string.hexadecimal() as Hash); } export function alertTransactionBuilder(): IBuilder { diff --git a/src/routes/alerts/entities/alert.dto.entity.ts b/src/routes/alerts/entities/alert.dto.entity.ts index 1ad7e1e195..e990dc743e 100644 --- a/src/routes/alerts/entities/alert.dto.entity.ts +++ b/src/routes/alerts/entities/alert.dto.entity.ts @@ -4,11 +4,12 @@ import type { AlertTransactionSchema, } from '@/routes/alerts/entities/schemas/alerts.schema'; import type { z } from 'zod'; +import type { Address, Hex } from 'viem'; export class AlertLog implements z.infer { - address!: `0x${string}`; - topics!: [signature: `0x${string}`, ...Array<`0x${string}`>]; - data!: `0x${string}`; + address!: Address; + topics!: [signature: Hex, ...Array
]; + data!: Address; } export class AlertTransaction @@ -18,8 +19,8 @@ export class AlertTransaction block_hash!: string; block_number!: number; hash!: string; - from!: `0x${string}`; - to!: `0x${string}`; + from!: Address; + to!: Address; logs!: Array; input!: string; value!: string; diff --git a/src/routes/alerts/entities/schemas/__tests__/alerts.schema.spec.ts b/src/routes/alerts/entities/schemas/__tests__/alerts.schema.spec.ts index 5bbefb3133..bd3c96c7de 100644 --- a/src/routes/alerts/entities/schemas/__tests__/alerts.schema.spec.ts +++ b/src/routes/alerts/entities/schemas/__tests__/alerts.schema.spec.ts @@ -9,7 +9,7 @@ import { AlertTransactionSchema, } from '@/routes/alerts/entities/schemas/alerts.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('Alerts schemas', () => { @@ -25,7 +25,7 @@ describe('Alerts schemas', () => { it('should checksum the alert log address', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const alertLog = alertLogBuilder() .with('address', nonChecksummedAddress) .build(); @@ -39,10 +39,7 @@ describe('Alerts schemas', () => { it('should not allow empty alert log event signature', () => { const alertLog = alertLogBuilder() - .with( - 'topics', - [] as unknown as [`0x${string}`, ...Array<`0x${string}`>], - ) + .with('topics', [] as unknown as [Address, ...Array
]) .build(); const result = AlertLogSchema.safeParse(alertLog); @@ -104,7 +101,7 @@ describe('Alerts schemas', () => { it('should checksum the alert transaction from and to addresses', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const alertTransaction = alertTransactionBuilder() .with('from', nonChecksummedAddress) .with('to', nonChecksummedAddress) diff --git a/src/routes/auth/entities/siwe.dto.entity.ts b/src/routes/auth/entities/siwe.dto.entity.ts index 327376ded5..e348d288c4 100644 --- a/src/routes/auth/entities/siwe.dto.entity.ts +++ b/src/routes/auth/entities/siwe.dto.entity.ts @@ -1,12 +1,13 @@ import { HexSchema } from '@/validation/entities/schemas/hex.schema'; import { ApiProperty } from '@nestjs/swagger'; import { z } from 'zod'; +import type { Address } from 'viem'; export class SiweDto implements z.infer { @ApiProperty() message!: string; @ApiProperty() - signature!: `0x${string}`; + signature!: Address; constructor(props: SiweDto) { this.message = props.message; diff --git a/src/routes/balances/balances.controller.ts b/src/routes/balances/balances.controller.ts index 55dfaaa437..b7de53beec 100644 --- a/src/routes/balances/balances.controller.ts +++ b/src/routes/balances/balances.controller.ts @@ -17,6 +17,7 @@ import { BalancesService } from '@/routes/balances/balances.service'; import { Balances } from '@/routes/balances/entities/balances.entity'; import { ValidationPipe } from '@/validation/pipes/validation.pipe'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; +import type { Address } from 'viem'; @ApiTags('balances') @Controller({ @@ -70,7 +71,7 @@ export class BalancesController { async getBalances( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Param('fiatCode') fiatCode: string, @Query('trusted', new DefaultValuePipe(false), ParseBoolPipe) trusted: boolean, diff --git a/src/routes/balances/balances.service.ts b/src/routes/balances/balances.service.ts index 50b6e5ecf0..827a722c7d 100644 --- a/src/routes/balances/balances.service.ts +++ b/src/routes/balances/balances.service.ts @@ -12,6 +12,7 @@ import { import { NULL_ADDRESS } from '@/routes/common/constants'; import orderBy from 'lodash/orderBy'; import { getNumberString } from '@/domain/common/utils/utils'; +import type { Address } from 'viem'; @Injectable() export class BalancesService { @@ -24,7 +25,7 @@ export class BalancesService { async getBalances(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; fiatCode: string; trusted: boolean; excludeSpam: boolean; diff --git a/src/routes/balances/entities/token.entity.ts b/src/routes/balances/entities/token.entity.ts index d424351ec3..2133526cf9 100644 --- a/src/routes/balances/entities/token.entity.ts +++ b/src/routes/balances/entities/token.entity.ts @@ -4,10 +4,11 @@ import { Erc20Token as DomainErc20Token, Erc721Token as DomainErc721Token, } from '@/domain/tokens/entities/token.entity'; +import type { Address } from 'viem'; class BaseToken { @ApiProperty() - address!: `0x${string}`; + address!: Address; @ApiProperty() decimals!: number; @ApiProperty() diff --git a/src/routes/chains/entities/chain.entity.ts b/src/routes/chains/entities/chain.entity.ts index 2ba26577c1..ca0b8abf56 100644 --- a/src/routes/chains/entities/chain.entity.ts +++ b/src/routes/chains/entities/chain.entity.ts @@ -38,6 +38,7 @@ import { } from '@/routes/chains/entities/theme.entity'; import { BalancesProvider } from '@/routes/chains/entities/balances-provider.entity'; import { ContractAddresses } from '@/routes/chains/entities/contract-addresses.entity'; +import type { Address } from 'viem'; @ApiExtraModels(ApiGasPriceOracle, ApiGasPriceFixed, ApiGasPriceFixedEIP1559) export class Chain { @@ -66,7 +67,7 @@ export class Chain { @ApiProperty() disabledWallets: Array; @ApiPropertyOptional({ type: String, nullable: true }) - ensRegistryAddress: `0x${string}` | null; + ensRegistryAddress: Address | null; @ApiProperty() balancesProvider: BalancesProvider; @ApiProperty() @@ -117,7 +118,7 @@ export class Chain { safeAppsRpcUri: RpcUri; shortName: string; theme: Theme; - ensRegistryAddress: `0x${string}` | null; + ensRegistryAddress: Address | null; isTestnet: boolean; chainLogoUri: string | null; balancesProvider: BalancesProvider; diff --git a/src/routes/chains/entities/contract-addresses.entity.ts b/src/routes/chains/entities/contract-addresses.entity.ts index 9933362abf..fb561064a5 100644 --- a/src/routes/chains/entities/contract-addresses.entity.ts +++ b/src/routes/chains/entities/contract-addresses.entity.ts @@ -1,23 +1,24 @@ import { ApiPropertyOptional } from '@nestjs/swagger'; import { ContractAddresses as DomainContractAddresses } from '@/domain/chains/entities/contract-addresses.entity'; +import type { Address } from 'viem'; export class ContractAddresses implements DomainContractAddresses { @ApiPropertyOptional({ type: String, nullable: true }) - safeSingletonAddress!: `0x${string}` | null; + safeSingletonAddress!: Address | null; @ApiPropertyOptional({ type: String, nullable: true }) - safeProxyFactoryAddress!: `0x${string}` | null; + safeProxyFactoryAddress!: Address | null; @ApiPropertyOptional({ type: String, nullable: true }) - multiSendAddress!: `0x${string}` | null; + multiSendAddress!: Address | null; @ApiPropertyOptional({ type: String, nullable: true }) - multiSendCallOnlyAddress!: `0x${string}` | null; + multiSendCallOnlyAddress!: Address | null; @ApiPropertyOptional({ type: String, nullable: true }) - fallbackHandlerAddress!: `0x${string}` | null; + fallbackHandlerAddress!: Address | null; @ApiPropertyOptional({ type: String, nullable: true }) - signMessageLibAddress!: `0x${string}` | null; + signMessageLibAddress!: Address | null; @ApiPropertyOptional({ type: String, nullable: true }) - createCallAddress!: `0x${string}` | null; + createCallAddress!: Address | null; @ApiPropertyOptional({ type: String, nullable: true }) - simulateTxAccessorAddress!: `0x${string}` | null; + simulateTxAccessorAddress!: Address | null; @ApiPropertyOptional({ type: String, nullable: true }) - safeWebAuthnSignerFactoryAddress!: `0x${string}` | null; + safeWebAuthnSignerFactoryAddress!: Address | null; } diff --git a/src/routes/collectibles/collectibles.controller.ts b/src/routes/collectibles/collectibles.controller.ts index 4acf1486f4..5a41dfc83e 100644 --- a/src/routes/collectibles/collectibles.controller.ts +++ b/src/routes/collectibles/collectibles.controller.ts @@ -16,6 +16,7 @@ import { Page } from '@/routes/common/entities/page.entity'; import { PaginationData } from '@/routes/common/pagination/pagination.data'; import { ValidationPipe } from '@/validation/pipes/validation.pipe'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; +import type { Address } from 'viem'; @ApiTags('collectibles') @Controller({ @@ -44,7 +45,7 @@ export class CollectiblesController { async getCollectibles( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @RouteUrlDecorator() routeUrl: URL, @PaginationDataDecorator() paginationData: PaginationData, @Query('trusted', new DefaultValuePipe(false), ParseBoolPipe) diff --git a/src/routes/collectibles/collectibles.service.ts b/src/routes/collectibles/collectibles.service.ts index b1ae2f30d4..f2fac6c1d7 100644 --- a/src/routes/collectibles/collectibles.service.ts +++ b/src/routes/collectibles/collectibles.service.ts @@ -7,6 +7,7 @@ import { cursorUrlFromLimitAndOffset, } from '@/routes/common/pagination/pagination.data'; import { IChainsRepository } from '@/domain/chains/chains.repository.interface'; +import type { Address } from 'viem'; @Injectable() export class CollectiblesService { @@ -19,7 +20,7 @@ export class CollectiblesService { async getCollectibles(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; routeUrl: Readonly; paginationData: PaginationData; trusted: boolean; diff --git a/src/routes/collectibles/entities/collectible.entity.ts b/src/routes/collectibles/entities/collectible.entity.ts index dae1dbafde..cb2d2f18d6 100644 --- a/src/routes/collectibles/entities/collectible.entity.ts +++ b/src/routes/collectibles/entities/collectible.entity.ts @@ -1,9 +1,10 @@ import { Collectible as DomainCollectible } from '@/domain/collectibles/entities/collectible.entity'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class Collectible implements DomainCollectible { @ApiProperty() - address!: `0x${string}`; + address!: Address; @ApiProperty() tokenName!: string; @ApiProperty() diff --git a/src/routes/common/__tests__/constants.ts b/src/routes/common/__tests__/constants.ts index d82f1b39b4..1b6543e4ba 100644 --- a/src/routes/common/__tests__/constants.ts +++ b/src/routes/common/__tests__/constants.ts @@ -1,7 +1,9 @@ +import type { Address } from 'viem'; + interface TestSafe { chainId: string; - address: `0x${string}`; - owners: Array<`0x${string}`>; + address: Address; + owners: Array
; } export const TEST_SAFE: TestSafe = { diff --git a/src/routes/common/address-info/address-info.helper.ts b/src/routes/common/address-info/address-info.helper.ts index f980aa668d..a99ff9b653 100644 --- a/src/routes/common/address-info/address-info.helper.ts +++ b/src/routes/common/address-info/address-info.helper.ts @@ -5,6 +5,7 @@ import { TokenRepository } from '@/domain/tokens/token.repository'; import { ITokenRepository } from '@/domain/tokens/token.repository.interface'; import { ILoggingService, LoggingService } from '@/logging/logging.interface'; import { AddressInfo } from '@/routes/common/entities/address-info.entity'; +import type { Address } from 'viem'; export type Source = 'CONTRACT' | 'TOKEN'; @@ -36,7 +37,7 @@ export class AddressInfoHelper { async get( chainId: string, - address: `0x${string}`, + address: Address, sources: Array, ): Promise { for (const source of sources) { @@ -65,7 +66,7 @@ export class AddressInfoHelper { */ async getOrDefault( chainId: string, - address: `0x${string}`, + address: Address, sources: Array, ): Promise { return this.get(chainId, address, sources).catch( @@ -82,7 +83,7 @@ export class AddressInfoHelper { */ async getCollection( chainId: string, - addresses: Array<`0x${string}`>, + addresses: Array
, sources: Array, ): Promise> { return Promise.allSettled( @@ -97,7 +98,7 @@ export class AddressInfoHelper { private async _getFromSource( chainId: string, - address: `0x${string}`, + address: Address, source: Source, ): Promise { switch (source) { diff --git a/src/routes/common/entities/transaction-data.dto.entity.ts b/src/routes/common/entities/transaction-data.dto.entity.ts index 29c0889b66..f356bcfeda 100644 --- a/src/routes/common/entities/transaction-data.dto.entity.ts +++ b/src/routes/common/entities/transaction-data.dto.entity.ts @@ -2,6 +2,7 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { z } from 'zod'; import { HexSchema } from '@/validation/entities/schemas/hex.schema'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; +import type { Address } from 'viem'; export const TransactionDataDtoSchema = z.object({ data: HexSchema, @@ -12,11 +13,11 @@ export class TransactionDataDto implements z.infer { @ApiProperty({ description: 'Hexadecimal value' }) - data: `0x${string}`; + data: Address; @ApiPropertyOptional({ description: 'The target Ethereum address' }) - to: `0x${string}`; + to: Address; - constructor(data: `0x${string}`, to: `0x${string}`) { + constructor(data: Address, to: Address) { this.data = data; this.to = to; } diff --git a/src/routes/common/interceptors/route-logger.interceptor.spec.ts b/src/routes/common/interceptors/route-logger.interceptor.spec.ts index 0d333519c8..b9723c8e7d 100644 --- a/src/routes/common/interceptors/route-logger.interceptor.spec.ts +++ b/src/routes/common/interceptors/route-logger.interceptor.spec.ts @@ -16,6 +16,7 @@ import { Server } from 'net'; import { ValidationPipe } from '@/validation/pipes/validation.pipe'; import { NumericStringSchema } from '@/validation/entities/schemas/numeric-string.schema'; import { ZodError } from 'zod'; +import type { Address } from 'viem'; // We expect 500 instead of the status code of the DataSourceError // The reason is that this test webserver does not have logic to map @@ -59,7 +60,7 @@ class TestController { @Get('validation-error') validationError( @Query('numeric_string', new ValidationPipe(NumericStringSchema)) - _: `0x${string}`, + _: Address, ): void {} /* eslint-enable @typescript-eslint/no-unused-vars */ diff --git a/src/routes/community/community.controller.ts b/src/routes/community/community.controller.ts index b59e153de6..6b38abf674 100644 --- a/src/routes/community/community.controller.ts +++ b/src/routes/community/community.controller.ts @@ -25,6 +25,7 @@ import { Query, } from '@nestjs/common'; import { ApiTags, ApiOkResponse, ApiQuery } from '@nestjs/swagger'; +import type { Address } from 'viem'; @ApiTags('community') @Controller({ @@ -64,7 +65,7 @@ export class CommunityController { @RouteUrlDecorator() routeUrl: URL, @PaginationDataDecorator() paginationData: PaginationData, @Query('holder', new ValidationPipe(AddressSchema.optional())) - holder?: `0x${string}`, + holder?: Address, ): Promise { return this.communityService.getCampaignActivities({ resourceId, @@ -98,7 +99,7 @@ export class CommunityController { async getCampaignRank( @Param('resourceId') resourceId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { return this.communityService.getCampaignRank({ resourceId, safeAddress }); } @@ -134,7 +135,7 @@ export class CommunityController { @Get('/locking/:safeAddress/rank') async getLockingRank( @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { return this.communityService.getLockingRank(safeAddress); } @@ -148,7 +149,7 @@ export class CommunityController { @Get('/locking/:safeAddress/history') async getLockingHistory( @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @RouteUrlDecorator() routeUrl: URL, @PaginationDataDecorator() paginationData: PaginationData, ): Promise { diff --git a/src/routes/community/community.service.ts b/src/routes/community/community.service.ts index 276957e5d9..508e1bcc5b 100644 --- a/src/routes/community/community.service.ts +++ b/src/routes/community/community.service.ts @@ -12,6 +12,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { CampaignActivity } from '@/domain/community/entities/campaign-activity.entity'; import { Eligibility } from '@/routes/community/entities/eligibility.entity'; import { EligibilityRequest } from '@/routes/community/entities/eligibility-request.entity'; +import type { Address } from 'viem'; @Injectable() export class CommunityService { @@ -48,7 +49,7 @@ export class CommunityService { async getCampaignActivities(args: { resourceId: string; - holder?: `0x${string}`; + holder?: Address; routeUrl: URL; paginationData: PaginationData; }): Promise> { @@ -100,7 +101,7 @@ export class CommunityService { async getCampaignRank(args: { resourceId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { return this.communityRepository.getCampaignRank(args); } @@ -127,12 +128,12 @@ export class CommunityService { }; } - async getLockingRank(safeAddress: `0x${string}`): Promise { + async getLockingRank(safeAddress: Address): Promise { return this.communityRepository.getLockingRank(safeAddress); } async getLockingHistory(args: { - safeAddress: `0x${string}`; + safeAddress: Address; routeUrl: URL; paginationData: PaginationData; }): Promise> { diff --git a/src/routes/community/entities/campaign-activity.entity.ts b/src/routes/community/entities/campaign-activity.entity.ts index d3c06c31d2..ce9005b32f 100644 --- a/src/routes/community/entities/campaign-activity.entity.ts +++ b/src/routes/community/entities/campaign-activity.entity.ts @@ -1,9 +1,10 @@ import { CampaignActivity as DomainCampaignActivity } from '@/domain/community/entities/campaign-activity.entity'; import { ApiProperty } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class CampaignActivity implements DomainCampaignActivity { @ApiProperty() - holder!: `0x${string}`; + holder!: Address; @ApiProperty({ type: String }) startDate!: Date; @ApiProperty({ type: String }) diff --git a/src/routes/community/entities/campaign-rank.entity.ts b/src/routes/community/entities/campaign-rank.entity.ts index 656282ad44..6c5a393ee5 100644 --- a/src/routes/community/entities/campaign-rank.entity.ts +++ b/src/routes/community/entities/campaign-rank.entity.ts @@ -1,9 +1,10 @@ import { CampaignRank as DomainCampaignRank } from '@/domain/community/entities/campaign-rank.entity'; import { ApiProperty } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class CampaignRank implements DomainCampaignRank { @ApiProperty() - holder!: `0x${string}`; + holder!: Address; @ApiProperty() position!: number; @ApiProperty() diff --git a/src/routes/community/entities/locking-event.page.entity.ts b/src/routes/community/entities/locking-event.page.entity.ts index c1ecc1b062..324cb7fbad 100644 --- a/src/routes/community/entities/locking-event.page.entity.ts +++ b/src/routes/community/entities/locking-event.page.entity.ts @@ -6,6 +6,7 @@ import { import { LockingEventType } from '@/domain/community/entities/schemas/locking-event.schema'; import { Page } from '@/routes/common/entities/page.entity'; import { ApiExtraModels, ApiProperty, getSchemaPath } from '@nestjs/swagger'; +import type { Address } from 'viem'; class LockEventItem implements DomainLockEventItem { @ApiProperty({ enum: [LockingEventType.LOCKED] }) @@ -13,9 +14,9 @@ class LockEventItem implements DomainLockEventItem { @ApiProperty({ type: String }) executionDate!: Date; @ApiProperty() - transactionHash!: `0x${string}`; + transactionHash!: Address; @ApiProperty() - holder!: `0x${string}`; + holder!: Address; @ApiProperty() amount!: string; @ApiProperty() @@ -28,9 +29,9 @@ class UnlockEventItem implements DomainUnlockEventItem { @ApiProperty({ type: String }) executionDate!: Date; @ApiProperty() - transactionHash!: `0x${string}`; + transactionHash!: Address; @ApiProperty() - holder!: `0x${string}`; + holder!: Address; @ApiProperty() amount!: string; @ApiProperty() @@ -45,9 +46,9 @@ class WithdrawEventItem implements DomainWithdrawEventItem { @ApiProperty({ type: String }) executionDate!: Date; @ApiProperty() - transactionHash!: `0x${string}`; + transactionHash!: Address; @ApiProperty() - holder!: `0x${string}`; + holder!: Address; @ApiProperty() amount!: string; @ApiProperty() diff --git a/src/routes/community/entities/locking-rank.entity.ts b/src/routes/community/entities/locking-rank.entity.ts index 1af049c028..61d9c9905a 100644 --- a/src/routes/community/entities/locking-rank.entity.ts +++ b/src/routes/community/entities/locking-rank.entity.ts @@ -1,9 +1,10 @@ import { LockingRank as DomainLockingRank } from '@/domain/community/entities/locking-rank.entity'; import { ApiProperty } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class LockingRank implements DomainLockingRank { @ApiProperty() - holder!: `0x${string}`; + holder!: Address; @ApiProperty() position!: number; @ApiProperty() diff --git a/src/routes/contracts/contracts.controller.ts b/src/routes/contracts/contracts.controller.ts index 1e3100a56f..4a68b0a5ab 100644 --- a/src/routes/contracts/contracts.controller.ts +++ b/src/routes/contracts/contracts.controller.ts @@ -11,6 +11,7 @@ import { Contract as ApiContract } from '@/routes/contracts/entities/contract.en import { ValidationPipe } from '@/validation/pipes/validation.pipe'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { NumericStringSchema } from '@/validation/entities/schemas/numeric-string.schema'; +import type { Address } from 'viem'; @ApiTags('contracts') @Controller({ @@ -44,7 +45,7 @@ export class ContractsController { async getContract( @Param('chainId', new ValidationPipe(NumericStringSchema)) chainId: string, @Param('contractAddress', new ValidationPipe(AddressSchema)) - contractAddress: `0x${string}`, + contractAddress: Address, ): Promise { return this.contractsService.getContract({ chainId, contractAddress }); } diff --git a/src/routes/contracts/contracts.service.ts b/src/routes/contracts/contracts.service.ts index 8b35ab6d60..0db9f96fc2 100644 --- a/src/routes/contracts/contracts.service.ts +++ b/src/routes/contracts/contracts.service.ts @@ -3,6 +3,7 @@ import { ContractsRepository } from '@/domain/contracts/contracts.repository'; import { IContractsRepository } from '@/domain/contracts/contracts.repository.interface'; import { Contract } from '@/domain/contracts/entities/contract.entity'; import { ContractMapper } from '@/routes/contracts/mappers/contract.mapper'; +import type { Address } from 'viem'; @Injectable() export class ContractsService { @@ -14,7 +15,7 @@ export class ContractsService { async getContract(args: { chainId: string; - contractAddress: `0x${string}`; + contractAddress: Address; }): Promise { const contract = await this.contractsRepository.getContract(args); return this.contractMapper.map(contract); diff --git a/src/routes/contracts/entities/contract.entity.ts b/src/routes/contracts/entities/contract.entity.ts index 2a79a7e056..915ddc3683 100644 --- a/src/routes/contracts/entities/contract.entity.ts +++ b/src/routes/contracts/entities/contract.entity.ts @@ -1,9 +1,10 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Contract as DomainContract } from '@/domain/contracts/entities/contract.entity'; +import type { Address } from 'viem'; export class Contract implements DomainContract { @ApiProperty() - address!: `0x${string}`; + address!: Address; @ApiProperty() name!: string; @ApiProperty() diff --git a/src/routes/data-decode/entities/__tests__/transaction-data.dto.builder.ts b/src/routes/data-decode/entities/__tests__/transaction-data.dto.builder.ts index 84d215468f..57f2acd7b1 100644 --- a/src/routes/data-decode/entities/__tests__/transaction-data.dto.builder.ts +++ b/src/routes/data-decode/entities/__tests__/transaction-data.dto.builder.ts @@ -2,10 +2,10 @@ import { faker } from '@faker-js/faker'; import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { TransactionDataDto } from '@/routes/common/entities/transaction-data.dto.entity'; -import { getAddress } from 'viem'; +import { getAddress, type Hex } from 'viem'; export function transactionDataDtoBuilder(): IBuilder { return new Builder() - .with('data', faker.string.hexadecimal() as `0x${string}`) + .with('data', faker.string.hexadecimal() as Hex) .with('to', getAddress(faker.finance.ethereumAddress())); } diff --git a/src/routes/data-decode/entities/data-decoded.entity.ts b/src/routes/data-decode/entities/data-decoded.entity.ts index 203ea635a1..dd3ffdd661 100644 --- a/src/routes/data-decode/entities/data-decoded.entity.ts +++ b/src/routes/data-decode/entities/data-decoded.entity.ts @@ -12,6 +12,7 @@ import { DataDecodedAccuracy, } from '@/domain/data-decoder/v2/entities/data-decoded.entity'; import { Operation } from '@/domain/safe/entities/operation.entity'; +import type { Address, Hex } from 'viem'; class BaseDataDecoded implements DomainBaseDataDecoded { @ApiProperty() @@ -32,10 +33,10 @@ class MultiSend implements DomainMultiSend { dataDecoded!: BaseDataDecoded; @ApiProperty() - to!: `0x${string}`; + to!: Address; @ApiPropertyOptional() - data!: `0x${string}` | null; + data!: Hex | null; } @ApiExtraModels(MultiSend, BaseDataDecoded) diff --git a/src/routes/data-decode/entities/schemas/__tests__/transaction-data.dto.schema.spec.ts b/src/routes/data-decode/entities/schemas/__tests__/transaction-data.dto.schema.spec.ts index 57859480c2..03f1de6e45 100644 --- a/src/routes/data-decode/entities/schemas/__tests__/transaction-data.dto.schema.spec.ts +++ b/src/routes/data-decode/entities/schemas/__tests__/transaction-data.dto.schema.spec.ts @@ -1,6 +1,6 @@ import { transactionDataDtoBuilder } from '@/routes/data-decode/entities/__tests__/transaction-data.dto.builder'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; import { TransactionDataDtoSchema } from '@/routes/common/entities/transaction-data.dto.entity'; @@ -16,7 +16,7 @@ describe('TransactionDataDtoSchema', () => { it('should checksum the to', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const transactionDataDto = transactionDataDtoBuilder() .with('to', nonChecksummedAddress) .build(); @@ -38,7 +38,7 @@ describe('TransactionDataDtoSchema', () => { it('should not allow non-hex data', () => { const transactionDataDto = transactionDataDtoBuilder() - .with('data', 'non-hex' as `0x${string}`) + .with('data', 'non-hex' as Address) .build(); const result = TransactionDataDtoSchema.safeParse(transactionDataDto); diff --git a/src/routes/delegates/delegates.controller.ts b/src/routes/delegates/delegates.controller.ts index 8ad0a5d2ad..4432814e69 100644 --- a/src/routes/delegates/delegates.controller.ts +++ b/src/routes/delegates/delegates.controller.ts @@ -35,6 +35,7 @@ import { CreateDelegateDtoSchema } from '@/routes/delegates/entities/schemas/cre import { DeleteDelegateDtoSchema } from '@/routes/delegates/entities/schemas/delete-delegate.dto.schema'; import { DeleteSafeDelegateDtoSchema } from '@/routes/delegates/entities/schemas/delete-safe-delegate.dto.schema'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; +import type { Address } from 'viem'; @ApiTags('delegates') @Controller({ @@ -169,7 +170,7 @@ export class DelegatesController { async deleteDelegate( @Param('chainId') chainId: string, @Param('delegateAddress', new ValidationPipe(AddressSchema)) - delegateAddress: `0x${string}`, + delegateAddress: Address, @Body(new ValidationPipe(DeleteDelegateDtoSchema)) deleteDelegateDto: DeleteDelegateDto, ): Promise { diff --git a/src/routes/delegates/delegates.service.ts b/src/routes/delegates/delegates.service.ts index 0f47b8edee..6fb02738d3 100644 --- a/src/routes/delegates/delegates.service.ts +++ b/src/routes/delegates/delegates.service.ts @@ -10,6 +10,7 @@ import { Delegate } from '@/routes/delegates/entities/delegate.entity'; import { DeleteDelegateDto } from '@/routes/delegates/entities/delete-delegate.dto.entity'; import { DeleteSafeDelegateDto } from '@/routes/delegates/entities/delete-safe-delegate.dto.entity'; import { GetDelegateDto } from '@/routes/delegates/entities/get-delegate.dto.entity'; +import type { Address } from 'viem'; @Injectable() export class DelegatesService { @@ -64,7 +65,7 @@ export class DelegatesService { async deleteDelegate(args: { chainId: string; - delegateAddress: `0x${string}`; + delegateAddress: Address; deleteDelegateDto: DeleteDelegateDto; }): Promise { return await this.repository.deleteDelegate({ diff --git a/src/routes/delegates/entities/__tests__/delete-safe-delegate.dto.builder.ts b/src/routes/delegates/entities/__tests__/delete-safe-delegate.dto.builder.ts index 0408203446..4fa477e53e 100644 --- a/src/routes/delegates/entities/__tests__/delete-safe-delegate.dto.builder.ts +++ b/src/routes/delegates/entities/__tests__/delete-safe-delegate.dto.builder.ts @@ -2,14 +2,11 @@ import { faker } from '@faker-js/faker'; import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { DeleteSafeDelegateDto } from '@/routes/delegates/entities/delete-safe-delegate.dto.entity'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; export function deleteSafeDelegateDtoBuilder(): IBuilder { return new Builder() .with('delegate', getAddress(faker.finance.ethereumAddress())) .with('safe', getAddress(faker.finance.ethereumAddress())) - .with( - 'signature', - faker.string.hexadecimal({ length: 32 }) as `0x${string}`, - ); + .with('signature', faker.string.hexadecimal({ length: 32 }) as Address); } diff --git a/src/routes/delegates/entities/create-delegate.dto.entity.ts b/src/routes/delegates/entities/create-delegate.dto.entity.ts index a2d6ca9ffe..b8571c1bf8 100644 --- a/src/routes/delegates/entities/create-delegate.dto.entity.ts +++ b/src/routes/delegates/entities/create-delegate.dto.entity.ts @@ -1,16 +1,17 @@ import { CreateDelegateDtoSchema } from '@/routes/delegates/entities/schemas/create-delegate.dto.schema'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { z } from 'zod'; +import type { Address } from 'viem'; export class CreateDelegateDto implements z.infer { @ApiPropertyOptional({ type: String, nullable: true }) - safe!: `0x${string}` | null; + safe!: Address | null; @ApiProperty() - delegate!: `0x${string}`; + delegate!: Address; @ApiProperty() - delegator!: `0x${string}`; + delegator!: Address; @ApiProperty() signature!: string; @ApiProperty() diff --git a/src/routes/delegates/entities/delete-delegate.dto.entity.ts b/src/routes/delegates/entities/delete-delegate.dto.entity.ts index c27589e9e1..67baa37f50 100644 --- a/src/routes/delegates/entities/delete-delegate.dto.entity.ts +++ b/src/routes/delegates/entities/delete-delegate.dto.entity.ts @@ -1,14 +1,15 @@ import { DeleteDelegateDtoSchema } from '@/routes/delegates/entities/schemas/delete-delegate.dto.schema'; import { ApiProperty } from '@nestjs/swagger'; import { z } from 'zod'; +import type { Address } from 'viem'; export class DeleteDelegateDto implements z.infer { @ApiProperty() - delegate!: `0x${string}`; + delegate!: Address; @ApiProperty() - delegator!: `0x${string}`; + delegator!: Address; @ApiProperty() signature!: string; } diff --git a/src/routes/delegates/entities/delete-safe-delegate.dto.entity.ts b/src/routes/delegates/entities/delete-safe-delegate.dto.entity.ts index 3c81a5dc09..e1ceacf591 100644 --- a/src/routes/delegates/entities/delete-safe-delegate.dto.entity.ts +++ b/src/routes/delegates/entities/delete-safe-delegate.dto.entity.ts @@ -1,14 +1,15 @@ import { DeleteSafeDelegateDtoSchema } from '@/routes/delegates/entities/schemas/delete-safe-delegate.dto.schema'; import { ApiProperty } from '@nestjs/swagger'; import { z } from 'zod'; +import type { Address } from 'viem'; export class DeleteSafeDelegateDto implements z.infer { @ApiProperty() - delegate!: `0x${string}`; + delegate!: Address; @ApiProperty() - safe!: `0x${string}`; + safe!: Address; @ApiProperty() - signature!: `0x${string}`; + signature!: Address; } diff --git a/src/routes/delegates/entities/get-delegate.dto.entity.ts b/src/routes/delegates/entities/get-delegate.dto.entity.ts index 12fd40a2a4..e9ea3c2490 100644 --- a/src/routes/delegates/entities/get-delegate.dto.entity.ts +++ b/src/routes/delegates/entities/get-delegate.dto.entity.ts @@ -1,21 +1,22 @@ import { GetDelegateDtoSchema } from '@/routes/delegates/entities/schemas/get-delegate.dto.schema'; import { ApiPropertyOptional } from '@nestjs/swagger'; import { z } from 'zod'; +import type { Address } from 'viem'; export class GetDelegateDto implements z.infer { @ApiPropertyOptional() - safe?: `0x${string}`; + safe?: Address; @ApiPropertyOptional() - delegate?: `0x${string}`; + delegate?: Address; @ApiPropertyOptional() - delegator?: `0x${string}`; + delegator?: Address; @ApiPropertyOptional() label?: string; constructor( - safe?: `0x${string}`, - delegate?: `0x${string}`, - delegator?: `0x${string}`, + safe?: Address, + delegate?: Address, + delegator?: Address, label?: string, ) { this.safe = safe; diff --git a/src/routes/delegates/entities/schemas/__tests__/create-delegate.dto.schema.spec.ts b/src/routes/delegates/entities/schemas/__tests__/create-delegate.dto.schema.spec.ts index 1bafba131c..1bfdf1b67e 100644 --- a/src/routes/delegates/entities/schemas/__tests__/create-delegate.dto.schema.spec.ts +++ b/src/routes/delegates/entities/schemas/__tests__/create-delegate.dto.schema.spec.ts @@ -1,7 +1,7 @@ import { createDelegateDtoBuilder } from '@/routes/delegates/entities/__tests__/create-delegate.dto.builder'; import { CreateDelegateDtoSchema } from '@/routes/delegates/entities/schemas/create-delegate.dto.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('CreateDelegateSchema', () => { @@ -16,7 +16,7 @@ describe('CreateDelegateSchema', () => { it('should checksum safe, delegate and delegator', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const createDelegateDto = createDelegateDtoBuilder() .with('safe', nonChecksummedAddress) .with('delegate', nonChecksummedAddress) diff --git a/src/routes/delegates/entities/schemas/__tests__/delete-delegate.dto.schema.spec.ts b/src/routes/delegates/entities/schemas/__tests__/delete-delegate.dto.schema.spec.ts index 314bd28e70..d3a08d6944 100644 --- a/src/routes/delegates/entities/schemas/__tests__/delete-delegate.dto.schema.spec.ts +++ b/src/routes/delegates/entities/schemas/__tests__/delete-delegate.dto.schema.spec.ts @@ -1,7 +1,7 @@ import { deleteDelegateDtoBuilder } from '@/routes/delegates/entities/__tests__/delete-delegate.dto.builder'; import { DeleteDelegateDtoSchema } from '@/routes/delegates/entities/schemas/delete-delegate.dto.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('DeleteDelegateSchema', () => { @@ -16,7 +16,7 @@ describe('DeleteDelegateSchema', () => { it('should checksum delegate and delegator', () => { const nonCheckSummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const deleteDelegateDto = deleteDelegateDtoBuilder() .with('delegate', nonCheckSummedAddress) .with('delegator', nonCheckSummedAddress) diff --git a/src/routes/delegates/entities/schemas/__tests__/delete-safe-delegate.dto.schema.spec.ts b/src/routes/delegates/entities/schemas/__tests__/delete-safe-delegate.dto.schema.spec.ts index 5377b0b030..a45f66d3b8 100644 --- a/src/routes/delegates/entities/schemas/__tests__/delete-safe-delegate.dto.schema.spec.ts +++ b/src/routes/delegates/entities/schemas/__tests__/delete-safe-delegate.dto.schema.spec.ts @@ -2,7 +2,7 @@ import { deleteSafeDelegateDtoBuilder } from '@/routes/delegates/entities/__test import type { DeleteSafeDelegateDto } from '@/routes/delegates/entities/delete-safe-delegate.dto.entity'; import { DeleteSafeDelegateDtoSchema } from '@/routes/delegates/entities/schemas/delete-safe-delegate.dto.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('DeleteSafeDelegateDtoSchema', () => { @@ -19,7 +19,7 @@ describe('DeleteSafeDelegateDtoSchema', () => { (key) => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const deleteSafeDelegateDto = deleteSafeDelegateDtoBuilder() .with(key, nonChecksummedAddress) .build(); @@ -36,7 +36,7 @@ describe('DeleteSafeDelegateDtoSchema', () => { it('should not allow non-hex signature', () => { const deleteSafeDelegateDto = deleteSafeDelegateDtoBuilder() - .with('signature', faker.string.numeric() as `0x${string}`) + .with('signature', faker.string.numeric() as Address) .build(); const result = DeleteSafeDelegateDtoSchema.safeParse(deleteSafeDelegateDto); diff --git a/src/routes/delegates/entities/schemas/__tests__/get-delegate.dto.schema.spec.ts b/src/routes/delegates/entities/schemas/__tests__/get-delegate.dto.schema.spec.ts index aa5ca093b4..1e4787a22e 100644 --- a/src/routes/delegates/entities/schemas/__tests__/get-delegate.dto.schema.spec.ts +++ b/src/routes/delegates/entities/schemas/__tests__/get-delegate.dto.schema.spec.ts @@ -1,6 +1,6 @@ import { GetDelegateDtoSchema } from '@/routes/delegates/entities/schemas/get-delegate.dto.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('GetDelegateDtoSchema', () => { @@ -70,7 +70,7 @@ describe('GetDelegateDtoSchema', () => { (property) => { const nonCheckSummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const getDelegateDto = { [property]: nonCheckSummedAddress }; const result = GetDelegateDtoSchema.safeParse(getDelegateDto); diff --git a/src/routes/delegates/v2/delegates.v2.controller.ts b/src/routes/delegates/v2/delegates.v2.controller.ts index ad7d5f9b97..eb30a640eb 100644 --- a/src/routes/delegates/v2/delegates.v2.controller.ts +++ b/src/routes/delegates/v2/delegates.v2.controller.ts @@ -32,6 +32,7 @@ import { ApiBadRequestResponse, ApiNoContentResponse, } from '@nestjs/swagger'; +import type { Address } from 'viem'; @ApiTags('delegates') @Controller({ version: '2' }) @@ -162,7 +163,7 @@ export class DelegatesV2Controller { @Delete('chains/:chainId/delegates/:delegateAddress') async deleteDelegate( @Param('chainId') chainId: string, - @Param('delegateAddress') delegateAddress: `0x${string}`, + @Param('delegateAddress') delegateAddress: Address, @Body(new ValidationPipe(DeleteDelegateV2DtoSchema)) deleteDelegateV2Dto: DeleteDelegateV2Dto, ): Promise { diff --git a/src/routes/delegates/v2/delegates.v2.service.ts b/src/routes/delegates/v2/delegates.v2.service.ts index 9f91ea4330..708bd9f473 100644 --- a/src/routes/delegates/v2/delegates.v2.service.ts +++ b/src/routes/delegates/v2/delegates.v2.service.ts @@ -10,6 +10,7 @@ import { CreateDelegateDto } from '@/routes/delegates/entities/create-delegate.d import { GetDelegateDto } from '@/routes/delegates/entities/get-delegate.dto.entity'; import { DeleteDelegateV2Dto } from '@/routes/delegates/v2/entities/delete-delegate.v2.dto.entity'; import { Inject, Injectable, NotFoundException } from '@nestjs/common'; +import type { Address } from 'viem'; @Injectable() export class DelegatesV2Service { @@ -66,7 +67,7 @@ export class DelegatesV2Service { async deleteDelegate(args: { chainId: string; - delegateAddress: `0x${string}`; + delegateAddress: Address; deleteDelegateV2Dto: DeleteDelegateV2Dto; }): Promise { const { deleteDelegateV2Dto } = args; @@ -97,9 +98,9 @@ export class DelegatesV2Service { private async _getDelegatorForDelegateAndSafe( chainId: string, - delegate: `0x${string}`, - safeAddress: `0x${string}`, - ): Promise<`0x${string}`> { + delegate: Address, + safeAddress: Address, + ): Promise
{ const response = await this.repository.getDelegates({ chainId, delegate, diff --git a/src/routes/delegates/v2/entities/__tests__/delete-delegate.v2.dto.builder.ts b/src/routes/delegates/v2/entities/__tests__/delete-delegate.v2.dto.builder.ts index 01ac37cada..d41e1e1a80 100644 --- a/src/routes/delegates/v2/entities/__tests__/delete-delegate.v2.dto.builder.ts +++ b/src/routes/delegates/v2/entities/__tests__/delete-delegate.v2.dto.builder.ts @@ -2,14 +2,11 @@ import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { DeleteDelegateV2Dto } from '@/routes/delegates/v2/entities/delete-delegate.v2.dto.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; export function deleteDelegateV2DtoBuilder(): IBuilder { return new Builder() .with('delegator', getAddress(faker.finance.ethereumAddress())) .with('safe', getAddress(faker.finance.ethereumAddress())) - .with( - 'signature', - faker.string.hexadecimal({ length: 32 }) as `0x${string}`, - ); + .with('signature', faker.string.hexadecimal({ length: 32 }) as Address); } diff --git a/src/routes/delegates/v2/entities/delete-delegate.v2.dto.entity.ts b/src/routes/delegates/v2/entities/delete-delegate.v2.dto.entity.ts index a45c79d5a5..09f57b1507 100644 --- a/src/routes/delegates/v2/entities/delete-delegate.v2.dto.entity.ts +++ b/src/routes/delegates/v2/entities/delete-delegate.v2.dto.entity.ts @@ -1,14 +1,15 @@ import { DeleteDelegateV2DtoSchema } from '@/routes/delegates/v2/entities/schemas/delete-delegate.v2.dto.schema'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { z } from 'zod'; +import type { Address } from 'viem'; export class DeleteDelegateV2Dto implements z.infer { @ApiPropertyOptional({ type: String, nullable: true }) - delegator!: `0x${string}` | null; + delegator!: Address | null; @ApiPropertyOptional({ type: String, nullable: true }) - safe!: `0x${string}` | null; + safe!: Address | null; @ApiProperty() signature!: string; } diff --git a/src/routes/estimations/entities/__tests__/get-estimation.dto.builder.ts b/src/routes/estimations/entities/__tests__/get-estimation.dto.builder.ts index 610575a2bb..9c12db07fd 100644 --- a/src/routes/estimations/entities/__tests__/get-estimation.dto.builder.ts +++ b/src/routes/estimations/entities/__tests__/get-estimation.dto.builder.ts @@ -2,12 +2,12 @@ import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { GetEstimationDto } from '@/domain/estimations/entities/get-estimation.dto.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { getAddress, type Hex } from 'viem'; export function getEstimationDtoBuilder(): IBuilder { return new Builder() .with('to', getAddress(faker.finance.ethereumAddress())) .with('value', faker.string.numeric()) - .with('data', faker.string.hexadecimal() as `0x${string}`) + .with('data', faker.string.hexadecimal() as Hex) .with('operation', faker.helpers.arrayElement([0, 1])); } diff --git a/src/routes/estimations/entities/get-estimation.dto.entity.ts b/src/routes/estimations/entities/get-estimation.dto.entity.ts index 2f0581e4b2..282229aa16 100644 --- a/src/routes/estimations/entities/get-estimation.dto.entity.ts +++ b/src/routes/estimations/entities/get-estimation.dto.entity.ts @@ -1,14 +1,15 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { GetEstimationDto as DomainGetEstimationDto } from '@/domain/estimations/entities/get-estimation.dto.entity'; import { Operation } from '@/domain/safe/entities/operation.entity'; +import type { Address, Hex } from 'viem'; export class GetEstimationDto implements DomainGetEstimationDto { @ApiProperty() - to!: `0x${string}`; + to!: Address; @ApiProperty() value!: string; @ApiPropertyOptional({ type: String, nullable: true }) - data!: `0x${string}` | null; + data!: Hex | null; @ApiProperty() operation!: Operation; } diff --git a/src/routes/estimations/entities/schemas/__tests__/get-estimation.dto.schema.spec.ts b/src/routes/estimations/entities/schemas/__tests__/get-estimation.dto.schema.spec.ts index 968de5d0f3..388628fa1a 100644 --- a/src/routes/estimations/entities/schemas/__tests__/get-estimation.dto.schema.spec.ts +++ b/src/routes/estimations/entities/schemas/__tests__/get-estimation.dto.schema.spec.ts @@ -1,7 +1,7 @@ import { getEstimationDtoBuilder } from '@/routes/estimations/entities/__tests__/get-estimation.dto.builder'; import { GetEstimationDtoSchema } from '@/routes/estimations/entities/schemas/get-estimation.dto.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('GetEstimationDtoSchema', () => { @@ -16,7 +16,7 @@ describe('GetEstimationDtoSchema', () => { it('should checksum the to field', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const getEstimationDto = getEstimationDtoBuilder() .with('to', nonChecksummedAddress) .build(); @@ -29,7 +29,7 @@ describe('GetEstimationDtoSchema', () => { }); it('should allow hex data', () => { - const hexData = faker.string.hexadecimal() as `0x${string}`; + const hexData = faker.string.hexadecimal() as Address; const getEstimationDto = getEstimationDtoBuilder() .with('data', hexData) .build(); @@ -42,7 +42,7 @@ describe('GetEstimationDtoSchema', () => { it('should not allow non-hex data', () => { const nonHexData = faker.string.alphanumeric(); const getEstimationDto = getEstimationDtoBuilder() - .with('data', nonHexData as `0x${string}`) + .with('data', nonHexData as Address) .build(); const result = GetEstimationDtoSchema.safeParse(getEstimationDto); diff --git a/src/routes/estimations/estimations.controller.ts b/src/routes/estimations/estimations.controller.ts index 684534c20d..a90c1836be 100644 --- a/src/routes/estimations/estimations.controller.ts +++ b/src/routes/estimations/estimations.controller.ts @@ -13,6 +13,7 @@ import { EstimationsService } from '@/routes/estimations/estimations.service'; import { ValidationPipe } from '@/validation/pipes/validation.pipe'; import { GetEstimationDtoSchema } from '@/routes/estimations/entities/schemas/get-estimation.dto.schema'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; +import type { Address } from 'viem'; @ApiTags('estimations') @Controller({ @@ -55,7 +56,7 @@ export class EstimationsController { @Post('chains/:chainId/safes/:address/multisig-transactions/estimations') async getEstimation( @Param('chainId') chainId: string, - @Param('address', new ValidationPipe(AddressSchema)) address: `0x${string}`, + @Param('address', new ValidationPipe(AddressSchema)) address: Address, @Body(new ValidationPipe(GetEstimationDtoSchema)) getEstimationDto: GetEstimationDto, ): Promise { diff --git a/src/routes/estimations/estimations.service.ts b/src/routes/estimations/estimations.service.ts index fef49a14e1..2f09f3011a 100644 --- a/src/routes/estimations/estimations.service.ts +++ b/src/routes/estimations/estimations.service.ts @@ -5,6 +5,7 @@ import { IEstimationsRepository } from '@/domain/estimations/estimations.reposit import { SafeRepository } from '@/domain/safe/safe.repository'; import { ISafeRepository } from '@/domain/safe/safe.repository.interface'; import { EstimationResponse } from '@/routes/estimations/entities/estimation-response.entity'; +import type { Address } from 'viem'; @Injectable() export class EstimationsService { @@ -26,7 +27,7 @@ export class EstimationsService { */ async getEstimation(args: { chainId: string; - address: `0x${string}`; + address: Address; getEstimationDto: GetEstimationDto; }): Promise { const estimation = await this.estimationsRepository.getEstimation(args); diff --git a/src/routes/hooks/entities/__tests__/executed-transaction.builder.ts b/src/routes/hooks/entities/__tests__/executed-transaction.builder.ts index 6fb8d68efb..68a467b6c5 100644 --- a/src/routes/hooks/entities/__tests__/executed-transaction.builder.ts +++ b/src/routes/hooks/entities/__tests__/executed-transaction.builder.ts @@ -3,7 +3,7 @@ import { Builder } from '@/__tests__/builder'; import { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import type { ExecutedTransaction } from '@/routes/hooks/entities/executed-transaction.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { getAddress, type Hash, type Hex } from 'viem'; export function executedTransactionEventBuilder(): IBuilder { return new Builder() @@ -11,11 +11,8 @@ export function executedTransactionEventBuilder(): IBuilder .with('to', getAddress(faker.finance.ethereumAddress())) .with('address', getAddress(faker.finance.ethereumAddress())) .with('chainId', faker.string.numeric()) - .with( - 'safeTxHash', - faker.string.hexadecimal({ length: 32 }) as `0x${string}`, - ) - .with('txHash', faker.string.hexadecimal({ length: 32 }) as `0x${string}`) + .with('safeTxHash', faker.string.hexadecimal({ length: 32 }) as Hash) + .with('txHash', faker.string.hexadecimal({ length: 32 }) as Hash) .with('failed', faker.helpers.arrayElement(['true', 'false'])) - .with('data', faker.string.hexadecimal() as `0x${string}`); + .with('data', faker.string.hexadecimal() as Hex); } diff --git a/src/routes/hooks/entities/__tests__/pending-transaction.builder.ts b/src/routes/hooks/entities/__tests__/pending-transaction.builder.ts index 3cf4e0ae92..ff8be07bf5 100644 --- a/src/routes/hooks/entities/__tests__/pending-transaction.builder.ts +++ b/src/routes/hooks/entities/__tests__/pending-transaction.builder.ts @@ -3,7 +3,7 @@ import { Builder } from '@/__tests__/builder'; import { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import type { PendingTransaction } from '@/routes/hooks/entities/pending-transaction.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { getAddress, type Hash } from 'viem'; export function pendingTransactionEventBuilder(): IBuilder { return new Builder() @@ -11,8 +11,5 @@ export function pendingTransactionEventBuilder(): IBuilder { .with('to', getAddress(faker.finance.ethereumAddress())) .with('address', getAddress(faker.finance.ethereumAddress())) .with('chainId', faker.string.numeric()) - .with( - 'safeTxHash', - faker.string.hexadecimal({ length: 32 }) as `0x${string}`, - ); + .with('safeTxHash', faker.string.hexadecimal({ length: 32 }) as Hash); } diff --git a/src/routes/hooks/entities/schemas/__tests__/delegate-events.schema.spec.ts b/src/routes/hooks/entities/schemas/__tests__/delegate-events.schema.spec.ts index 017937913d..fe23fc4c78 100644 --- a/src/routes/hooks/entities/schemas/__tests__/delegate-events.schema.spec.ts +++ b/src/routes/hooks/entities/schemas/__tests__/delegate-events.schema.spec.ts @@ -9,7 +9,7 @@ import { NewDelegateEventSchema, UpdatedDelegateEventSchema, } from '@/routes/hooks/entities/schemas/delegate-events.schema'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; describe.each([ ['NewDelegateEventSchema', NewDelegateEventSchema, newDelegateEventBuilder], @@ -52,7 +52,7 @@ describe.each([ (field) => { const nonChecksummedAddress = faker.finance.ethereumAddress(); const event = builder() - .with(field, nonChecksummedAddress as `0x${string}`) + .with(field, nonChecksummedAddress as Address) .build(); const result = Schema.safeParse(event); diff --git a/src/routes/hooks/entities/schemas/__tests__/deleted-multisig-transaction.schema.spec.ts b/src/routes/hooks/entities/schemas/__tests__/deleted-multisig-transaction.schema.spec.ts index aae5f28c62..c3d30be50b 100644 --- a/src/routes/hooks/entities/schemas/__tests__/deleted-multisig-transaction.schema.spec.ts +++ b/src/routes/hooks/entities/schemas/__tests__/deleted-multisig-transaction.schema.spec.ts @@ -2,7 +2,7 @@ import { deletedMultisigTransactionEventBuilder } from '@/routes/hooks/entities/ import type { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import { DeletedMultisigTransactionEventSchema } from '@/routes/hooks/entities/schemas/deleted-multisig-transaction.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('DeletedMultisigTransactionEventSchema', () => { @@ -47,7 +47,7 @@ describe('DeletedMultisigTransactionEventSchema', () => { it('should not allow a non-address address', () => { const deletedMultisigTransactionEvent = deletedMultisigTransactionEventBuilder() - .with('address', faker.string.alpha() as `0x${string}`) + .with('address', faker.string.alpha() as Address) .build(); const result = DeletedMultisigTransactionEventSchema.safeParse( @@ -68,7 +68,7 @@ describe('DeletedMultisigTransactionEventSchema', () => { it('should checksum the address', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const deletedMultisigTransactionEvent = deletedMultisigTransactionEventBuilder() .with('address', nonChecksummedAddress) diff --git a/src/routes/hooks/entities/schemas/__tests__/executed-transaction.schema.spec.ts b/src/routes/hooks/entities/schemas/__tests__/executed-transaction.schema.spec.ts index 63d1b72c52..4090ccca09 100644 --- a/src/routes/hooks/entities/schemas/__tests__/executed-transaction.schema.spec.ts +++ b/src/routes/hooks/entities/schemas/__tests__/executed-transaction.schema.spec.ts @@ -2,7 +2,7 @@ import { executedTransactionEventBuilder } from '@/routes/hooks/entities/__tests import type { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import { ExecutedTransactionEventSchema } from '@/routes/hooks/entities/schemas/executed-transaction.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('ExecutedTransactionEventSchema', () => { @@ -46,7 +46,7 @@ describe('ExecutedTransactionEventSchema', () => { 'should not allow a non-address %s', (field) => { const executedTransactionEvent = executedTransactionEventBuilder() - .with(field, faker.string.sample() as `0x${string}`) + .with(field, faker.string.sample() as Address) .build(); const result = ExecutedTransactionEventSchema.safeParse( @@ -70,7 +70,7 @@ describe('ExecutedTransactionEventSchema', () => { (field) => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const executedTransactionEvent = executedTransactionEventBuilder() .with(field, nonChecksummedAddress) .build(); @@ -109,7 +109,7 @@ describe('ExecutedTransactionEventSchema', () => { it('should not allow a non-hex data', () => { const executedTransactionEvent = executedTransactionEventBuilder() - .with('data', faker.string.sample() as `0x${string}`) + .with('data', faker.string.sample() as Address) .build(); const result = ExecutedTransactionEventSchema.safeParse( diff --git a/src/routes/hooks/entities/schemas/__tests__/incoming-ether.schema.spec.ts b/src/routes/hooks/entities/schemas/__tests__/incoming-ether.schema.spec.ts index 67cdcf913e..e9e7a032a1 100644 --- a/src/routes/hooks/entities/schemas/__tests__/incoming-ether.schema.spec.ts +++ b/src/routes/hooks/entities/schemas/__tests__/incoming-ether.schema.spec.ts @@ -2,7 +2,7 @@ import { incomingEtherEventBuilder } from '@/routes/hooks/entities/__tests__/inc import type { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import { IncomingEtherEventSchema } from '@/routes/hooks/entities/schemas/incoming-ether.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('IncomingEtherEventSchema', () => { @@ -36,7 +36,7 @@ describe('IncomingEtherEventSchema', () => { it('should not allow a non-address address', () => { const incomingEtherEvent = incomingEtherEventBuilder() - .with('address', faker.string.alpha() as `0x${string}`) + .with('address', faker.string.alpha() as Address) .build(); const result = IncomingEtherEventSchema.safeParse(incomingEtherEvent); @@ -55,7 +55,7 @@ describe('IncomingEtherEventSchema', () => { it('should checksum the address', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const incomingEtherEvent = incomingEtherEventBuilder() .with('address', nonChecksummedAddress) .build(); diff --git a/src/routes/hooks/entities/schemas/__tests__/incoming-token.schema.spec.ts b/src/routes/hooks/entities/schemas/__tests__/incoming-token.schema.spec.ts index 2c317f9423..657225c9e4 100644 --- a/src/routes/hooks/entities/schemas/__tests__/incoming-token.schema.spec.ts +++ b/src/routes/hooks/entities/schemas/__tests__/incoming-token.schema.spec.ts @@ -2,7 +2,7 @@ import { incomingTokenEventBuilder } from '@/routes/hooks/entities/__tests__/inc import type { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import { IncomingTokenEventSchema } from '@/routes/hooks/entities/schemas/incoming-token.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('IncomingTokenEventSchema', () => { @@ -38,7 +38,7 @@ describe('IncomingTokenEventSchema', () => { 'should not allow a non-address %s', (field) => { const incomingTokenEvent = incomingTokenEventBuilder() - .with(field, faker.string.alpha() as `0x${string}`) + .with(field, faker.string.alpha() as Address) .build(); const result = IncomingTokenEventSchema.safeParse(incomingTokenEvent); @@ -60,7 +60,7 @@ describe('IncomingTokenEventSchema', () => { (field) => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const incomingTokenEvent = incomingTokenEventBuilder() .with(field, nonChecksummedAddress) .build(); diff --git a/src/routes/hooks/entities/schemas/__tests__/message-created.schema.spec.ts b/src/routes/hooks/entities/schemas/__tests__/message-created.schema.spec.ts index 5255a42057..fe2ec71a03 100644 --- a/src/routes/hooks/entities/schemas/__tests__/message-created.schema.spec.ts +++ b/src/routes/hooks/entities/schemas/__tests__/message-created.schema.spec.ts @@ -2,7 +2,7 @@ import { messageCreatedEventBuilder } from '@/routes/hooks/entities/__tests__/me import type { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import { MessageCreatedEventSchema } from '@/routes/hooks/entities/schemas/message-created.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('MessageCreatedEventSchema', () => { @@ -36,7 +36,7 @@ describe('MessageCreatedEventSchema', () => { it('should not allow a non-address address', () => { const messageCreatedEvent = messageCreatedEventBuilder() - .with('address', faker.string.alpha() as `0x${string}`) + .with('address', faker.string.alpha() as Address) .build(); const result = MessageCreatedEventSchema.safeParse(messageCreatedEvent); @@ -55,7 +55,7 @@ describe('MessageCreatedEventSchema', () => { it('should checksum the address', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const messageCreatedEvent = messageCreatedEventBuilder() .with('address', nonChecksummedAddress) .build(); diff --git a/src/routes/hooks/entities/schemas/__tests__/module-transaction.schema.spec.ts b/src/routes/hooks/entities/schemas/__tests__/module-transaction.schema.spec.ts index 5daf2f85f4..9f6c624a4e 100644 --- a/src/routes/hooks/entities/schemas/__tests__/module-transaction.schema.spec.ts +++ b/src/routes/hooks/entities/schemas/__tests__/module-transaction.schema.spec.ts @@ -1,7 +1,7 @@ import { ModuleTransactionEventSchema } from '@/routes/hooks/entities/schemas/module-transaction.schema'; import type { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; import { moduleTransactionEventBuilder } from '@/routes/hooks/entities/__tests__/module-transaction.builder'; @@ -45,7 +45,7 @@ describe('ModuleTransactionEventSchema', () => { 'should not allow a non-address %s', (field) => { const moduleTransactionEvent = moduleTransactionEventBuilder() - .with(field, faker.string.alpha() as `0x${string}`) + .with(field, faker.string.alpha() as Address) .build(); const result = ModuleTransactionEventSchema.safeParse( @@ -69,7 +69,7 @@ describe('ModuleTransactionEventSchema', () => { (field) => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const moduleTransactionEvent = moduleTransactionEventBuilder() .with(field, nonChecksummedAddress) .build(); diff --git a/src/routes/hooks/entities/schemas/__tests__/new-confirmation.schema.spec.ts b/src/routes/hooks/entities/schemas/__tests__/new-confirmation.schema.spec.ts index edaab8f1ab..8a4c899b07 100644 --- a/src/routes/hooks/entities/schemas/__tests__/new-confirmation.schema.spec.ts +++ b/src/routes/hooks/entities/schemas/__tests__/new-confirmation.schema.spec.ts @@ -2,7 +2,7 @@ import { newConfirmationEventBuilder } from '@/routes/hooks/entities/__tests__/n import type { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import { NewConfirmationEventSchema } from '@/routes/hooks/entities/schemas/new-confirmation.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('NewConfirmationEventSchema', () => { @@ -41,7 +41,7 @@ describe('NewConfirmationEventSchema', () => { 'should not allow a non-address %s', (field) => { const newConfirmationEvent = newConfirmationEventBuilder() - .with(field, faker.string.alpha() as `0x${string}`) + .with(field, faker.string.alpha() as Address) .build(); const result = NewConfirmationEventSchema.safeParse(newConfirmationEvent); @@ -63,7 +63,7 @@ describe('NewConfirmationEventSchema', () => { (field) => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const newConfirmationEvent = newConfirmationEventBuilder() .with(field, nonChecksummedAddress) .build(); diff --git a/src/routes/hooks/entities/schemas/__tests__/new-message-confirmation.schema.spec.ts b/src/routes/hooks/entities/schemas/__tests__/new-message-confirmation.schema.spec.ts index dd2da14cdd..51bab61b4b 100644 --- a/src/routes/hooks/entities/schemas/__tests__/new-message-confirmation.schema.spec.ts +++ b/src/routes/hooks/entities/schemas/__tests__/new-message-confirmation.schema.spec.ts @@ -2,7 +2,7 @@ import { newMessageConfirmationEventBuilder } from '@/routes/hooks/entities/__te import type { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import { NewMessageConfirmationEventSchema } from '@/routes/hooks/entities/schemas/new-message-confirmation.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('NewMessageConfirmationEventSchema', () => { @@ -44,7 +44,7 @@ describe('NewMessageConfirmationEventSchema', () => { it('should not allow non-address address', () => { const newMessageConfirmationEvent = newMessageConfirmationEventBuilder() - .with('address', faker.string.alpha() as `0x${string}`) + .with('address', faker.string.alpha() as Address) .build(); const result = NewMessageConfirmationEventSchema.safeParse( @@ -65,7 +65,7 @@ describe('NewMessageConfirmationEventSchema', () => { it('should checksum the address', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const newMessageConfirmationEvent = newMessageConfirmationEventBuilder() .with('address', nonChecksummedAddress) .build(); diff --git a/src/routes/hooks/entities/schemas/__tests__/outgoing-ether.schema.spec.ts b/src/routes/hooks/entities/schemas/__tests__/outgoing-ether.schema.spec.ts index b710e27463..f131e8a83d 100644 --- a/src/routes/hooks/entities/schemas/__tests__/outgoing-ether.schema.spec.ts +++ b/src/routes/hooks/entities/schemas/__tests__/outgoing-ether.schema.spec.ts @@ -2,7 +2,7 @@ import { outgoingEtherEventBuilder } from '@/routes/hooks/entities/__tests__/out import type { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import { OutgoingEtherEventSchema } from '@/routes/hooks/entities/schemas/outgoing-ether.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('OutgoingEtherEventSchema', () => { @@ -36,7 +36,7 @@ describe('OutgoingEtherEventSchema', () => { it('should not allow a non-address address', () => { const outgoingEtherEvent = outgoingEtherEventBuilder() - .with('address', faker.string.alpha() as `0x${string}`) + .with('address', faker.string.alpha() as Address) .build(); const result = OutgoingEtherEventSchema.safeParse(outgoingEtherEvent); @@ -55,7 +55,7 @@ describe('OutgoingEtherEventSchema', () => { it('should checksum the address', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const outgoingEtherEvent = outgoingEtherEventBuilder() .with('address', nonChecksummedAddress) .build(); diff --git a/src/routes/hooks/entities/schemas/__tests__/outgoing-token.schema.spec.ts b/src/routes/hooks/entities/schemas/__tests__/outgoing-token.schema.spec.ts index 70ddf0333b..8ac052639e 100644 --- a/src/routes/hooks/entities/schemas/__tests__/outgoing-token.schema.spec.ts +++ b/src/routes/hooks/entities/schemas/__tests__/outgoing-token.schema.spec.ts @@ -2,7 +2,7 @@ import { outgoingTokenEventBuilder } from '@/routes/hooks/entities/__tests__/out import type { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import { OutgoingTokenEventSchema } from '@/routes/hooks/entities/schemas/outgoing-token.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('OutgoingTokenEventSchema', () => { @@ -38,7 +38,7 @@ describe('OutgoingTokenEventSchema', () => { 'should not allow a non-address %s', (field) => { const outgoingTokenEvent = outgoingTokenEventBuilder() - .with(field, faker.string.alpha() as `0x${string}`) + .with(field, faker.string.alpha() as Address) .build(); const result = OutgoingTokenEventSchema.safeParse(outgoingTokenEvent); @@ -60,7 +60,7 @@ describe('OutgoingTokenEventSchema', () => { (field) => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const outgoingTokenEvent = outgoingTokenEventBuilder() .with(field, nonChecksummedAddress) .build(); diff --git a/src/routes/hooks/entities/schemas/__tests__/pending-transaction.schema.spec.ts b/src/routes/hooks/entities/schemas/__tests__/pending-transaction.schema.spec.ts index f8c767c13f..777d63ab5b 100644 --- a/src/routes/hooks/entities/schemas/__tests__/pending-transaction.schema.spec.ts +++ b/src/routes/hooks/entities/schemas/__tests__/pending-transaction.schema.spec.ts @@ -2,7 +2,7 @@ import { pendingTransactionEventBuilder } from '@/routes/hooks/entities/__tests_ import type { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import { PendingTransactionEventSchema } from '@/routes/hooks/entities/schemas/pending-transaction.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('PendingTransactionEventSchema', () => { @@ -46,7 +46,7 @@ describe('PendingTransactionEventSchema', () => { 'should not allow a non-address %s', (field) => { const pendingTransactionEvent = pendingTransactionEventBuilder() - .with(field, faker.string.sample() as `0x${string}`) + .with(field, faker.string.sample() as Address) .build(); const result = PendingTransactionEventSchema.safeParse( @@ -70,7 +70,7 @@ describe('PendingTransactionEventSchema', () => { (field) => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const pendingTransactionEvent = pendingTransactionEventBuilder() .with(field, nonChecksummedAddress) .build(); diff --git a/src/routes/hooks/entities/schemas/__tests__/safe-created.schema.spec.ts b/src/routes/hooks/entities/schemas/__tests__/safe-created.schema.spec.ts index 5beb0e4fc9..a2e8b68b85 100644 --- a/src/routes/hooks/entities/schemas/__tests__/safe-created.schema.spec.ts +++ b/src/routes/hooks/entities/schemas/__tests__/safe-created.schema.spec.ts @@ -2,7 +2,7 @@ import { safeCreatedEventBuilder } from '@/routes/hooks/entities/__tests__/safe- import type { TransactionEventType } from '@/routes/hooks/entities/event-type.entity'; import { SafeCreatedEventSchema } from '@/routes/hooks/entities/schemas/safe-created.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('SafeCreatedEventSchema', () => { @@ -17,7 +17,7 @@ describe('SafeCreatedEventSchema', () => { it('should checksum the address', () => { const nonChecksummedAddress = faker.finance.ethereumAddress().toLowerCase(); const safeCreatedEvent = safeCreatedEventBuilder() - .with('address', nonChecksummedAddress as `0x${string}`) + .with('address', nonChecksummedAddress as Address) .build(); const result = SafeCreatedEventSchema.safeParse(safeCreatedEvent); diff --git a/src/routes/hooks/hooks-notifications.spec.ts b/src/routes/hooks/hooks-notifications.spec.ts index 657b609af5..126dae9a86 100644 --- a/src/routes/hooks/hooks-notifications.spec.ts +++ b/src/routes/hooks/hooks-notifications.spec.ts @@ -20,7 +20,7 @@ import { IConfigurationService } from '@/config/configuration.service.interface' import type { INetworkService } from '@/datasources/network/network.service.interface'; import { NetworkService } from '@/datasources/network/network.service.interface'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { getAddress, type Hash, type Hex } from 'viem'; import { pageBuilder } from '@/domain/entities/__tests__/page.builder'; import { nativeTokenTransferBuilder } from '@/domain/safe/entities/__tests__/native-token-transfer.builder'; import { erc721TransferBuilder } from '@/domain/safe/entities/__tests__/erc721-transfer.builder'; @@ -207,15 +207,15 @@ describe('Hook Events for Notifications (Unit) pt. 1', () => { const transfers = [ nativeTokenTransferBuilder() .with('to', event.address) - .with('transactionHash', event.txHash as `0x${string}`) + .with('transactionHash', event.txHash as Hash) .build(), erc721TransferBuilder() .with('to', event.address) - .with('transactionHash', event.txHash as `0x${string}`) + .with('transactionHash', event.txHash as Hash) .build(), erc20TransferBuilder() .with('to', event.address) - .with('transactionHash', event.txHash as `0x${string}`) + .with('transactionHash', event.txHash as Hash) .build(), ]; return Promise.resolve({ @@ -291,17 +291,17 @@ describe('Hook Events for Notifications (Unit) pt. 1', () => { nativeTokenTransferBuilder() .with('from', event.address) .with('to', event.address) - .with('transactionHash', event.txHash as `0x${string}`) + .with('transactionHash', event.txHash as Hash) .build(), erc721TransferBuilder() .with('from', event.address) .with('to', event.address) - .with('transactionHash', event.txHash as `0x${string}`) + .with('transactionHash', event.txHash as Hash) .build(), erc20TransferBuilder() .with('from', event.address) .with('to', event.address) - .with('transactionHash', event.txHash as `0x${string}`) + .with('transactionHash', event.txHash as Hash) .build(), ]; return Promise.resolve({ @@ -651,7 +651,7 @@ describe('Hook Events for Notifications (Unit) pt. 1', () => { const event = messageCreatedEventBuilder().build(); const chain = chainBuilder().with('chainId', event.chainId).build(); const message = messageBuilder() - .with('messageHash', event.messageHash as `0x${string}`) + .with('messageHash', event.messageHash as Hash) .build(); const subscribers = faker.helpers.multiple( () => ({ @@ -812,7 +812,7 @@ describe('Hook Events for Notifications (Unit) pt. 1', () => { subscribers, ); const message = messageBuilder() - .with('messageHash', event.messageHash as `0x${string}`) + .with('messageHash', event.messageHash as Hash) .with( 'confirmations', subscribers.map((subscriber) => { @@ -888,7 +888,7 @@ describe('Hook Events for Notifications (Unit) pt. 1', () => { return messageConfirmationBuilder().with('owner', owner).build(); }); const message = messageBuilder() - .with('messageHash', event.messageHash as `0x${string}`) + .with('messageHash', event.messageHash as Hash) .with('confirmations', confirmations) .build(); @@ -1309,7 +1309,7 @@ describe('Hook Events for Notifications (Unit) pt. 1', () => { .with('threshold', faker.number.int({ min: 2 })) .build(); const message = messageBuilder() - .with('messageHash', event.messageHash as `0x${string}`) + .with('messageHash', event.messageHash as Hash) .build(); const subscribers = faker.helpers.multiple( () => ({ @@ -1471,7 +1471,7 @@ describe('Hook Events for Notifications (Unit) pt. 1', () => { .build(); }); const message = messageBuilder() - .with('messageHash', event.messageHash as `0x${string}`) + .with('messageHash', event.messageHash as Hash) .with( 'confirmations', subscribers.map((subscriber) => { @@ -1558,7 +1558,7 @@ describe('Hook Events for Notifications (Unit) pt. 1', () => { return messageConfirmationBuilder().with('owner', owner).build(); }); const message = messageBuilder() - .with('messageHash', event.messageHash as `0x${string}`) + .with('messageHash', event.messageHash as Hash) .with('confirmations', confirmations) .build(); @@ -1702,7 +1702,7 @@ describe('Hook Events for Notifications (Unit) pt. 1', () => { .with('threshold', faker.number.int({ min: 2 })) .build(); const message = messageBuilder() - .with('messageHash', event.messageHash as `0x${string}`) + .with('messageHash', event.messageHash as Hash) .build(); const subscribers = faker.helpers.multiple( () => ({ @@ -1849,8 +1849,7 @@ describe('Hook Events for Notifications (Unit) pt. 1', () => { data: rawify(safe), }); } else if (url === `${chain.transactionService}/api/v2/delegates/`) { - const payloadDelegate = networkRequest?.params - ?.delegate as `0x${string}`; + const payloadDelegate = networkRequest?.params?.delegate as Hex; const delegator = delegateDelegators[payloadDelegate]; const results = delegator ? [ @@ -1968,7 +1967,7 @@ describe('Hook Events for Notifications (Unit) pt. 1', () => { ) .build(); const message = messageBuilder() - .with('messageHash', event.messageHash as `0x${string}`) + .with('messageHash', event.messageHash as Hash) .with('confirmations', [ messageConfirmationBuilder().with('owner', safeOwners[0]).build(), ]) @@ -1993,8 +1992,7 @@ describe('Hook Events for Notifications (Unit) pt. 1', () => { data: rawify(safe), }); } else if (url === `${chain.transactionService}/api/v2/delegates/`) { - const payloadDelegate = networkRequest?.params - ?.delegate as `0x${string}`; + const payloadDelegate = networkRequest?.params?.delegate as Hex; const delegator = delegateDelegators[payloadDelegate]; const results = delegator ? [ diff --git a/src/routes/messages/entities/__tests__/create-message.dto.builder.ts b/src/routes/messages/entities/__tests__/create-message.dto.builder.ts index 3bce41a707..dcd735b266 100644 --- a/src/routes/messages/entities/__tests__/create-message.dto.builder.ts +++ b/src/routes/messages/entities/__tests__/create-message.dto.builder.ts @@ -3,6 +3,7 @@ import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { CreateMessageDto } from '@/routes/messages/entities/create-message.dto.entity'; import { fakeJson } from '@/__tests__/faker'; +import type { Hex } from 'viem'; const SIGNATURE_LENGTH = 130; @@ -11,7 +12,7 @@ export function createMessageDtoBuilder(): IBuilder { .with('message', faker.word.words({ count: { min: 1, max: 5 } })) .with( 'signature', - faker.string.hexadecimal({ length: SIGNATURE_LENGTH }) as `0x${string}`, + faker.string.hexadecimal({ length: SIGNATURE_LENGTH }) as Hex, ) .with('origin', fakeJson()); } diff --git a/src/routes/messages/entities/__tests__/typed-data.builder.ts b/src/routes/messages/entities/__tests__/typed-data.builder.ts index f3c4c626d1..5cb074fa97 100644 --- a/src/routes/messages/entities/__tests__/typed-data.builder.ts +++ b/src/routes/messages/entities/__tests__/typed-data.builder.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Hex, getAddress } from 'viem'; import { Builder } from '@/__tests__/builder'; import type { IBuilder } from '@/__tests__/builder'; import type { TypedData } from '@/domain/messages/entities/typed-data.entity'; @@ -39,7 +39,7 @@ export function typedDataDomainBuilder(): IBuilder { return new Builder() .with('chainId', faker.number.int()) .with('name', faker.lorem.word()) - .with('salt', faker.string.hexadecimal({ length: 64 }) as `0x${string}`) + .with('salt', faker.string.hexadecimal({ length: 64 }) as Hex) .with('verifyingContract', getAddress(faker.finance.ethereumAddress())) .with('version', faker.system.semver()); } diff --git a/src/routes/messages/entities/__tests__/update-message-signature.dto.builder.ts b/src/routes/messages/entities/__tests__/update-message-signature.dto.builder.ts index 89283a9deb..df7e26ae69 100644 --- a/src/routes/messages/entities/__tests__/update-message-signature.dto.builder.ts +++ b/src/routes/messages/entities/__tests__/update-message-signature.dto.builder.ts @@ -2,10 +2,11 @@ import { faker } from '@faker-js/faker'; import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { UpdateMessageSignatureDto } from '@/routes/messages/entities/update-message-signature.entity'; +import type { Hex } from 'viem'; export function updateMessageSignatureDtoBuilder(): IBuilder { return new Builder().with( 'signature', - faker.string.hexadecimal({ length: 130 }) as `0x${string}`, + faker.string.hexadecimal({ length: 130 }) as Hex, ); } diff --git a/src/routes/messages/entities/create-message.dto.entity.ts b/src/routes/messages/entities/create-message.dto.entity.ts index e1f3100719..58e2a27395 100644 --- a/src/routes/messages/entities/create-message.dto.entity.ts +++ b/src/routes/messages/entities/create-message.dto.entity.ts @@ -7,6 +7,7 @@ import { getSchemaPath, } from '@nestjs/swagger'; import { z } from 'zod'; +import type { Address } from 'viem'; @ApiExtraModels(TypedData) export class CreateMessageDto @@ -19,7 +20,7 @@ export class CreateMessageDto @ApiPropertyOptional({ type: Number, nullable: true, deprecated: true }) safeAppId!: number | null; @ApiProperty() - signature!: `0x${string}`; + signature!: Address; @ApiPropertyOptional({ type: String, nullable: true }) origin!: string | null; } diff --git a/src/routes/messages/entities/message-confirmation.entity.ts b/src/routes/messages/entities/message-confirmation.entity.ts index 65316e2687..cf51464e0d 100644 --- a/src/routes/messages/entities/message-confirmation.entity.ts +++ b/src/routes/messages/entities/message-confirmation.entity.ts @@ -1,13 +1,14 @@ import { ApiProperty } from '@nestjs/swagger'; import { AddressInfo } from '@/routes/common/entities/address-info.entity'; +import type { Hex } from 'viem'; export class MessageConfirmation { @ApiProperty() owner: AddressInfo; @ApiProperty() - signature: `0x${string}`; + signature: Hex; - constructor(owner: AddressInfo, signature: `0x${string}`) { + constructor(owner: AddressInfo, signature: Hex) { this.owner = owner; this.signature = signature; } diff --git a/src/routes/messages/entities/message.entity.ts b/src/routes/messages/entities/message.entity.ts index 01c312809a..7ec90eb85f 100644 --- a/src/routes/messages/entities/message.entity.ts +++ b/src/routes/messages/entities/message.entity.ts @@ -7,6 +7,7 @@ import { import { AddressInfo } from '@/routes/common/entities/address-info.entity'; import { MessageConfirmation } from '@/routes/messages/entities/message-confirmation.entity'; import { TypedData } from '@/routes/messages/entities/typed-data.entity'; +import type { Hash, Hex } from 'viem'; export enum MessageStatus { NeedsConfirmation = 'NEEDS_CONFIRMATION', @@ -16,7 +17,7 @@ export enum MessageStatus { @ApiExtraModels(TypedData) export class Message { @ApiProperty() - messageHash: `0x${string}`; + messageHash: Hash; @ApiProperty({ enum: MessageStatus }) status: MessageStatus; @ApiPropertyOptional({ type: String, nullable: true }) @@ -40,12 +41,12 @@ export class Message { @ApiProperty({ type: MessageConfirmation, isArray: true }) confirmations: Array; @ApiPropertyOptional({ type: String, nullable: true }) - preparedSignature: `0x${string}` | null; + preparedSignature: Hex | null; @ApiPropertyOptional({ type: String, nullable: true }) origin: string | null; constructor( - messageHash: `0x${string}`, + messageHash: Hash, status: MessageStatus, logoUri: string | null, name: string | null, @@ -56,7 +57,7 @@ export class Message { confirmationsRequired: number, proposedBy: AddressInfo, confirmations: Array, - preparedSignature: `0x${string}` | null, + preparedSignature: Hex | null, origin: string | null, ) { this.messageHash = messageHash; diff --git a/src/routes/messages/entities/schemas/__tests__/create-message.dto.schema.spec.ts b/src/routes/messages/entities/schemas/__tests__/create-message.dto.schema.spec.ts index 3710282984..8cdda8b5fc 100644 --- a/src/routes/messages/entities/schemas/__tests__/create-message.dto.schema.spec.ts +++ b/src/routes/messages/entities/schemas/__tests__/create-message.dto.schema.spec.ts @@ -3,6 +3,7 @@ import { createMessageDtoBuilder } from '@/routes/messages/entities/__tests__/cr import { CreateMessageDtoSchema } from '@/routes/messages/entities/schemas/create-message.dto.schema'; import { faker } from '@faker-js/faker'; import { ZodError } from 'zod'; +import type { Address } from 'viem'; describe('CreateMessageDtoSchema', () => { describe('message', () => { @@ -141,7 +142,7 @@ describe('CreateMessageDtoSchema', () => { describe('signature', () => { it('should not validate a non-hex signature', () => { const createMessageDto = createMessageDtoBuilder() - .with('signature', faker.string.numeric() as `0x${string}`) + .with('signature', faker.string.numeric() as Address) .build(); const result = CreateMessageDtoSchema.safeParse(createMessageDto); diff --git a/src/routes/messages/entities/schemas/__tests__/update-message.dto.schema.spec.ts b/src/routes/messages/entities/schemas/__tests__/update-message.dto.schema.spec.ts index 05c63f4d12..24b9955afb 100644 --- a/src/routes/messages/entities/schemas/__tests__/update-message.dto.schema.spec.ts +++ b/src/routes/messages/entities/schemas/__tests__/update-message.dto.schema.spec.ts @@ -2,6 +2,7 @@ import { updateMessageSignatureDtoBuilder } from '@/routes/messages/entities/__t import { UpdateMessageSignatureDtoSchema } from '@/routes/messages/entities/schemas/update-message-signature.dto.schema'; import { faker } from '@faker-js/faker'; import { ZodError } from 'zod'; +import type { Address, Hash } from 'viem'; describe('UpdateMessageSignatureDtoSchema', () => { it('should validate a valid updateMessageSignatureDto', () => { @@ -17,7 +18,7 @@ describe('UpdateMessageSignatureDtoSchema', () => { it('should not allow a non-hex signature', () => { const updateMessageSignatureDto = updateMessageSignatureDtoBuilder() - .with('signature', faker.string.alphanumeric() as `0x${string}`) + .with('signature', faker.string.alphanumeric() as Address) .build(); const result = UpdateMessageSignatureDtoSchema.safeParse( @@ -47,10 +48,7 @@ describe('UpdateMessageSignatureDtoSchema', () => { it('should not allow non-signature length hex strings', () => { const updateMessageSignatureDto = updateMessageSignatureDtoBuilder() - .with( - 'signature', - faker.string.hexadecimal({ length: 129 }) as `0x${string}`, - ) + .with('signature', faker.string.hexadecimal({ length: 129 }) as Hash) .build(); const result = UpdateMessageSignatureDtoSchema.safeParse( diff --git a/src/routes/messages/entities/typed-data.entity.ts b/src/routes/messages/entities/typed-data.entity.ts index 8557c0aa88..16e228c4a5 100644 --- a/src/routes/messages/entities/typed-data.entity.ts +++ b/src/routes/messages/entities/typed-data.entity.ts @@ -5,6 +5,7 @@ import { ApiPropertyOptional, getSchemaPath, } from '@nestjs/swagger'; +import type { Address } from 'viem'; class TypedDataDomain { @ApiPropertyOptional({ type: Number }) @@ -16,12 +17,12 @@ class TypedDataDomain { name?: string; @ApiPropertyOptional({ type: String }) - salt?: `0x${string}`; + salt?: Address; @ApiPropertyOptional({ type: String, }) - verifyingContract?: `0x${string}`; + verifyingContract?: Address; @ApiPropertyOptional({ type: String, diff --git a/src/routes/messages/entities/update-message-signature.entity.ts b/src/routes/messages/entities/update-message-signature.entity.ts index 7489c00dce..d466d0e5f1 100644 --- a/src/routes/messages/entities/update-message-signature.entity.ts +++ b/src/routes/messages/entities/update-message-signature.entity.ts @@ -1,10 +1,11 @@ import { UpdateMessageSignatureDtoSchema } from '@/routes/messages/entities/schemas/update-message-signature.dto.schema'; import { ApiProperty } from '@nestjs/swagger'; import { z } from 'zod'; +import type { Address } from 'viem'; export class UpdateMessageSignatureDto implements z.infer { @ApiProperty() - signature!: `0x${string}`; + signature!: Address; } diff --git a/src/routes/messages/messages.controller.spec.ts b/src/routes/messages/messages.controller.spec.ts index 17a17703e8..676ab4c137 100644 --- a/src/routes/messages/messages.controller.spec.ts +++ b/src/routes/messages/messages.controller.spec.ts @@ -23,7 +23,7 @@ import type { SafeApp } from '@/routes/safe-apps/entities/safe-app.entity'; import { NetworkResponseError } from '@/datasources/network/entities/network.error.entity'; import type { Server } from 'net'; import { rawify } from '@/validation/entities/raw.entity'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'; import { GlobalErrorFilter } from '@/routes/common/filters/global-error.filter'; import { APP_FILTER } from '@nestjs/core'; @@ -1445,7 +1445,7 @@ describe('Messages controller', () => { }); message.messageHash = faker.string.hexadecimal({ length: 64, - }) as `0x${string}`; + }) as Address; networkService.get.mockImplementation(({ url }) => { switch (url) { case `${safeConfigUrl}/api/v1/chains/${chain.chainId}`: diff --git a/src/routes/messages/messages.controller.ts b/src/routes/messages/messages.controller.ts index 982593cc81..776fa3e473 100644 --- a/src/routes/messages/messages.controller.ts +++ b/src/routes/messages/messages.controller.ts @@ -24,6 +24,7 @@ import { ValidationPipe } from '@/validation/pipes/validation.pipe'; import { UpdateMessageSignatureDtoSchema } from '@/routes/messages/entities/schemas/update-message-signature.dto.schema'; import { CreateMessageDtoSchema } from '@/routes/messages/entities/schemas/create-message.dto.schema'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; +import type { Address, Hash } from 'viem'; @ApiTags('messages') @Controller({ @@ -59,7 +60,7 @@ export class MessagesController { @Get('chains/:chainId/messages/:messageHash') async getMessageByHash( @Param('chainId') chainId: string, - @Param('messageHash') messageHash: `0x${string}`, + @Param('messageHash') messageHash: Hash, ): Promise { return this.messagesService.getMessageByHash({ chainId, messageHash }); } @@ -97,7 +98,7 @@ export class MessagesController { async getMessagesBySafe( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @RouteUrlDecorator() routeUrl: URL, @PaginationDataDecorator() paginationData: PaginationData, ): Promise> { @@ -140,7 +141,7 @@ export class MessagesController { async createMessage( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Body(new ValidationPipe(CreateMessageDtoSchema)) createMessageDto: CreateMessageDto, ): Promise { @@ -184,7 +185,7 @@ export class MessagesController { @Post('chains/:chainId/messages/:messageHash/signatures') async updateMessageSignature( @Param('chainId') chainId: string, - @Param('messageHash') messageHash: `0x${string}`, + @Param('messageHash') messageHash: Hash, @Body(new ValidationPipe(UpdateMessageSignatureDtoSchema)) updateMessageSignatureDto: UpdateMessageSignatureDto, ): Promise { diff --git a/src/routes/messages/messages.service.ts b/src/routes/messages/messages.service.ts index 00bdf66d84..4574ebcce3 100644 --- a/src/routes/messages/messages.service.ts +++ b/src/routes/messages/messages.service.ts @@ -18,6 +18,7 @@ import { UpdateMessageSignatureDto } from '@/routes/messages/entities/update-mes import { MessageMapper } from '@/routes/messages/mappers/message-mapper'; import { LoggingService, ILoggingService } from '@/logging/logging.interface'; import { LogType } from '@/domain/common/entities/log-type.entity'; +import type { Address, Hash } from 'viem'; @Injectable() export class MessagesService { @@ -32,7 +33,7 @@ export class MessagesService { async getMessageByHash(args: { chainId: string; - messageHash: `0x${string}`; + messageHash: Hash; }): Promise { const message = await this.messagesRepository.getMessageByHash(args); const safe = await this.safeRepository.getSafe({ @@ -44,7 +45,7 @@ export class MessagesService { async getMessagesBySafe(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; paginationData: PaginationData; routeUrl: Readonly; }): Promise> { @@ -126,7 +127,7 @@ export class MessagesService { async createMessage(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; createMessageDto: CreateMessageDto; }): Promise { this.logProposeMessage(args); @@ -142,7 +143,7 @@ export class MessagesService { async updateMessageSignature(args: { chainId: string; - messageHash: `0x${string}`; + messageHash: Hash; updateMessageSignatureDto: UpdateMessageSignatureDto; }): Promise { return await this.messagesRepository.updateMessageSignature({ diff --git a/src/routes/notifications/v1/entities/__tests__/create-registration-v2.dto.builder.ts b/src/routes/notifications/v1/entities/__tests__/create-registration-v2.dto.builder.ts index 539f383069..7266ea8b48 100644 --- a/src/routes/notifications/v1/entities/__tests__/create-registration-v2.dto.builder.ts +++ b/src/routes/notifications/v1/entities/__tests__/create-registration-v2.dto.builder.ts @@ -10,6 +10,7 @@ import { toBytes, } from 'viem'; import { DeviceType } from '@/domain/notifications/v1/entities/device.entity'; +import type { Address, Hex } from 'viem'; export const createV2RegisterDtoBuilder = async ( args: RegisterDeviceDto, @@ -22,7 +23,7 @@ export const createV2RegisterDtoBuilder = async ( const safeV2Array: Array<{ authPayload: AuthPayload; upsertSubscriptionsDto: UpsertSubscriptionsDto & { - signature: `0x${string}`; + signature: Hex; }; }> = []; @@ -36,7 +37,7 @@ export const createV2RegisterDtoBuilder = async ( deviceType: args.deviceType, deviceUuid: args.uuid ?? null, safes: [], - signature: safeV1Registration.signatures[0] as `0x${string}`, + signature: safeV1Registration.signatures[0] as Address, }, authPayload: new AuthPayload(), }; @@ -56,7 +57,7 @@ export const createV2RegisterDtoBuilder = async ( (safeV2Safes) => safeV2Safes.address, ); - let recoveredAddress: `0x${string}`; + let recoveredAddress: Address; if (args.deviceType === DeviceType.Web) { recoveredAddress = await recoverMessageAddress({ message: { @@ -83,8 +84,8 @@ export const createV2RegisterDtoBuilder = async ( const messageToRecover = ( args: RegisterDeviceDto, - safeAddresses: Array<`0x${string}`>, -): `0x${string}` => { + safeAddresses: Array
, +): Address => { return keccak256( toBytes( `gnosis-safe${args.timestamp}${args.uuid}${args.cloudMessagingToken}${safeAddresses.sort().join('')}`, diff --git a/src/routes/notifications/v1/entities/__tests__/create-signature.builder.ts b/src/routes/notifications/v1/entities/__tests__/create-signature.builder.ts index e0eb2c0ca3..40f5f2d197 100644 --- a/src/routes/notifications/v1/entities/__tests__/create-signature.builder.ts +++ b/src/routes/notifications/v1/entities/__tests__/create-signature.builder.ts @@ -1,12 +1,13 @@ import type { UUID } from 'crypto'; import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'; +import type { Address } from 'viem'; export async function safeRegistrationSignatureBuilder(args: { signaturePrefix: string; uuid: UUID; cloudMessagingToken: UUID; timestamp: number; - safeAddresses: Array<`0x${string}`>; + safeAddresses: Array
; }): Promise { const privateKey = generatePrivateKey(); const signer = privateKeyToAccount(privateKey); diff --git a/src/routes/notifications/v1/notifications.controller.ts b/src/routes/notifications/v1/notifications.controller.ts index b1807b54a9..6c5f519225 100644 --- a/src/routes/notifications/v1/notifications.controller.ts +++ b/src/routes/notifications/v1/notifications.controller.ts @@ -33,6 +33,7 @@ import { } from 'viem'; import { UuidSchema } from '@/validation/entities/schemas/uuid.schema'; import { DeviceType } from '@/domain/notifications/v1/entities/device.entity'; +import type { Address, Hex } from 'viem'; @ApiTags('notifications') @Controller({ path: '', version: '1' }) @@ -103,7 +104,7 @@ export class NotificationsController { Parameters[0] & { upsertSubscriptionsDto: { safes: Array; - signature: `0x${string}`; + signature: Hex; }; } > = []; @@ -121,7 +122,7 @@ export class NotificationsController { >[0] & { upsertSubscriptionsDto: { safes: Array; - signature: `0x${string}`; + signature: Hex; }; } = { upsertSubscriptionsDto: { @@ -129,14 +130,14 @@ export class NotificationsController { deviceType: args.deviceType, deviceUuid: (args.uuid as UUID) || undefined, safes: [], - signature: (safeV1Signature as `0x${string}`) ?? undefined, + signature: (safeV1Signature as Hex) ?? undefined, }, authPayload: new AuthPayload(), }; const uniqueSafeAddresses = new Set(safeV1Registration.safes); for (const safeAddresses of uniqueSafeAddresses) { safeV2.upsertSubscriptionsDto.safes.push({ - address: safeAddresses as `0x${string}`, + address: safeAddresses as Address, chainId: safeV1Registration.chainId, notificationTypes: Object.values(NotificationType), }); @@ -151,7 +152,7 @@ export class NotificationsController { (safeV2Safes) => safeV2Safes.address, ); - let recoveredAddress: `0x${string}` | undefined = undefined; + let recoveredAddress: Address | undefined = undefined; if (safeV2.upsertSubscriptionsDto.signature) { recoveredAddress = await this.recoverAddress({ registerDeviceDto: args, @@ -189,11 +190,11 @@ export class NotificationsController { safeV2Dto: Parameters[0] & { upsertSubscriptionsDto: { safes: Array; - signature: `0x${string}`; + signature: Hex; }; }; - safeAddresses: Array<`0x${string}`>; - }): Promise<`0x${string}`> { + safeAddresses: Array
; + }): Promise
{ /** * @todo Explore the feasibility of using a unified method to recover signatures for both web and other clients. */ @@ -272,7 +273,7 @@ export class NotificationsController { @Param('chainId') chainId: string, @Param('uuid', new ValidationPipe(UuidSchema)) uuid: UUID, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { await this.notificationServiceV2.deleteSubscription({ deviceUuid: uuid, @@ -286,11 +287,11 @@ export class NotificationsController { safeV2Dto: Parameters[0] & { upsertSubscriptionsDto: { safes: Array; - signature: `0x${string}`; + signature: Hex; }; }; - safeAddresses: Array<`0x${string}`>; - }): `0x${string}` { + safeAddresses: Array
; + }): Address { return keccak256( toBytes( `gnosis-safe${args.registerDeviceDto.timestamp}${args.registerDeviceDto.uuid}${args.registerDeviceDto.cloudMessagingToken}${args.safeAddresses.sort().join('')}`, diff --git a/src/routes/notifications/v2/entities/delete-all-subscriptions.dto.entity.ts b/src/routes/notifications/v2/entities/delete-all-subscriptions.dto.entity.ts index cda8730ea5..87365dc84f 100644 --- a/src/routes/notifications/v2/entities/delete-all-subscriptions.dto.entity.ts +++ b/src/routes/notifications/v2/entities/delete-all-subscriptions.dto.entity.ts @@ -1,6 +1,7 @@ import { ApiProperty } from '@nestjs/swagger'; import type { UUID } from 'crypto'; import { DeleteAllSubscriptionsDto as DomainDeleteAllSubscriptionsDto } from '@/domain/notifications/v2/entities/delete-all-subscriptions.dto.entity'; +import type { Address } from 'viem'; export class DeleteAllSubscriptionItemDto { @ApiProperty() @@ -10,7 +11,7 @@ export class DeleteAllSubscriptionItemDto { public readonly deviceUuid!: UUID; @ApiProperty() - public readonly safeAddress!: `0x${string}`; + public readonly safeAddress!: Address; @ApiProperty({ type: 'string', @@ -22,7 +23,7 @@ export class DeleteAllSubscriptionItemDto { '• null: Deletes only subscriptions with no signer address\n' + '• Valid address: Deletes only subscriptions with that specific signer address', }) - public readonly signerAddress?: `0x${string}` | null; + public readonly signerAddress?: Address | null; } export class DeleteAllSubscriptionsDto diff --git a/src/routes/notifications/v2/entities/upsert-subscriptions.dto.entity.ts b/src/routes/notifications/v2/entities/upsert-subscriptions.dto.entity.ts index 9fc81b2d0e..f2439ffbc2 100644 --- a/src/routes/notifications/v2/entities/upsert-subscriptions.dto.entity.ts +++ b/src/routes/notifications/v2/entities/upsert-subscriptions.dto.entity.ts @@ -6,6 +6,7 @@ import { } from '@/domain/notifications/v2/entities/upsert-subscriptions.dto.entity'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import type { UUID } from 'crypto'; +import type { Address } from 'viem'; export class UpsertSubscriptionsSafesDto implements DomainUpsertSubscriptionsSafesDto @@ -14,7 +15,7 @@ export class UpsertSubscriptionsSafesDto chainId!: string; @ApiProperty() - address!: `0x${string}`; + address!: Address; @ApiProperty({ isArray: true, diff --git a/src/routes/notifications/v2/notifications.controller.ts b/src/routes/notifications/v2/notifications.controller.ts index 34a9063005..8ea7d50040 100644 --- a/src/routes/notifications/v2/notifications.controller.ts +++ b/src/routes/notifications/v2/notifications.controller.ts @@ -35,6 +35,7 @@ import { OptionalAuthGuard } from '@/routes/auth/guards/optional-auth.guard'; import { NotificationType } from '@/datasources/notifications/entities/notification-type.entity.db'; import { DeleteAllSubscriptionsDtoSchema } from '@/domain/notifications/v2/entities/delete-all-subscriptions.dto.entity'; import { DeleteAllSubscriptionsDto } from '@/routes/notifications/v2/entities/delete-all-subscriptions.dto.entity'; +import type { Address } from 'viem'; @ApiTags('notifications') @Controller({ path: '', version: '2' }) @@ -119,7 +120,7 @@ export class NotificationsControllerV2 { @Param('deviceUuid', new ValidationPipe(UuidSchema)) deviceUuid: UUID, @Param('chainId', new ValidationPipe(NumericStringSchema)) chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Auth() authPayload: AuthPayload, ): Promise> { return this.notificationsService.getSafeSubscription({ @@ -165,7 +166,7 @@ export class NotificationsControllerV2 { @Param('deviceUuid', new ValidationPipe(UuidSchema)) deviceUuid: UUID, @Param('chainId', new ValidationPipe(NumericStringSchema)) chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { return this.notificationsService.deleteSubscription({ deviceUuid, diff --git a/src/routes/notifications/v2/notifications.service.ts b/src/routes/notifications/v2/notifications.service.ts index 6aacc2ebf1..8915c6cade 100644 --- a/src/routes/notifications/v2/notifications.service.ts +++ b/src/routes/notifications/v2/notifications.service.ts @@ -4,6 +4,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { UUID } from 'crypto'; import { NotificationType } from '@/datasources/notifications/entities/notification-type.entity.db'; import { INotificationsRepositoryV2 } from '@/domain/notifications/v2/notifications.repository.interface'; +import type { Address } from 'viem'; @Injectable() export class NotificationsServiceV2 { @@ -25,7 +26,7 @@ export class NotificationsServiceV2 { authPayload: AuthPayload; deviceUuid: UUID; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise> { return await this.notificationsRepository.getSafeSubscription(args); } @@ -33,7 +34,7 @@ export class NotificationsServiceV2 { async deleteSubscription(args: { deviceUuid: UUID; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { await this.notificationsRepository.deleteSubscription(args); } @@ -42,7 +43,7 @@ export class NotificationsServiceV2 { subscriptions: Array<{ chainId: string; deviceUuid: UUID; - safeAddress: `0x${string}`; + safeAddress: Address; }>; }): Promise { await this.notificationsRepository.deleteAllSubscriptions(args); diff --git a/src/routes/owners/entities/safe-list.entity.ts b/src/routes/owners/entities/safe-list.entity.ts index 5f68f529ac..33c3ae09a2 100644 --- a/src/routes/owners/entities/safe-list.entity.ts +++ b/src/routes/owners/entities/safe-list.entity.ts @@ -1,7 +1,8 @@ import { ApiProperty } from '@nestjs/swagger'; import { SafeList as DomainSafeList } from '@/domain/safe/entities/safe-list.entity'; +import type { Address } from 'viem'; export class SafeList implements DomainSafeList { @ApiProperty() - safes!: Array<`0x${string}`>; + safes!: Array
; } diff --git a/src/routes/owners/owners.controller.v1.ts b/src/routes/owners/owners.controller.v1.ts index ce7ec458e4..1a6a2143f6 100644 --- a/src/routes/owners/owners.controller.v1.ts +++ b/src/routes/owners/owners.controller.v1.ts @@ -9,6 +9,7 @@ import { SafeList } from '@/routes/owners/entities/safe-list.entity'; import { OwnersService } from '@/routes/owners/owners.service'; import { ValidationPipe } from '@/validation/pipes/validation.pipe'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; +import type { Address } from 'viem'; @ApiTags('owners') @Controller({ @@ -42,7 +43,7 @@ export class OwnersControllerV1 { async getSafesByOwner( @Param('chainId') chainId: string, @Param('ownerAddress', new ValidationPipe(AddressSchema)) - ownerAddress: `0x${string}`, + ownerAddress: Address, ): Promise { return this.ownersService.getSafesByOwner({ chainId, ownerAddress }); } @@ -65,7 +66,7 @@ export class OwnersControllerV1 { @Get('owners/:ownerAddress/safes') async getAllSafesByOwner( @Param('ownerAddress', new ValidationPipe(AddressSchema)) - ownerAddress: `0x${string}`, + ownerAddress: Address, ): Promise<{ [chainId: string]: Array }> { return this.ownersService.deprecated__getAllSafesByOwner({ ownerAddress }); } diff --git a/src/routes/owners/owners.controller.v2.ts b/src/routes/owners/owners.controller.v2.ts index 6ee36829aa..162d0f6def 100644 --- a/src/routes/owners/owners.controller.v2.ts +++ b/src/routes/owners/owners.controller.v2.ts @@ -8,6 +8,7 @@ import { import { OwnersService } from '@/routes/owners/owners.service'; import { ValidationPipe } from '@/validation/pipes/validation.pipe'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; +import type { Address } from 'viem'; @ApiTags('owners') @Controller({ @@ -45,7 +46,7 @@ export class OwnersControllerV2 { @Get('owners/:ownerAddress/safes') async getAllSafesByOwner( @Param('ownerAddress', new ValidationPipe(AddressSchema)) - ownerAddress: `0x${string}`, + ownerAddress: Address, ): Promise<{ [chainId: string]: Array | null }> { return this.ownersService.getAllSafesByOwner({ ownerAddress }); } diff --git a/src/routes/owners/owners.service.ts b/src/routes/owners/owners.service.ts index 1ef72ee1d0..df68069162 100644 --- a/src/routes/owners/owners.service.ts +++ b/src/routes/owners/owners.service.ts @@ -2,6 +2,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { SafeRepository } from '@/domain/safe/safe.repository'; import { ISafeRepository } from '@/domain/safe/safe.repository.interface'; import { SafeList } from '@/routes/owners/entities/safe-list.entity'; +import type { Address } from 'viem'; @Injectable() export class OwnersService { @@ -12,7 +13,7 @@ export class OwnersService { async getSafesByOwner(args: { chainId: string; - ownerAddress: `0x${string}`; + ownerAddress: Address; }): Promise { return this.safeRepository.getSafesByOwner(args); } @@ -20,13 +21,13 @@ export class OwnersService { // TODO: Remove with /owners/:ownerAddress/safes // @deprecated async deprecated__getAllSafesByOwner(args: { - ownerAddress: `0x${string}`; + ownerAddress: Address; }): Promise<{ [chainId: string]: Array }> { return this.safeRepository.deprecated__getAllSafesByOwner(args); } async getAllSafesByOwner(args: { - ownerAddress: `0x${string}`; + ownerAddress: Address; }): Promise<{ [chainId: string]: Array | null }> { return this.safeRepository.getAllSafesByOwner(args); } diff --git a/src/routes/positions/positions.controller.ts b/src/routes/positions/positions.controller.ts index 9839d43c7b..ea580e53df 100644 --- a/src/routes/positions/positions.controller.ts +++ b/src/routes/positions/positions.controller.ts @@ -4,6 +4,7 @@ import { PositionsService } from '@/routes/positions/positions.service'; import { ValidationPipe } from '@/validation/pipes/validation.pipe'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { Protocol } from '@/routes/positions/entities/protocol.entity'; +import type { Address } from 'viem'; @ApiTags('positions') @Controller({ @@ -18,7 +19,7 @@ export class PositionsController { async getPositions( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Param('fiatCode') fiatCode: string, ): Promise> { return this.positionsService.getPositions({ diff --git a/src/routes/positions/positions.service.spec.ts b/src/routes/positions/positions.service.spec.ts index 3bd131b8de..11a84d38d8 100644 --- a/src/routes/positions/positions.service.spec.ts +++ b/src/routes/positions/positions.service.spec.ts @@ -6,6 +6,7 @@ import { PositionType } from '@/domain/positions/entities/position-type.entity'; import { faker } from '@faker-js/faker/.'; import { NULL_ADDRESS } from '@/routes/common/constants'; import type { Chain } from '@/domain/chains/entities/chain.entity'; +import type { Address } from 'viem'; const positionsRepoMock = jest.mocked({ getPositions: jest.fn(), @@ -69,7 +70,7 @@ describe('PositionsService', () => { const res = await service.getPositions({ chainId: '1', - safeAddress: faker.finance.ethereumAddress() as `0x${string}`, + safeAddress: faker.finance.ethereumAddress() as Address, fiatCode: 'USD', }); @@ -153,7 +154,7 @@ describe('PositionsService', () => { const res = await service.getPositions({ chainId: '1', - safeAddress: faker.finance.ethereumAddress() as `0x${string}`, + safeAddress: faker.finance.ethereumAddress() as Address, fiatCode: 'USD', }); @@ -190,7 +191,7 @@ describe('PositionsService', () => { const [aave] = await service.getPositions({ chainId: '1', - safeAddress: faker.finance.ethereumAddress() as `0x${string}`, + safeAddress: faker.finance.ethereumAddress() as Address, fiatCode: 'USD', }); @@ -218,7 +219,7 @@ describe('PositionsService', () => { const [maker] = await service.getPositions({ chainId: '1', - safeAddress: '0x1' as `0x${string}`, + safeAddress: '0x1' as Address, fiatCode: 'USD', }); @@ -241,7 +242,7 @@ describe('PositionsService', () => { const [unknown] = await service.getPositions({ chainId: '1', - safeAddress: '0x1' as `0x${string}`, + safeAddress: '0x1' as Address, fiatCode: 'USD', }); @@ -266,7 +267,7 @@ describe('PositionsService', () => { const [protocol] = await service.getPositions({ chainId: '1', - safeAddress: '0x1' as `0x${string}`, + safeAddress: '0x1' as Address, fiatCode: 'USD', }); @@ -294,7 +295,7 @@ describe('PositionsService', () => { const [aave] = await service.getPositions({ chainId: '1', - safeAddress: '0x1' as `0x${string}`, + safeAddress: '0x1' as Address, fiatCode: 'USD', }); @@ -307,7 +308,7 @@ describe('PositionsService', () => { positionsRepoMock.getPositions.mockResolvedValue([]); const res = await service.getPositions({ chainId: '1', - safeAddress: faker.finance.ethereumAddress() as `0x${string}`, + safeAddress: faker.finance.ethereumAddress() as Address, fiatCode: 'USD', }); expect(res).toEqual([]); diff --git a/src/routes/positions/positions.service.ts b/src/routes/positions/positions.service.ts index 002c259a44..0b413859c6 100644 --- a/src/routes/positions/positions.service.ts +++ b/src/routes/positions/positions.service.ts @@ -12,6 +12,7 @@ import { PositionGroup } from '@/routes/positions/entities/position-group.entity import { ZerionApplicationMetadataSchema } from '@/datasources/balances-api/entities/zerion-balance.entity'; import { z } from 'zod'; import { PositionType } from '@/domain/positions/entities/position-type.entity'; +import type { Address } from 'viem'; interface PositionEntry extends Position { protocol: string | null; @@ -30,7 +31,7 @@ export class PositionsService { async getPositions(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; fiatCode: string; }): Promise> { const { chainId } = args; diff --git a/src/routes/recovery/entities/add-recovery-module.dto.entity.ts b/src/routes/recovery/entities/add-recovery-module.dto.entity.ts index 0bbf9173fc..ba28e6eca5 100644 --- a/src/routes/recovery/entities/add-recovery-module.dto.entity.ts +++ b/src/routes/recovery/entities/add-recovery-module.dto.entity.ts @@ -1,10 +1,11 @@ import { AddRecoveryModuleDtoSchema } from '@/routes/recovery/entities/schemas/add-recovery-module.dto.schema'; import { ApiProperty } from '@nestjs/swagger'; import { z } from 'zod'; +import type { Address } from 'viem'; export class AddRecoveryModuleDto implements z.infer { @ApiProperty() - moduleAddress!: `0x${string}`; + moduleAddress!: Address; } diff --git a/src/routes/recovery/entities/schemas/__tests__/add-recovery-module.dto.schema.spec.ts b/src/routes/recovery/entities/schemas/__tests__/add-recovery-module.dto.schema.spec.ts index 251c0984b2..ba18698d3c 100644 --- a/src/routes/recovery/entities/schemas/__tests__/add-recovery-module.dto.schema.spec.ts +++ b/src/routes/recovery/entities/schemas/__tests__/add-recovery-module.dto.schema.spec.ts @@ -1,7 +1,7 @@ import { addRecoveryModuleDtoBuilder } from '@/routes/recovery/entities/__tests__/add-recovery-module.dto.builder'; import { AddRecoveryModuleDtoSchema } from '@/routes/recovery/entities/schemas/add-recovery-module.dto.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('AddRecoveryModuleDtoSchema', () => { @@ -16,7 +16,7 @@ describe('AddRecoveryModuleDtoSchema', () => { it('should checksum the moduleAddress', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const addRecoveryModuleDto = addRecoveryModuleDtoBuilder() .with('moduleAddress', nonChecksummedAddress) .build(); diff --git a/src/routes/recovery/recovery.controller.ts b/src/routes/recovery/recovery.controller.ts index 6b1c04e653..571fa21995 100644 --- a/src/routes/recovery/recovery.controller.ts +++ b/src/routes/recovery/recovery.controller.ts @@ -16,6 +16,7 @@ import { Auth } from '@/routes/auth/decorators/auth.decorator'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { AuthPayload } from '@/domain/auth/entities/auth-payload.entity'; import { ValidationPipe } from '@/validation/pipes/validation.pipe'; +import type { Address } from 'viem'; @ApiTags('recovery') @Controller({ @@ -31,7 +32,7 @@ export class RecoveryController { async addRecoveryModule( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Body(new ValidationPipe(AddRecoveryModuleDtoSchema)) addRecoveryModuleDto: AddRecoveryModuleDto, @Auth() authPayload: AuthPayload, @@ -50,9 +51,9 @@ export class RecoveryController { async deleteRecoveryModule( @Param('chainId') chainId: string, @Param('moduleAddress', new ValidationPipe(AddressSchema)) - moduleAddress: `0x${string}`, + moduleAddress: Address, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Auth() authPayload: AuthPayload, ): Promise { return this.recoveryService.deleteRecoveryModule({ diff --git a/src/routes/recovery/recovery.service.ts b/src/routes/recovery/recovery.service.ts index f6670de5d5..e70a567767 100644 --- a/src/routes/recovery/recovery.service.ts +++ b/src/routes/recovery/recovery.service.ts @@ -5,6 +5,7 @@ import { AddRecoveryModuleDto } from '@/routes/recovery/entities/add-recovery-mo import { AlertsRegistration } from '@/domain/alerts/entities/alerts-registration.entity'; import { AuthPayload } from '@/domain/auth/entities/auth-payload.entity'; import { ISafeRepository } from '@/domain/safe/safe.repository.interface'; +import type { Address } from 'viem'; @Injectable() export class RecoveryService { @@ -17,7 +18,7 @@ export class RecoveryService { async addRecoveryModule(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; addRecoveryModuleDto: AddRecoveryModuleDto; authPayload: AuthPayload; }): Promise { @@ -67,8 +68,8 @@ export class RecoveryService { async deleteRecoveryModule(args: { chainId: string; - moduleAddress: `0x${string}`; - safeAddress: `0x${string}`; + moduleAddress: Address; + safeAddress: Address; authPayload: AuthPayload; }): Promise { if ( diff --git a/src/routes/relay/entities/relay.dto.entity.ts b/src/routes/relay/entities/relay.dto.entity.ts index 16c162af58..9a1e093b4d 100644 --- a/src/routes/relay/entities/relay.dto.entity.ts +++ b/src/routes/relay/entities/relay.dto.entity.ts @@ -1,16 +1,17 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { z } from 'zod'; import { RelayDtoSchema } from '@/routes/relay/entities/schemas/relay.dto.schema'; +import type { Address } from 'viem'; export class RelayDto implements z.infer { @ApiProperty() version!: string; @ApiProperty() - to!: `0x${string}`; + to!: Address; @ApiProperty() - data!: `0x${string}`; + data!: Address; @ApiPropertyOptional({ type: String, diff --git a/src/routes/relay/relay.controller.ts b/src/routes/relay/relay.controller.ts index 3fa9a1f1ea..c5073664e8 100644 --- a/src/routes/relay/relay.controller.ts +++ b/src/routes/relay/relay.controller.ts @@ -21,6 +21,7 @@ import { RelayDtoSchema } from '@/routes/relay/entities/schemas/relay.dto.schema import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { Relay } from '@/routes/relay/entities/relay.entity'; import { RelaysRemaining } from '@/routes/relay/entities/relays-remaining.entity'; +import type { Address } from 'viem'; @ApiTags('relay') @Controller({ @@ -98,7 +99,7 @@ export class RelayController { async getRelaysRemaining( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { return this.relayService.getRelaysRemaining({ chainId, safeAddress }); } diff --git a/src/routes/relay/relay.service.ts b/src/routes/relay/relay.service.ts index dec58c8b20..ca83277d89 100644 --- a/src/routes/relay/relay.service.ts +++ b/src/routes/relay/relay.service.ts @@ -4,6 +4,7 @@ import { RelayDto } from '@/routes/relay/entities/relay.dto.entity'; import { IConfigurationService } from '@/config/configuration.service.interface'; import { Relay } from '@/routes/relay/entities/relay.entity'; import { RelaysRemaining } from '@/routes/relay/entities/relays-remaining.entity'; +import type { Address } from 'viem'; @Injectable() export class RelayService { @@ -31,7 +32,7 @@ export class RelayService { async getRelaysRemaining(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise<{ remaining: number; limit: number }> { const currentCount = await this.relayRepository.getRelayCount({ chainId: args.chainId, diff --git a/src/routes/safes/safes.controller.ts b/src/routes/safes/safes.controller.ts index 58618369c4..b8dc69f56a 100644 --- a/src/routes/safes/safes.controller.ts +++ b/src/routes/safes/safes.controller.ts @@ -24,6 +24,7 @@ import { } from '@/routes/safes/entities/caip-10-addresses.entity'; import { ValidationPipe } from '@/validation/pipes/validation.pipe'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; +import type { Address } from 'viem'; @ApiTags('safes') @Controller({ @@ -59,7 +60,7 @@ export class SafesController { async getSafe( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { return this.service.getSafeInfo({ chainId, safeAddress }); } @@ -91,7 +92,7 @@ export class SafesController { async getNonces( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { return this.service.getNonces({ chainId, safeAddress }); } @@ -154,7 +155,7 @@ export class SafesController { @Query('exclude_spam', new DefaultValuePipe(true), ParseBoolPipe) excludeSpam: boolean, @Query('wallet_address', new ValidationPipe(AddressSchema.optional())) - walletAddress?: `0x${string}`, + walletAddress?: Address, ): Promise> { return this.service.getSafeOverview({ currency, diff --git a/src/routes/safes/safes.service.ts b/src/routes/safes/safes.service.ts index 990ae3de2e..e71d15c328 100644 --- a/src/routes/safes/safes.service.ts +++ b/src/routes/safes/safes.service.ts @@ -26,6 +26,7 @@ import { IConfigurationService } from '@/config/configuration.service.interface' import { LoggingService, ILoggingService } from '@/logging/logging.interface'; import { asError } from '@/logging/utils'; import { Caip10Addresses } from '@/routes/safes/entities/caip-10-addresses.entity'; +import type { Address } from 'viem'; @Injectable() export class SafesService { @@ -51,7 +52,7 @@ export class SafesService { async getSafeInfo(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const [safe, { recommendedMasterCopyVersion }, supportedSingletons] = await Promise.all([ @@ -133,7 +134,7 @@ export class SafesService { addresses: Caip10Addresses; trusted: boolean; excludeSpam: boolean; - walletAddress?: `0x${string}`; + walletAddress?: Address; }): Promise> { const limitedSafes = args.addresses.slice(0, this.maxOverviews); @@ -198,7 +199,7 @@ export class SafesService { public async getNonces(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const nonce = await this.safeRepository.getNonces(args); return new SafeNonces(nonce); @@ -206,7 +207,7 @@ export class SafesService { private computeAwaitingConfirmation(args: { transactions: Array; - walletAddress: `0x${string}`; + walletAddress: Address; }): number { return args.transactions.reduce( (acc, { confirmationsRequired, confirmations }) => { @@ -232,7 +233,7 @@ export class SafesService { private async getCollectiblesTag( chainId: string, - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { const lastCollectibleTransfer = await this.safeRepository .getCollectibleTransfers({ @@ -274,7 +275,7 @@ export class SafesService { */ private async getTxHistoryTagDate( chainId: string, - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { const txPages = await Promise.allSettled([ this.safeRepository.getMultisigTransactions({ @@ -323,7 +324,7 @@ export class SafesService { private async modifiedMessageTag( chainId: string, - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { const messages = await this.messagesRepository.getMessagesBySafe({ chainId, diff --git a/src/routes/spaces/address-books.controller.spec.ts b/src/routes/spaces/address-books.controller.spec.ts index 97f8ec4583..19c5253d1d 100644 --- a/src/routes/spaces/address-books.controller.spec.ts +++ b/src/routes/spaces/address-books.controller.spec.ts @@ -15,7 +15,7 @@ import { faker } from '@faker-js/faker'; import type { INestApplication } from '@nestjs/common'; import type { Server } from 'net'; import request from 'supertest'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { DB_MAX_SAFE_INTEGER } from '@/domain/common/constants'; import type { AuthPayload } from '@/domain/auth/entities/auth-payload.entity'; import { addressBookItemBuilder } from '@/domain/spaces/address-books/entities/__tests__/address-book-item.db.builder'; @@ -258,7 +258,7 @@ describe('AddressBooksController', () => { it('should return a 403 if the AuthPayload is empty', async () => { const { spaceId } = await createSpace(); const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); @@ -800,10 +800,10 @@ describe('AddressBooksController', () => { const createAddressBookItem = async (args: { spaceId: string; adminAccessToken: string; - address?: `0x${string}`; + address?: Address; }): Promise<{ mockName: string; - mockAddress: `0x${string}`; + mockAddress: Address; mockChainIds: Array; }> => { const mockAddress = diff --git a/src/routes/spaces/address-books.controller.ts b/src/routes/spaces/address-books.controller.ts index 793a122ed7..c65679214e 100644 --- a/src/routes/spaces/address-books.controller.ts +++ b/src/routes/spaces/address-books.controller.ts @@ -34,6 +34,7 @@ import { } from '@/routes/spaces/entities/upsert-address-book-items.dto.entity'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { SpacesAddressBookRateLimitGuard } from '@/routes/spaces/guards/spaces-address-book-rate-limit.guard'; +import type { Address } from 'viem'; @ApiTags('spaces') @Controller({ path: 'spaces', version: '1' }) @@ -157,7 +158,7 @@ export class AddressBooksController { @Param('spaceId', ParseIntPipe, new ValidationPipe(RowSchema.shape.id)) spaceId: number, @Param('address', new ValidationPipe(AddressSchema)) - address: `0x${string}`, + address: Address, ): Promise { return this.service.deleteByAddress({ authPayload, spaceId, address }); } diff --git a/src/routes/spaces/entities/invite-users.dto.entity.ts b/src/routes/spaces/entities/invite-users.dto.entity.ts index 2ca7bebd14..f2e33be263 100644 --- a/src/routes/spaces/entities/invite-users.dto.entity.ts +++ b/src/routes/spaces/entities/invite-users.dto.entity.ts @@ -7,6 +7,7 @@ import { NAME_MAX_LENGTH, NAME_MIN_LENGTH, } from '@/domain/common/entities/name.schema'; +import type { Address } from 'viem'; const InviteUserDtoSchema = z .array( @@ -24,7 +25,7 @@ export const InviteUsersDtoSchema = z.object({ export class InviteUserDto { @ApiProperty() - public readonly address!: `0x${string}`; + public readonly address!: Address; @ApiProperty({ type: String, diff --git a/src/routes/spaces/entities/upsert-address-book-items.dto.entity.ts b/src/routes/spaces/entities/upsert-address-book-items.dto.entity.ts index a9479b93c3..3b2c6fc6a4 100644 --- a/src/routes/spaces/entities/upsert-address-book-items.dto.entity.ts +++ b/src/routes/spaces/entities/upsert-address-book-items.dto.entity.ts @@ -1,6 +1,7 @@ import { z } from 'zod'; import { AddressSchema } from '@/validation/entities/schemas/address.schema'; import { ApiExtraModels, ApiProperty, getSchemaPath } from '@nestjs/swagger'; +import type { Address } from 'viem'; const AddressBookItemSchema = z.object({ name: z.string(), @@ -13,7 +14,7 @@ class AddressBookItem implements z.infer { readonly name!: string; @ApiProperty({ type: String }) - readonly address!: `0x${string}`; + readonly address!: Address; @ApiProperty({ type: String, isArray: true }) readonly chainIds!: Array; diff --git a/src/routes/spaces/space-safes.controller.spec.ts b/src/routes/spaces/space-safes.controller.spec.ts index 1502323f89..a89580ec0b 100644 --- a/src/routes/spaces/space-safes.controller.spec.ts +++ b/src/routes/spaces/space-safes.controller.spec.ts @@ -17,7 +17,7 @@ import { checkGuardIsApplied } from '@/__tests__/util/check-guard'; import { AuthGuard } from '@/routes/auth/guards/auth.guard'; import { authPayloadDtoBuilder } from '@/domain/auth/entities/__tests__/auth-payload-dto.entity.builder'; import { faker } from '@faker-js/faker/.'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { chainBuilder } from '@/domain/chains/entities/__tests__/chain.builder'; import { nameBuilder } from '@/domain/common/entities/name.builder'; import { createTestModule } from '@/__tests__/testing-module'; @@ -424,7 +424,7 @@ describe('SpaceSafesController', () => { it('Should return a 403 if the AuthPayload is empty', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); const spaceId = faker.number.int(); @@ -853,7 +853,7 @@ describe('SpaceSafesController', () => { it('Should return a 403 if the AuthPayload is empty', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); const spaceId = faker.number.int(); @@ -1185,7 +1185,7 @@ describe('SpaceSafesController', () => { it('Should return a 403 if the AuthPayload is empty', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); const spaceId = faker.number.int(); diff --git a/src/routes/spaces/space-safes.service.ts b/src/routes/spaces/space-safes.service.ts index a37be8250e..cfb6541504 100644 --- a/src/routes/spaces/space-safes.service.ts +++ b/src/routes/spaces/space-safes.service.ts @@ -11,6 +11,7 @@ import { groupBy, mapValues } from 'lodash'; import { ISpaceSafesRepository } from '@/domain/spaces/space-safes.repository.interface'; import { IMembersRepository } from '@/domain/users/members.repository.interface'; import { In } from 'typeorm'; +import type { Address } from 'viem'; @Injectable() export class SpaceSafesService { @@ -69,7 +70,7 @@ export class SpaceSafesService { private assertSignerAddress( authPayload: AuthPayload, - ): asserts authPayload is AuthPayload & { signer_address: `0x${string}` } { + ): asserts authPayload is AuthPayload & { signer_address: Address } { if (!authPayload.signer_address) { throw new UnauthorizedException('Signer address not provided'); } @@ -77,7 +78,7 @@ export class SpaceSafesService { private async isAdmin( spaceId: Space['id'], - signerAddress: `0x${string}`, + signerAddress: Address, ): Promise { const { id: userId } = await this.userRepository.findByWalletAddressOrFail(signerAddress); @@ -104,7 +105,7 @@ export class SpaceSafesService { private async isMember( spaceId: Space['id'], - signerAddress: `0x${string}`, + signerAddress: Address, ): Promise { const { id: userId } = await this.userRepository.findByWalletAddressOrFail(signerAddress); diff --git a/src/routes/spaces/spaces.controller.spec.ts b/src/routes/spaces/spaces.controller.spec.ts index 0579ca838e..907ae0febc 100644 --- a/src/routes/spaces/spaces.controller.spec.ts +++ b/src/routes/spaces/spaces.controller.spec.ts @@ -26,6 +26,7 @@ import { UserStatus } from '@/domain/users/entities/user.entity'; import { getEnumKey } from '@/domain/common/utils/enum'; import { nameBuilder } from '@/domain/common/entities/name.builder'; import { createTestModule } from '@/__tests__/testing-module'; +import type { Address } from 'viem'; describe('SpacesController', () => { let app: INestApplication; @@ -162,7 +163,7 @@ describe('SpacesController', () => { it('Should return a 403 if the AuthPayload is empty', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); @@ -302,7 +303,7 @@ describe('SpacesController', () => { it('Should return a 403 if the AuthPayload is empty', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); @@ -445,7 +446,7 @@ describe('SpacesController', () => { it('Should return a 403 is the AuthPayload is empty', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); @@ -678,7 +679,7 @@ describe('SpacesController', () => { it('Should return a 403 is the AuthPayload is empty', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); @@ -742,7 +743,7 @@ describe('SpacesController', () => { it('Should return a 403 is the AuthPayload is empty', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); const spaceId = faker.number.int({ min: 1 }); @@ -1106,7 +1107,7 @@ describe('SpacesController', () => { it('Should return a 403 is the AuthPayload is empty', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); const spaceId = faker.number.int({ min: 1 }); diff --git a/src/routes/spaces/spaces.service.ts b/src/routes/spaces/spaces.service.ts index 542620ce9e..bf9f8fcd45 100644 --- a/src/routes/spaces/spaces.service.ts +++ b/src/routes/spaces/spaces.service.ts @@ -18,6 +18,7 @@ import { UnauthorizedException, } from '@nestjs/common'; import { In } from 'typeorm'; +import type { Address } from 'viem'; export class SpacesService { public constructor( @@ -125,7 +126,7 @@ export class SpacesService { private assertSignerAddress( authPayload: AuthPayload, - ): asserts authPayload is AuthPayload & { signer_address: `0x${string}` } { + ): asserts authPayload is AuthPayload & { signer_address: Address } { if (!authPayload.signer_address) { throw new UnauthorizedException('Signer address not provided'); } @@ -133,7 +134,7 @@ export class SpacesService { public async isAdmin( spaceId: Space['id'], - signerAddress: `0x${string}`, + signerAddress: Address, ): Promise { const { id: userId } = await this.userRepository.findByWalletAddressOrFail(signerAddress); diff --git a/src/routes/targeted-messaging/entities/submission.entity.ts b/src/routes/targeted-messaging/entities/submission.entity.ts index a0edc3c669..aa92f5018a 100644 --- a/src/routes/targeted-messaging/entities/submission.entity.ts +++ b/src/routes/targeted-messaging/entities/submission.entity.ts @@ -1,4 +1,5 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class Submission { @ApiProperty() @@ -6,14 +7,14 @@ export class Submission { @ApiProperty() targetedSafeId!: number; @ApiProperty() - signerAddress!: `0x${string}`; + signerAddress!: Address; @ApiPropertyOptional({ type: Date, nullable: true }) completionDate!: Date | null; constructor( outreachId: number, targetedSafeId: number, - signerAddress: `0x${string}`, + signerAddress: Address, completionDate: Date | null, ) { this.outreachId = outreachId; diff --git a/src/routes/targeted-messaging/targeted-messaging.controller.ts b/src/routes/targeted-messaging/targeted-messaging.controller.ts index 3a8b9e1135..6b44e8bd08 100644 --- a/src/routes/targeted-messaging/targeted-messaging.controller.ts +++ b/src/routes/targeted-messaging/targeted-messaging.controller.ts @@ -28,6 +28,7 @@ import { ApiTags, } from '@nestjs/swagger'; import { Response } from 'express'; +import type { Address } from 'viem'; @ApiTags('targeted-messaging') @Controller({ @@ -49,7 +50,7 @@ export class TargetedMessagingController { outreachId: number, @Param('chainId', new ValidationPipe(NumericStringSchema)) chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { return this.service.getTargetedSafe({ outreachId, chainId, safeAddress }); } @@ -64,9 +65,9 @@ export class TargetedMessagingController { outreachId: number, @Param('chainId', new ValidationPipe(NumericStringSchema)) chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Param('signerAddress', new ValidationPipe(AddressSchema)) - signerAddress: `0x${string}`, + signerAddress: Address, ): Promise { try { const submission = await this.service.getSubmission({ @@ -99,9 +100,9 @@ export class TargetedMessagingController { outreachId: number, @Param('chainId', new ValidationPipe(NumericStringSchema)) chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Param('signerAddress', new ValidationPipe(AddressSchema)) - signerAddress: `0x${string}`, + signerAddress: Address, @Body(new ValidationPipe(CreateSubmissionDtoSchema)) createSubmissionDto: CreateSubmissionDto, ): Promise { diff --git a/src/routes/targeted-messaging/targeted-messaging.service.ts b/src/routes/targeted-messaging/targeted-messaging.service.ts index 26af886d71..0072451d02 100644 --- a/src/routes/targeted-messaging/targeted-messaging.service.ts +++ b/src/routes/targeted-messaging/targeted-messaging.service.ts @@ -5,6 +5,7 @@ import { CreateSubmissionDto } from '@/routes/targeted-messaging/entities/create import { Submission } from '@/routes/targeted-messaging/entities/submission.entity'; import { TargetedSafe as RouteTargetedSafe } from '@/routes/targeted-messaging/entities/targeted-safe.entity'; import { BadRequestException, Inject, Injectable } from '@nestjs/common'; +import type { Address } from 'viem'; @Injectable() export class TargetedMessagingService { @@ -16,7 +17,7 @@ export class TargetedMessagingService { async getTargetedSafe(args: { outreachId: TargetedSafe['outreachId']; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const targetedSafe = await this.repository.getTargetedSafe(args); return { @@ -28,8 +29,8 @@ export class TargetedMessagingService { async getSubmission(args: { outreachId: number; chainId: string; - safeAddress: `0x${string}`; - signerAddress: `0x${string}`; + safeAddress: Address; + signerAddress: Address; }): Promise { const targetedSafe = await this.repository.getTargetedSafe(args); try { @@ -60,7 +61,7 @@ export class TargetedMessagingService { private async getOrAddSafeToOutreach(args: { outreachId: number; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { try { return await this.repository.getTargetedSafe(args); @@ -84,8 +85,8 @@ export class TargetedMessagingService { async createSubmission(args: { outreachId: number; chainId: string; - safeAddress: `0x${string}`; - signerAddress: `0x${string}`; + safeAddress: Address; + signerAddress: Address; createSubmissionDto: CreateSubmissionDto; }): Promise { const targetedSafe = await this.getOrAddSafeToOutreach(args); diff --git a/src/routes/transactions/__tests__/controllers/add-transaction-confirmations.transactions.controller.spec.ts b/src/routes/transactions/__tests__/controllers/add-transaction-confirmations.transactions.controller.spec.ts index 838bec8d26..d6b399f255 100644 --- a/src/routes/transactions/__tests__/controllers/add-transaction-confirmations.transactions.controller.spec.ts +++ b/src/routes/transactions/__tests__/controllers/add-transaction-confirmations.transactions.controller.spec.ts @@ -35,7 +35,7 @@ import { type ILoggingService, LoggingService, } from '@/logging/logging.interface'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { dataDecodedBuilder } from '@/domain/data-decoder/v2/entities/__tests__/data-decoded.builder'; import { contractBuilder } from '@/domain/data-decoder/v2/entities/__tests__/contract.builder'; @@ -420,7 +420,7 @@ describe('Add transaction confirmations - Transactions Controller (Unit)', () => }); transaction.data = faker.string.hexadecimal({ length: 64, - }) as `0x${string}`; + }) as Address; await request(app.getHttpServer()) .post( @@ -473,7 +473,7 @@ describe('Add transaction confirmations - Transactions Controller (Unit)', () => }), ) as MultisigTransaction; transaction.confirmations![0].signature = - transaction.confirmations![0].signature!.slice(0, 129) as `0x${string}`; + transaction.confirmations![0].signature!.slice(0, 129) as Address; const addConfirmationDto = addConfirmationDtoBuilder() .with('signature', transaction.confirmations![0].signature) .build(); @@ -511,7 +511,7 @@ describe('Add transaction confirmations - Transactions Controller (Unit)', () => }), ) as MultisigTransaction; transaction.confirmations![0].signature = - transaction.confirmations![0].signature!.slice(0, 128) as `0x${string}`; + transaction.confirmations![0].signature!.slice(0, 128) as Address; const addConfirmationDto = addConfirmationDtoBuilder() .with('signature', transaction.confirmations![0].signature) .build(); diff --git a/src/routes/transactions/__tests__/controllers/get-transaction-by-id.transactions.controller.spec.ts b/src/routes/transactions/__tests__/controllers/get-transaction-by-id.transactions.controller.spec.ts index 7dfa0f5ce2..af673a539d 100644 --- a/src/routes/transactions/__tests__/controllers/get-transaction-by-id.transactions.controller.spec.ts +++ b/src/routes/transactions/__tests__/controllers/get-transaction-by-id.transactions.controller.spec.ts @@ -26,6 +26,7 @@ import { IConfigurationService } from '@/config/configuration.service.interface' import type { INetworkService } from '@/datasources/network/network.service.interface'; import { NetworkService } from '@/datasources/network/network.service.interface'; import { NetworkResponseError } from '@/datasources/network/entities/network.error.entity'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; import type { Server } from 'net'; import { rawify } from '@/validation/entities/raw.entity'; @@ -445,7 +446,7 @@ describe('Get by id - Transactions Controller (Unit)', () => { const tx = await multisigTransactionBuilder() .with('safe', safe.address) .with('operation', 0) - .with('data', faker.string.hexadecimal({ length: 32 }) as `0x${string}`) + .with('data', faker.string.hexadecimal({ length: 32 }) as Address) .with('isExecuted', true) .with('isSuccessful', true) .with('executionDate', executionDate) @@ -639,7 +640,7 @@ describe('Get by id - Transactions Controller (Unit)', () => { const tx = await multisigTransactionBuilder() .with('safe', safe.address) .with('operation', 0) - .with('data', faker.string.hexadecimal({ length: 32 }) as `0x${string}`) + .with('data', faker.string.hexadecimal({ length: 32 }) as Address) .with('isExecuted', true) .with('isSuccessful', true) .with('executionDate', executionDate) @@ -834,7 +835,7 @@ describe('Get by id - Transactions Controller (Unit)', () => { .with('safe', safe.address) .with('operation', 0) .with('nonce', 4) - .with('data', faker.string.hexadecimal({ length: 32 }) as `0x${string}`) + .with('data', faker.string.hexadecimal({ length: 32 }) as Address) .with('isExecuted', false) .with('isSuccessful', null) .with('executionDate', executionDate) @@ -1147,7 +1148,7 @@ describe('Get by id - Transactions Controller (Unit)', () => { }); multisigTransaction.data = faker.string.hexadecimal({ length: 64, - }) as `0x${string}`; + }) as Address; const getSafeUrl = `${chain.transactionService}/api/v1/safes/${safe.address}`; const getChainUrl = `${safeConfigUrl}/api/v1/chains/${chain.chainId}`; const getMultisigTransactionUrl = `${chain.transactionService}/api/v1/multisig-transactions/${multisigTransaction.safeTxHash}/`; diff --git a/src/routes/transactions/__tests__/controllers/list-multisig-transactions-by-safe.transactions.controller.spec.ts b/src/routes/transactions/__tests__/controllers/list-multisig-transactions-by-safe.transactions.controller.spec.ts index 8baf1d0c55..775e54b1fe 100644 --- a/src/routes/transactions/__tests__/controllers/list-multisig-transactions-by-safe.transactions.controller.spec.ts +++ b/src/routes/transactions/__tests__/controllers/list-multisig-transactions-by-safe.transactions.controller.spec.ts @@ -25,7 +25,7 @@ import { import type { INetworkService } from '@/datasources/network/network.service.interface'; import { NetworkService } from '@/datasources/network/network.service.interface'; import { NetworkResponseError } from '@/datasources/network/entities/network.error.entity'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import type { Server } from 'net'; import { rawify } from '@/validation/entities/raw.entity'; import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'; @@ -458,7 +458,7 @@ describe('List multisig transactions by Safe - Transactions Controller (Unit)', const domainTransaction = await multisigTransactionBuilder() .with('safe', safe.address) .with('value', '0') - .with('data', faker.string.hexadecimal({ length: 32 }) as `0x${string}`) + .with('data', faker.string.hexadecimal({ length: 32 }) as Address) .with('isExecuted', true) .with('isSuccessful', true) .with('confirmationsRequired', 3) diff --git a/src/routes/transactions/__tests__/controllers/list-queued-transactions-by-safe.transactions.controller.spec.ts b/src/routes/transactions/__tests__/controllers/list-queued-transactions-by-safe.transactions.controller.spec.ts index 88295b030f..8f162f8867 100644 --- a/src/routes/transactions/__tests__/controllers/list-queued-transactions-by-safe.transactions.controller.spec.ts +++ b/src/routes/transactions/__tests__/controllers/list-queued-transactions-by-safe.transactions.controller.spec.ts @@ -27,7 +27,7 @@ import { faker } from '@faker-js/faker'; import type { INestApplication } from '@nestjs/common'; import type { Server } from 'net'; import request from 'supertest'; -import { getAddress } from 'viem'; +import { getAddress, type Hash } from 'viem'; import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'; describe('List queued transactions by Safe - Transactions Controller (Unit)', () => { @@ -706,7 +706,7 @@ describe('List queued transactions by Safe - Transactions Controller (Unit)', () }; const nonce1 = await getTransaction(1); const nonce2 = await getTransaction(2); - nonce1.data = faker.string.hexadecimal({ length: 64 }) as `0x${string}`; + nonce1.data = faker.string.hexadecimal({ length: 64 }) as Hash; const transactions: Array = [ multisigToJson(nonce1) as MultisigTransaction, multisigToJson(nonce2) as MultisigTransaction, diff --git a/src/routes/transactions/__tests__/controllers/preview-transaction-kiln.transactions.controller.spec.ts b/src/routes/transactions/__tests__/controllers/preview-transaction-kiln.transactions.controller.spec.ts index db95d45c8a..26ff939e5f 100644 --- a/src/routes/transactions/__tests__/controllers/preview-transaction-kiln.transactions.controller.spec.ts +++ b/src/routes/transactions/__tests__/controllers/preview-transaction-kiln.transactions.controller.spec.ts @@ -37,6 +37,7 @@ import { import { rawify } from '@/validation/entities/raw.entity'; import { createTestModule } from '@/__tests__/testing-module'; import { rewardsFeeBuilder } from '@/datasources/staking-api/entities/__tests__/rewards-fee.entity.builder'; +import type { Address } from 'viem'; describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { let app: INestApplication; @@ -930,7 +931,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = requestValidatorsExitEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -1057,7 +1058,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = requestValidatorsExitEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -1214,7 +1215,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = requestValidatorsExitEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -1287,7 +1288,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = requestValidatorsExitEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -1371,7 +1372,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = requestValidatorsExitEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -1457,7 +1458,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = requestValidatorsExitEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -1546,7 +1547,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = requestValidatorsExitEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -1645,7 +1646,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = requestValidatorsExitEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -1745,7 +1746,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = batchWithdrawCLFeeEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -1871,7 +1872,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = batchWithdrawCLFeeEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -2028,7 +2029,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = batchWithdrawCLFeeEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -2110,7 +2111,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = batchWithdrawCLFeeEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -2200,7 +2201,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = batchWithdrawCLFeeEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -2289,7 +2290,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = batchWithdrawCLFeeEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -2377,7 +2378,7 @@ describe('Preview transaction - Kiln - Transactions Controller (Unit)', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = batchWithdrawCLFeeEncoder() .with('_publicKeys', concat(validators)) .encode(); diff --git a/src/routes/transactions/__tests__/controllers/propose-transaction.transactions.controller.spec.ts b/src/routes/transactions/__tests__/controllers/propose-transaction.transactions.controller.spec.ts index dbbc0ef9ba..82bc0c7e90 100644 --- a/src/routes/transactions/__tests__/controllers/propose-transaction.transactions.controller.spec.ts +++ b/src/routes/transactions/__tests__/controllers/propose-transaction.transactions.controller.spec.ts @@ -16,7 +16,7 @@ import { tokenBuilder } from '@/domain/tokens/__tests__/token.builder'; import type { INetworkService } from '@/datasources/network/network.service.interface'; import { NetworkService } from '@/datasources/network/network.service.interface'; import { proposeTransactionDtoBuilder } from '@/routes/transactions/entities/__tests__/propose-transaction.dto.builder'; -import { concat, getAddress } from 'viem'; +import { type Address, concat, getAddress } from 'viem'; import type { Server } from 'net'; import { rawify } from '@/validation/entities/raw.entity'; import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'; @@ -1037,7 +1037,7 @@ describe('Propose transaction - Transactions Controller (Unit)', () => { }); transaction.data = faker.string.hexadecimal({ length: 64, - }) as `0x${string}`; + }) as Address; const proposeTransactionDto = proposeTransactionDtoBuilder() .with('to', transaction.to) .with('value', transaction.value) @@ -1120,7 +1120,7 @@ describe('Propose transaction - Transactions Controller (Unit)', () => { signers: [signer], }); transaction.confirmations![0].signature = - transaction.confirmations![0].signature!.slice(0, 129) as `0x${string}`; + transaction.confirmations![0].signature!.slice(0, 129) as Address; const proposeTransactionDto = proposeTransactionDtoBuilder() .with('to', transaction.to) .with('value', transaction.value) @@ -1168,7 +1168,7 @@ describe('Propose transaction - Transactions Controller (Unit)', () => { signers: [signer], }); transaction.confirmations![0].signature = - transaction.confirmations![0].signature!.slice(0, 128) as `0x${string}`; + transaction.confirmations![0].signature!.slice(0, 128) as Address; const proposeTransactionDto = proposeTransactionDtoBuilder() .with('to', transaction.to) .with('value', transaction.value) diff --git a/src/routes/transactions/__tests__/encoders/erc4262-encoder.builder.ts b/src/routes/transactions/__tests__/encoders/erc4262-encoder.builder.ts index e0bd7add4b..c2f1c32860 100644 --- a/src/routes/transactions/__tests__/encoders/erc4262-encoder.builder.ts +++ b/src/routes/transactions/__tests__/encoders/erc4262-encoder.builder.ts @@ -1,5 +1,5 @@ import { faker } from '@faker-js/faker'; -import { encodeFunctionData, erc4626Abi, getAddress } from 'viem'; +import { type Address, encodeFunctionData, erc4626Abi, getAddress } from 'viem'; import { Builder } from '@/__tests__/builder'; import type { IEncoder } from '@/__tests__/encoder-builder'; @@ -7,14 +7,14 @@ import type { IEncoder } from '@/__tests__/encoder-builder'; type Erc4262DepositArgs = { assets: bigint; - receiver: `0x${string}`; + receiver: Address; }; class Erc4262DepositEncoder extends Builder implements IEncoder { - encode(): `0x${string}` { + encode(): Address { const args = this.build(); return encodeFunctionData({ @@ -35,15 +35,15 @@ export function erc4262DepositEncoder(): Erc4262DepositEncoder extends Builder implements IEncoder { - encode(): `0x${string}` { + encode(): Address { const args = this.build(); return encodeFunctionData({ diff --git a/src/routes/transactions/__tests__/entities/add-confirmation.dto.builder.ts b/src/routes/transactions/__tests__/entities/add-confirmation.dto.builder.ts index d435ee5dde..895a64f633 100644 --- a/src/routes/transactions/__tests__/entities/add-confirmation.dto.builder.ts +++ b/src/routes/transactions/__tests__/entities/add-confirmation.dto.builder.ts @@ -2,10 +2,11 @@ import { faker } from '@faker-js/faker'; import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { AddConfirmationDto } from '@/routes/transactions/entities/add-confirmation.dto'; +import type { Hex } from 'viem'; export function addConfirmationDtoBuilder(): IBuilder { return new Builder().with( 'signature', - faker.string.hexadecimal({ length: 130 }) as `0x${string}`, + faker.string.hexadecimal({ length: 130 }) as Hex, ); } diff --git a/src/routes/transactions/decoders/erc4262-decoder.helper.spec.ts b/src/routes/transactions/decoders/erc4262-decoder.helper.spec.ts index a0c1db4b0a..d4a96df617 100644 --- a/src/routes/transactions/decoders/erc4262-decoder.helper.spec.ts +++ b/src/routes/transactions/decoders/erc4262-decoder.helper.spec.ts @@ -4,6 +4,7 @@ import { erc4262DepositEncoder, erc4262WithdrawEncoder, } from '@/routes/transactions/__tests__/encoders/erc4262-encoder.builder'; +import type { Hex } from 'viem'; describe('ERC4262Decoder', () => { let target: Erc4262Decoder; @@ -35,7 +36,7 @@ describe('ERC4262Decoder', () => { }); it('throws if the function call cannot be decoded', () => { - const data = faker.string.hexadecimal({ length: 138 }) as `0x${string}`; + const data = faker.string.hexadecimal({ length: 138 }) as Hex; expect(() => target.decodeFunctionData({ data })).toThrow(); }); diff --git a/src/routes/transactions/entities/__tests__/preview-transaction.dto.builder.ts b/src/routes/transactions/entities/__tests__/preview-transaction.dto.builder.ts index 0add3ec945..2cf4a6ca85 100644 --- a/src/routes/transactions/entities/__tests__/preview-transaction.dto.builder.ts +++ b/src/routes/transactions/entities/__tests__/preview-transaction.dto.builder.ts @@ -2,12 +2,12 @@ import { faker } from '@faker-js/faker'; import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { PreviewTransactionDto } from '@/routes/transactions/entities/preview-transaction.dto.entity'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; export function previewTransactionDtoBuilder(): IBuilder { return new Builder() .with('to', getAddress(faker.finance.ethereumAddress())) - .with('data', faker.string.hexadecimal({ length: 32 }) as `0x${string}`) + .with('data', faker.string.hexadecimal({ length: 32 }) as Address) .with('value', faker.string.numeric()) .with('operation', faker.helpers.arrayElement([0, 1])); } diff --git a/src/routes/transactions/entities/__tests__/propose-transaction.dto.builder.ts b/src/routes/transactions/entities/__tests__/propose-transaction.dto.builder.ts index ec0104123a..b3fafa4d90 100644 --- a/src/routes/transactions/entities/__tests__/propose-transaction.dto.builder.ts +++ b/src/routes/transactions/entities/__tests__/propose-transaction.dto.builder.ts @@ -3,13 +3,13 @@ import type { Operation } from '@/domain/safe/entities/operation.entity'; import type { IBuilder } from '@/__tests__/builder'; import { Builder } from '@/__tests__/builder'; import type { ProposeTransactionDto } from '@/routes/transactions/entities/propose-transaction.dto.entity'; -import { getAddress } from 'viem'; +import { type Hash, type Hex, getAddress } from 'viem'; export function proposeTransactionDtoBuilder(): IBuilder { return new Builder() .with('to', getAddress(faker.finance.ethereumAddress())) .with('value', faker.string.numeric()) - .with('data', faker.string.hexadecimal({ length: 32 }) as `0x${string}`) + .with('data', faker.string.hexadecimal({ length: 32 }) as Hex) .with('nonce', faker.string.numeric()) .with('operation', faker.helpers.arrayElement([0, 1]) as Operation) .with('safeTxGas', faker.string.numeric()) @@ -17,14 +17,8 @@ export function proposeTransactionDtoBuilder(): IBuilder .with('gasPrice', faker.string.numeric()) .with('gasToken', getAddress(faker.finance.ethereumAddress())) .with('refundReceiver', getAddress(faker.finance.ethereumAddress())) - .with( - 'safeTxHash', - faker.string.hexadecimal({ length: 32 }) as `0x${string}`, - ) + .with('safeTxHash', faker.string.hexadecimal({ length: 32 }) as Hash) .with('sender', getAddress(faker.finance.ethereumAddress())) - .with( - 'signature', - faker.string.hexadecimal({ length: 130 }) as `0x${string}`, - ) + .with('signature', faker.string.hexadecimal({ length: 130 }) as Hex) .with('origin', faker.word.sample()); } diff --git a/src/routes/transactions/entities/add-confirmation.dto.ts b/src/routes/transactions/entities/add-confirmation.dto.ts index 887e6ab960..d988fe67af 100644 --- a/src/routes/transactions/entities/add-confirmation.dto.ts +++ b/src/routes/transactions/entities/add-confirmation.dto.ts @@ -1,7 +1,8 @@ import { ApiProperty } from '@nestjs/swagger'; import { AddConfirmationDto as DomainCreateConfirmationDto } from '@/domain/transactions/entities/add-confirmation.dto.entity'; +import type { Address } from 'viem'; export class AddConfirmationDto implements DomainCreateConfirmationDto { @ApiProperty() - signature!: `0x${string}`; + signature!: Address; } diff --git a/src/routes/transactions/entities/bridge/bridge-info.entity.ts b/src/routes/transactions/entities/bridge/bridge-info.entity.ts index 796554c6ab..8cce12b6a6 100644 --- a/src/routes/transactions/entities/bridge/bridge-info.entity.ts +++ b/src/routes/transactions/entities/bridge/bridge-info.entity.ts @@ -13,6 +13,7 @@ import { TransactionInfoType, } from '@/routes/transactions/entities/transaction-info.entity'; import { ApiExtraModels, ApiProperty } from '@nestjs/swagger'; +import type { Address } from 'viem'; @ApiExtraModels(BridgeFee) export class SwapTransactionInfo extends TransactionInfo { @@ -112,7 +113,7 @@ export class BridgeAndSwapTransactionInfo extends TransactionInfo { status: BridgeStatus['status'] | 'AWAITING_EXECUTION'; substatus: BridgeStatus['substatus'] | 'AWAITING_EXECUTION'; fees: { - tokenAddress: `0x${string}`; + tokenAddress: Address; integratorFee: string; lifiFee: string; } | null; diff --git a/src/routes/transactions/entities/bridge/fees.entity.ts b/src/routes/transactions/entities/bridge/fees.entity.ts index 58136fb8bf..d54917736b 100644 --- a/src/routes/transactions/entities/bridge/fees.entity.ts +++ b/src/routes/transactions/entities/bridge/fees.entity.ts @@ -1,8 +1,9 @@ import { ApiProperty } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class BridgeFee { @ApiProperty() - readonly tokenAddress: `0x${string}`; + readonly tokenAddress: Address; @ApiProperty() readonly integratorFee: string; @@ -11,7 +12,7 @@ export class BridgeFee { readonly lifiFee: string; constructor(args: { - tokenAddress: `0x${string}`; + tokenAddress: Address; integratorFee: string; lifiFee: string; }) { diff --git a/src/routes/transactions/entities/creation-transaction.entity.ts b/src/routes/transactions/entities/creation-transaction.entity.ts index a0d019b515..65d65627ad 100644 --- a/src/routes/transactions/entities/creation-transaction.entity.ts +++ b/src/routes/transactions/entities/creation-transaction.entity.ts @@ -1,20 +1,21 @@ import { CreationTransaction as DomainCreationTransaction } from '@/domain/safe/entities/creation-transaction.entity'; import { DataDecoded } from '@/routes/data-decode/entities/data-decoded.entity'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import type { Address, Hash } from 'viem'; export class CreationTransaction implements DomainCreationTransaction { @ApiProperty() created: Date; @ApiProperty() - creator: `0x${string}`; + creator: Address; @ApiProperty() - transactionHash: `0x${string}`; + transactionHash: Hash; @ApiProperty() - factoryAddress: `0x${string}`; + factoryAddress: Address; @ApiPropertyOptional({ type: String, nullable: true }) - masterCopy: `0x${string}` | null; + masterCopy: Address | null; @ApiPropertyOptional({ type: String, nullable: true }) - setupData: `0x${string}` | null; + setupData: Address | null; @ApiPropertyOptional({ type: String, nullable: true }) saltNonce: string | null; @ApiPropertyOptional({ type: DataDecoded, nullable: true }) @@ -22,11 +23,11 @@ export class CreationTransaction implements DomainCreationTransaction { constructor( created: Date, - creator: `0x${string}`, - transactionHash: `0x${string}`, - factoryAddress: `0x${string}`, - masterCopy: `0x${string}` | null, - setupData: `0x${string}` | null, + creator: Address, + transactionHash: Hash, + factoryAddress: Address, + masterCopy: Address | null, + setupData: Address | null, saltNonce: string | null, dataDecoded: DataDecoded | null, ) { diff --git a/src/routes/transactions/entities/human-description.entity.ts b/src/routes/transactions/entities/human-description.entity.ts index 6852eef200..dff2c8e3e4 100644 --- a/src/routes/transactions/entities/human-description.entity.ts +++ b/src/routes/transactions/entities/human-description.entity.ts @@ -4,6 +4,7 @@ import { ApiPropertyOptional, getSchemaPath, } from '@nestjs/swagger'; +import type { Address } from 'viem'; export enum RichFragmentType { Text = 'text', @@ -44,7 +45,7 @@ export class RichTextFragment extends RichDecodedInfoFragment { } export class RichAddressFragment extends RichDecodedInfoFragment { - constructor(value: `0x${string}`) { + constructor(value: Address) { super(RichFragmentType.Address, value); } } diff --git a/src/routes/transactions/entities/preview-transaction.dto.entity.ts b/src/routes/transactions/entities/preview-transaction.dto.entity.ts index 7d3ba592b8..4895e05209 100644 --- a/src/routes/transactions/entities/preview-transaction.dto.entity.ts +++ b/src/routes/transactions/entities/preview-transaction.dto.entity.ts @@ -2,14 +2,15 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Operation } from '@/domain/safe/entities/operation.entity'; import { z } from 'zod'; import { PreviewTransactionDtoSchema } from '@/routes/transactions/entities/schemas/preview-transaction.dto.schema'; +import type { Address, Hex } from 'viem'; export class PreviewTransactionDto implements z.infer { @ApiProperty() - to!: `0x${string}`; + to!: Address; @ApiPropertyOptional({ type: String, nullable: true }) - data!: `0x${string}` | null; + data!: Hex | null; @ApiProperty() value!: string; @ApiProperty() diff --git a/src/routes/transactions/entities/propose-transaction.dto.entity.ts b/src/routes/transactions/entities/propose-transaction.dto.entity.ts index 3ddf367959..4b28691823 100644 --- a/src/routes/transactions/entities/propose-transaction.dto.entity.ts +++ b/src/routes/transactions/entities/propose-transaction.dto.entity.ts @@ -1,14 +1,15 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { Operation } from '@/domain/safe/entities/operation.entity'; import { ProposeTransactionDto as DomainProposeTransactionDto } from '@/domain/transactions/entities/propose-transaction.dto.entity'; +import type { Address, Hash, Hex } from 'viem'; export class ProposeTransactionDto implements DomainProposeTransactionDto { @ApiProperty() - to!: `0x${string}`; + to!: Address; @ApiProperty() value!: string; @ApiPropertyOptional({ type: String, nullable: true }) - data!: `0x${string}` | null; + data!: Hex | null; @ApiProperty() nonce!: string; @ApiProperty() @@ -20,15 +21,15 @@ export class ProposeTransactionDto implements DomainProposeTransactionDto { @ApiProperty() gasPrice!: string; @ApiProperty() - gasToken!: `0x${string}`; + gasToken!: Address; @ApiPropertyOptional({ type: String, nullable: true }) - refundReceiver!: `0x${string}` | null; + refundReceiver!: Address | null; @ApiProperty() - safeTxHash!: `0x${string}`; + safeTxHash!: Hash; @ApiProperty() - sender!: `0x${string}`; + sender!: Address; @ApiPropertyOptional({ type: String, nullable: true }) - signature!: `0x${string}` | null; + signature!: Hex | null; @ApiPropertyOptional({ type: String, nullable: true }) origin!: string | null; } diff --git a/src/routes/transactions/entities/schemas/__tests__/add-confirmation.dto.schema.spec.ts b/src/routes/transactions/entities/schemas/__tests__/add-confirmation.dto.schema.spec.ts index f487bf93b6..c865f836d5 100644 --- a/src/routes/transactions/entities/schemas/__tests__/add-confirmation.dto.schema.spec.ts +++ b/src/routes/transactions/entities/schemas/__tests__/add-confirmation.dto.schema.spec.ts @@ -1,12 +1,13 @@ import { AddConfirmationDtoSchema } from '@/routes/transactions/entities/schemas/add-confirmation.dto.schema'; import { faker } from '@faker-js/faker'; import { ZodError } from 'zod'; +import type { Address } from 'viem'; describe('AddConfirmationDtoSchema', () => { it('should validate a signature', () => { const signature = faker.string.hexadecimal({ length: 130, - }) as `0x${string}`; + }) as Address; const result = AddConfirmationDtoSchema.safeParse({ signature }); expect(result.success).toBe(true); @@ -17,7 +18,7 @@ describe('AddConfirmationDtoSchema', () => { it('supports the signedSafeTxHash property', () => { const signedSafeTxHash = faker.string.hexadecimal({ length: 130, - }) as `0x${string}`; + }) as Address; const result = AddConfirmationDtoSchema.safeParse({ signedSafeTxHash }); diff --git a/src/routes/transactions/entities/schemas/__tests__/preview-transaction.dto.schema.spec.ts b/src/routes/transactions/entities/schemas/__tests__/preview-transaction.dto.schema.spec.ts index 266655a074..311e600db8 100644 --- a/src/routes/transactions/entities/schemas/__tests__/preview-transaction.dto.schema.spec.ts +++ b/src/routes/transactions/entities/schemas/__tests__/preview-transaction.dto.schema.spec.ts @@ -1,7 +1,7 @@ import { previewTransactionDtoBuilder } from '@/routes/transactions/entities/__tests__/preview-transaction.dto.builder'; import { PreviewTransactionDtoSchema } from '@/routes/transactions/entities/schemas/preview-transaction.dto.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { ZodError } from 'zod'; describe('PreviewTransactionDtoSchema', () => { @@ -16,7 +16,7 @@ describe('PreviewTransactionDtoSchema', () => { it('should checksum the address', () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const previewTransactionDto = previewTransactionDtoBuilder() .with('to', nonChecksummedAddress) .build(); diff --git a/src/routes/transactions/entities/schemas/__tests__/propose-transaction.dto.schema.spec.ts b/src/routes/transactions/entities/schemas/__tests__/propose-transaction.dto.schema.spec.ts index 64664dafb2..d4202b1bf2 100644 --- a/src/routes/transactions/entities/schemas/__tests__/propose-transaction.dto.schema.spec.ts +++ b/src/routes/transactions/entities/schemas/__tests__/propose-transaction.dto.schema.spec.ts @@ -2,7 +2,7 @@ import type { Operation } from '@/domain/safe/entities/operation.entity'; import { proposeTransactionDtoBuilder } from '@/routes/transactions/entities/__tests__/propose-transaction.dto.builder'; import { ProposeTransactionDtoSchema } from '@/routes/transactions/entities/schemas/propose-transaction.dto.schema'; import { faker } from '@faker-js/faker'; -import { getAddress } from 'viem'; +import { type Address, getAddress, type Hash, type Hex } from 'viem'; import { ZodError } from 'zod'; describe('ProposeTransactionDtoSchema', () => { @@ -17,7 +17,7 @@ describe('ProposeTransactionDtoSchema', () => { ['to' as const, 'gasToken' as const, 'sender' as const].forEach((field) => { it(`should not allow non-address ${field}`, () => { const proposeTransactionDto = proposeTransactionDtoBuilder() - .with(field, faker.string.alphanumeric() as `0x${string}`) + .with(field, faker.string.alphanumeric() as Address) .build(); const result = ProposeTransactionDtoSchema.safeParse( @@ -38,7 +38,7 @@ describe('ProposeTransactionDtoSchema', () => { it(`should checksum ${field}`, () => { const nonChecksummedAddress = faker.finance .ethereumAddress() - .toLowerCase() as `0x${string}`; + .toLowerCase() as Address; const proposeTransactionDto = proposeTransactionDtoBuilder() .with(field, nonChecksummedAddress) .build(); @@ -95,7 +95,7 @@ describe('ProposeTransactionDtoSchema', () => { it('should validate if safeTxHash is hex', () => { const proposeTransactionDto = proposeTransactionDtoBuilder() - .with('safeTxHash', faker.string.hexadecimal() as `0x${string}`) + .with('safeTxHash', faker.string.hexadecimal() as Hash) .build(); const result = ProposeTransactionDtoSchema.safeParse(proposeTransactionDto); @@ -105,7 +105,7 @@ describe('ProposeTransactionDtoSchema', () => { it('should not allow non-hex safeTxHash', () => { const proposeTransactionDto = proposeTransactionDtoBuilder() - .with('safeTxHash', faker.string.alphanumeric() as `0x${string}`) + .with('safeTxHash', faker.string.alphanumeric() as Hash) .build(); const result = ProposeTransactionDtoSchema.safeParse(proposeTransactionDto); @@ -123,10 +123,7 @@ describe('ProposeTransactionDtoSchema', () => { it('should validate if signature is hex', () => { const proposeTransactionDto = proposeTransactionDtoBuilder() - .with( - 'signature', - faker.string.hexadecimal({ length: 130 }) as `0x${string}`, - ) + .with('signature', faker.string.hexadecimal({ length: 130 }) as Hex) .build(); const result = ProposeTransactionDtoSchema.safeParse(proposeTransactionDto); @@ -136,7 +133,7 @@ describe('ProposeTransactionDtoSchema', () => { it('should not allow non-hex signature', () => { const proposeTransactionDto = proposeTransactionDtoBuilder() - .with('signature', faker.string.alphanumeric() as `0x${string}`) + .with('signature', faker.string.alphanumeric() as Address) .build(); const result = ProposeTransactionDtoSchema.safeParse(proposeTransactionDto); diff --git a/src/routes/transactions/entities/staking/native-staking-deposit-info.entity.ts b/src/routes/transactions/entities/staking/native-staking-deposit-info.entity.ts index 86e6e0e6f2..c4834035e3 100644 --- a/src/routes/transactions/entities/staking/native-staking-deposit-info.entity.ts +++ b/src/routes/transactions/entities/staking/native-staking-deposit-info.entity.ts @@ -9,6 +9,7 @@ import { TransactionInfoType, } from '@/routes/transactions/entities/transaction-info.entity'; import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import type { Address } from 'viem'; export type NativeStakingDepositInfo = StakingTimeInfo & StakingFinancialInfo; @@ -67,7 +68,7 @@ export class NativeStakingDepositTransactionInfo nullable: true, description: 'Populated after transaction has been executed', }) - validators: Array<`0x${string}`> | null; + validators: Array
| null; constructor(args: { status: StakingStatus; @@ -84,7 +85,7 @@ export class NativeStakingDepositTransactionInfo expectedFiatAnnualReward: number; expectedFiatMonthlyReward: number; tokenInfo: TokenInfo; - validators: Array<`0x${string}`> | null; + validators: Array
| null; }) { super(TransactionInfoType.NativeStakingDeposit, null); this.status = args.status; diff --git a/src/routes/transactions/entities/staking/native-staking-validators-exit-info.entity.ts b/src/routes/transactions/entities/staking/native-staking-validators-exit-info.entity.ts index 557e062dd5..720296cd92 100644 --- a/src/routes/transactions/entities/staking/native-staking-validators-exit-info.entity.ts +++ b/src/routes/transactions/entities/staking/native-staking-validators-exit-info.entity.ts @@ -5,6 +5,7 @@ import { TransactionInfoType, } from '@/routes/transactions/entities/transaction-info.entity'; import { ApiProperty } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class NativeStakingValidatorsExitTransactionInfo extends TransactionInfo { @ApiProperty({ enum: [TransactionInfoType.NativeStakingValidatorsExit] }) @@ -29,7 +30,7 @@ export class NativeStakingValidatorsExitTransactionInfo extends TransactionInfo tokenInfo: TokenInfo; @ApiProperty() - validators: Array<`0x${string}`>; + validators: Array
; constructor(args: { status: StakingStatus; @@ -38,7 +39,7 @@ export class NativeStakingValidatorsExitTransactionInfo extends TransactionInfo value: string; numValidators: number; tokenInfo: TokenInfo; - validators: Array<`0x${string}`>; + validators: Array
; }) { super(TransactionInfoType.NativeStakingValidatorsExit, null); this.status = args.status; diff --git a/src/routes/transactions/entities/staking/native-staking-withdraw-info.entity.ts b/src/routes/transactions/entities/staking/native-staking-withdraw-info.entity.ts index 1d1760a4bd..e2a62b4de9 100644 --- a/src/routes/transactions/entities/staking/native-staking-withdraw-info.entity.ts +++ b/src/routes/transactions/entities/staking/native-staking-withdraw-info.entity.ts @@ -4,6 +4,7 @@ import { TransactionInfoType, } from '@/routes/transactions/entities/transaction-info.entity'; import { ApiProperty } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class NativeStakingWithdrawTransactionInfo extends TransactionInfo { @ApiProperty({ enum: [TransactionInfoType.NativeStakingWithdraw] }) @@ -16,12 +17,12 @@ export class NativeStakingWithdrawTransactionInfo extends TransactionInfo { tokenInfo: TokenInfo; @ApiProperty() - validators: Array<`0x${string}`>; + validators: Array
; constructor(args: { value: string; tokenInfo: TokenInfo; - validators: Array<`0x${string}`>; + validators: Array
; }) { super(TransactionInfoType.NativeStakingWithdraw, null); this.value = args.value; diff --git a/src/routes/transactions/entities/swaps/swap-order-info.entity.ts b/src/routes/transactions/entities/swaps/swap-order-info.entity.ts index 21803c4793..ed2654182e 100644 --- a/src/routes/transactions/entities/swaps/swap-order-info.entity.ts +++ b/src/routes/transactions/entities/swaps/swap-order-info.entity.ts @@ -13,6 +13,7 @@ import { OrderStatus, } from '@/domain/swaps/entities/order.entity'; import { TokenInfo } from '@/routes/transactions/entities/swaps/token-info.entity'; +import type { Address } from 'viem'; export interface OrderInfo { uid: string; @@ -28,7 +29,7 @@ export interface OrderInfo { executedFee: string; executedFeeToken: TokenInfo; receiver: string | null; - owner: `0x${string}`; + owner: Address; fullAppData: Record | null; } @@ -114,7 +115,7 @@ export class SwapOrderTransactionInfo @ApiProperty({ type: String, }) - owner: `0x${string}`; + owner: Address; @ApiPropertyOptional({ type: Object, @@ -139,7 +140,7 @@ export class SwapOrderTransactionInfo executedFee: string; executedFeeToken: TokenInfo; receiver: string | null; - owner: `0x${string}`; + owner: Address; fullAppData: Record | null; }) { super(TransactionInfoType.SwapOrder, null); diff --git a/src/routes/transactions/entities/swaps/token-info.entity.ts b/src/routes/transactions/entities/swaps/token-info.entity.ts index bec17c518a..6e1bcd61e9 100644 --- a/src/routes/transactions/entities/swaps/token-info.entity.ts +++ b/src/routes/transactions/entities/swaps/token-info.entity.ts @@ -1,8 +1,9 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class TokenInfo { @ApiProperty({ description: 'The token address' }) - address: `0x${string}`; + address: Address; @ApiProperty({ description: 'The token decimals' }) decimals: number; @@ -24,7 +25,7 @@ export class TokenInfo { trusted: boolean; constructor(args: { - address: `0x${string}`; + address: Address; decimals: number; logoUri: string | null; name: string; diff --git a/src/routes/transactions/entities/swaps/twap-order-info.entity.ts b/src/routes/transactions/entities/swaps/twap-order-info.entity.ts index b1f0cdbfae..c3be1161e8 100644 --- a/src/routes/transactions/entities/swaps/twap-order-info.entity.ts +++ b/src/routes/transactions/entities/swaps/twap-order-info.entity.ts @@ -14,6 +14,7 @@ import { ApiPropertyOptional, getSchemaPath, } from '@nestjs/swagger'; +import type { Address } from 'viem'; export enum DurationType { Auto = 'AUTO', @@ -66,7 +67,7 @@ export class StartTimeAtEpoch { export type TwapOrderInfo = { status: OrderStatus; kind: OrderKind.Sell; - activeOrderUid: `0x${string}` | null; + activeOrderUid: Address | null; class: OrderClass.Limit; validUntil: number; sellAmount: string; @@ -79,8 +80,8 @@ export type TwapOrderInfo = { executedFeeToken: TokenInfo; sellToken: TokenInfo; buyToken: TokenInfo; - receiver: `0x${string}`; - owner: `0x${string}`; + receiver: Address; + owner: Address; numberOfParts: string; partSellAmount: string; minPartLimit: string; @@ -120,7 +121,7 @@ export class TwapOrderTransactionInfo nullable: true, description: 'The order UID of the active order, or null if none is active', }) - activeOrderUid: `0x${string}` | null; + activeOrderUid: Address | null; @ApiProperty({ description: 'The timestamp when the TWAP expires' }) validUntil: number; @@ -176,12 +177,12 @@ export class TwapOrderTransactionInfo @ApiProperty({ description: 'The address to receive the proceeds of the trade', }) - receiver: `0x${string}`; + receiver: Address; @ApiProperty({ type: String, }) - owner: `0x${string}`; + owner: Address; @ApiPropertyOptional({ type: Object, @@ -231,7 +232,7 @@ export class TwapOrderTransactionInfo constructor(args: { status: OrderStatus; kind: OrderKind.Sell; - activeOrderUid: `0x${string}` | null; + activeOrderUid: Address | null; class: OrderClass.Limit; validUntil: number; sellAmount: string; @@ -242,8 +243,8 @@ export class TwapOrderTransactionInfo executedFeeToken: TokenInfo; sellToken: TokenInfo; buyToken: TokenInfo; - receiver: `0x${string}`; - owner: `0x${string}`; + receiver: Address; + owner: Address; fullAppData: Record | null; numberOfParts: string; partSellAmount: string; diff --git a/src/routes/transactions/entities/transaction-data.entity.ts b/src/routes/transactions/entities/transaction-data.entity.ts index b19c36563a..a4aca6a0f2 100644 --- a/src/routes/transactions/entities/transaction-data.entity.ts +++ b/src/routes/transactions/entities/transaction-data.entity.ts @@ -12,6 +12,7 @@ import { Erc721Token, NativeToken, } from '@/routes/balances/entities/token.entity'; +import type { Address } from 'viem'; @ApiExtraModels(AddressInfo, DataDecoded, Erc20Token, Erc721Token, NativeToken) export class TransactionData { @@ -47,7 +48,7 @@ export class TransactionData { nullable: true, }) tokenInfoIndex: Record< - `0x${string}`, + Address, Erc20Token | Erc721Token | NativeToken > | null; @@ -60,7 +61,7 @@ export class TransactionData { trustedDelegateCallTarget: boolean | null, addressInfoIndex: Record | null, tokenInfoIndex: Record< - `0x${string}`, + Address, Erc20Token | Erc721Token | NativeToken > | null, ) { diff --git a/src/routes/transactions/entities/transaction.entity.ts b/src/routes/transactions/entities/transaction.entity.ts index e85949e60f..565a7d866c 100644 --- a/src/routes/transactions/entities/transaction.entity.ts +++ b/src/routes/transactions/entities/transaction.entity.ts @@ -11,13 +11,14 @@ import { MultisigExecutionInfo } from '@/routes/transactions/entities/multisig-e import { SafeAppInfo } from '@/routes/transactions/entities/safe-app-info.entity'; import { TransactionInfo } from '@/routes/transactions/entities/transaction-info.entity'; import { TransactionStatus } from '@/routes/transactions/entities/transaction-status.entity'; +import type { Hash } from 'viem'; @ApiExtraModels(ModuleExecutionInfo, MultisigExecutionInfo) export class Transaction extends BaseTransaction { @ApiProperty() id: string; @ApiPropertyOptional({ type: String, nullable: true }) - txHash: `0x${string}` | null; + txHash: Hash | null; @ApiProperty() timestamp: number; @ApiProperty({ enum: TransactionStatus }) @@ -40,7 +41,7 @@ export class Transaction extends BaseTransaction { txInfo: TransactionInfo, executionInfo: ExecutionInfo | null = null, safeAppInfo: SafeAppInfo | null = null, - txHash: `0x${string}` | null = null, + txHash: Hash | null = null, ) { super(txInfo); this.id = id; diff --git a/src/routes/transactions/entities/transfers/erc20-transfer.entity.ts b/src/routes/transactions/entities/transfers/erc20-transfer.entity.ts index e6e28aa196..2664de9a39 100644 --- a/src/routes/transactions/entities/transfers/erc20-transfer.entity.ts +++ b/src/routes/transactions/entities/transfers/erc20-transfer.entity.ts @@ -3,12 +3,13 @@ import { Transfer, TransferType, } from '@/routes/transactions/entities/transfers/transfer.entity'; +import type { Address } from 'viem'; export class Erc20Transfer extends Transfer { @ApiProperty({ enum: [TransferType.Erc20] }) override type = TransferType.Erc20; @ApiProperty() - tokenAddress: `0x${string}`; + tokenAddress: Address; @ApiProperty() value: string; @ApiPropertyOptional({ type: String, nullable: true }) @@ -25,7 +26,7 @@ export class Erc20Transfer extends Transfer { imitation: boolean; constructor( - tokenAddress: `0x${string}`, + tokenAddress: Address, value: string, tokenName: string | null = null, tokenSymbol: string | null = null, diff --git a/src/routes/transactions/entities/transfers/erc721-transfer.entity.ts b/src/routes/transactions/entities/transfers/erc721-transfer.entity.ts index 7ffeaf702c..61de3f3146 100644 --- a/src/routes/transactions/entities/transfers/erc721-transfer.entity.ts +++ b/src/routes/transactions/entities/transfers/erc721-transfer.entity.ts @@ -3,12 +3,13 @@ import { Transfer, TransferType, } from '@/routes/transactions/entities/transfers/transfer.entity'; +import type { Address } from 'viem'; export class Erc721Transfer extends Transfer { @ApiProperty({ enum: [TransferType.Erc721] }) override type = TransferType.Erc721; @ApiProperty() - tokenAddress: `0x${string}`; + tokenAddress: Address; @ApiProperty() tokenId: string; @ApiPropertyOptional({ type: String, nullable: true }) @@ -21,7 +22,7 @@ export class Erc721Transfer extends Transfer { trusted: boolean | null; constructor( - tokenAddress: `0x${string}`, + tokenAddress: Address, tokenId: string, tokenName: string | null = null, tokenSymbol: string | null = null, diff --git a/src/routes/transactions/entities/txs-creation-transaction.entity.ts b/src/routes/transactions/entities/txs-creation-transaction.entity.ts index 2176bc20d2..c9b82303e6 100644 --- a/src/routes/transactions/entities/txs-creation-transaction.entity.ts +++ b/src/routes/transactions/entities/txs-creation-transaction.entity.ts @@ -1,29 +1,30 @@ import { ApiProperty } from '@nestjs/swagger'; import { CreationTransaction as DomainCreationTransaction } from '@/domain/safe/entities/creation-transaction.entity'; +import type { Address, Hash } from 'viem'; export class TXSCreationTransaction implements DomainCreationTransaction { @ApiProperty() created: Date; @ApiProperty() - creator: `0x${string}`; + creator: Address; @ApiProperty() - transactionHash: `0x${string}`; + transactionHash: Hash; @ApiProperty() - factoryAddress: `0x${string}`; + factoryAddress: Address; @ApiProperty() - masterCopy: `0x${string}` | null; + masterCopy: Address | null; @ApiProperty() - setupData: `0x${string}` | null; + setupData: Address | null; @ApiProperty() saltNonce: string | null; constructor(args: { created: Date; - creator: `0x${string}`; - transactionHash: `0x${string}`; - factoryAddress: `0x${string}`; - masterCopy: `0x${string}` | null; - setupData: `0x${string}` | null; + creator: Address; + transactionHash: Hash; + factoryAddress: Address; + masterCopy: Address | null; + setupData: Address | null; saltNonce: string | null; }) { this.created = args.created; diff --git a/src/routes/transactions/entities/txs-multisig-transaction.entity.ts b/src/routes/transactions/entities/txs-multisig-transaction.entity.ts index c4aa7abb92..b14aff2dab 100644 --- a/src/routes/transactions/entities/txs-multisig-transaction.entity.ts +++ b/src/routes/transactions/entities/txs-multisig-transaction.entity.ts @@ -5,20 +5,21 @@ import { } from '@/domain/safe/entities/multisig-transaction.entity'; import { Operation } from '@/domain/safe/entities/operation.entity'; import { ApiProperty } from '@nestjs/swagger'; +import type { Address, Hash, Hex } from 'viem'; export class TXSMultisigTransaction implements DomainMultisigTransaction { @ApiProperty() - safe: `0x${string}`; + safe: Address; @ApiProperty() - to: `0x${string}`; + to: Address; @ApiProperty() value: string; @ApiProperty() - data: `0x${string}` | null; + data: Hex | null; @ApiProperty() operation: Operation; @ApiProperty() - gasToken: `0x${string}` | null; + gasToken: Address | null; @ApiProperty() safeTxGas: number | null; @ApiProperty() @@ -26,11 +27,11 @@ export class TXSMultisigTransaction implements DomainMultisigTransaction { @ApiProperty() gasPrice: string | null; @ApiProperty() - proposer: `0x${string}` | null; + proposer: Address | null; @ApiProperty() - proposedByDelegate: `0x${string}` | null; + proposedByDelegate: Address | null; @ApiProperty() - refundReceiver: `0x${string}` | null; + refundReceiver: Address | null; @ApiProperty() nonce: number; @ApiProperty() @@ -42,11 +43,11 @@ export class TXSMultisigTransaction implements DomainMultisigTransaction { @ApiProperty() blockNumber: number | null; @ApiProperty() - transactionHash: `0x${string}` | null; + transactionHash: Hash | null; @ApiProperty() - safeTxHash: `0x${string}`; + safeTxHash: Hash; @ApiProperty() - executor: `0x${string}` | null; + executor: Address | null; @ApiProperty() isExecuted: boolean; @ApiProperty() @@ -64,32 +65,32 @@ export class TXSMultisigTransaction implements DomainMultisigTransaction { @ApiProperty() confirmations: Array | null; @ApiProperty() - signatures: `0x${string}` | null; + signatures: Hex | null; @ApiProperty() trusted: boolean; constructor(args: { - safe: `0x${string}`; - to: `0x${string}`; + safe: Address; + to: Address; value: string; - data: `0x${string}` | null; + data: Hex | null; dataDecoded: DataDecoded | null; operation: Operation; - gasToken: `0x${string}` | null; + gasToken: Address | null; safeTxGas: number | null; baseGas: number | null; gasPrice: string | null; - proposer: `0x${string}` | null; - proposedByDelegate: `0x${string}` | null; - refundReceiver: `0x${string}` | null; + proposer: Address | null; + proposedByDelegate: Address | null; + refundReceiver: Address | null; nonce: number; executionDate: Date | null; submissionDate: Date; modified: Date | null; blockNumber: number | null; - transactionHash: `0x${string}` | null; - safeTxHash: `0x${string}`; - executor: `0x${string}` | null; + transactionHash: Hash | null; + safeTxHash: Hash; + executor: Address | null; isExecuted: boolean; isSuccessful: boolean | null; ethGasPrice: string | null; @@ -98,7 +99,7 @@ export class TXSMultisigTransaction implements DomainMultisigTransaction { origin: string | null; confirmationsRequired: number; confirmations: Array | null; - signatures: `0x${string}` | null; + signatures: Hex | null; trusted: boolean; }) { this.safe = args.safe; diff --git a/src/routes/transactions/entities/vaults/vault-info.entity.ts b/src/routes/transactions/entities/vaults/vault-info.entity.ts index 160df5cf81..9f890fa4e5 100644 --- a/src/routes/transactions/entities/vaults/vault-info.entity.ts +++ b/src/routes/transactions/entities/vaults/vault-info.entity.ts @@ -1,8 +1,9 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; +import type { Address } from 'viem'; export class VaultInfo { @ApiProperty() - address: `0x${string}`; + address: Address; @ApiProperty() name: string; @@ -17,7 +18,7 @@ export class VaultInfo { logoUri: string; constructor(args: { - address: `0x${string}`; + address: Address; name: string; description: string; dashboardUri: string | null; diff --git a/src/routes/transactions/helpers/gp-v2-order.helper.ts b/src/routes/transactions/helpers/gp-v2-order.helper.ts index 925c93e22f..0b1c9c3ee9 100644 --- a/src/routes/transactions/helpers/gp-v2-order.helper.ts +++ b/src/routes/transactions/helpers/gp-v2-order.helper.ts @@ -1,6 +1,7 @@ import { GPv2OrderParameters } from '@/domain/swaps/contracts/decoders/gp-v2-decoder.helper'; import { Injectable } from '@nestjs/common'; import { TypedDataDomain, encodePacked, hashTypedData } from 'viem'; +import type { Address } from 'viem'; @Injectable() export class GPv2OrderHelper { @@ -43,9 +44,9 @@ export class GPv2OrderHelper { */ public computeOrderUid(args: { chainId: string; - owner: `0x${string}`; + owner: Address; order: GPv2OrderParameters; - }): `0x${string}` { + }): Address { return encodePacked( ['bytes32', 'address', 'uint32'], [this.hashOrder(args), args.owner, args.order.validTo], @@ -65,7 +66,7 @@ export class GPv2OrderHelper { private hashOrder(args: { chainId: string; order: GPv2OrderParameters; - }): `0x${string}` { + }): Address { return hashTypedData({ domain: this.getDomain(args.chainId), primaryType: GPv2OrderHelper.TypedDataPrimaryType, diff --git a/src/routes/transactions/helpers/kiln-native-staking.helper.spec.ts b/src/routes/transactions/helpers/kiln-native-staking.helper.spec.ts index 2ed0d42af3..6cf058382f 100644 --- a/src/routes/transactions/helpers/kiln-native-staking.helper.spec.ts +++ b/src/routes/transactions/helpers/kiln-native-staking.helper.spec.ts @@ -13,6 +13,7 @@ import type { ILoggingService } from '@/logging/logging.interface'; import { KilnNativeStakingHelper } from '@/routes/transactions/helpers/kiln-native-staking.helper'; import { TransactionFinder } from '@/routes/transactions/helpers/transaction-finder.helper'; import { faker } from '@faker-js/faker'; +import type { Address } from 'viem'; import { concat, getAddress } from 'viem'; const mockLoggingService = { @@ -103,7 +104,7 @@ describe('KilnNativeStakingHelper', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const _publicKeys = concat(validators); const result = target.splitPublicKeys(_publicKeys); diff --git a/src/routes/transactions/helpers/kiln-native-staking.helper.ts b/src/routes/transactions/helpers/kiln-native-staking.helper.ts index 92987fe4e2..e9b9a3b367 100644 --- a/src/routes/transactions/helpers/kiln-native-staking.helper.ts +++ b/src/routes/transactions/helpers/kiln-native-staking.helper.ts @@ -8,6 +8,7 @@ import { } from '@/routes/transactions/helpers/transaction-finder.helper'; import { Injectable, Module } from '@nestjs/common'; import { getAbiItem, toFunctionSelector } from 'viem'; +import type { Address, Hex } from 'viem'; @Injectable() export class KilnNativeStakingHelper { @@ -27,10 +28,10 @@ export class KilnNativeStakingHelper { constructor(private readonly transactionFinder: TransactionFinder) {} public findDepositTransaction(args: { - to?: `0x${string}`; - data: `0x${string}`; + to?: Address; + data: Hex; value: string; - }): { to?: `0x${string}`; data: `0x${string}`; value: string } | null { + }): { to?: Address; data: Hex; value: string } | null { const selector = toFunctionSelector( KilnNativeStakingHelper.DEPOSIT_SIGNATURE, ); @@ -41,10 +42,10 @@ export class KilnNativeStakingHelper { } public findValidatorsExitTransaction(args: { - to?: `0x${string}`; - data: `0x${string}`; + to?: Address; + data: Hex; value: string; - }): { to?: `0x${string}`; data: `0x${string}`; value: string } | null { + }): { to?: Address; data: Hex; value: string } | null { const selector = toFunctionSelector( KilnNativeStakingHelper.VALIDATORS_EXIT_SIGNATURE, ); @@ -55,10 +56,10 @@ export class KilnNativeStakingHelper { } public findWithdrawTransaction(args: { - to?: `0x${string}`; - data: `0x${string}`; + to?: Address; + data: Hex; value: string; - }): { to?: `0x${string}`; data: `0x${string}`; value: string } | null { + }): { to?: Address; data: Hex; value: string } | null { const selector = toFunctionSelector( KilnNativeStakingHelper.WITHDRAW_SIGNATURE, ); @@ -77,10 +78,10 @@ export class KilnNativeStakingHelper { * @param publicKeys - the public keys to split * @returns */ - public splitPublicKeys(publicKeys: `0x${string}`): Array<`0x${string}`> { + public splitPublicKeys(publicKeys: Address): Array
{ // Remove initial `0x` of decoded `_publicKeys` const publicKeysString = publicKeys.slice(2); - const publicKeysArray: Array<`0x${string}`> = []; + const publicKeysArray: Array
= []; for ( let i = 0; i < publicKeysString.length; diff --git a/src/routes/transactions/helpers/kiln-vault.helper.ts b/src/routes/transactions/helpers/kiln-vault.helper.ts index 8aa4602fe3..0b2cfd2127 100644 --- a/src/routes/transactions/helpers/kiln-vault.helper.ts +++ b/src/routes/transactions/helpers/kiln-vault.helper.ts @@ -8,6 +8,7 @@ import { } from '@/routes/transactions/helpers/transaction-finder.helper'; import { Injectable, Module } from '@nestjs/common'; import { + Address, ContractFunctionName, DecodeFunctionDataReturnType, erc4626Abi, @@ -27,8 +28,8 @@ export class KilnVaultHelper extends Erc4262Decoder { 'to' | 'data' | 'value' >, ): { - to?: `0x${string}`; - data: `0x${string}`; + to?: Address; + data: Address; assets: number; } | null { const decoded = this.getDecodedTransaction({ @@ -52,8 +53,8 @@ export class KilnVaultHelper extends Erc4262Decoder { 'to' | 'data' | 'value' >, ): { - to?: `0x${string}`; - data: `0x${string}`; + to?: Address; + data: Address; assets: number; } | null { const decoded = @@ -90,8 +91,8 @@ export class KilnVaultHelper extends Erc4262Decoder { >; }): { transaction: { - to?: `0x${string}`; - data: `0x${string}`; + to?: Address; + data: Address; value: string; }; args: DecodeFunctionDataReturnType['args']; diff --git a/src/routes/transactions/helpers/lifi-helper.ts b/src/routes/transactions/helpers/lifi-helper.ts index cf22245f53..5c5a066d53 100644 --- a/src/routes/transactions/helpers/lifi-helper.ts +++ b/src/routes/transactions/helpers/lifi-helper.ts @@ -8,7 +8,7 @@ import { TransactionFinderModule, } from '@/routes/transactions/helpers/transaction-finder.helper'; import { Inject, Injectable, Module } from '@nestjs/common'; -import { isAddressEqual } from 'viem'; +import { type Address, isAddressEqual } from 'viem'; @Injectable() export class LiFiHelper { @@ -23,8 +23,8 @@ export class LiFiHelper { chainId: string; transaction: MultisigTransaction | ModuleTransaction; }): Promise<{ - to?: `0x${string}`; - data: `0x${string}`; + to?: Address; + data: Address; value: string; } | null> { return await this.findTransactionByPredicate({ @@ -39,8 +39,8 @@ export class LiFiHelper { chainId: string; transaction: MultisigTransaction | ModuleTransaction; }): Promise<{ - to?: `0x${string}`; - data: `0x${string}`; + to?: Address; + data: Address; value: string; } | null> { return await this.findTransactionByPredicate({ @@ -55,8 +55,8 @@ export class LiFiHelper { chainId: string; transaction: MultisigTransaction | ModuleTransaction; }): Promise<{ - to?: `0x${string}`; - data: `0x${string}`; + to?: Address; + data: Address; value: string; } | null> { return await this.findTransactionByPredicate({ @@ -73,10 +73,10 @@ export class LiFiHelper { private async findTransactionByPredicate(args: { chainId: string; transaction: MultisigTransaction | ModuleTransaction; - predicate: (data: `0x${string}`) => boolean; + predicate: (data: Address) => boolean; }): Promise<{ - to?: `0x${string}`; - data: `0x${string}`; + to?: Address; + data: Address; value: string; } | null> { if (!args.transaction.data || args.transaction.data === '0x') { diff --git a/src/routes/transactions/helpers/swap-order.helper.spec.ts b/src/routes/transactions/helpers/swap-order.helper.spec.ts index 1f970ef5e1..cd5dba1a9c 100644 --- a/src/routes/transactions/helpers/swap-order.helper.spec.ts +++ b/src/routes/transactions/helpers/swap-order.helper.spec.ts @@ -4,7 +4,7 @@ import type { GPv2Decoder } from '@/domain/swaps/contracts/decoders/gp-v2-decode import { faker } from '@faker-js/faker'; import { orderBuilder } from '@/domain/swaps/entities/__tests__/order.builder'; import { tokenBuilder } from '@/domain/tokens/__tests__/token.builder'; -import { getAddress } from 'viem'; +import { type Address, getAddress, type Hex } from 'viem'; import type { IConfigurationService } from '@/config/configuration.service.interface'; import { OrderKind, OrderStatus } from '@/domain/swaps/entities/order.entity'; import { SwapOrderHelper } from '@/routes/transactions/helpers/swap-order.helper'; @@ -74,7 +74,7 @@ describe('Swap Order Helper tests', () => { .with('sellToken', getAddress(sellToken.address)) .build(); gpv2DecoderMock.getOrderUidFromSetPreSignature.mockReturnValue( - order.uid as `0x${string}`, + order.uid as Address, ); swapsRepositoryMock.getOrder.mockResolvedValue(order); tokenRepositoryMock.getToken.mockImplementation(({ address }) => { @@ -85,7 +85,7 @@ describe('Swap Order Helper tests', () => { const actual = await target.getOrder({ chainId, - orderUid: order.uid as `0x${string}`, + orderUid: order.uid as Address, }); expect(actual).toEqual({ @@ -129,7 +129,7 @@ describe('Swap Order Helper tests', () => { it(`should throw if repository getOrder throws an error`, async () => { const chainId = faker.string.numeric(); - const orderUid = faker.string.hexadecimal({ length: 112 }) as `0x${string}`; + const orderUid = faker.string.hexadecimal({ length: 112 }) as Hex; const error = new Error('Order not found'); swapsRepositoryMock.getOrder.mockRejectedValue(error); @@ -176,7 +176,7 @@ describe('Swap Order Helper tests', () => { await expect( target.getOrder({ chainId, - orderUid: order.uid as `0x${string}`, + orderUid: order.uid as Address, }), ).rejects.toThrow('Unknown order kind'); diff --git a/src/routes/transactions/helpers/swap-order.helper.ts b/src/routes/transactions/helpers/swap-order.helper.ts index df27426550..e89dab67fd 100644 --- a/src/routes/transactions/helpers/swap-order.helper.ts +++ b/src/routes/transactions/helpers/swap-order.helper.ts @@ -21,6 +21,7 @@ import { ChainsRepositoryModule, IChainsRepository, } from '@/domain/chains/chains.repository.interface'; +import type { Address, Hex } from 'viem'; @Injectable() export class SwapOrderHelper { @@ -53,7 +54,7 @@ export class SwapOrderHelper { * @private * @returns The swap order if found, otherwise null */ - public findSwapOrder(data: `0x${string}`): `0x${string}` | null { + public findSwapOrder(data: Hex): Hex | null { return ( this.transactionFinder.findTransaction( (transaction) => @@ -82,7 +83,7 @@ export class SwapOrderHelper { */ async getOrder(args: { chainId: string; - orderUid: `0x${string}`; + orderUid: Address; }): Promise { const order = await this.swapsRepository.getOrder( args.chainId, @@ -125,7 +126,7 @@ export class SwapOrderHelper { */ public async getToken(args: { chainId: string; - address: `0x${string}`; + address: Address; }): Promise { // We perform lower case comparison because the provided address (3rd party service) // might not be checksummed. diff --git a/src/routes/transactions/helpers/transaction-data-finder.helper.spec.ts b/src/routes/transactions/helpers/transaction-data-finder.helper.spec.ts index 989a2bfad4..89ff362fd9 100644 --- a/src/routes/transactions/helpers/transaction-data-finder.helper.spec.ts +++ b/src/routes/transactions/helpers/transaction-data-finder.helper.spec.ts @@ -6,7 +6,7 @@ import { MultiSendDecoder } from '@/domain/contracts/decoders/multi-send-decoder import type { ILoggingService } from '@/logging/logging.interface'; import { TransactionFinder } from '@/routes/transactions/helpers/transaction-finder.helper'; import { faker } from '@faker-js/faker'; -import { encodeFunctionData, erc20Abi, getAddress } from 'viem'; +import { type Address, encodeFunctionData, erc20Abi, getAddress } from 'viem'; const mockLoggingService = { warn: jest.fn(), @@ -56,7 +56,7 @@ describe('TransactionFinder', () => { 'transactions', multiSendTransactionsEncoder([transaction]), ); - const isTransactionData = (args: { data: `0x${string}` }): boolean => { + const isTransactionData = (args: { data: Address }): boolean => { return args.data === transaction.data; }; diff --git a/src/routes/transactions/helpers/transaction-finder.helper.ts b/src/routes/transactions/helpers/transaction-finder.helper.ts index 1ae9931ffc..4ee9d07058 100644 --- a/src/routes/transactions/helpers/transaction-finder.helper.ts +++ b/src/routes/transactions/helpers/transaction-finder.helper.ts @@ -1,5 +1,6 @@ import { MultiSendDecoder } from '@/domain/contracts/decoders/multi-send-decoder.helper'; import { Injectable, Module } from '@nestjs/common'; +import type { Address, Hex } from 'viem'; @Injectable() export class TransactionFinder { @@ -13,12 +14,9 @@ export class TransactionFinder { * @returns transaction data if found, otherwise null */ public findTransaction( - isTransactionData: (args: { - to?: `0x${string}`; - data: `0x${string}`; - }) => boolean, - transaction: { to?: `0x${string}`; data: `0x${string}`; value: string }, - ): { to?: `0x${string}`; data: `0x${string}`; value: string } | null { + isTransactionData: (args: { to?: Address; data: Hex }) => boolean, + transaction: { to?: Address; data: Hex; value: string }, + ): { to?: Address; data: Hex; value: string } | null { if (isTransactionData(transaction)) { return transaction; } diff --git a/src/routes/transactions/helpers/transaction-verifier.helper.spec.ts b/src/routes/transactions/helpers/transaction-verifier.helper.spec.ts index d12a352d69..36c2ea3db5 100644 --- a/src/routes/transactions/helpers/transaction-verifier.helper.spec.ts +++ b/src/routes/transactions/helpers/transaction-verifier.helper.spec.ts @@ -1,6 +1,6 @@ import { faker } from '@faker-js/faker'; import { get } from 'lodash'; -import { concat, getAddress } from 'viem'; +import { type Address, concat, getAddress } from 'viem'; import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts'; import { SignatureType } from '@/domain/common/entities/signature-type.entity'; import { pageBuilder } from '@/domain/entities/__tests__/page.builder'; @@ -150,7 +150,7 @@ describe('TransactionVerifierHelper', () => { }); transaction.confirmations![0].signature = faker.string.hexadecimal({ length: 130, - }) as `0x${string}`; + }) as Address; expect(() => { return target.verifyApiTransaction({ chainId, safe, transaction }); @@ -175,7 +175,7 @@ describe('TransactionVerifierHelper', () => { }); transaction.confirmations![0].signature = faker.string.hexadecimal({ length: 130, - }) as `0x${string}`; + }) as Address; expect(() => { return target.verifyApiTransaction({ chainId, safe, transaction }); @@ -270,7 +270,7 @@ describe('TransactionVerifierHelper', () => { }); transaction.data = faker.string.hexadecimal({ length: 64, - }) as `0x${string}`; + }) as Address; expect(() => { return target.verifyApiTransaction({ chainId, safe, transaction }); @@ -387,7 +387,7 @@ describe('TransactionVerifierHelper', () => { safe, }); transaction.confirmations![0].signature = - transaction.confirmations![0].signature!.slice(0, 129) as `0x${string}`; + transaction.confirmations![0].signature!.slice(0, 129) as Address; expect(() => { return target.verifyApiTransaction({ chainId, safe, transaction }); @@ -411,7 +411,7 @@ describe('TransactionVerifierHelper', () => { safe, }); transaction.confirmations![0].signature = - transaction.confirmations![0].signature!.slice(0, 128) as `0x${string}`; + transaction.confirmations![0].signature!.slice(0, 128) as Address; expect(() => { return target.verifyApiTransaction({ chainId, safe, transaction }); @@ -1181,7 +1181,7 @@ describe('TransactionVerifierHelper', () => { }); transaction.data = faker.string.hexadecimal({ length: 64, - }) as `0x${string}`; + }) as Address; const proposal = proposeTransactionDtoBuilder() .with('to', transaction.to) .with('value', transaction.value) @@ -1254,7 +1254,7 @@ describe('TransactionVerifierHelper', () => { safe, }); transaction.confirmations![0].signature = - transaction.confirmations![0].signature!.slice(0, 129) as `0x${string}`; + transaction.confirmations![0].signature!.slice(0, 129) as Address; const proposal = proposeTransactionDtoBuilder() .with('to', transaction.to) .with('value', transaction.value) @@ -1306,7 +1306,7 @@ describe('TransactionVerifierHelper', () => { safe, }); transaction.confirmations![0].signature = - transaction.confirmations![0].signature!.slice(0, 128) as `0x${string}`; + transaction.confirmations![0].signature!.slice(0, 128) as Address; const proposal = proposeTransactionDtoBuilder() .with('to', transaction.to) .with('value', transaction.value) @@ -1982,7 +1982,7 @@ describe('TransactionVerifierHelper', () => { }); transaction.data = faker.string.hexadecimal({ length: 64, - }) as `0x${string}`; + }) as Address; expect(() => { return target.verifyConfirmation({ @@ -2056,7 +2056,7 @@ describe('TransactionVerifierHelper', () => { transaction, signature: faker.helpers.arrayElement( transaction.confirmations!.map((confirmation) => { - return confirmation.signature!.slice(0, 129) as `0x${string}`; + return confirmation.signature!.slice(0, 129) as Address; }), ), }); @@ -2100,7 +2100,7 @@ describe('TransactionVerifierHelper', () => { transaction, signature: faker.helpers.arrayElement( transaction.confirmations!.map((confirmation) => { - return confirmation.signature!.slice(0, 128) as `0x${string}`; + return confirmation.signature!.slice(0, 128) as Address; }), ), }); diff --git a/src/routes/transactions/helpers/transaction-verifier.helper.ts b/src/routes/transactions/helpers/transaction-verifier.helper.ts index d7367f10e0..b9263abf4e 100644 --- a/src/routes/transactions/helpers/transaction-verifier.helper.ts +++ b/src/routes/transactions/helpers/transaction-verifier.helper.ts @@ -15,7 +15,7 @@ import { LogType } from '@/domain/common/entities/log-type.entity'; import { SafeSignature } from '@/domain/common/entities/safe-signature'; import { SignatureType } from '@/domain/common/entities/signature-type.entity'; import { LogSource } from '@/domain/common/entities/log-source.entity'; -import { isAddressEqual } from 'viem'; +import { type Address, type Hash, Hex, isAddressEqual } from 'viem'; import { IContractsRepository } from '@/domain/contracts/contracts.repository.interface'; import { Operation } from '@/domain/safe/entities/operation.entity'; import { parseSignaturesByType } from '@/domain/common/utils/signatures'; @@ -38,7 +38,7 @@ export class TransactionVerifierHelper { private readonly isApiSignatureVerificationEnabled: boolean; private readonly isProposalHashVerificationEnabled: boolean; private readonly isProposalSignatureVerificationEnabled: boolean; - private readonly blocklist: Array<`0x${string}`>; + private readonly blocklist: Array
; constructor( @Inject(IConfigurationService) @@ -122,7 +122,7 @@ export class TransactionVerifierHelper { chainId: string; safe: Safe; transaction: MultisigTransaction; - signature: `0x${string}`; + signature: Hex; }): void { const code = HttpStatus.UNPROCESSABLE_ENTITY; @@ -178,7 +178,7 @@ export class TransactionVerifierHelper { transaction: MultisigTransaction; code: HttpStatus; }): void { - let safeTxHash: `0x${string}`; + let safeTxHash: Hash; try { safeTxHash = getSafeTxHash(args); } catch { @@ -213,7 +213,7 @@ export class TransactionVerifierHelper { baseGas: Number(args.proposal.baseGas), }; - let safeTxHash: `0x${string}`; + let safeTxHash: Hash; try { safeTxHash = getSafeTxHash({ ...args, @@ -246,7 +246,7 @@ export class TransactionVerifierHelper { transaction: MultisigTransaction; code: HttpStatus; }): void { - let safeTxHash: `0x${string}`; + let safeTxHash: Hash; try { safeTxHash = getSafeTxHash(args); } catch { @@ -423,7 +423,7 @@ export class TransactionVerifierHelper { chainId: string; safe: Safe; transaction: MultisigTransaction; - signature: `0x${string}`; + signature: Hex; code: HttpStatus; }): void { const signature = new SafeSignature({ @@ -469,7 +469,7 @@ export class TransactionVerifierHelper { private logMalformedSafeTxHash(args: { chainId: string; safe: Safe; - safeTxHash: `0x${string}`; + safeTxHash: Hash; transaction: BaseMultisigTransaction; source: LogSource; }): void { @@ -488,7 +488,7 @@ export class TransactionVerifierHelper { private logMismatchSafeTxHash(args: { chainId: string; safe: Safe; - safeTxHash: `0x${string}`; + safeTxHash: Hash; transaction: BaseMultisigTransaction; source: LogSource; }): void { @@ -507,8 +507,8 @@ export class TransactionVerifierHelper { private logBlockedAddress(args: { chainId: string; safe: Safe; - safeTxHash: `0x${string}`; - blockedAddress: `0x${string}`; + safeTxHash: Hash; + blockedAddress: Address; source: LogSource; }): void { this.loggingService.error({ @@ -526,9 +526,9 @@ export class TransactionVerifierHelper { private logInvalidSignature(args: { chainId: string; safe: Safe; - safeTxHash: `0x${string}`; - signerAddress: `0x${string}`; - signature: `0x${string}`; + safeTxHash: Hash; + signerAddress: Address; + signature: Hex; source: LogSource; }): void { this.loggingService.error({ diff --git a/src/routes/transactions/helpers/twap-order.helper.ts b/src/routes/transactions/helpers/twap-order.helper.ts index 932431462d..8aeaff7a1a 100644 --- a/src/routes/transactions/helpers/twap-order.helper.ts +++ b/src/routes/transactions/helpers/twap-order.helper.ts @@ -21,7 +21,7 @@ import { } from '@/routes/transactions/entities/swaps/twap-order-info.entity'; import { GPv2OrderParameters } from '@/domain/swaps/contracts/decoders/gp-v2-decoder.helper'; import { Injectable, Module } from '@nestjs/common'; -import { isAddressEqual } from 'viem'; +import { type Address, type Hex, isAddressEqual } from 'viem'; /** * @@ -44,10 +44,7 @@ export class TwapOrderHelper { * @param args.data - data of the transaction * @returns TWAP order data if found, otherwise null */ - public findTwapOrder(args: { - to: `0x${string}`; - data: `0x${string}`; - }): `0x${string}` | null { + public findTwapOrder(args: { to: Address; data: Hex }): Hex | null { return ( this.transactionFinder.findTransaction( ({ to, data }) => { diff --git a/src/routes/transactions/mappers/common/bridge-transaction.mapper.spec.ts b/src/routes/transactions/mappers/common/bridge-transaction.mapper.spec.ts index 348bf1a505..feb453a654 100644 --- a/src/routes/transactions/mappers/common/bridge-transaction.mapper.spec.ts +++ b/src/routes/transactions/mappers/common/bridge-transaction.mapper.spec.ts @@ -8,6 +8,7 @@ import { BridgeTransactionMapper } from './bridge-transaction.mapper'; import { SwapTransactionInfo } from '@/routes/transactions/entities/bridge/bridge-info.entity'; import { TokenInfo } from '@/routes/transactions/entities/swaps/token-info.entity'; import type { IChainsRepository } from '@/domain/chains/chains.repository.interface'; +import type { Address, Hash, Hex } from 'viem'; describe('BridgeTransactionMapper (Unit)', () => { let mapper: BridgeTransactionMapper; @@ -59,21 +60,21 @@ describe('BridgeTransactionMapper (Unit)', () => { describe('mapSwap', () => { it('should return a SwapTransactionInfo', async () => { - const data = faker.string.hexadecimal({ length: 40 }) as `0x${string}`; + const data = faker.string.hexadecimal({ length: 40 }) as Hex; const decoded = { transactionId: faker.string.hexadecimal({ length: 64, - }) as `0x${string}`, - toAddress: faker.string.hexadecimal({ length: 40 }) as `0x${string}`, - fromToken: faker.string.hexadecimal({ length: 40 }) as `0x${string}`, - toToken: faker.string.hexadecimal({ length: 40 }) as `0x${string}`, + }) as Hex, + toAddress: faker.string.hexadecimal({ length: 40 }) as Address, + fromToken: faker.string.hexadecimal({ length: 40 }) as Address, + toToken: faker.string.hexadecimal({ length: 40 }) as Address, fromAmount: BigInt(1000000), toAmount: BigInt(1000000), fees: { - tokenAddress: faker.finance.ethereumAddress() as `0x${string}`, + tokenAddress: faker.finance.ethereumAddress() as Address, integratorFee: BigInt(100), lifiFee: BigInt(200), - integratorAddress: faker.finance.ethereumAddress() as `0x${string}`, + integratorAddress: faker.finance.ethereumAddress() as Address, }, }; liFiDecoder.decodeSwap.mockReturnValue(decoded); @@ -82,7 +83,7 @@ describe('BridgeTransactionMapper (Unit)', () => { data, chainId: faker.string.numeric(), executionDate: null, - safeAddress: faker.finance.ethereumAddress() as `0x${string}`, + safeAddress: faker.finance.ethereumAddress() as Address, }); expect(result).toBeInstanceOf(SwapTransactionInfo); @@ -92,34 +93,34 @@ describe('BridgeTransactionMapper (Unit)', () => { describe('mapSwapAndBridge', () => { const chainId = faker.string.numeric(); - const data = faker.string.hexadecimal({ length: 40 }) as `0x${string}`; + const data = faker.string.hexadecimal({ length: 40 }) as Hex; const safeAddress = faker.string.hexadecimal({ length: 40, - }) as `0x${string}`; - const fromToken = faker.string.hexadecimal({ length: 40 }) as `0x${string}`; - const toAddress = faker.string.hexadecimal({ length: 40 }) as `0x${string}`; + }) as Address; + const fromToken = faker.string.hexadecimal({ length: 40 }) as Address; + const toAddress = faker.string.hexadecimal({ length: 40 }) as Address; const toChain = BigInt(faker.number.int()); it('should map a queued bridge transaction', async () => { const decoded = { transactionId: faker.string.hexadecimal({ length: 64, - }) as `0x${string}`, + }) as Hex, fromToken, toAddress, toChain, fromAmount: BigInt(1000000), - toToken: faker.string.hexadecimal({ length: 40 }) as `0x${string}`, + toToken: faker.string.hexadecimal({ length: 40 }) as Address, minAmount: BigInt(1000000), fees: { tokenAddress: faker.string.hexadecimal({ length: 40, - }) as `0x${string}`, + }) as Address, integratorFee: BigInt(100), lifiFee: BigInt(200), integratorAddress: faker.string.hexadecimal({ length: 40, - }) as `0x${string}`, + }) as Address, }, bridge: 'lifi', }; @@ -175,22 +176,22 @@ describe('BridgeTransactionMapper (Unit)', () => { const decoded = { transactionId: faker.string.hexadecimal({ length: 64, - }) as `0x${string}`, + }) as Hex, fromToken, toAddress, toChain, fromAmount: BigInt(1000000), - toToken: faker.string.hexadecimal({ length: 40 }) as `0x${string}`, + toToken: faker.string.hexadecimal({ length: 40 }) as Address, minAmount: BigInt(1000000), fees: { tokenAddress: faker.string.hexadecimal({ length: 40, - }) as `0x${string}`, + }) as Address, integratorFee: BigInt(100), lifiFee: BigInt(200), integratorAddress: faker.string.hexadecimal({ length: 40, - }) as `0x${string}`, + }) as Address, }, bridge: 'lifi', }; @@ -221,7 +222,7 @@ describe('BridgeTransactionMapper (Unit)', () => { transactionId: decoded.transactionId, receiving: { value: '1000000', - txHash: faker.string.hexadecimal({ length: 64 }) as `0x${string}`, + txHash: faker.string.hexadecimal({ length: 64 }) as Hash, chainId: decoded.toChain.toString(), txLink: faker.internet.url(), token: { @@ -238,7 +239,7 @@ describe('BridgeTransactionMapper (Unit)', () => { gasPrice: '0', gasUsed: '0', gasToken: { - address: faker.string.hexadecimal({ length: 40 }) as `0x${string}`, + address: faker.string.hexadecimal({ length: 40 }) as Address, decimals: 18, symbol: 'ETH', name: 'Ethereum', @@ -251,8 +252,8 @@ describe('BridgeTransactionMapper (Unit)', () => { timestamp: null, }, lifiExplorerLink: faker.internet.url(), - fromAddress: faker.string.hexadecimal({ length: 40 }) as `0x${string}`, - toAddress: faker.string.hexadecimal({ length: 40 }) as `0x${string}`, + fromAddress: faker.string.hexadecimal({ length: 40 }) as Address, + toAddress: faker.string.hexadecimal({ length: 40 }) as Address, metadata: { integrator: faker.string.alpha({ length: 10 }), }, @@ -299,22 +300,22 @@ describe('BridgeTransactionMapper (Unit)', () => { const decoded = { transactionId: faker.string.hexadecimal({ length: 64, - }) as `0x${string}`, + }) as Hex, fromToken, toAddress, toChain, fromAmount: BigInt(1000000), - toToken: faker.string.hexadecimal({ length: 40 }) as `0x${string}`, + toToken: faker.string.hexadecimal({ length: 40 }) as Address, minAmount: BigInt(1000000), fees: { tokenAddress: faker.string.hexadecimal({ length: 40, - }) as `0x${string}`, + }) as Address, integratorFee: BigInt(100), lifiFee: BigInt(200), integratorAddress: faker.string.hexadecimal({ length: 40, - }) as `0x${string}`, + }) as Address, }, bridge: 'lifi', }; @@ -343,7 +344,7 @@ describe('BridgeTransactionMapper (Unit)', () => { substatus: 'UNKNOWN_FAILED_ERROR', substatusMessage: 'Transaction failed', sending: { - txHash: faker.string.hexadecimal({ length: 64 }) as `0x${string}`, + txHash: faker.string.hexadecimal({ length: 64 }) as Hash, chainId, txLink: faker.internet.url(), }, @@ -382,12 +383,12 @@ describe('BridgeTransactionMapper (Unit)', () => { const decoded = { transactionId: faker.string.hexadecimal({ length: 64, - }) as `0x${string}`, + }) as Hex, fromToken, toAddress, toChain, fromAmount: BigInt(1000000), - toToken: faker.string.hexadecimal({ length: 40 }) as `0x${string}`, + toToken: faker.string.hexadecimal({ length: 40 }) as Address, minAmount: BigInt(1000000), fees: null, bridge: 'lifi', diff --git a/src/routes/transactions/mappers/common/bridge-transaction.mapper.ts b/src/routes/transactions/mappers/common/bridge-transaction.mapper.ts index 8642072eed..26d8b13e81 100644 --- a/src/routes/transactions/mappers/common/bridge-transaction.mapper.ts +++ b/src/routes/transactions/mappers/common/bridge-transaction.mapper.ts @@ -6,12 +6,12 @@ import { TokenInfo } from '@/routes/transactions/entities/swaps/token-info.entit import { AddressInfoHelper } from '@/routes/common/address-info/address-info.helper'; import { IBridgeRepository } from '@/domain/bridge/bridge.repository.interface'; import { BridgeStatus } from '@/domain/bridge/entities/bridge-status.entity'; -import { Address } from 'viem'; import { BridgeAndSwapTransactionInfo } from '@/routes/transactions/entities/bridge/bridge-info.entity'; import { Token } from '@/domain/tokens/entities/token.entity'; import { NULL_ADDRESS } from '@/routes/common/constants'; import { IChainsRepository } from '@/domain/chains/chains.repository.interface'; import { BridgeFee } from '@/routes/transactions/entities/bridge/fees.entity'; +import type { Address } from 'viem'; @Injectable() export class BridgeTransactionMapper { @@ -27,10 +27,10 @@ export class BridgeTransactionMapper { ) {} public async mapSwap(args: { - data: `0x${string}`; + data: Address; executionDate: Date | null; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const decoded = this.liFiDecoder.decodeSwap(args.data); @@ -75,9 +75,9 @@ export class BridgeTransactionMapper { public async mapSwapAndBridge(args: { chainId: string; - data: `0x${string}`; + data: Address; executionDate: Date | null; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const decoded = this.liFiDecoder.decodeBridgeAndMaybeSwap(args.data); @@ -108,7 +108,7 @@ export class BridgeTransactionMapper { } private async _getTokenInfo(args: { - tokenAddress: `0x${string}`; + tokenAddress: Address; chainId: string; }): Promise { const isNativeCoin = args.tokenAddress === NULL_ADDRESS; @@ -118,7 +118,7 @@ export class BridgeTransactionMapper { ); return { type: 'NATIVE_TOKEN' as const, - address: NULL_ADDRESS as `0x${string}`, + address: NULL_ADDRESS as Address, decimals: nativeCurrency.decimals, logoUri: nativeCurrency.logoUri, name: nativeCurrency.name, @@ -135,7 +135,7 @@ export class BridgeTransactionMapper { private async getExecutedSwapInfo(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; decoded: ReturnType; }): Promise<{ toAmount: string; @@ -164,7 +164,7 @@ export class BridgeTransactionMapper { private async getSwapAndBridgeInfo(args: { executionDate: Date | null; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; decoded: ReturnType; }): Promise<{ toAmount: string | null; diff --git a/src/routes/transactions/mappers/common/data-decoded-param.helper.spec.ts b/src/routes/transactions/mappers/common/data-decoded-param.helper.spec.ts index af7d01e080..65fea7a070 100644 --- a/src/routes/transactions/mappers/common/data-decoded-param.helper.spec.ts +++ b/src/routes/transactions/mappers/common/data-decoded-param.helper.spec.ts @@ -5,7 +5,7 @@ import { type DataDecodedParameter, } from '@/domain/data-decoder/v2/entities/data-decoded.entity'; import { DataDecodedParamHelper } from '@/routes/transactions/mappers/common/data-decoded-param.helper'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; describe('DataDecoded param helper (Unit)', () => { const helper = new DataDecodedParamHelper(); @@ -467,7 +467,7 @@ describe('DataDecoded param helper (Unit)', () => { operation: 0, to: getAddress(faker.finance.ethereumAddress()), value: faker.string.numeric(), - data: faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + data: faker.string.hexadecimal({ length: 32 }) as Address, dataDecoded: { method: faker.word.sample(), parameters: [ @@ -506,7 +506,7 @@ describe('DataDecoded param helper (Unit)', () => { operation: 0, to: getAddress(faker.finance.ethereumAddress()), value: faker.string.numeric(), - data: faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + data: faker.string.hexadecimal({ length: 32 }) as Address, dataDecoded: { method: faker.word.sample(), parameters: [ @@ -527,7 +527,7 @@ describe('DataDecoded param helper (Unit)', () => { operation: 0, to: getAddress(faker.finance.ethereumAddress()), value: faker.string.numeric(), - data: faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + data: faker.string.hexadecimal({ length: 32 }) as Address, dataDecoded: { method: faker.word.sample(), parameters: [ @@ -575,7 +575,7 @@ describe('DataDecoded param helper (Unit)', () => { operation: 1, to: getAddress(faker.finance.ethereumAddress()), value: faker.string.numeric(), - data: faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + data: faker.string.hexadecimal({ length: 32 }) as Address, dataDecoded: { method: faker.word.sample(), parameters: [ @@ -614,7 +614,7 @@ describe('DataDecoded param helper (Unit)', () => { operation: 1, to: getAddress(faker.finance.ethereumAddress()), value: faker.string.numeric(), - data: faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + data: faker.string.hexadecimal({ length: 32 }) as Address, dataDecoded: { method: faker.word.sample(), parameters: [ @@ -635,7 +635,7 @@ describe('DataDecoded param helper (Unit)', () => { operation: 0, to: getAddress(faker.finance.ethereumAddress()), value: faker.string.numeric(), - data: faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + data: faker.string.hexadecimal({ length: 32 }) as Address, dataDecoded: { method: faker.word.sample(), parameters: [ @@ -674,14 +674,14 @@ describe('DataDecoded param helper (Unit)', () => { operation: 1, to: getAddress(faker.finance.ethereumAddress()), value: faker.string.numeric(), - data: faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + data: faker.string.hexadecimal({ length: 32 }) as Address, dataDecoded: null, }, { operation: 0, to: getAddress(faker.finance.ethereumAddress()), value: faker.string.numeric(), - data: faker.string.hexadecimal({ length: 32 }) as `0x${string}`, + data: faker.string.hexadecimal({ length: 32 }) as Address, dataDecoded: null, }, ], diff --git a/src/routes/transactions/mappers/common/human-descriptions.mapper.spec.ts b/src/routes/transactions/mappers/common/human-descriptions.mapper.spec.ts index 7001ad3a2f..fc20a2bf34 100644 --- a/src/routes/transactions/mappers/common/human-descriptions.mapper.spec.ts +++ b/src/routes/transactions/mappers/common/human-descriptions.mapper.spec.ts @@ -1,4 +1,10 @@ -import { encodeFunctionData, formatUnits, getAddress, parseAbi } from 'viem'; +import { + type Address, + encodeFunctionData, + formatUnits, + getAddress, + parseAbi, +} from 'viem'; import { faker } from '@faker-js/faker'; import type { TokenRepository } from '@/domain/tokens/token.repository'; import { tokenBuilder } from '@/domain/tokens/__tests__/token.builder'; @@ -92,7 +98,7 @@ describe('Human descriptions mapper (Unit)', () => { const data = 'something that is not hex'; const transaction = multisigTransactionBuilder() - .with('data', data as `0x${string}`) + .with('data', data as Address) .build(); const humanDescription = await mapper.mapHumanDescription( @@ -122,7 +128,7 @@ describe('Human descriptions mapper (Unit)', () => { const corruptedData = mockTransferData.slice(0, -7); const transaction = multisigTransactionBuilder() - .with('data', corruptedData as `0x${string}`) + .with('data', corruptedData as Address) .build(); const humanDescription = await mapper.mapHumanDescription( diff --git a/src/routes/transactions/mappers/common/native-staking.mapper.spec.ts b/src/routes/transactions/mappers/common/native-staking.mapper.spec.ts index c5076d1885..b5a044533a 100644 --- a/src/routes/transactions/mappers/common/native-staking.mapper.spec.ts +++ b/src/routes/transactions/mappers/common/native-staking.mapper.spec.ts @@ -31,7 +31,7 @@ import { KilnNativeStakingHelper } from '@/routes/transactions/helpers/kiln-nati import { TransactionFinder } from '@/routes/transactions/helpers/transaction-finder.helper'; import { NativeStakingMapper } from '@/routes/transactions/mappers/common/native-staking.mapper'; import { faker } from '@faker-js/faker'; -import { concat, getAddress } from 'viem'; +import { type Address, concat, getAddress, type Hash } from 'viem'; const mockStakingRepository = jest.mocked({ getDeployment: jest.fn(), @@ -243,7 +243,7 @@ describe('NativeStakingMapper', () => { casing: 'lower', }); const depositEventEvent = depositEventEventBuilder() - .with('pubkey', pubkey as `0x${string}`) + .with('pubkey', pubkey as Address) .encode(); const transactionStatus = transactionStatusBuilder() .with( @@ -258,7 +258,7 @@ describe('NativeStakingMapper', () => { .build(), ) .build(); - const txHash = faker.string.hexadecimal() as `0x${string}`; + const txHash = faker.string.hexadecimal() as Hash; mockChainsRepository.getChain.mockResolvedValue(chain); mockStakingRepository.getDeployment.mockResolvedValue(deployment); mockStakingRepository.getNetworkStats.mockResolvedValue(networkStats); @@ -413,7 +413,7 @@ describe('NativeStakingMapper', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const transaction = multisigTransactionBuilder().build(); const data = requestValidatorsExitEncoder() .with('_publicKeys', concat(validators)) @@ -537,7 +537,7 @@ describe('NativeStakingMapper', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const data = batchWithdrawCLFeeEncoder() .with('_publicKeys', concat(validators)) .encode(); @@ -611,7 +611,7 @@ describe('NativeStakingMapper', () => { length: KilnDecoder.KilnPublicKeyLength, casing: 'lower', }), - ] as Array<`0x${string}`>; + ] as Array
; const withdrawalEvent = withdrawalEventBuilder(); const withdrawalEventParams = withdrawalEvent.build(); const withdrawalEventEncoded = withdrawalEvent.encode(); @@ -646,7 +646,7 @@ describe('NativeStakingMapper', () => { .with('_publicKeys', concat(validators)) .encode(); const safeAddress = getAddress(faker.finance.ethereumAddress()); - const txHash = faker.string.hexadecimal() as `0x${string}`; + const txHash = faker.string.hexadecimal() as Hash; mockChainsRepository.getChain.mockResolvedValue(chain); mockStakingRepository.getDeployment.mockResolvedValue(deployment); mockStakingRepository.getNetworkStats.mockResolvedValue(networkStats); @@ -762,7 +762,7 @@ describe('NativeStakingMapper', () => { it('should return NOT_STAKED if there are no public keys', async () => { const chainId = faker.string.numeric(); const safeAddress = getAddress(faker.finance.ethereumAddress()); - const publicKeys: Array<`0x${string}`> = []; + const publicKeys: Array
= []; const actual = await target._getStatus({ chainId, diff --git a/src/routes/transactions/mappers/common/native-staking.mapper.ts b/src/routes/transactions/mappers/common/native-staking.mapper.ts index 185d6f2192..01baa66683 100644 --- a/src/routes/transactions/mappers/common/native-staking.mapper.ts +++ b/src/routes/transactions/mappers/common/native-staking.mapper.ts @@ -20,6 +20,7 @@ import { KilnNativeStakingHelper, KilnNativeStakingHelperModule, } from '@/routes/transactions/helpers/kiln-native-staking.helper'; +import type { Address, Hash } from 'viem'; @Injectable() export class NativeStakingMapper { @@ -48,9 +49,9 @@ export class NativeStakingMapper { */ public async mapDepositInfo(args: { chainId: string; - to: `0x${string}`; + to: Address; value: string | null; - txHash: `0x${string}` | null; + txHash: Hash | null; }): Promise { const [chain, deployment, rewardsFee] = await Promise.all([ this.chainsRepository.getChain(args.chainId), @@ -127,12 +128,12 @@ export class NativeStakingMapper { * @param args.txHash - the transaction hash of the deposit transaction * @param args.chainId - the chain ID of the native staking deployment * - * @returns {Array<`0x${string}`> | null} the public keys of the validators + * @returns {Array
| null} the public keys of the validators */ private async getDepositPublicKeys(args: { - txHash: `0x${string}` | null; + txHash: Hash | null; chainId: string; - }): Promise | null> { + }): Promise | null> { if (!args.txHash) { return null; } @@ -172,9 +173,9 @@ export class NativeStakingMapper { */ public async mapValidatorsExitInfo(args: { chainId: string; - safeAddress: `0x${string}`; - to: `0x${string}`; - data: `0x${string}`; + safeAddress: Address; + to: Address; + data: Address; }): Promise { const [chain, deployment] = await Promise.all([ this.chainsRepository.getChain(args.chainId), @@ -234,10 +235,10 @@ export class NativeStakingMapper { */ public async mapWithdrawInfo(args: { chainId: string; - safeAddress: `0x${string}`; - to: `0x${string}`; - txHash: `0x${string}` | null; - data: `0x${string}`; + safeAddress: Address; + to: Address; + txHash: Hash | null; + data: Address; }): Promise { const [chain, deployment] = await Promise.all([ this.chainsRepository.getChain(args.chainId), @@ -282,17 +283,17 @@ export class NativeStakingMapper { * we return the value get the exact value from the transaction logs instead. * * @param {string | nulle} args.txHash - the transaction hash of the withdraw transaction - * @param {Array<`0x${string}`>} args.publicKeys - the public keys to get the value for + * @param {Array
} args.publicKeys - the public keys to get the value for * @param {string} args.chainId - the chain ID of the native staking deployment * @param {string} args.safeAddress - the Safe staking * * @returns {number} the value to withdraw or withdrawn */ private async getWithdrawValue(args: { - txHash: `0x${string}` | null; - publicKeys: Array<`0x${string}`>; + txHash: Hash | null; + publicKeys: Array
; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { if (!args.txHash) { const stakes = await this.stakingRepository.getStakes({ @@ -352,8 +353,8 @@ export class NativeStakingMapper { */ public async _getStatus(args: { chainId: string; - safeAddress: `0x${string}`; - publicKeys: Array<`0x${string}`> | null; + safeAddress: Address; + publicKeys: Array
| null; }): Promise { if (!args.publicKeys || args.publicKeys.length === 0) { return StakingStatus.NotStaked; diff --git a/src/routes/transactions/mappers/common/swap-order.mapper.ts b/src/routes/transactions/mappers/common/swap-order.mapper.ts index 79a7902943..11b17bf1e5 100644 --- a/src/routes/transactions/mappers/common/swap-order.mapper.ts +++ b/src/routes/transactions/mappers/common/swap-order.mapper.ts @@ -10,6 +10,7 @@ import { SwapAppsHelper, SwapAppsHelperModule, } from '@/routes/transactions/helpers/swap-apps.helper'; +import type { Address } from 'viem'; @Injectable() export class SwapOrderMapper { @@ -21,9 +22,9 @@ export class SwapOrderMapper { async mapSwapOrder( chainId: string, - transaction: { data: `0x${string}` }, + transaction: { data: Address }, ): Promise { - const orderUid: `0x${string}` | null = + const orderUid: Address | null = this.gpv2Decoder.getOrderUidFromSetPreSignature(transaction.data); if (!orderUid) { throw new Error('Order UID not found in transaction data'); diff --git a/src/routes/transactions/mappers/common/transaction-data.mapper.spec.ts b/src/routes/transactions/mappers/common/transaction-data.mapper.spec.ts index 7fa99a3404..2e2a6b56b4 100644 --- a/src/routes/transactions/mappers/common/transaction-data.mapper.spec.ts +++ b/src/routes/transactions/mappers/common/transaction-data.mapper.spec.ts @@ -13,7 +13,7 @@ import { AddressInfo } from '@/routes/common/entities/address-info.entity'; import { MULTI_SEND_METHOD_NAME } from '@/routes/transactions/constants'; import type { DataDecodedParamHelper } from '@/routes/transactions/mappers/common/data-decoded-param.helper'; import { TransactionDataMapper } from '@/routes/transactions/mappers/common/transaction-data.mapper'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import type { MultisigTransactionInfoMapper } from '@/routes/transactions/mappers/common/transaction-info.mapper'; import type { IChainsRepository } from '@/domain/chains/chains.repository.interface'; import type { TokenRepository } from '@/domain/tokens/token.repository'; @@ -315,7 +315,7 @@ describe('Transaction Data Mapper (Unit)', () => { operation: 0, to: getAddress(faker.finance.ethereumAddress()), value: faker.string.numeric(), - data: faker.string.hexadecimal() as `0x${string}`, + data: faker.string.hexadecimal() as Address, dataDecoded: dataDecodedBuilder() .with('method', 'swap') .with('parameters', [ @@ -367,7 +367,7 @@ describe('Transaction Data Mapper (Unit)', () => { { operation: 0, to: getAddress(faker.finance.ethereumAddress()), - data: faker.string.hexadecimal() as `0x${string}`, + data: faker.string.hexadecimal() as Address, value: faker.string.numeric(), dataDecoded: dataDecodedBuilder() .with('method', 'swap') @@ -386,7 +386,7 @@ describe('Transaction Data Mapper (Unit)', () => { operation: 0, to: contractAddress, value: faker.string.numeric(), - data: faker.string.hexadecimal() as `0x${string}`, + data: faker.string.hexadecimal() as Address, dataDecoded: dataDecodedBuilder() .with('method', 'swap') .with('parameters', [ @@ -403,7 +403,7 @@ describe('Transaction Data Mapper (Unit)', () => { { operation: 0, to: contractAddress, - data: faker.string.hexadecimal() as `0x${string}`, + data: faker.string.hexadecimal() as Address, value: faker.string.numeric(), dataDecoded: dataDecodedBuilder() .with('method', 'swap') diff --git a/src/routes/transactions/mappers/common/transaction-data.mapper.ts b/src/routes/transactions/mappers/common/transaction-data.mapper.ts index efdacf2580..560eb40d7f 100644 --- a/src/routes/transactions/mappers/common/transaction-data.mapper.ts +++ b/src/routes/transactions/mappers/common/transaction-data.mapper.ts @@ -19,6 +19,7 @@ import { PreviewTransactionDto } from '@/routes/transactions/entities/preview-tr import { TransactionData } from '@/routes/transactions/entities/transaction-data.entity'; import { DataDecodedParamHelper } from '@/routes/transactions/mappers/common/data-decoded-param.helper'; import { AddressInfo } from '@/routes/common/entities/address-info.entity'; +import type { Address } from 'viem'; import { getAddress } from 'viem'; import { Erc20Token, @@ -56,7 +57,7 @@ export class TransactionDataMapper { chainId: string, previewTransactionDto: PreviewTransactionDto, dataDecoded: DataDecoded | null, - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { const [toAddress, isTrustedDelegateCall, addressInfoIndex] = await Promise.all([ @@ -106,7 +107,7 @@ export class TransactionDataMapper { async isTrustedDelegateCall( chainId: string, operation: Operation, - to: `0x${string}`, + to: Address, dataDecoded: DataDecoded | null, ): Promise { if (operation !== Operation.DELEGATE) return null; @@ -140,9 +141,9 @@ export class TransactionDataMapper { */ async buildTokenInfoIndex(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; dataDecoded: BaseDataDecoded | null; - }): Promise> { + }): Promise> { if ( !args.dataDecoded?.parameters || args.dataDecoded.method !== MULTI_SEND_METHOD_NAME @@ -172,14 +173,14 @@ export class TransactionDataMapper { * @param args.chainId - chain ID to use * @param args.safeAddress - Safe address to use * @param args.parameters - array of {@link DataDecodedParameter} - * @returns {@link Array<`0x${string}`>} - array of token addresses + * @returns {@link Array
} - array of token addresses */ private _getBatchTransferredTokenAddresses(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; parameters: Array; - }): Array<`0x${string}`> { - const tokens = new Set<`0x${string}`>(); + }): Array
{ + const tokens = new Set
(); for (const parameter of args.parameters) { const isMultiSend = @@ -220,7 +221,7 @@ export class TransactionDataMapper { * @returns {@link Array} - array of token info */ private async _getTokenInfos(args: { - tokenAddresses: Array<`0x${string}`>; + tokenAddresses: Array
; chainId: string; }): Promise> { const tokenAddresses = args.tokenAddresses.slice( @@ -237,7 +238,7 @@ export class TransactionDataMapper { ); return { type: 'NATIVE_TOKEN' as const, - address: NULL_ADDRESS as `0x${string}`, + address: NULL_ADDRESS as Address, decimals: nativeCurrency.decimals, logoUri: nativeCurrency.logoUri, name: nativeCurrency.name, diff --git a/src/routes/transactions/mappers/common/transaction-info.mapper.ts b/src/routes/transactions/mappers/common/transaction-info.mapper.ts index 9943f2d0e8..63ee61b3cb 100644 --- a/src/routes/transactions/mappers/common/transaction-info.mapper.ts +++ b/src/routes/transactions/mappers/common/transaction-info.mapper.ts @@ -42,6 +42,7 @@ import { BaseDataDecoded, DataDecoded, } from '@/domain/data-decoder/v2/entities/data-decoded.entity'; +import type { Address } from 'viem'; @Injectable() export class MultisigTransactionInfoMapper { @@ -325,7 +326,7 @@ export class MultisigTransactionInfoMapper { return null; } - const orderData: `0x${string}` | null = this.swapOrderHelper.findSwapOrder( + const orderData: Address | null = this.swapOrderHelper.findSwapOrder( transaction.data, ); @@ -588,7 +589,7 @@ export class MultisigTransactionInfoMapper { } public isValidTokenTransfer( - safeAddress: `0x${string}`, + safeAddress: Address, dataDecoded: BaseDataDecoded | null, ): boolean { return ( @@ -611,7 +612,7 @@ export class MultisigTransactionInfoMapper { } private isSafeSenderOrReceiver( - safeAddress: `0x${string}`, + safeAddress: Address, dataDecoded: BaseDataDecoded | null, ): boolean { if (!dataDecoded) return false; diff --git a/src/routes/transactions/mappers/common/twap-order.mapper.ts b/src/routes/transactions/mappers/common/twap-order.mapper.ts index c4ba686b38..5cb2cbb7fe 100644 --- a/src/routes/transactions/mappers/common/twap-order.mapper.ts +++ b/src/routes/transactions/mappers/common/twap-order.mapper.ts @@ -29,6 +29,7 @@ import { SwapAppsHelperModule, } from '@/routes/transactions/helpers/swap-apps.helper'; import { GPv2OrderParameters } from '@/domain/swaps/contracts/decoders/gp-v2-decoder.helper'; +import type { Address, Hex } from 'viem'; @Injectable() export class TwapOrderMapper { @@ -61,8 +62,8 @@ export class TwapOrderMapper { */ async mapTwapOrder( chainId: string, - safeAddress: `0x${string}`, - transaction: { data: `0x${string}`; executionDate: Date | null }, + safeAddress: Address, + transaction: { data: Hex; executionDate: Date | null }, ): Promise { // Decode `staticInput` of `createWithContextCall` const twapStruct = this.composableCowDecoder.decodeTwapStruct( @@ -228,7 +229,7 @@ export class TwapOrderMapper { private async getPartOrders(args: { partsToFetch: Array; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise | null> { const orders: Array = []; @@ -274,10 +275,10 @@ export class TwapOrderMapper { private async getOrderStatus(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; twapParts: Array; partOrders: Array | null; - activeOrderUid: `0x${string}` | null; + activeOrderUid: Address | null; executionDate: Date | null; }): Promise { if (!args.executionDate) { diff --git a/src/routes/transactions/mappers/common/vault-transaction.mapper.spec.ts b/src/routes/transactions/mappers/common/vault-transaction.mapper.spec.ts index 2fb1c7ecf7..3c373676bc 100644 --- a/src/routes/transactions/mappers/common/vault-transaction.mapper.spec.ts +++ b/src/routes/transactions/mappers/common/vault-transaction.mapper.spec.ts @@ -15,7 +15,7 @@ import { VaultInfo } from '@/routes/transactions/entities/vaults/vault-info.enti import { VaultTransactionMapper } from '@/routes/transactions/mappers/common/vault-transaction.mapper'; import { faker } from '@faker-js/faker/.'; import { NotFoundException } from '@nestjs/common'; -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; const mockEarnRepository = jest.mocked({ getDeployment: jest.fn(), @@ -44,7 +44,7 @@ describe('VaultTransactionMapper', () => { it('should map deposit info correctly', async () => { const chain = chainBuilder().build(); const safeAddress = getAddress(faker.finance.ethereumAddress()); - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Address; const assets = 1_000_000; const deployment = deploymentBuilder() .with('product_type', 'defi') @@ -151,7 +151,7 @@ describe('VaultTransactionMapper', () => { it('should fail if the deployment product type is not DeFi', async () => { const chain = chainBuilder().build(); const safeAddress = getAddress(faker.finance.ethereumAddress()); - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Address; const assets = faker.number.int(); const deployment = deploymentBuilder() .with('product_type', 'pooling') @@ -174,7 +174,7 @@ describe('VaultTransactionMapper', () => { it('should fail if the deployment is not active', async () => { const chain = chainBuilder().build(); const safeAddress = getAddress(faker.finance.ethereumAddress()); - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Address; const assets = faker.number.int(); const deployment = deploymentBuilder() .with('product_type', 'defi') @@ -197,7 +197,7 @@ describe('VaultTransactionMapper', () => { it('should fail if the deployment chainId is different', async () => { const chain = chainBuilder().build(); const safeAddress = getAddress(faker.finance.ethereumAddress()); - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Address; const assets = faker.number.int(); const deployment = deploymentBuilder() .with('product_type', 'defi') @@ -225,7 +225,7 @@ describe('VaultTransactionMapper', () => { it('should map redeem info correctly', async () => { const chain = chainBuilder().build(); const safeAddress = getAddress(faker.finance.ethereumAddress()); - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Address; const assets = 1_000_000; const deployment = deploymentBuilder() .with('product_type', 'defi') @@ -329,7 +329,7 @@ describe('VaultTransactionMapper', () => { it('should fail if the deployment product type is not DeFi', async () => { const chain = chainBuilder().build(); const safeAddress = getAddress(faker.finance.ethereumAddress()); - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Address; const assets = faker.number.int(); const deployment = deploymentBuilder() .with('product_type', 'defi') @@ -352,7 +352,7 @@ describe('VaultTransactionMapper', () => { it('should fail if the deployment is not active', async () => { const chain = chainBuilder().build(); const safeAddress = getAddress(faker.finance.ethereumAddress()); - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Address; const assets = faker.number.int(); const deployment = deploymentBuilder() .with('product_type', 'defi') @@ -375,7 +375,7 @@ describe('VaultTransactionMapper', () => { it('should fail if the deployment chainId is different', async () => { const chain = chainBuilder().build(); const safeAddress = getAddress(faker.finance.ethereumAddress()); - const data = faker.string.hexadecimal() as `0x${string}`; + const data = faker.string.hexadecimal() as Address; const assets = faker.number.int(); const deployment = deploymentBuilder() .with('product_type', 'defi') diff --git a/src/routes/transactions/mappers/common/vault-transaction.mapper.ts b/src/routes/transactions/mappers/common/vault-transaction.mapper.ts index f20635fed0..87c87b7b1e 100644 --- a/src/routes/transactions/mappers/common/vault-transaction.mapper.ts +++ b/src/routes/transactions/mappers/common/vault-transaction.mapper.ts @@ -14,6 +14,7 @@ import { VaultRedeemTransactionInfo as VaultRedeemTransactionInfo, } from '@/routes/transactions/entities/vaults/vault-transaction-info.entity'; import { Inject, Injectable, NotFoundException } from '@nestjs/common'; +import type { Address } from 'viem'; @Injectable() export class VaultTransactionMapper { @@ -26,10 +27,10 @@ export class VaultTransactionMapper { public async mapDepositInfo(args: { chainId: string; - to: `0x${string}`; + to: Address; assets: number; - data: `0x${string}`; - safeAddress: `0x${string}`; + data: Address; + safeAddress: Address; }): Promise { const deployment = await this.earnRepository.getDeployment({ chainId: args.chainId, @@ -73,10 +74,10 @@ export class VaultTransactionMapper { public async mapRedeemInfo(args: { chainId: string; - to: `0x${string}`; + to: Address; assets: number; - data: `0x${string}`; - safeAddress: `0x${string}`; + data: Address; + safeAddress: Address; }): Promise { const deployment = await this.earnRepository.getDeployment({ chainId: args.chainId, @@ -133,7 +134,7 @@ export class VaultTransactionMapper { private async mapAdditionalRewards(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; additionalRewards: Array | null; }): Promise> { if (!args.additionalRewards) { diff --git a/src/routes/transactions/mappers/multisig-transactions/multisig-transaction-details.mapper.spec.ts b/src/routes/transactions/mappers/multisig-transactions/multisig-transaction-details.mapper.spec.ts index 78efec546d..15436bc253 100644 --- a/src/routes/transactions/mappers/multisig-transactions/multisig-transaction-details.mapper.spec.ts +++ b/src/routes/transactions/mappers/multisig-transactions/multisig-transaction-details.mapper.spec.ts @@ -21,6 +21,7 @@ import type { ILoggingService } from '@/logging/logging.interface'; import type { IContractsRepository } from '@/domain/contracts/contracts.repository.interface'; import { Operation } from '@/domain/safe/entities/operation.entity'; import { dataDecodedBuilder } from '@/domain/data-decoder/v2/entities/__tests__/data-decoded.builder'; +import type { Address } from 'viem'; const addressInfoHelper = jest.mocked({ getOrDefault: jest.fn(), @@ -73,7 +74,7 @@ describe('MultisigTransactionDetails mapper (Unit)', () => { function initTarget(args: { ethSign: boolean; - blocklist: Array<`0x${string}`>; + blocklist: Array
; }): void { mockConfigurationService.getOrThrow.mockImplementation((key) => { if (key === 'blockchain.blocklist') return args.blocklist; diff --git a/src/routes/transactions/mappers/multisig-transactions/multisig-transaction-details.mapper.ts b/src/routes/transactions/mappers/multisig-transactions/multisig-transaction-details.mapper.ts index f78f3d2f58..bc12961cdc 100644 --- a/src/routes/transactions/mappers/multisig-transactions/multisig-transaction-details.mapper.ts +++ b/src/routes/transactions/mappers/multisig-transactions/multisig-transaction-details.mapper.ts @@ -18,6 +18,7 @@ import { MultisigTransactionStatusMapper } from '@/routes/transactions/mappers/m import { MultisigTransactionNoteMapper } from '@/routes/transactions/mappers/multisig-transactions/multisig-transaction-note.mapper'; import { TransactionVerifierHelper } from '@/routes/transactions/helpers/transaction-verifier.helper'; import { DataDecoded } from '@/domain/data-decoder/v2/entities/data-decoded.entity'; +import { type Address } from 'viem'; @Injectable() export class MultisigTransactionDetailsMapper { @@ -116,7 +117,7 @@ export class MultisigTransactionDetailsMapper { */ private async _getRecipientAddressInfo( chainId: string, - address: `0x${string}`, + address: Address, ): Promise { return await this.addressInfoHelper.getOrDefault(chainId, address, [ 'TOKEN', diff --git a/src/routes/transactions/mappers/multisig-transactions/multisig-transaction.mapper.ts b/src/routes/transactions/mappers/multisig-transactions/multisig-transaction.mapper.ts index 49fb015122..e6d917847e 100644 --- a/src/routes/transactions/mappers/multisig-transactions/multisig-transaction.mapper.ts +++ b/src/routes/transactions/mappers/multisig-transactions/multisig-transaction.mapper.ts @@ -13,7 +13,7 @@ import { MultisigTransactionStatusMapper } from '@/routes/transactions/mappers/m import { TransactionVerifierHelper } from '@/routes/transactions/helpers/transaction-verifier.helper'; import { AddressInfoHelper } from '@/routes/common/address-info/address-info.helper'; import { DataDecodedParamHelper } from '@/routes/transactions/mappers/common/data-decoded-param.helper'; -import { getAddress, isAddress } from 'viem'; +import { type Address, getAddress, isAddress } from 'viem'; import { DataDecoded } from '@/domain/data-decoder/v2/entities/data-decoded.entity'; import { IDataDecoderRepository } from '@/domain/data-decoder/v2/data-decoder.repository.interface'; @@ -79,7 +79,7 @@ export class MultisigTransactionMapper { chainId: string; transactions: Array; }): Promise { - const addresses: Set<`0x${string}`> = new Set(); + const addresses: Set
= new Set(); for (const transaction of args.transactions) { addresses.add(transaction.safe); addresses.add(transaction.to); diff --git a/src/routes/transactions/mappers/transactions-history.mapper.ts b/src/routes/transactions/mappers/transactions-history.mapper.ts index 9aa409f72a..e82bb9d9c6 100644 --- a/src/routes/transactions/mappers/transactions-history.mapper.ts +++ b/src/routes/transactions/mappers/transactions-history.mapper.ts @@ -25,6 +25,7 @@ import { EthereumTransaction } from '@/domain/safe/entities/ethereum-transaction import { AddressInfoHelper } from '@/routes/common/address-info/address-info.helper'; import { DataDecoded } from '@/domain/data-decoder/v2/entities/data-decoded.entity'; import { IDataDecoderRepository } from '@/domain/data-decoder/v2/data-decoder.repository.interface'; +import type { Address } from 'viem'; @Injectable() export class TransactionsHistoryMapper { @@ -146,7 +147,7 @@ export class TransactionsHistoryMapper { private getAddressesFromTransfers( transferTransactions: Array, - ): Array<`0x${string}`> { + ): Array
{ return transferTransactions.flatMap((tx) => [ tx.from, @@ -155,7 +156,7 @@ export class TransactionsHistoryMapper { transfer.from, 'tokenAddress' in transfer ? transfer.tokenAddress : undefined, ]) ?? []), - ].filter((address): address is `0x${string}` => !!address), + ].filter((address): address is Address => !!address), ); } diff --git a/src/routes/transactions/mappers/transfers/swap-transfer-info.mapper.ts b/src/routes/transactions/mappers/transfers/swap-transfer-info.mapper.ts index a704e8aef6..b449e70be3 100644 --- a/src/routes/transactions/mappers/transfers/swap-transfer-info.mapper.ts +++ b/src/routes/transactions/mappers/transfers/swap-transfer-info.mapper.ts @@ -6,7 +6,7 @@ import { GPv2OrderHelper } from '@/routes/transactions/helpers/gp-v2-order.helpe import { SwapOrderHelper } from '@/routes/transactions/helpers/swap-order.helper'; import { AddressInfo } from '@/routes/common/entities/address-info.entity'; import { SwapTransferTransactionInfo } from '@/routes/transactions/swap-transfer-transaction-info.entity'; -import { getAddress, isAddressEqual } from 'viem'; +import { type Address, getAddress, isAddressEqual } from 'viem'; import { ISwapsRepository } from '@/domain/swaps/swaps.repository'; import { Order } from '@/domain/swaps/entities/order.entity'; import { SwapAppsHelper } from '@/routes/transactions/helpers/swap-apps.helper'; @@ -37,7 +37,7 @@ export class SwapTransferInfoMapper { recipient: AddressInfo; direction: TransferDirection; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; transferInfo: Transfer; domainTransfer: DomainTransfer; }): Promise { diff --git a/src/routes/transactions/mappers/transfers/transfer-info.mapper.ts b/src/routes/transactions/mappers/transfers/transfer-info.mapper.ts index 433f317a44..6f1b13776c 100644 --- a/src/routes/transactions/mappers/transfers/transfer-info.mapper.ts +++ b/src/routes/transactions/mappers/transfers/transfer-info.mapper.ts @@ -18,6 +18,7 @@ import { SwapTransferInfoMapper } from '@/routes/transactions/mappers/transfers/ import { SwapTransferTransactionInfo } from '@/routes/transactions/swap-transfer-transaction-info.entity'; import { AddressInfo } from '@/routes/common/entities/address-info.entity'; import { LoggingService, ILoggingService } from '@/logging/logging.interface'; +import { type Address } from 'viem'; @Injectable() export class TransferInfoMapper { @@ -84,7 +85,7 @@ export class TransferInfoMapper { recipient: AddressInfo; direction: TransferDirection; chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; transferInfo: Transfer; domainTransfer: DomainTransfer; }): Promise { @@ -137,7 +138,7 @@ export class TransferInfoMapper { private getToken( chainId: string, - tokenAddress: `0x${string}` | null, + tokenAddress: Address | null, ): Promise { if (!tokenAddress) { throw Error('Invalid token address for transfer'); diff --git a/src/routes/transactions/swap-transfer-transaction-info.entity.ts b/src/routes/transactions/swap-transfer-transaction-info.entity.ts index 663dcb8181..c97659d0f3 100644 --- a/src/routes/transactions/swap-transfer-transaction-info.entity.ts +++ b/src/routes/transactions/swap-transfer-transaction-info.entity.ts @@ -23,6 +23,7 @@ import { import { Erc20Transfer } from '@/routes/transactions/entities/transfers/erc20-transfer.entity'; import { Erc721Transfer } from '@/routes/transactions/entities/transfers/erc721-transfer.entity'; import { NativeCoinTransfer } from '@/routes/transactions/entities/transfers/native-coin-transfer.entity'; +import type { Address } from 'viem'; export class SwapTransferTransactionInfo extends TransactionInfo @@ -124,7 +125,7 @@ export class SwapTransferTransactionInfo @ApiProperty({ type: String, }) - owner: `0x${string}`; + owner: Address; @ApiPropertyOptional({ type: Object, @@ -156,7 +157,7 @@ export class SwapTransferTransactionInfo executedFee: string; executedFeeToken: TokenInfo; receiver: string | null; - owner: `0x${string}`; + owner: Address; fullAppData: Record | null; }) { // TransferTransactionInfo constructor diff --git a/src/routes/transactions/transactions-history.imitation-transactions.controller.spec.ts b/src/routes/transactions/transactions-history.imitation-transactions.controller.spec.ts index 8389d13667..a9efc8c87c 100644 --- a/src/routes/transactions/transactions-history.imitation-transactions.controller.spec.ts +++ b/src/routes/transactions/transactions-history.imitation-transactions.controller.spec.ts @@ -31,7 +31,7 @@ import { erc20TransferBuilder, toJson as erc20TransferToJson, } from '@/domain/safe/entities/__tests__/erc20-transfer.builder'; -import { getAddress, parseUnits, zeroAddress } from 'viem'; +import { type Address, getAddress, parseUnits, zeroAddress } from 'viem'; import { erc20TransferEncoder } from '@/domain/relay/contracts/__tests__/encoders/erc20-encoder.builder'; import type { EthereumTransaction } from '@/domain/safe/entities/ethereum-transaction.entity'; import type { MultisigTransaction } from '@/domain/safe/entities/multisig-transaction.entity'; @@ -97,7 +97,7 @@ describe('Transactions History Controller (Unit) - Imitation Transactions', () = await app.close(); }); - function getImitationAddress(address: `0x${string}`): `0x${string}` { + function getImitationAddress(address: Address): Address { // + 2 is to account for the '0x' prefix const prefix = address.slice(0, prefixLength + 2); const suffix = address.slice(-suffixLength); @@ -115,7 +115,7 @@ describe('Transactions History Controller (Unit) - Imitation Transactions', () = let multisigToken: Token; let multisigTransaction: MultisigTransaction; let multisigTransactionDataDecoded: DataDecoded; - let imitationAddress: `0x${string}`; + let imitationAddress: Address; let imitationToken: Token; let imitationOutgoingTransaction: EthereumTransaction; let imitationIncomingTransaction: EthereumTransaction; @@ -2857,7 +2857,7 @@ describe('Transactions History Controller (Unit) - Imitation Transactions', () = let notImitatedMultisigToken: Token; let notImitatedMultisigTransaction: MultisigTransaction; let notImitatedMultisigTransactionDataDecoded: DataDecoded; - let imitationAddress: `0x${string}`; + let imitationAddress: Address; let notImitatedMultisigTransfer: ERC20Transfer; let imitationIncomingTransfer: ERC20Transfer; let imitationIncomingTransaction: EthereumTransaction; diff --git a/src/routes/transactions/transactions.controller.ts b/src/routes/transactions/transactions.controller.ts index 08b63db454..23ad9b9901 100644 --- a/src/routes/transactions/transactions.controller.ts +++ b/src/routes/transactions/transactions.controller.ts @@ -54,6 +54,7 @@ import { TimezoneSchema } from '@/validation/entities/schemas/timezone.schema'; import { TXSMultisigTransaction } from '@/routes/transactions/entities/txs-multisig-transaction.entity'; import { TXSMultisigTransactionPage } from '@/routes/transactions/entities/txs-multisig-transaction-page.entity'; import { TXSCreationTransaction } from '@/routes/transactions/entities/txs-creation-transaction.entity'; +import type { Address } from 'viem'; @ApiTags('transactions') @Controller({ @@ -144,7 +145,7 @@ export class TransactionsController { async getDomainMultisigTransactions( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Param('failed', new ParseBoolPipe({ optional: true })) failed?: boolean, @Query('modified__lt') modified__lt?: string, @Query('modified__gt') modified__gt?: string, @@ -283,11 +284,11 @@ export class TransactionsController { @RouteUrlDecorator() routeUrl: URL, @PaginationDataDecorator() paginationData: PaginationData, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Query('execution_date__gte') executionDateGte?: string, @Query('execution_date__lte') executionDateLte?: string, @Query('to', new ValidationPipe(AddressSchema.optional())) - to?: `0x${string}`, + to?: Address, @Query('value') value?: string, @Query('nonce') nonce?: string, @Query('executed', new ParseBoolPipe({ optional: true })) @@ -400,7 +401,7 @@ export class TransactionsController { @RouteUrlDecorator() routeUrl: URL, @PaginationDataDecorator() paginationData: PaginationData, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Query('to') to?: string, @Query('module') module?: string, @Query('transaction_hash') txHash?: string, @@ -534,17 +535,17 @@ export class TransactionsController { @Param('chainId') chainId: string, @RouteUrlDecorator() routeUrl: URL, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @PaginationDataDecorator() paginationData: PaginationData, @Query('trusted', new DefaultValuePipe(true), ParseBoolPipe) trusted: boolean, @Query('execution_date__gte') executionDateGte?: string, @Query('execution_date__lte') executionDateLte?: string, @Query('to', new ValidationPipe(AddressSchema.optional())) - to?: `0x${string}`, + to?: Address, @Query('value') value?: string, @Query('token_address', new ValidationPipe(AddressSchema.optional())) - tokenAddress?: `0x${string}`, + tokenAddress?: Address, ): Promise>> { return this.transactionsService.getIncomingTransfers({ chainId, @@ -597,7 +598,7 @@ export class TransactionsController { async previewTransaction( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Body(new ValidationPipe(PreviewTransactionDtoSchema)) previewTransactionDto: PreviewTransactionDto, ): Promise { @@ -646,7 +647,7 @@ export class TransactionsController { @Param('chainId') chainId: string, @RouteUrlDecorator() routeUrl: URL, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @PaginationDataDecorator() paginationData: PaginationData, @Query('trusted', new DefaultValuePipe(true), ParseBoolPipe) trusted: boolean, @@ -720,7 +721,7 @@ export class TransactionsController { @Param('chainId') chainId: string, @RouteUrlDecorator() routeUrl: URL, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @PaginationDataDecorator() paginationData: PaginationData, @Query('timezone_offset', new DefaultValuePipe(0), ParseIntPipe) timezoneOffsetMs: number, @@ -776,7 +777,7 @@ export class TransactionsController { async proposeTransaction( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, @Body(new ValidationPipe(ProposeTransactionDtoSchema)) proposeTransactionDto: ProposeTransactionDto, ): Promise { @@ -815,7 +816,7 @@ export class TransactionsController { async getCreationTransaction( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { return this.transactionsService.getCreationTransaction({ chainId, @@ -830,7 +831,7 @@ export class TransactionsController { async getDomainCreationTransaction( @Param('chainId') chainId: string, @Param('safeAddress', new ValidationPipe(AddressSchema)) - safeAddress: `0x${string}`, + safeAddress: Address, ): Promise { return this.transactionsService.getDomainCreationTransaction({ chainId, diff --git a/src/routes/transactions/transactions.service.ts b/src/routes/transactions/transactions.service.ts index afebe69692..27655c8bdf 100644 --- a/src/routes/transactions/transactions.service.ts +++ b/src/routes/transactions/transactions.service.ts @@ -52,6 +52,7 @@ import { TXSCreationTransaction } from '@/routes/transactions/entities/txs-creat import { ITokenRepository } from '@/domain/tokens/token.repository.interface'; import { IConfigurationService } from '@/config/configuration.service.interface'; import { IDataDecoderRepository } from '@/domain/data-decoder/v2/data-decoder.repository.interface'; +import type { Address } from 'viem'; @Injectable() export class TransactionsService { @@ -210,10 +211,10 @@ export class TransactionsService { chainId: string; routeUrl: Readonly; paginationData: PaginationData; - safeAddress: `0x${string}`; + safeAddress: Address; executionDateGte?: string; executionDateLte?: string; - to?: `0x${string}`; + to?: Address; value?: string; nonce?: string; executed?: boolean; @@ -280,7 +281,7 @@ export class TransactionsService { } async getDomainMultisigTransactions(args: { - safeAddress: `0x${string}`; + safeAddress: Address; chainId: string; // Transaction Service parameters failed?: boolean; @@ -353,7 +354,7 @@ export class TransactionsService { async getModuleTransactions(args: { chainId: string; routeUrl: Readonly; - safeAddress: `0x${string}`; + safeAddress: Address; to?: string; module?: string; txHash?: string; @@ -401,12 +402,12 @@ export class TransactionsService { async getIncomingTransfers(args: { chainId: string; routeUrl: Readonly; - safeAddress: `0x${string}`; + safeAddress: Address; executionDateGte?: string; executionDateLte?: string; - to?: `0x${string}`; + to?: Address; value?: string; - tokenAddress?: `0x${string}`; + tokenAddress?: Address; paginationData?: PaginationData; onlyTrusted: boolean; }): Promise>> { @@ -451,7 +452,7 @@ export class TransactionsService { async previewTransaction(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; previewTransactionDto: PreviewTransactionDto; }): Promise { const safe = await this.safeRepository.getSafe({ @@ -468,7 +469,7 @@ export class TransactionsService { async getTransactionQueue(args: { chainId: string; routeUrl: Readonly; - safeAddress: `0x${string}`; + safeAddress: Address; paginationData: PaginationData; trusted?: boolean; }): Promise> { @@ -518,7 +519,7 @@ export class TransactionsService { async getTransactionHistory(args: { chainId: string; routeUrl: Readonly; - safeAddress: `0x${string}`; + safeAddress: Address; paginationData: PaginationData; timezoneOffsetMs: number; onlyTrusted: boolean; @@ -574,7 +575,7 @@ export class TransactionsService { async proposeTransaction(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; proposeTransactionDto: ProposeTransactionDto; }): Promise { this.logProposeTx(args); @@ -608,7 +609,7 @@ export class TransactionsService { async getCreationTransaction(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const tx = await this.safeRepository.getCreationTransaction(args); const dataDecoded = @@ -624,7 +625,7 @@ export class TransactionsService { async getDomainCreationTransaction(args: { chainId: string; - safeAddress: `0x${string}`; + safeAddress: Address; }): Promise { const tx = await this.safeRepository.getCreationTransaction(args); return new TXSCreationTransaction(tx); @@ -660,7 +661,7 @@ export class TransactionsService { private async parseTokenValue(args: { chainId: string; value: string; - tokenAddress?: `0x${string}`; + tokenAddress?: Address; }): Promise { if (!args.tokenAddress) { return parseEther(args.value).toString(); diff --git a/src/routes/users/entities/user-with-wallets.entity.ts b/src/routes/users/entities/user-with-wallets.entity.ts index ba45dddce2..65def9152d 100644 --- a/src/routes/users/entities/user-with-wallets.entity.ts +++ b/src/routes/users/entities/user-with-wallets.entity.ts @@ -2,13 +2,14 @@ import { ApiExtraModels, ApiProperty } from '@nestjs/swagger'; import { UserStatus } from '@/domain/users/entities/user.entity'; import type { User } from '@/domain/users/entities/user.entity'; import type { Wallet } from '@/domain/wallets/entities/wallet.entity'; +import type { Address } from 'viem'; class UserWallet implements Pick { @ApiProperty() id!: number; @ApiProperty() - address!: `0x${string}`; + address!: Address; } @ApiExtraModels(UserWallet) diff --git a/src/routes/users/users.controller.spec.ts b/src/routes/users/users.controller.spec.ts index 29ca1536bf..83c4cf9c2e 100644 --- a/src/routes/users/users.controller.spec.ts +++ b/src/routes/users/users.controller.spec.ts @@ -1,4 +1,4 @@ -import { getAddress } from 'viem'; +import { type Address, getAddress } from 'viem'; import { faker } from '@faker-js/faker'; import request from 'supertest'; import { TestAppProvider } from '@/__tests__/test-app.provider'; @@ -135,7 +135,7 @@ describe('UsersController', () => { it('should return a 403 is the AuthPayload is empty', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); @@ -198,7 +198,7 @@ describe('UsersController', () => { it('should return a 403 is the AuthPayload is empty', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); @@ -259,7 +259,7 @@ describe('UsersController', () => { it('should return a 403 is the AuthPayload is empty', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); @@ -355,7 +355,7 @@ describe('UsersController', () => { it('should return a 403 is the AuthPayload is empty', async () => { const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); @@ -892,7 +892,7 @@ ${messageObj.resources?.reduce((acc, cur) => `${acc}\n- ${cur}`, 'Resources:')}` it('should return a 403 is the AuthPayload is empty', async () => { const walletAddress = getAddress(faker.finance.ethereumAddress()); const authPayloadDto = authPayloadDtoBuilder() - .with('signer_address', undefined as unknown as `0x${string}`) + .with('signer_address', undefined as unknown as Address) .build(); const accessToken = jwtService.sign(authPayloadDto); diff --git a/src/routes/users/users.controller.ts b/src/routes/users/users.controller.ts index 8f139cfb70..2863a2cfe4 100644 --- a/src/routes/users/users.controller.ts +++ b/src/routes/users/users.controller.ts @@ -30,6 +30,7 @@ import { WalletAddedToUser } from '@/routes/users/entities/wallet-added-to-user. import { SiweDtoSchema } from '@/routes/auth/entities/siwe.dto.entity'; import { SiweDto } from '@/routes/auth/entities/siwe.dto.entity'; import type { AuthPayload } from '@/domain/auth/entities/auth-payload.entity'; +import { type Address } from 'viem'; @ApiTags('users') @Controller({ path: 'users', version: '1' }) @@ -172,7 +173,7 @@ export class UsersController { @UseGuards(AuthGuard) public async deleteWalletFromUser( @Param('walletAddress', new ValidationPipe(AddressSchema)) - walletAddress: `0x${string}`, + walletAddress: Address, @Auth() authPayload: AuthPayload, ): Promise { return await this.usersService.deleteWalletFromUser({ diff --git a/src/routes/users/users.service.ts b/src/routes/users/users.service.ts index a84241f7f5..2a7be8d607 100644 --- a/src/routes/users/users.service.ts +++ b/src/routes/users/users.service.ts @@ -9,6 +9,7 @@ import type { CreatedUserWithWallet } from '@/routes/users/entities/created-user import type { WalletAddedToUser } from '@/routes/users/entities/wallet-added-to-user.entity'; import { getEnumKey } from '@/domain/common/utils/enum'; import type { SiweDto } from '@/routes/auth/entities/siwe.dto.entity'; +import type { Address } from 'viem'; export class UsersService { public constructor( @@ -53,7 +54,7 @@ export class UsersService { public async deleteWalletFromUser(args: { authPayload: AuthPayload; - walletAddress: `0x${string}`; + walletAddress: Address; }): Promise { return await this.usersRepository.deleteWalletFromUser(args); } diff --git a/src/validation/entities/schemas/__tests__/event-topics.schema.spec.ts b/src/validation/entities/schemas/__tests__/event-topics.schema.spec.ts index 2bbc7fbc85..74fce429a8 100644 --- a/src/validation/entities/schemas/__tests__/event-topics.schema.spec.ts +++ b/src/validation/entities/schemas/__tests__/event-topics.schema.spec.ts @@ -1,10 +1,11 @@ import { EventTopicsSchema } from '@/validation/entities/schemas/event-topics.schema'; import { faker } from '@faker-js/faker/.'; +import type { Address } from 'viem'; describe('EventTopicsSchema', () => { it('validate an EventTopicsSchema', () => { const eventTopics = faker.helpers.multiple( - () => faker.string.hexadecimal() as `0x${string}`, + () => faker.string.hexadecimal() as Address, { count: { min: 1, max: 5 } }, ); @@ -30,7 +31,7 @@ describe('EventTopicsSchema', () => { it('should not allow non-hex topics', () => { const topics = faker.helpers.multiple( - () => faker.string.alpha() as `0x${string}`, + () => faker.string.alpha() as Address, { count: { min: 1, max: 5 } }, ); diff --git a/src/validation/entities/schemas/__tests__/signature.schema.spec.ts b/src/validation/entities/schemas/__tests__/signature.schema.spec.ts index c4b1d3cc09..e9d3fac98d 100644 --- a/src/validation/entities/schemas/__tests__/signature.schema.spec.ts +++ b/src/validation/entities/schemas/__tests__/signature.schema.spec.ts @@ -1,11 +1,12 @@ import { faker } from '@faker-js/faker'; import { SignatureSchema } from '@/validation/entities/schemas/signature.schema'; +import type { Hex } from 'viem'; describe('SignatureSchema', () => { it('should validate a signature', () => { const signature = faker.string.hexadecimal({ length: 130, - }) as `0x${string}`; + }) as Hex; const result = SignatureSchema.safeParse(signature); @@ -15,7 +16,7 @@ describe('SignatureSchema', () => { it('should validate a concatenated signature', () => { const signature = faker.string.hexadecimal({ length: 130 * faker.number.int({ min: 2, max: 5 }), - }) as `0x${string}`; + }) as Hex; const result = SignatureSchema.safeParse(signature); @@ -23,7 +24,7 @@ describe('SignatureSchema', () => { }); it('should not validate a non-hex signature', () => { - const signature = faker.string.alphanumeric() as `0x${string}`; + const signature = faker.string.alphanumeric() as Hex; const result = SignatureSchema.safeParse(signature); @@ -49,7 +50,7 @@ describe('SignatureSchema', () => { it('should not validate a incorrect length signature', () => { const signature = faker.string.hexadecimal({ length: 129, - }) as `0x${string}`; + }) as Hex; const result = SignatureSchema.safeParse(signature); diff --git a/src/validation/entities/schemas/hexbytes.schema.ts b/src/validation/entities/schemas/hexbytes.schema.ts index adcf7d97a4..c5a7a88621 100644 --- a/src/validation/entities/schemas/hexbytes.schema.ts +++ b/src/validation/entities/schemas/hexbytes.schema.ts @@ -1,6 +1,7 @@ import { HexSchema } from '@/validation/entities/schemas/hex.schema'; +import type { Address } from 'viem'; -export function isHexBytes(value: `0x${string}`): boolean { +export function isHexBytes(value: Address): boolean { return value.length % 2 === 0; } diff --git a/src/validation/entities/schemas/signature.schema.ts b/src/validation/entities/schemas/signature.schema.ts index d060666364..cc777d1ab2 100644 --- a/src/validation/entities/schemas/signature.schema.ts +++ b/src/validation/entities/schemas/signature.schema.ts @@ -1,12 +1,13 @@ import { SIGNATURE_HEX_LENGTH } from '@/domain/common/utils/signatures'; import { HEX_PREFIX_LENGTH } from '@/routes/common/constants'; import { HexBytesSchema } from '@/validation/entities/schemas/hexbytes.schema'; +import type { Hex } from 'viem'; // We only validate the likeness of a signature, e.g. that it is at least // an EOA but maybe a contract signature or an unknown concatenation of // both as this schema is used for signatures in the queue/history. // We only verify the integrity of signatures in the queue. -export function isSignatureLike(value: `0x${string}`): boolean { +export function isSignatureLike(value: Hex): boolean { return value.length - HEX_PREFIX_LENGTH >= SIGNATURE_HEX_LENGTH; }