@keplr-wallet/background 0.13.1 → 0.13.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keplr-wallet/background",
3
- "version": "0.13.1",
3
+ "version": "0.13.3",
4
4
  "main": "build/index.js",
5
5
  "author": "chainapsis",
6
6
  "license": "Apache-2.0",
@@ -32,17 +32,17 @@
32
32
  "@ethersproject/hash": "^5.7.0",
33
33
  "@ethersproject/transactions": "^5.7.0",
34
34
  "@ethersproject/wallet": "^5.7.0",
35
- "@keplr-wallet/chain-validator": "0.13.1",
36
- "@keplr-wallet/common": "0.13.1",
37
- "@keplr-wallet/cosmos": "0.13.1",
38
- "@keplr-wallet/crypto": "0.13.1",
39
- "@keplr-wallet/ledger-cosmos": "0.13.1",
40
- "@keplr-wallet/popup": "0.13.1",
41
- "@keplr-wallet/proto-types": "0.13.1",
42
- "@keplr-wallet/router": "0.13.1",
43
- "@keplr-wallet/simple-fetch": "0.13.1",
44
- "@keplr-wallet/types": "0.13.1",
45
- "@keplr-wallet/unit": "0.13.1",
35
+ "@keplr-wallet/chain-validator": "0.13.3",
36
+ "@keplr-wallet/common": "0.13.3",
37
+ "@keplr-wallet/cosmos": "0.13.3",
38
+ "@keplr-wallet/crypto": "0.13.3",
39
+ "@keplr-wallet/ledger-cosmos": "0.13.3",
40
+ "@keplr-wallet/popup": "0.13.3",
41
+ "@keplr-wallet/proto-types": "0.13.3",
42
+ "@keplr-wallet/router": "0.13.3",
43
+ "@keplr-wallet/simple-fetch": "0.13.3",
44
+ "@keplr-wallet/types": "0.13.3",
45
+ "@keplr-wallet/unit": "0.13.3",
46
46
  "@ledgerhq/hw-app-eth": "6.42.8",
47
47
  "@ledgerhq/hw-app-starknet": "^3.0.1",
48
48
  "@ledgerhq/hw-transport": "^6.31.4",
@@ -69,5 +69,5 @@
69
69
  "mobx-utils": "^6",
70
70
  "starknet": "^7"
71
71
  },
72
- "gitHead": "005bf5131f8612e3a773b864b673361ca9d9ab85"
72
+ "gitHead": "43844091838596f5c4ebd3d9386ddd5151398b04"
73
73
  }
package/src/index.ts CHANGED
@@ -219,6 +219,7 @@ export function init(
219
219
  interactionService,
220
220
  chainsUIService,
221
221
  analyticsService,
222
+ backgroundTxService,
222
223
  msgPrivilegedOrigins,
223
224
  msgPrivilegedCosmwasmContractMap
224
225
  );
@@ -22,6 +22,8 @@ import {
22
22
  RequestCosmosSignDirectAuxMsg,
23
23
  GetCosmosKeysForEachVaultWithSearchSettledMsg,
24
24
  PrivilegeCosmosSignAminoExecuteCosmWasmMsg,
25
+ RequestSignFigureMarketsAuthMsg,
26
+ RequestCosmosSignDirectWithMessagesMsg,
25
27
  } from "./messages";
26
28
  import { KeyRingCosmosService } from "./service";
27
29
  import { PermissionInteractiveService } from "../permission-interactive";
@@ -119,6 +121,16 @@ export const getHandler: (
119
121
  env,
120
122
  msg as PrivilegeCosmosSignAminoExecuteCosmWasmMsg
121
123
  );
124
+ case RequestSignFigureMarketsAuthMsg:
125
+ return handleRequestSignFigureMarketsAuthMsg(
126
+ service,
127
+ permissionInteractionService
128
+ )(env, msg as RequestSignFigureMarketsAuthMsg);
129
+ case RequestCosmosSignDirectWithMessagesMsg:
130
+ return handleRequestCosmosSignDirectWithMessagesMsg(
131
+ service,
132
+ permissionInteractionService
133
+ )(env, msg as RequestCosmosSignDirectWithMessagesMsg);
122
134
  default:
123
135
  throw new KeplrError("keyring", 221, "Unknown msg type");
124
136
  }
@@ -490,3 +502,52 @@ const handleRequestCosmosSignDirectAuxMsg: (
490
502
  };
