@@ -11,6 +11,7 @@ import {
11
11
SenderContext ,
12
12
TxSendError ,
13
13
TxSignError ,
14
+ TxSignErrorCode ,
14
15
WalletApi ,
15
16
WithSenderContext
16
17
} from '@cardano-sdk/dapp-connector' ;
@@ -29,10 +30,10 @@ import {
29
30
import { HexBlob , ManagedFreeableScope } from '@cardano-sdk/util' ;
30
31
import { InMemoryUnspendableUtxoStore , createInMemoryWalletStores } from '../../src/persistence' ;
31
32
import { InitializeTxProps , InitializeTxResult } from '@cardano-sdk/tx-construction' ;
33
+ import { NEVER , firstValueFrom , of } from 'rxjs' ;
32
34
import { Providers , createWallet } from './util' ;
33
35
import { address_0_0 , address_1_0 , rewardAccount_0 , rewardAccount_1 } from '../services/ChangeAddress/testData' ;
34
36
import { buildDRepIDFromDRepKey , signTx , waitForWalletStateSettle } from '../util' ;
35
- import { firstValueFrom , of } from 'rxjs' ;
36
37
import { dummyLogger as logger } from 'ts-log' ;
37
38
import { stakeKeyDerivationPath , testAsyncKeyAgent } from '../../../key-management/test/mocks' ;
38
39
import uniq from 'lodash/uniq.js' ;
@@ -50,7 +51,7 @@ const {
50
51
51
52
type TestProviders = Required < Pick < Providers , 'txSubmitProvider' | 'networkInfoProvider' > > ;
52
53
const mockCollateralCallback = jest . fn ( ) . mockResolvedValue ( [ mockUtxo [ 3 ] ] ) ;
53
- const createMockGenericCallback = ( ) => jest . fn ( ) . mockResolvedValue ( true ) ;
54
+ const createMockGenericCallback = < T > ( result : T ) => jest . fn ( ) . mockResolvedValue ( result ) ;
54
55
const foreignTx = Serialization . TxCBOR (
55
56
'84a70081825820dce442e983f3f5cd5b2644bc57f749075390f1fbae9ab55bf454342959c885db00018182583900d161d64eef0eeb59f9124f520f8c8f3b717ed04198d54c8b17e604aea63c153fb3ea8a4ea4f165574ea91173756de0bf30222ca0e95a649a1a0082607b021a0016360509a1581cb77934706fa311b6568d1070c2d23f092324b35ad623aa571a0e3726a14e4d6573685f476966745f43617264200b5820d8175f3b1276a48939a6ccee220a7f81b6422167317ba3ff6325cba1fb6ccbe70d818258208d68748457cd0f1a8596f41fd2125a415315897d2da4a4b94335829cee7198ae001281825820dce442e983f3f5cd5b2644bc57f749075390f1fbae9ab55bf454342959c885db00a2068259016b590168010000333232323232323223223222253330083232533300d3010002132533300b3370e6eb4c034009200113371e0020122940dd718058008b180700099299980499b8748008c028dd50008a5eb7bdb1804dd5980718059baa001323300100132330010013756601e602060206020602060186ea8c03cc030dd50019129998070008a5eb7bdb1804c8c8c8c94ccc03ccdc8a45000021533300f3371e91010000210031005133013337606ea4008dd3000998030030019bab3010003375c601c0046024004602000244a66601a002298103d87a8000132323232533300e337220140042a66601c66e3c0280084cdd2a4000660246e980052f5c02980103d87a80001330060060033756601e0066eb8c034008c044008c03c00452613656375c0026eb80055cd2ab9d5573caae7d5d02ba157449810f4e4d6573685f476966745f43617264004c011e581cb77934706fa311b6568d1070c2d23f092324b35ad623aa571a0e3726000159023c59023901000033323232323232322322232323225333009323232533300c3007300d3754002264646464a666026602c00426464a666024601a60266ea803854ccc048c034c04cdd5191980080080311299980b8008a60103d87a80001323253330163375e603660306ea800804c4cdd2a40006603400497ae0133004004001301b002301900115333012300c00113371e00402029405854ccc048cdc3800a4002266e3c0080405281bad3013002375c60220022c602800264a66601e601260206ea800452f5bded8c026eacc050c044dd500099191980080099198008009bab3016301730173017301700522533301500114bd6f7b630099191919299980b19b91488100002153330163371e9101000021003100513301a337606ea4008dd3000998030030019bab3017003375c602a0046032004602e00244a666028002298103d87a800013232323253330153372200e0042a66602a66e3c01c0084cdd2a4000660326e980052f5c02980103d87a80001330060060033756602c0066eb8c050008c060008c058004dd7180998081baa00337586024002601c6ea800858c040c044008c03c004c02cdd50008a4c26cac64a66601060060022a66601660146ea8010526161533300830020011533300b300a37540082930b0b18041baa003370e90011b8748000dd7000ab9a5573aaae7955cfaba05742ae8930010f4e4d6573685f476966745f43617264004c012bd8799fd8799f58203159a6f2ae24c5bfbed947fe0ecfe936f088c8d265484e6979cacb607d33c811ff05ff0001058284000040821a006acfc01ab2d05e00840100d87a80821a006acfc01ab2d05e00f5f6'
56
57
) ;
@@ -74,9 +75,9 @@ const createWalletAndApiWithStores = async (
74
75
wallet . utxo . available$ = of ( availableUtxos ) ;
75
76
}
76
77
const confirmationCallback = {
77
- signData : createMockGenericCallback ( ) ,
78
- signTx : createMockGenericCallback ( ) ,
79
- submitTx : createMockGenericCallback ( ) ,
78
+ signData : createMockGenericCallback ( { cancel$ : NEVER } ) ,
79
+ signTx : createMockGenericCallback ( { cancel$ : NEVER } ) ,
80
+ submitTx : createMockGenericCallback ( true ) ,
80
81
...( ! ! getCollateralCallback && { getCollateral : getCollateralCallback } )
81
82
} ;
82
83
wallet . governance . getPubDRepKey = jest . fn ( wallet . governance . getPubDRepKey ) ;
@@ -613,12 +614,25 @@ describe('cip30', () => {
613
614
614
615
it ( 'doesnt invoke confirmationCallback.signTx if an error occurs' , async ( ) => {
615
616
const finalizeTxSpy = jest . spyOn ( wallet , 'finalizeTx' ) . mockClear ( ) ;
616
- confirmationCallback . signTx = jest . fn ( ) . mockResolvedValueOnce ( true ) . mockClear ( ) ;
617
+ confirmationCallback . signTx = jest . fn ( ) . mockResolvedValueOnce ( { cancel$ : NEVER } ) . mockClear ( ) ;
617
618
618
619
await expect ( api . signTx ( context , foreignTx , false ) ) . rejects . toThrowError ( ) ;
619
620
expect ( finalizeTxSpy ) . not . toHaveBeenCalled ( ) ;
620
621
expect ( confirmationCallback . signTx ) . not . toHaveBeenCalled ( ) ;
621
622
} ) ;
623
+
624
+ it ( 'rejects with UserDeclined error if cancel$ emits before finalizeTx resolves' , async ( ) => {
625
+ jest . spyOn ( wallet , 'finalizeTx' ) . mockResolvedValueOnce (
626
+ new Promise ( ( ) => {
627
+ // never resolves or rejects
628
+ } )
629
+ ) ;
630
+ confirmationCallback . signTx = jest . fn ( ) . mockResolvedValueOnce ( { cancel$ : of ( void 0 ) } ) ;
631
+
632
+ await expect ( api . signTx ( context , hexTx ) ) . rejects . toThrowError (
633
+ expect . objectContaining ( { code : TxSignErrorCode . UserDeclined } )
634
+ ) ;
635
+ } ) ;
622
636
} ) ;
623
637
624
638
describe ( 'api.signData' , ( ) => {
@@ -661,6 +675,20 @@ describe('cip30', () => {
661
675
) ;
662
676
expect ( confirmationCallback . signData ) . toBeCalledWith ( expect . objectContaining ( { sender : context . sender } ) ) ;
663
677
} ) ;
678
+
679
+ it ( 'rejects with UserDeclined error if cancel$ emits before finalizeTx resolves' , async ( ) => {
680
+ const [ { address } ] = await firstValueFrom ( wallet . addresses$ ) ;
681
+ jest . spyOn ( wallet , 'signData' ) . mockResolvedValueOnce (
682
+ new Promise ( ( ) => {
683
+ // never resolves or rejects
684
+ } )
685
+ ) ;
686
+ confirmationCallback . signData = jest . fn ( ) . mockResolvedValueOnce ( { cancel$ : of ( void 0 ) } ) ;
687
+
688
+ await expect ( api . signData ( context , address , HexBlob ( 'abc123' ) ) ) . rejects . toThrowError (
689
+ expect . objectContaining ( { code : DataSignErrorCode . UserDeclined } )
690
+ ) ;
691
+ } ) ;
664
692
} ) ;
665
693
666
694
describe ( 'api.submitTx' , ( ) => {
@@ -741,8 +769,8 @@ describe('cip30', () => {
741
769
describe ( 'signData' , ( ) => {
742
770
const payload = 'abc123' ;
743
771
744
- test ( 'resolves true ' , async ( ) => {
745
- confirmationCallback . signData = jest . fn ( ) . mockResolvedValueOnce ( true ) ;
772
+ test ( 'resolves ok ' , async ( ) => {
773
+ confirmationCallback . signData = jest . fn ( ) . mockResolvedValueOnce ( { cancel$ : NEVER } ) ;
746
774
await expect ( api . signData ( context , address , payload ) ) . resolves . not . toThrow ( ) ;
747
775
} ) ;
748
776
@@ -757,7 +785,7 @@ describe('cip30', () => {
757
785
} ) ;
758
786
759
787
test ( 'gets the Cardano.Address equivalent of the hex address' , async ( ) => {
760
- confirmationCallback . signData = jest . fn ( ) . mockResolvedValueOnce ( true ) ;
788
+ confirmationCallback . signData = jest . fn ( ) . mockResolvedValueOnce ( { cancel$ : NEVER } ) ;
761
789
762
790
const hexAddr = Cardano . Address . fromBech32 ( address ) . toBytes ( ) ;
763
791
@@ -776,8 +804,8 @@ describe('cip30', () => {
776
804
hexTx = Serialization . Transaction . fromCore ( finalizedTx ) . toCbor ( ) ;
777
805
} ) ;
778
806
779
- test ( 'resolves true ' , async ( ) => {
780
- confirmationCallback . signTx = jest . fn ( ) . mockResolvedValueOnce ( true ) ;
807
+ test ( 'resolves ok ' , async ( ) => {
808
+ confirmationCallback . signTx = jest . fn ( ) . mockResolvedValueOnce ( { cancel$ : NEVER } ) ;
781
809
await expect ( api . signTx ( context , hexTx ) ) . resolves . not . toThrow ( ) ;
782
810
} ) ;
783
811
@@ -869,8 +897,8 @@ describe('cip30', () => {
869
897
mockApi = cip30 . createWalletApi (
870
898
of ( mockWallet ) ,
871
899
{
872
- signData : jest . fn ( ) . mockResolvedValue ( true ) ,
873
- signTx : jest . fn ( ) . mockResolvedValue ( true ) ,
900
+ signData : jest . fn ( ) . mockResolvedValue ( { cancel$ : NEVER } ) ,
901
+ signTx : jest . fn ( ) . mockResolvedValue ( { cancel$ : NEVER } ) ,
874
902
submitTx : jest . fn ( ) . mockResolvedValue ( true )
875
903
} ,
876
904
{ logger }
0 commit comments