feat: add Starknet blockchain integration#3570
Draft
TaprootFreak wants to merge 8 commits intodevelopfrom
Draft
Conversation
Add full Starknet support as a non-EVM blockchain with native account abstraction. Includes client, service, module, DTOs, deployment script, config entries, explorer URLs, and exchange service mappings. Env vars: STARKNET_GATEWAY_URL, STARKNET_WALLET_ADDRESS, STARKNET_WALLET_PRIVATE_KEY
Starkscan permanently redirects to Voyager (301). Replace explorer URL. Use isSuccess() type guard instead of as-any casts on receipt types.
Add address detection, signature verification, payment request, and UserAddressType for Starknet in CryptoService. Signature verification uses on-chain verifyMessageInStarknet via the account contract.
- BlockchainAdapter: add STARKNET to token client balance update - PaymentLinkFeeService: add STARKNET with fee 0 - PaymentBalanceService: add STARKNET to chainsWithoutPaymentBalance - PaymentRequestMapper: add STARKNET to payment link payment case
- Remove unused HttpService injection (starknet SDK handles HTTP) - Remove unused StarknetTokenDto - Remove unnecessary SharedModule import - Fix verifySignature: hash message with starknetKeccak before verify - Reduce local variables in getTokenBalance/getTokenBalances - Align section comments with codebase convention (UPPERCASE) - Reorder methods: balances, transactions, send, verification, fees
Account creation is now conditional — only instantiated when STARKNET_WALLET_ADDRESS and STARKNET_WALLET_PRIVATE_KEY are set. Write operations throw a clear error instead of crashing on startup.
Contract.call('balanceOf') returns { balance: bigint }, not a raw
value. Destructure the named field instead of calling toString()
on the object (which produced "[object Object]" → NaN).
Verified with integration tests against Starknet mainnet:
15/15 tests pass (balance, decimals, receipts, tx queries, hashing).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add Starknet (L2 ZK-STARK rollup on Ethereum) as new non-EVM blockchain with native account abstraction. This PR covers the infrastructure layer — blockchain client, service, address detection, signature verification, explorer URLs, and all enum/registry mappings.
Starknet is NOT EVM-compatible. It uses its own Cairo VM, stark-curve ECDSA signatures, felt-based addresses (32 bytes), and native account abstraction (every account is a smart contract). The integration follows the same pattern as Solana/Monero (custom
BlockchainClientimplementation).New files
src/integration/blockchain/starknet/starknet-client.ts— RPC client (balance, send, tx queries, signature verification)src/integration/blockchain/starknet/services/starknet.service.ts— NestJS service wrappersrc/integration/blockchain/starknet/starknet.module.ts— NestJS modulesrc/integration/blockchain/starknet/starknet.util.ts— Wei/amount conversions (18 decimals for STRK and ETH)src/integration/blockchain/starknet/dto/starknet.dto.ts— Transaction/token DTOsscripts/deploy-starknet-account.ts— Key generation + OZ account contract deploymentModified files (infrastructure)
blockchain.enum.ts—STARKNET = 'Starknet'blockchain.module.ts— import/exportStarknetModuleblockchain-registry.service.ts— registerStarknetService/StarknetClientin types and switchblockchain.util.ts— explorer URL (voyager.online), tx/address/token pathsconfig.ts— address format (0x[0-9a-fA-F]{50,64}), signature format, env vars, blockchain config blockcrypto.service.ts— address detection, signature verification (on-chain via account contract), payment request,UserAddressType.STARKNETuser.enum.ts—STARKNET = 'Starknet'inUserAddressTypeModified files (enum mappings)
exchange.test.ts—Starknet: undefinedref-reward.service.ts—Starknet: undefinedinPayoutLimitsModified files (business layer)
blockchain.adapter.ts— addSTARKNETto token client balance update (prevents crash in liquidity management)payment-link-fee.service.ts— addSTARKNETwith fee 0payment-balance.service.ts— addSTARKNETtochainsWithoutPaymentBalancepayment-request.mapper.ts— addSTARKNETto payment link payment caseEnvironment variables
STARKNET_GATEWAY_URL— RPC endpoint (Alchemy, Infura, etc.)STARKNET_WALLET_ADDRESS— deployed account contract addressSTARKNET_WALLET_PRIVATE_KEY— stark-curve private keyDependencies
starknet^9.4.2 (starknet.js SDK)Account deployment (before first use)
Starknet has native account abstraction — every account is a smart contract. Before the wallet can send transactions, the account contract must be deployed once:
Uses OpenZeppelin Account v0.8.1 class hash (verified against starknet.js docs).
Open items (follow-up PRs)
Payout/Payin/DEX strategies (not needed until assets are activated)
Strategy files are required per blockchain for payout, payin, and DEX operations. These are only triggered when Starknet assets exist in the database AND are enabled for buy/sell. Without DB assets, no code path reaches these strategies.
Needed files (follow same pattern as Solana strategies):
payout/strategies/payout/impl/starknet-coin.strategy.tspayout/strategies/payout/impl/starknet-token.strategy.tspayout/strategies/prepare/impl/starknet.strategy.tspayin/strategies/register/impl/starknet.strategy.tspayin/strategies/send/impl/starknet-coin.strategy.tspayin/strategies/send/impl/starknet-token.strategy.tsdex/strategies/check-liquidity/impl/starknet-coin.strategy.tsdex/strategies/check-liquidity/impl/starknet-token.strategy.tsdex/strategies/purchase-liquidity/impl/starknet-coin.strategy.tsdex/strategies/purchase-liquidity/impl/starknet-token.strategy.tsdex/strategies/sell-liquidity/impl/starknet-coin.strategy.tsdex/strategies/sell-liquidity/impl/starknet-token.strategy.tsdex/strategies/supplementary/impl/starknet.strategy.tsPlus corresponding strategy registry tests.
Deposit address generation (Account Abstraction complexity)
deposit.service.tsneeds acreateStarknetDeposits()method. Unlike EVM/Solana where addresses are derived from a seed, Starknet requires deploying an account contract for each deposit address. This needs a custom implementation:This is architecturally different from all other blockchains and warrants its own PR.
Balance/Transaction API endpoints
blockchain-balance.service.tsandblockchain-transaction.service.tsneed Starknet cases for the external REST API. Currently returnsBadRequestException("Blockchain Starknet is not supported for balance queries")— acceptable for initial rollout.Payment Link full support
Starknet is in
chainsWithoutPaymentBalance, so payment links won't be generated. To enable:STARKNETtoPaymentLinkBlockchainsarraySTARKNETtopayment-activation.service.tsswitchSTARKNETtoVerifiedTxIdBlockchainsorUnverifiedTxIdBlockchainsin payment-link enumschainsWithoutPaymentBalanceExchange network mappings
All exchange services have
Starknet: undefined. When exchanges add Starknet withdrawal support, update with the correct network name (e.g.Starknet: 'STRK'for Binance).Database
Create Starknet assets in the database:
Coin, decimals: 18)Token, chainId:0x049d...dc7, decimals: 18)Test plan
npm run build)