@@ -22,7 +22,11 @@ import {
2222import Decimal from "decimal.js" ;
2323import { ExternalAddress } from "../coinbase/address/external_address" ;
2424import { StakeOptionsMode } from "../coinbase/types" ;
25- import { ExecutionLayerWithdrawalOptionsBuilder , StakingOperation } from "../coinbase/staking_operation" ;
25+ import {
26+ ConsensusLayerExitOptionBuilder ,
27+ ExecutionLayerWithdrawalOptionsBuilder ,
28+ StakingOperation ,
29+ } from "../coinbase/staking_operation" ;
2630import { Asset } from "../coinbase/asset" ;
2731import { randomUUID } from "crypto" ;
2832import { StakingReward } from "../coinbase/staking_reward" ;
@@ -410,6 +414,77 @@ describe("ExternalAddress", () => {
410414 expect ( Coinbase . apiClients . stake ! . buildStakingOperation ) . toHaveBeenCalledTimes ( 0 ) ;
411415 } ) ;
412416
417+ describe ( "native eth consensus layer exits" , ( ) => {
418+ it ( "should successfully build an unstake operation" , async ( ) => {
419+ Coinbase . apiClients . stake ! . buildStakingOperation = mockReturnValue ( STAKING_OPERATION_MODEL ) ;
420+ Coinbase . apiClients . asset ! . getAsset = getAssetMock ( ) ;
421+
422+ const builder = new ConsensusLayerExitOptionBuilder ( ) ;
423+ builder . addValidator ( "0x123" ) ;
424+ builder . addValidator ( "0x456" ) ;
425+ builder . addValidator ( "0x456" ) ;
426+ builder . addValidator ( "0x789" ) ;
427+ builder . addValidator ( "0x789" ) ;
428+ const options = await builder . build ( ) ;
429+
430+ const op = await address . buildUnstakeOperation (
431+ new Decimal ( "0" ) ,
432+ Coinbase . assets . Eth ,
433+ StakeOptionsMode . NATIVE ,
434+ options ,
435+ ) ;
436+
437+ expect ( Coinbase . apiClients . stake ! . buildStakingOperation ) . toHaveBeenCalledWith ( {
438+ address_id : address . getId ( ) ,
439+ network_id : address . getNetworkId ( ) ,
440+ asset_id : Coinbase . assets . Eth ,
441+ action : "unstake" ,
442+ options : {
443+ mode : StakeOptionsMode . NATIVE ,
444+ unstake_type : "consensus" ,
445+ validator_pub_keys : "0x123,0x456,0x789" ,
446+ } ,
447+ } ) ;
448+ expect ( op ) . toBeInstanceOf ( StakingOperation ) ;
449+ } ) ;
450+
451+ it ( "should respect existing options" , async ( ) => {
452+ Coinbase . apiClients . stake ! . buildStakingOperation = mockReturnValue ( STAKING_OPERATION_MODEL ) ;
453+ Coinbase . apiClients . asset ! . getAsset = getAssetMock ( ) ;
454+
455+ let options : { [ key : string ] : string } = { some_other_option : "value" } ;
456+
457+ const builder = new ConsensusLayerExitOptionBuilder ( ) ;
458+ builder . addValidator ( "0x123" ) ;
459+ builder . addValidator ( "0x456" ) ;
460+ builder . addValidator ( "0x456" ) ;
461+ builder . addValidator ( "0x789" ) ;
462+ builder . addValidator ( "0x789" ) ;
463+ options = await builder . build ( options ) ;
464+
465+ const op = await address . buildUnstakeOperation (
466+ new Decimal ( "0" ) ,
467+ Coinbase . assets . Eth ,
468+ StakeOptionsMode . NATIVE ,
469+ options ,
470+ ) ;
471+
472+ expect ( Coinbase . apiClients . stake ! . buildStakingOperation ) . toHaveBeenCalledWith ( {
473+ address_id : address . getId ( ) ,
474+ network_id : address . getNetworkId ( ) ,
475+ asset_id : Coinbase . assets . Eth ,
476+ action : "unstake" ,
477+ options : {
478+ mode : StakeOptionsMode . NATIVE ,
479+ some_other_option : "value" ,
480+ unstake_type : "consensus" ,
481+ validator_pub_keys : "0x123,0x456,0x789" ,
482+ } ,
483+ } ) ;
484+ expect ( op ) . toBeInstanceOf ( StakingOperation ) ;
485+ } ) ;
486+ } ) ;
487+
413488 describe ( "native eth execution layer withdrawals" , ( ) => {
414489 it ( "should successfully build an unstake operation" , async ( ) => {
415490 Coinbase . apiClients . stake ! . buildStakingOperation = mockReturnValue ( STAKING_OPERATION_MODEL ) ;
@@ -434,7 +509,7 @@ describe("ExternalAddress", () => {
434509 action : "unstake" ,
435510 options : {
436511 mode : StakeOptionsMode . NATIVE ,
437- withdrawal_credential_type : "0x02 " ,
512+ unstake_type : "execution " ,
438513 validator_unstake_amounts :
439514 '{"0x123":"1000000000000000000000","0x456":"2000000000000000000000"}' ,
440515 } ,
@@ -467,7 +542,7 @@ describe("ExternalAddress", () => {
467542 options : {
468543 mode : StakeOptionsMode . NATIVE ,
469544 some_other_option : "value" ,
470- withdrawal_credential_type : "0x02 " ,
545+ unstake_type : "execution " ,
471546 validator_unstake_amounts : '{"0x123":"1000000000000000000000"}' ,
472547 } ,
473548 } ) ;
0 commit comments