491
503
  };
492
504
  };
505
+
506
+ const handleRequestSignFigureMarketsAuthMsg: (
507
+ service: KeyRingCosmosService,
508
+ permissionInteractionService: PermissionInteractiveService
509
+ ) => InternalHandler<RequestSignFigureMarketsAuthMsg> = (
510
+ service,
511
+ permissionInteractionService
512
+ ) => {
513
+ return async (env, msg) => {
514
+ await permissionInteractionService.ensureEnabled(
515
+ env,
516
+ [msg.chainId],
517
+ msg.origin
518
+ );
519
+
520
+ return await service.signFigureMarketsAuth(
521
+ env,
522
+ msg.origin,
523
+ msg.chainId,
524
+ msg.signer,
525
+ msg.message
526
+ );
527
+ };
528
+ };
529
+
530
+ const handleRequestCosmosSignDirectWithMessagesMsg: (
531
+ service: KeyRingCosmosService,
532
+ permissionInteractionService: PermissionInteractiveService
533
+ ) => InternalHandler<RequestCosmosSignDirectWithMessagesMsg> = (
534
+ service,
535
+ permissionInteractionService
536
+ ) => {
537
+ return async (env, msg) => {
538
+ await permissionInteractionService.ensureEnabled(
539
+ env,
540
+ [msg.chainId],
541
+ msg.origin
542
+ );
543
+
544
+ return await service.signDirectWithMessagesSelected(
545
+ env,
546
+ msg.origin,
547
+ msg.chainId,
548
+ msg.signer,
549
+ msg.messages,
550
+ msg.signDirectWithMessagesOptions
551
+ );
552
+ };
553
+ };
@@ -17,6 +17,8 @@ import {
17
17
  PrivilegeCosmosSignAminoDelegateMsg,
18
18
  RequestCosmosSignDirectAuxMsg,
19
19
  PrivilegeCosmosSignAminoExecuteCosmWasmMsg,
20
+ RequestSignFigureMarketsAuthMsg,
21
+ RequestCosmosSignDirectWithMessagesMsg,
20
22
  } from "./messages";
21
23
  import { ROUTE } from "./constants";
22
24
  import { getHandler } from "./handler";
@@ -43,6 +45,8 @@ export function init(
43
45
  router.registerMessage(RequestICNSAdr36SignaturesMsg);
44
46
  router.registerMessage(EnableVaultsWithCosmosAddressMsg);
45
47
  router.registerMessage(RequestCosmosSignDirectAuxMsg);
48
+ router.registerMessage(RequestSignFigureMarketsAuthMsg);
49
+ router.registerMessage(RequestCosmosSignDirectWithMessagesMsg);
46
50
 
47
51
  router.addHandler(ROUTE, getHandler(service, permissionInteractionService));
48
52
  }
@@ -850,3 +850,97 @@ export class EnableVaultsWithCosmosAddressMsg extends Message<
850
850
  return EnableVaultsWithCosmosAddressMsg.type();
851
851
  }
852
852
  }
