You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(deposits): add chain-specific address handling for L2 deposits
This commit fixes a critical bug in the gasless deposit flow where all L2
chains were receiving 20-byte Ethereum addresses, which is incorrect for
non-EVM chains like Sui and StarkNet that require 32-byte addresses.
Changes:
- Add EVM_L2_CHAINS constant to identify EVM-compatible L2s (Arbitrum, Base)
- Add isEVML2Chain() helper method for chain type detection
- Update buildGaslessRelayPayload() to use chain-specific owner extraction:
- EVM L2s (Arbitrum, Base): Extract 20-byte address from 32-byte extraData
- Non-EVM L2s (Sui, StarkNet): Use full 32-byte extraData as owner
- Fix existing tests to use correct 32-byte fixtures for non-EVM chains
- Add comprehensive test coverage for all chain types and edge cases
- Improve JSDoc documentation for gasless deposit methods
This ensures deposits to Sui and StarkNet chains will use the correct
address format, preventing deposit failures on non-EVM L2 chains.
@@ -465,7 +480,7 @@ proper extraData encoding for the destination chain.
465
480
| Name | Type | Description |
466
481
| :------ | :------ | :------ |
467
482
|`bitcoinRecoveryAddress`|`string`| P2PKH or P2WPKH Bitcoin address for emergency recovery |
468
-
|`depositOwner`|`string`| Ethereum address that will receive the minted tBTC. For L1 deposits, this is the user's Ethereum address. For L2 deposits, this is typically the signer's address (obtained from the destination chain BitcoinDepositor). |
483
+
|`depositOwner`|`string`| Ethereum address that will receive the minted tBTC. - For L1 deposits: This address is used directly and encoded as bytes32 in the deposit's extraData. - For L2 deposits: This parameter is currently ignored; the deposit owner is automatically resolved from the destination chain's BitcoinDepositor contract (typically the signer's address). This ensures proper integration with the L2 cross-chain infrastructure. |
469
484
|`destinationChainName`|[`GaslessDestination`](../README.md#gaslessdestination)| Target chain name for the deposit. Must be one of the supported chains (case-sensitive): - "L1" - Direct L1 deposits via NativeBTCDepositor - "Arbitrum" - Arbitrum L2 deposits - "Base" - Base L2 deposits - "Sui" - Sui L2 deposits - "StarkNet" - StarkNet L2 deposits (note: capital 'N') Note: "Solana" is not currently supported for gasless deposits |
470
485
471
486
#### Returns
@@ -478,16 +493,15 @@ GaslessDepositResult containing deposit object, receipt, and chain name
478
493
479
494
Throws an error if:
480
495
- Bitcoin recovery address is not P2PKH or P2WPKH
481
-
- Deposit owner is not a valid Ethereum address
482
496
- Destination chain name is not in the supported list
483
497
- Destination chain contracts not initialized (for L2 deposits)
484
498
- NativeBTCDepositor address not available (for L1 deposits)
485
-
- Deposit owner cannot be resolved (for L2 deposits)
499
+
- Deposit owner cannot be resolved from L2 signer (for L2 deposits)
Internal helper for L2 gasless deposits using L1BitcoinDepositor.
524
-
Pattern based on initiateCrossChainDeposit.
547
+
548
+
This method creates a cross-chain deposit where the deposit owner is
549
+
automatically resolved from the L2 BitcoinDepositor contract. The pattern
550
+
is based on initiateCrossChainDeposit but returns the enriched
551
+
GaslessDepositResult instead of just a Deposit object.
525
552
526
553
#### Parameters
527
554
528
555
| Name | Type | Description |
529
556
| :------ | :------ | :------ |
530
557
|`bitcoinRecoveryAddress`|`string`| Bitcoin address for recovery if deposit fails (P2PKH or P2WPKH). |
531
-
|`destinationChainName`|[`DestinationChainName`](../README.md#destinationchainname)| Name of the L2 destination chain (e.g., "Base", "Arbitrum", "Optimism"). |
558
+
|`destinationChainName`|[`DestinationChainName`](../README.md#destinationchainname)| Name of the L2 destination chain (e.g., "Base", "Arbitrum", "Sui", "StarkNet"). |
0 commit comments