4848import com .sparrowwallet .hummingbird .registry .solana .SolNFTItem ;
4949import com .sparrowwallet .hummingbird .registry .solana .SolSignRequest ;
5050import com .sparrowwallet .hummingbird .registry .sui .SuiSignRequest ;
51+ import com .sparrowwallet .hummingbird .registry .KeystoneSignRequest ;
52+
5153
5254import org .json .JSONException ;
5355import org .json .JSONObject ;
@@ -92,7 +94,9 @@ public Destination run(ScanResult r) throws BaseException {
9294 return new QRHardwareCallProcessor ().run (r .resolve ());
9395 } else if (r .getType ().equals (ScanResultTypes .UR_CARDANO_SIGN_REQUEST )) {
9496 return new CardanoSignRequestProcessor ().run (r .resolve ());
95- } else {
97+ } else if (r .getType ().equals (ScanResultTypes .UR_KEYSTONE_SIGN_REQUEST )){
98+ return new KeystoneSignRequestProcessor ().run (r .resolve ());
99+ }else {
96100 throw UnimplementedException .newInstance ();
97101 }
98102 }
@@ -101,8 +105,94 @@ interface URResolver {
101105 Destination run (Object object ) throws BaseException ;
102106 }
103107
104- private static class ETHSignRequestProcessor implements URResolver {
108+ private static class KeystoneSignRequestProcessor implements URResolver {
109+
110+
111+ @ Override
112+ public Destination run (Object object ) throws BaseException {
113+ KeystoneSignRequest keystoneSignRequest = (KeystoneSignRequest ) object ;
114+ String origin = keystoneSignRequest .getOrigin ();
115+ String hexString = Hex .toHexString (keystoneSignRequest .getSignData ());
116+ JSONObject json = tryDecodeAsJson (hexString );
105117
118+ if (json == null ) {
119+ json = tryDecodeAsProtobuf (hexString );
120+ }
121+ if (json != null ) {
122+ Destination destination = decodeAndProcess (json );
123+ if (destination == null ) {
124+ throw UnknownQrCodeException .newInstance ();
125+ }
126+ return destination ;
127+ } else {
128+ throw UnknownQrCodeException .newInstance ();
129+ }
130+ }
131+
132+
133+ private JSONObject tryDecodeAsJson (String hex ) {
134+ try {
135+ return new JSONObject (new String (Hex .decode (hex )));
136+ } catch (Exception ignored ) {
137+ }
138+ return null ;
139+ }
140+
141+ private JSONObject tryDecodeAsProtobuf (String hex ) {
142+ JSONObject object ;
143+ hex = ZipUtil .unzip (hex );
144+ object = new ProtoParser (Hex .decode (hex )).parseToJson ();
145+ return object ;
146+ }
147+
148+ private Destination decodeAndProcess (JSONObject object ) throws BaseException {
149+ Destination destination = checkWebAuth (object );
150+ if (destination != null ) return destination ;
151+ if (object .has ("TransactionType" )) {
152+ Bundle bundle = new Bundle ();
153+ bundle .putString (BundleKeys .SIGN_DATA_KEY , object .toString ());
154+ return new Destination (R .id .action_to_rippleConfirmTransactionFragment , bundle );
155+ }
156+ if (object .optString ("type" ).equals ("TYPE_SIGN_TX" )) {
157+ return handleSign (object );
158+ }
159+ throw UnknownQrCodeException .newInstance ();
160+ }
161+
162+ private Destination checkWebAuth (JSONObject object ) {
163+ try {
164+ JSONObject webAuth = object .optJSONObject ("data" );
165+ if (webAuth != null && webAuth .optString ("type" ).equals ("webAuth" )) {
166+ String data = webAuth .getString ("data" );
167+ Bundle bundle = new Bundle ();
168+ bundle .putString (BundleKeys .WEB_AUTH_DATA_KEY , data );
169+ return new Destination (R .id .action_to_webAuthResultFragment , bundle );
170+ }
171+ } catch (JSONException e ) {
172+ e .printStackTrace ();
173+ }
174+ return null ;
175+ }
176+
177+ private Destination handleSign (JSONObject object )
178+ throws BaseException {
179+ String xfp = new GetMasterFingerprintCallable ().call ();
180+ if (!object .optString ("xfp" ).toUpperCase ().equals (xfp .toUpperCase ())){
181+ throw XfpNotMatchException .newInstance ();
182+ }
183+ try {
184+ Bundle bundle = new Bundle ();
185+ bundle .putString (BundleKeys .SIGN_DATA_KEY , object .getJSONObject ("signTx" ).toString ());
186+ return new Destination (R .id .action_to_keystoneConfirmTransactionFragment , bundle );
187+ } catch (JSONException e ) {
188+ e .printStackTrace ();
189+ return null ;
190+ }
191+ }
192+ }
193+
194+
195+ private static class ETHSignRequestProcessor implements URResolver {
106196 @ Override
107197 public Destination run (Object object ) throws BaseException {
108198 EthSignRequest ethSignRequest = (EthSignRequest ) object ;
@@ -548,7 +638,7 @@ private Destination checkWebAuth(JSONObject object) {
548638 private Destination handleSign (JSONObject object )
549639 throws BaseException {
550640 String xfp = new GetMasterFingerprintCallable ().call ();
551- if (!object .optString ("xfp" ).equals (xfp )) {
641+ if (!object .optString ("xfp" ).toUpperCase (). equals (xfp . toUpperCase () )) {
552642 throw XfpNotMatchException .newInstance ();
553643 }
554644 try {
0 commit comments