853
+
854
+ export class RequestSignFigureMarketsAuthMsg extends Message<{
855
+ signedMessage: string;
856
+ signature: StdSignature;
857
+ }> {
858
+ public static type() {
859
+ return "request-sign-figure-markets-auth";
860
+ }
861
+
862
+ constructor(
863
+ public readonly chainId: string,
864
+ public readonly signer: string,
865
+ public readonly message: string
866
+ ) {
867
+ super();
868
+ }
869
+
870
+ validateBasic(): void {
871
+ if (!this.chainId) {
872
+ throw new KeplrError("keyring", 270, "chain id not set");
873
+ }
874
+
875
+ if (!this.signer) {
876
+ throw new KeplrError("keyring", 230, "signer not set");
877
+ }
878
+
879
+ // Validate bech32 address.
880
+ Bech32Address.validate(this.signer);
881
+
882
+ if (!this.message) {
883
+ throw new KeplrError("keyring", 231, "message not set");
884
+ }
885
+ }
886
+
887
+ override approveExternal(): boolean {
888
+ return true;
889
+ }
890
+
891
+ route(): string {
892
+ return ROUTE;
893
+ }
894
+
895
+ type(): string {
896
+ return RequestSignFigureMarketsAuthMsg.type();
897
+ }
898
+ }
899
+
900
+ export class RequestCosmosSignDirectWithMessagesMsg extends Message<{
901
+ readonly txHash: string;
902
+ }> {
903
+ public static type() {
904
+ return "request-cosmos-sign-direct-with-messages";
905
+ }
906
+
907
+ constructor(
908
+ public readonly chainId: string,
909
+ public readonly signer: string,
910
+ // base64 encoded protobuf messages.
911
+ public readonly messages: string[],
912
+ public readonly signDirectWithMessagesOptions: {
913
+ memo?: string;
914
+ sync?: boolean;
915
+ timeoutHeight?: number;
916
+ gasAdjustment?: number;
917
+ }
918
+ ) {
919
+ super();
920
+ }
921
+
922
+ validateBasic(): void {
923
+ if (!this.chainId) {
924
+ throw new KeplrError("keyring", 270, "chain id not set");
925
+ }
926
+
927
+ if (!this.signer) {
928
+ throw new KeplrError("keyring", 230, "signer not set");
929
+ }
930
+
931
+ // Validate bech32 address.
932
+ Bech32Address.validate(this.signer);
933
+ }
934
+
935
+ override approveExternal(): boolean {
936
+ return true;
937
+ }
938
+
939
+ route(): string {
940
+ return ROUTE;
941
+ }
942
+
943
+ type(): string {
944
+ return RequestCosmosSignDirectWithMessagesMsg.type();
945
+ }
946
+ }
@@ -7,11 +7,13 @@ import {
7
7
  DirectSignResponse,
8
8
  KeplrSignOptions,
9
9
  Key,
10
+ StdFee,
10
11
  StdSignature,
11
12
  StdSignDoc,
12
13
  } from "@keplr-wallet/types";
13
14
  import { APP_PORT, Env, KeplrError } from "@keplr-wallet/router";
