Skip to content

Commit ac56381

Browse files
committed
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.
1 parent c8ec759 commit ac56381

File tree

4 files changed

+476
-49
lines changed

4 files changed

+476
-49
lines changed

typescript/api-reference/classes/DepositsService.md

Lines changed: 81 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Service exposing features related to tBTC v2 deposits.
1616
- [ADDRESS\_HEX\_CHARS](DepositsService.md#address_hex_chars)
1717
- [ADDRESS\_HEX\_LENGTH](DepositsService.md#address_hex_length)
1818
- [BYTES32\_HEX\_LENGTH](DepositsService.md#bytes32_hex_length)
19+
- [EVM\_L2\_CHAINS](DepositsService.md#evm_l2_chains)
1920
- [SUPPORTED\_GASLESS\_CHAINS](DepositsService.md#supported_gasless_chains)
2021
- [bitcoinClient](DepositsService.md#bitcoinclient)
2122
- [depositRefundLocktimeDuration](DepositsService.md#depositrefundlocktimeduration)
@@ -32,6 +33,7 @@ Service exposing features related to tBTC v2 deposits.
3233
- [initiateGaslessDeposit](DepositsService.md#initiategaslessdeposit)
3334
- [initiateL1GaslessDeposit](DepositsService.md#initiatel1gaslessdeposit)
3435
- [initiateL2GaslessDeposit](DepositsService.md#initiatel2gaslessdeposit)
36+
- [isEVML2Chain](DepositsService.md#isevml2chain)
3537
- [resolveNativeBTCDepositorFromNetwork](DepositsService.md#resolvenativebtcdepositorfromnetwork)
3638
- [setDefaultDepositor](DepositsService.md#setdefaultdepositor)
3739
- [setNativeBTCDepositor](DepositsService.md#setnativebtcdepositor)
@@ -57,7 +59,7 @@ Service exposing features related to tBTC v2 deposits.
5759

5860
#### Defined in
5961

60-
[services/deposits/deposits-service.ts:235](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L235)
62+
[services/deposits/deposits-service.ts:241](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L241)
6163

6264
## Properties
6365

@@ -83,7 +85,7 @@ Gets cross-chain contracts for the given supported L2 chain.
8385

8486
#### Defined in
8587

86-
[services/deposits/deposits-service.ts:226](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L226)
88+
[services/deposits/deposits-service.ts:232](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L232)
8789

8890
___
8991

@@ -96,7 +98,7 @@ initiated by this service.
9698

9799
#### Defined in
98100

99-
[services/deposits/deposits-service.ts:219](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L219)
101+
[services/deposits/deposits-service.ts:225](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L225)
100102

101103
___
102104

@@ -109,7 +111,7 @@ L1 gasless deposits.
109111

110112
#### Defined in
111113

112-
[services/deposits/deposits-service.ts:233](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L233)
114+
[services/deposits/deposits-service.ts:239](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L239)
113115

114116
___
115117

@@ -122,7 +124,7 @@ Used when extracting address from bytes32 extraData.
122124

123125
#### Defined in
124126

125-
[services/deposits/deposits-service.ts:205](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L205)
127+
[services/deposits/deposits-service.ts:211](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L211)
126128

127129
___
128130

@@ -135,7 +137,7 @@ Used for L2 deposit owner encoding and extraData validation.
135137

136138
#### Defined in
137139

138-
[services/deposits/deposits-service.ts:199](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L199)
140+
[services/deposits/deposits-service.ts:205](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L205)
139141

140142
___
141143

@@ -148,6 +150,19 @@ Used for L1 deposit owner encoding and extraData validation.
148150

149151
#### Defined in
150152

153+
[services/deposits/deposits-service.ts:199](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L199)
154+
155+
___
156+
157+
### EVM\_L2\_CHAINS
158+
159+
`Private` `Readonly` **EVM\_L2\_CHAINS**: readonly [``"Arbitrum"``, ``"Base"``]
160+
161+
EVM-compatible L2 chains that require 20-byte address format for deposit owners.
162+
Non-EVM L2s (Sui, StarkNet) require 32-byte format.
163+
164+
#### Defined in
165+
151166
[services/deposits/deposits-service.ts:193](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L193)
152167

153168
___
@@ -177,7 +192,7 @@ Bitcoin client handle.
177192

178193
#### Defined in
179194

180-
[services/deposits/deposits-service.ts:214](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L214)
195+
[services/deposits/deposits-service.ts:220](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L220)
181196

182197
___
183198

@@ -202,7 +217,7 @@ Handle to tBTC contracts.
202217

203218
#### Defined in
204219

205-
[services/deposits/deposits-service.ts:210](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L210)
220+
[services/deposits/deposits-service.ts:216](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L216)
206221

207222
## Methods
208223

@@ -274,7 +289,7 @@ Error if vault address cannot be retrieved from contracts
274289

275290
#### Defined in
276291

277-
[services/deposits/deposits-service.ts:562](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L562)
292+
[services/deposits/deposits-service.ts:596](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L596)
278293

279294
___
280295

@@ -296,7 +311,7 @@ ___
296311

297312
#### Defined in
298313

299-
[services/deposits/deposits-service.ts:699](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L699)
314+
[services/deposits/deposits-service.ts:745](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L745)
300315

301316
___
302317

@@ -315,7 +330,7 @@ Chain identifier of the NativeBTCDepositor or undefined if not available.
315330

316331
#### Defined in
317332

318-
[services/deposits/deposits-service.ts:658](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L658)
333+
[services/deposits/deposits-service.ts:704](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L704)
319334

320335
___
321336

@@ -369,7 +384,7 @@ This is actually a call to initiateDepositWithProxy with a built-in
369384

370385
#### Defined in
371386

372-
[services/deposits/deposits-service.ts:351](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L351)
387+
[services/deposits/deposits-service.ts:368](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L368)
373388

374389
___
375390

@@ -403,7 +418,7 @@ Throws an error if one of the following occurs:
403418

404419
#### Defined in
405420

406-
[services/deposits/deposits-service.ts:264](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L264)
421+
[services/deposits/deposits-service.ts:281](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L281)
407422

408423
___
409424

@@ -445,7 +460,7 @@ Throws an error if one of the following occurs:
445460

446461
#### Defined in
447462

448-
[services/deposits/deposits-service.ts:303](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L303)
463+
[services/deposits/deposits-service.ts:320](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L320)
449464

450465
___
451466

@@ -465,7 +480,7 @@ proper extraData encoding for the destination chain.
465480
| Name | Type | Description |
466481
| :------ | :------ | :------ |
467482
| `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. |
469484
| `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 |
470485

471486
#### Returns
@@ -478,16 +493,15 @@ GaslessDepositResult containing deposit object, receipt, and chain name
478493

479494
Throws an error if:
480495
- Bitcoin recovery address is not P2PKH or P2WPKH
481-
- Deposit owner is not a valid Ethereum address
482496
- Destination chain name is not in the supported list
483497
- Destination chain contracts not initialized (for L2 deposits)
484498
- 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)
486500
- No active wallet in Bridge contract
487501

488502
#### Defined in
489503

490-
[services/deposits/deposits-service.ts:402](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L402)
504+
[services/deposits/deposits-service.ts:422](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L422)
491505

492506
___
493507

@@ -497,22 +511,31 @@ ___
497511

498512
Internal helper for L1 gasless deposits using NativeBTCDepositor.
499513

514+
This method creates an L1 deposit where the depositOwner is encoded as
515+
bytes32 extraData in the deposit receipt. The NativeBTCDepositor address
516+
is resolved either from the constructor parameter, the setter override,
517+
or the network-based mapping.
518+
500519
#### Parameters
501520

502521
| Name | Type | Description |
503522
| :------ | :------ | :------ |
504523
| `bitcoinRecoveryAddress` | `string` | Bitcoin address for recovery if deposit fails (P2PKH or P2WPKH). |
505-
| `depositOwner` | `string` | Ethereum address that will receive the minted tBTC on L1. |
524+
| `depositOwner` | `string` | Ethereum address that will receive the minted tBTC on L1. This is encoded as bytes32 and stored in extraData. |
506525

507526
#### Returns
508527

509528
`Promise`\<[`GaslessDepositResult`](../interfaces/GaslessDepositResult.md)\>
510529

511530
Promise resolving to GaslessDepositResult containing deposit, receipt, and "L1" chain name.
512531

532+
**`Throws`**
533+
534+
Error if NativeBTCDepositor address is not available for the current network.
535+
513536
#### Defined in
514537

515-
[services/deposits/deposits-service.ts:431](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L431)
538+
[services/deposits/deposits-service.ts:459](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L459)
516539

517540
___
518541

@@ -521,24 +544,56 @@ ___
521544
**initiateL2GaslessDeposit**(`bitcoinRecoveryAddress`, `destinationChainName`): `Promise`\<[`GaslessDepositResult`](../interfaces/GaslessDepositResult.md)\>
522545

523546
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.
525552

526553
#### Parameters
527554

528555
| Name | Type | Description |
529556
| :------ | :------ | :------ |
530557
| `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"). |
532559

533560
#### Returns
534561

535562
`Promise`\<[`GaslessDepositResult`](../interfaces/GaslessDepositResult.md)\>
536563

537564
Promise resolving to GaslessDepositResult containing deposit, receipt, and destination chain name.
538565

566+
**`Throws`**
567+
568+
Error if cross-chain contracts are not initialized or deposit owner cannot be resolved.
569+
570+
#### Defined in
571+
572+
[services/deposits/deposits-service.ts:512](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L512)
573+
574+
___
575+
576+
### isEVML2Chain
577+
578+
**isEVML2Chain**(`chainName`): `boolean`
579+
580+
Checks if the given chain name is an EVM-compatible L2 chain.
581+
582+
#### Parameters
583+
584+
| Name | Type | Description |
585+
| :------ | :------ | :------ |
586+
| `chainName` | `string` | Name of the destination chain to check |
587+
588+
#### Returns
589+
590+
`boolean`
591+
592+
true if the chain is an EVM L2 (Arbitrum, Base), false otherwise
593+
539594
#### Defined in
540595

541-
[services/deposits/deposits-service.ts:478](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L478)
596+
[services/deposits/deposits-service.ts:260](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L260)
542597

543598
___
544599

@@ -558,7 +613,7 @@ Chain identifier of the NativeBTCDepositor contract, or undefined
558613

559614
#### Defined in
560615

561-
[services/deposits/deposits-service.ts:678](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L678)
616+
[services/deposits/deposits-service.ts:724](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L724)
562617

563618
___
564619

@@ -587,7 +642,7 @@ Typically, there is no need to use this method when DepositsService
587642

588643
#### Defined in
589644

590-
[services/deposits/deposits-service.ts:777](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L777)
645+
[services/deposits/deposits-service.ts:823](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L823)
591646

592647
___
593648

@@ -610,4 +665,4 @@ Useful for custom deployments or testing environments.
610665

611666
#### Defined in
612667

613-
[services/deposits/deposits-service.ts:668](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L668)
668+
[services/deposits/deposits-service.ts:714](https://github.com/threshold-network/tbtc-v2/blob/main/typescript/src/services/deposits/deposits-service.ts#L714)

0 commit comments

Comments
 (0)