14
15
  import {
16
+ BaseAccount,
15
17
  Bech32Address,
16
18
  ChainIdHelper,
17
19
  checkAndValidateADR36AminoSignDoc,
@@ -29,16 +31,24 @@ import { InteractionService } from "../interaction";
29
31
  import { Buffer } from "buffer/";
30
32
  import {
31
33
  AuthInfo,
34
+ Fee,
32
35
  SignDoc,
33
36
  SignDocDirectAux,
37
+ SignerInfo,
34
38
  TxBody,
39
+ TxRaw,
35
40
  } from "@keplr-wallet/proto-types/cosmos/tx/v1beta1/tx";
36
41
  import Long from "long";
37
42
  import { PubKeySecp256k1 } from "@keplr-wallet/crypto";
38
43
  import { AnalyticsService } from "../analytics";
39
44
  import { ChainsUIService } from "../chains-ui";
40
- import { Int } from "@keplr-wallet/unit";
45
+ import { Dec, Int } from "@keplr-wallet/unit";
41
46
  import bigInteger from "big-integer";
47
+ import { PubKey } from "@keplr-wallet/proto-types/cosmos/crypto/secp256k1/keys";
48
+ import { SignMode } from "@keplr-wallet/proto-types/cosmos/tx/signing/v1beta1/signing";
49
+ import { Any } from "@keplr-wallet/proto-types/google/protobuf/any";
50
+ import { simpleFetch } from "@keplr-wallet/simple-fetch";
51
+ import { BackgroundTxService } from "../tx";
42
52
 
43
53
  export class KeyRingCosmosService {
44
54
  constructor(
@@ -47,6 +57,7 @@ export class KeyRingCosmosService {
47
57
  protected readonly interactionService: InteractionService,
48
58
  protected readonly chainsUIService: ChainsUIService,
49
59
  protected readonly analyticsService: AnalyticsService,
60
+ protected readonly backgroundTxService: BackgroundTxService,
50
61
  protected readonly msgPrivilegedOrigins: string[],
51
62
  protected readonly msgPrivilegedCosmwasmContractMap: Record<
52
63
  string,
@@ -1050,6 +1061,281 @@ export class KeyRingCosmosService {
1050
1061
  );
1051
1062
  }
1052
1063
 
1064
+ async signDirectWithMessagesSelected(
1065
+ env: Env,
1066
+ origin: string,
1067
+ chainId: string,
1068
+ signer: string,
1069
+ // base64 encoded protobuf messages.
1070
+ messages: string[],
1071
+ signDirectWithMessagesOptions: {
1072
+ memo?: string;
1073
+ sync?: boolean;
1074
+ timeoutHeight?: number;
1075
+ gasAdjustment?: number;
1076
+ }
1077
+ ): Promise<{
1078
+ txHash: string;
1079
+ }> {
1080
+ return await this.signDirectWithMessages(
1081
+ env,
1082
+ origin,
1083
+ this.keyRingService.selectedVaultId,
1084
+ chainId,
1085
+ signer,
1086
+ messages,
1087
+ signDirectWithMessagesOptions
1088
+ );
1089
+ }
1090
+
1091
+ async signDirectWithMessages(
1092
+ env: Env,
1093
+ origin: string,
1094
+ vaultId: string,
1095
+ chainId: string,
1096
+ signer: string,
1097
+ // base64 encoded protobuf messages.
1098
+ messages: string[],
1099
+ signDirectWithMessagesOptions: {
1100
+ memo?: string;
1101
+ sync?: boolean;
1102
+ timeoutHeight?: number;
1103
+ gasAdjustment?: number;
1104
+ }
1105
+ ): Promise<{
1106
+ txHash: string;
1107
+ }> {
1108
+ const useEthereumSign =
1109
+ this.chainsService
1110
+ .getChainInfoOrThrow(chainId)
1111
+ .features?.includes("eth-key-sign") === true;
1112
+
1113
+ const chainIsInjective = chainId.startsWith("injective");
1114
+ const chainIsStratos = chainId.startsWith("stratos");
1115
+ const chainIsCysic = chainId.startsWith("cysic");
1116
+
1117
+ const key = await this.getKey(vaultId, chainId);
1118
+ const bech32Address = key.bech32Address;
1119
+
1120
+ const account = await BaseAccount.fetchFromRest(
1121
+ this.chainsService.getChainInfoOrThrow(chainId).rest,
1122
+ bech32Address,
1123
+ true
1124
+ );
1125
+
1126
+ const anyMessages: Any[] = messages.map((message) => {
1127
+ const bz = Buffer.from(message, "base64");
1128
+ const any = Any.decode(bz);
1129
+ return {
1130
+ typeUrl: any.typeUrl,
1131
+ value: any.value,
1132
+ };
1133
+ });
1134
+
1135
+ const feeCurrency =
1136
+ this.chainsService.getChainInfoOrThrow(chainId).feeCurrencies[0];
1137
+
1138
+ const { gasUsed } = await this.simulateTx(
1139
+ vaultId,
1140
+ chainId,
1141
+ anyMessages,
1142
+ {
1143
+ amount: [
1144
+ {
1145
+ denom: feeCurrency.coinMinimalDenom,
1146
+ amount: "1",
1147
+ },
1148
+ ],
1149
+ },
1150
+ signDirectWithMessagesOptions.memo
1151
+ );
1152
+ const gasAdjustment = signDirectWithMessagesOptions.gasAdjustment || 1.5;
1153
+
1154
+ const gasLimitDec = new Dec(gasUsed).mulTruncate(new Dec(gasAdjustment));
1155
+
1156
+ const signDoc = {
1157
+ bodyBytes: TxBody.encode(
1158
+ TxBody.fromPartial({
1159
+ messages: anyMessages,
1160
+ memo: signDirectWithMessagesOptions.memo,
1161
+ })
1162
+ ).finish(),
1163
+ authInfoBytes: AuthInfo.encode({
1164
+ signerInfos: [
1165
+ {
1166
+ publicKey: {
1167
+ typeUrl: (() => {
1168
+ if (!useEthereumSign) {
1169
+ return "/cosmos.crypto.secp256k1.PubKey";
1170
+ }
1171
+
1172
+ if (chainIsInjective) {
1173
+ return "/injective.crypto.v1beta1.ethsecp256k1.PubKey";
1174
+ }
1175
+
1176
+ if (chainIsStratos) {
1177
+ return "/stratos.crypto.v1.ethsecp256k1.PubKey";
1178
+ }
1179
+
1180
+ if (
1181
+ this.chainsService
1182
+ .getChainInfoOrThrow(chainId)
1183
+ .features?.includes("eth-secp256k1-cosmos")
1184
+ ) {
1185
+ return "/cosmos.evm.crypto.v1.ethsecp256k1.PubKey";
1186
+ }
1187
+ if (
1188
+ this.chainsService
1189
+ .getChainInfoOrThrow(chainId)
1190
+ .features?.includes("eth-secp256k1-initia")
1191
+ ) {
1192
+ return "/initia.crypto.v1beta1.ethsecp256k1.PubKey";
1193
+ }
1194
+
1195
+ if (chainIsCysic) {
1196
+ return "/cysicmint.crypto.v1.ethsecp256k1.PubKey";
1197
+ }
1198
+
1199
+ return "/ethermint.crypto.v1.ethsecp256k1.PubKey";
1200
+ })(),
1201
+ value: PubKey.encode({
1202
+ key: key.pubKey,
1203
+ }).finish(),
1204
+ },
1205
+ modeInfo: {
1206
+ single: {
1207
+ mode: SignMode.SIGN_MODE_DIRECT,
1208
+ },
1209
+ multi: undefined,
1210
+ },
1211
+ sequence: account.getSequence().toString(),
1212
+ },
1213
+ ],
1214
+ fee: Fee.fromPartial({
1215
+ amount: [
1216
+ {
1217
+ denom: feeCurrency.coinMinimalDenom,
1218
+ amount: new Dec(feeCurrency.gasPriceStep?.average ?? 0.025)
1219
+ .mul(gasLimitDec)
1220
+ .roundUp()
1221
+ .toString(),
1222
+ },
1223
+ ],
1224
+ gasLimit: gasLimitDec.roundUp().toString(),
1225
+ }),
1226
+ }).finish(),
1227
+ chainId: chainId,
1228
+ accountNumber: account.getAccountNumber().toString(),
1229
+ };
1230
+
1231
+ const signed = await this.signDirect(
1232
+ env,
1233
+ origin,
1234
+ vaultId,
1235
+ chainId,
1236
+ signer,
1237
+ signDoc,
1238
+ {
1239
+ preferNoSetMemo: !!signDirectWithMessagesOptions.memo,
1240
+ preferNoSetFee: true,
1241
+ }
1242
+ );
1243
+
1244
+ const tx = TxRaw.encode({
1245
+ bodyBytes: signed.signed.bodyBytes,
1246
+ authInfoBytes: signed.signed.authInfoBytes,
1247
+ signatures: [Buffer.from(signed.signature.signature, "base64")],
1248
+ }).finish();
1249
+
1250
+ const waitFulfillment = signDirectWithMessagesOptions.sync !== false;
1251
+ const txHash = await this.backgroundTxService.sendTx(chainId, tx, "sync", {
1252
+ waitFulfillment,
1253
+ });
1254
+
1255
+ if (waitFulfillment) {
1256
+ await new Promise((resolve) => setTimeout(resolve, 500));
1257
+ }
1258
+ return {
1259
+ txHash: Buffer.from(txHash).toString("hex"),
1260
+ };
1261
+ }
1262
+
1263
+ async simulateTx(
1264
+ vaultId: string,
1265
+ chainId: string,
1266
+ msgs: Any[],
1267
+ fee: Omit<StdFee, "gas">,
1268
+ memo: string = ""
1269
+ ): Promise<{
1270
+ gasUsed: number;
1271
+ }> {
1272
+ const key = await this.getKey(vaultId, chainId);
1273
+ const bech32Address = key.bech32Address;
1274
+
1275
+ const account = await BaseAccount.fetchFromRest(
1276
+ this.chainsService.getChainInfoOrThrow(chainId).rest,
1277
+ bech32Address,
1278
+ true
1279
+ );
1280
+
1281
+ const unsignedTx = TxRaw.encode({
1282
+ bodyBytes: TxBody.encode(
1283
+ TxBody.fromPartial({
1284
+ messages: msgs,
1285
+ memo: memo,
1286
+ })
1287
+ ).finish(),
1288
+ authInfoBytes: AuthInfo.encode({
1289
+ signerInfos: [
1290
+ SignerInfo.fromPartial({
1291
+ // Pub key is ignored.
1292
+ // It is fine to ignore the pub key when simulating tx.
1293
+ // However, the estimated gas would be slightly smaller because tx size doesn't include pub key.
1294
+ modeInfo: {
1295
+ single: {
1296
+ mode: SignMode.SIGN_MODE_LEGACY_AMINO_JSON,
1297
+ },
1298
+ multi: undefined,
1299
+ },
1300
+ sequence: account.getSequence().toString(),
1301
+ }),
1302
+ ],
1303
+ fee: Fee.fromPartial({
1304
+ amount: fee.amount.map((amount) => {
1305
+ return { amount: amount.amount, denom: amount.denom };
1306
+ }),
1307
+ }),
1308
+ }).finish(),
1309
+ // Because of the validation of tx itself, the signature must exist.
1310
+ // However, since they do not actually verify the signature, it is okay to use any value.
1311
+ signatures: [new Uint8Array(64)],
1312
+ }).finish();
1313
+
1314
+ // TODO: Add response type
1315
+ const result = await simpleFetch<any>(
1316
+ this.chainsService.getChainInfoOrThrow(chainId).rest,
1317
+ "/cosmos/tx/v1beta1/simulate",
1318
+ {
1319
+ method: "POST",
1320
+ headers: {
1321
+ "content-type": "application/json",
1322
+ },
1323
+ body: JSON.stringify({
1324
+ tx_bytes: Buffer.from(unsignedTx).toString("base64"),
1325
+ }),
1326
+ }
1327
+ );
1328
+
1329
+ const gasUsed = parseInt(result.data.gas_info.gas_used);
1330
+ if (Number.isNaN(gasUsed)) {
1331
+ throw new Error(`Invalid integer gas: ${result.data.gas_info.gas_used}`);
1332
+ }
1333
+
1334
+ return {
1335
+ gasUsed,
1336
+ };
1337
+ }
1338
+
1053
1339
  /**
1054
1340
  * Sign a direct-encoded transaction with pre-authorization
1055
1341
  * @dev only sign the transaction, not simulate or broadcast
@@ -1459,6 +1745,70 @@ export class KeyRingCosmosService {
1459
1745
  );
1460
1746
  }
1461
1747
 
1748
+ async signFigureMarketsAuth(
1749
+ _env: Env,
1750
+ origin: string,
1751
+ chainId: string,
1752
+ signer: string,
1753
+ // base64 encoded.
1754
+ message: string
1755
+ ): Promise<{
1756
+ signedMessage: string;
1757
+ signature: StdSignature;
1758
+ }> {
1759
+ const parsed = JSON.parse(Buffer.from(message, "base64").toString());
1760
+ if (
1761
+ parsed.chainId !== this.chainsService.getChainInfoOrThrow(chainId).chainId
1762
+ ) {
1763
+ throw new Error("chain id unmatched");
1764
+ }
1765
+ if (new URL(parsed.domain).origin !== new URL(origin).origin) {
1766
+ throw new Error("domain and origin unmatched");
1767
+ }
1768
+
1769
+ const vaultId = this.keyRingService.selectedVaultId;
1770
+
1771
+ const chainInfo = this.chainsService.getChainInfoOrThrow(chainId);
1772
+ const isEthermintLike = KeyRingService.isEthermintLike(chainInfo);
1773
+ const forceEVMLedger = chainInfo.features?.includes(
1774
+ "force-enable-evm-ledger"
1775
+ );
1776
+
1777
+ const keyInfo = this.keyRingService.getKeyInfo(vaultId);
1778
+ if (!keyInfo) {
1779
+ throw new Error("Null key info");
1780
+ }
1781
+
1782
+ if (isEthermintLike && keyInfo.type === "ledger" && !forceEVMLedger) {
1783
+ KeyRingCosmosService.throwErrorIfEthermintWithLedgerButNotSupported(
1784
+ chainId
1785
+ );
1786
+ }
1787
+
1788
+ const key = await this.getKey(vaultId, chainId);
1789
+ const bech32Prefix =
1790
+ this.chainsService.getChainInfoOrThrow(chainId).bech32Config
1791
+ ?.bech32PrefixAccAddr ?? "";
1792
+ const bech32Address = new Bech32Address(key.address).toBech32(bech32Prefix);
1793
+ if (signer !== bech32Address || parsed.address !== bech32Address) {
1794
+ throw new Error("Signer mismatched");
1795
+ }
1796
+
1797
+ const signature = await this.keyRingService.sign(
1798
+ chainId,
1799
+ vaultId,
1800
+ Buffer.from(message, "base64"),
1801
+ isEthermintLike ? "keccak256" : "sha256"
1802
+ );
1803
+ return {
1804
+ signedMessage: message,
1805
+ signature: encodeSecp256k1Signature(
1806
+ key.pubKey,
1807
+ new Uint8Array([...signature.r, ...signature.s])
1808
+ ),
1809
+ };
1810
+ }
1811
+
1462
1812
  async requestICNSAdr36SignaturesSelected(
1463
1813
  env: Env,
1464
1814
  origin: string,