@keplr-wallet/background 0.13.0 → 0.13.2
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/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/keyring-cosmos/handler.js +16 -0
- package/build/keyring-cosmos/handler.js.map +1 -1
- package/build/keyring-cosmos/init.js +2 -0
- package/build/keyring-cosmos/init.js.map +1 -1
- package/build/keyring-cosmos/messages.d.ts +38 -0
- package/build/keyring-cosmos/messages.js +69 -1
- package/build/keyring-cosmos/messages.js.map +1 -1
- package/build/keyring-cosmos/service.d.ts +28 -2
- package/build/keyring-cosmos/service.js +217 -1
- package/build/keyring-cosmos/service.js.map +1 -1
- package/package.json +13 -13
- package/src/index.ts +1 -0
- package/src/keyring-cosmos/handler.ts +61 -0
- package/src/keyring-cosmos/init.ts +4 -0
- package/src/keyring-cosmos/messages.ts +94 -0
- package/src/keyring-cosmos/service.ts +347 -1
|
@@ -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,277 @@ 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 txHash = await this.backgroundTxService.sendTx(chainId, tx, "sync", {
|
|
1251
|
+
skipTracingTxResult: true,
|
|
1252
|
+
});
|
|
1253
|
+
|
|
1254
|
+
return {
|
|
1255
|
+
txHash: Buffer.from(txHash).toString("hex"),
|
|
1256
|
+
};
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
async simulateTx(
|
|
1260
|
+
vaultId: string,
|
|
1261
|
+
chainId: string,
|
|
1262
|
+
msgs: Any[],
|
|
1263
|
+
fee: Omit<StdFee, "gas">,
|
|
1264
|
+
memo: string = ""
|
|
1265
|
+
): Promise<{
|
|
1266
|
+
gasUsed: number;
|
|
1267
|
+
}> {
|
|
1268
|
+
const key = await this.getKey(vaultId, chainId);
|
|
1269
|
+
const bech32Address = key.bech32Address;
|
|
1270
|
+
|
|
1271
|
+
const account = await BaseAccount.fetchFromRest(
|
|
1272
|
+
this.chainsService.getChainInfoOrThrow(chainId).rest,
|
|
1273
|
+
bech32Address,
|
|
1274
|
+
true
|
|
1275
|
+
);
|
|
1276
|
+
|
|
1277
|
+
const unsignedTx = TxRaw.encode({
|
|
1278
|
+
bodyBytes: TxBody.encode(
|
|
1279
|
+
TxBody.fromPartial({
|
|
1280
|
+
messages: msgs,
|
|
1281
|
+
memo: memo,
|
|
1282
|
+
})
|
|
1283
|
+
).finish(),
|
|
1284
|
+
authInfoBytes: AuthInfo.encode({
|
|
1285
|
+
signerInfos: [
|
|
1286
|
+
SignerInfo.fromPartial({
|
|
1287
|
+
// Pub key is ignored.
|
|
1288
|
+
// It is fine to ignore the pub key when simulating tx.
|
|
1289
|
+
// However, the estimated gas would be slightly smaller because tx size doesn't include pub key.
|
|
1290
|
+
modeInfo: {
|
|
1291
|
+
single: {
|
|
1292
|
+
mode: SignMode.SIGN_MODE_LEGACY_AMINO_JSON,
|
|
1293
|
+
},
|
|
1294
|
+
multi: undefined,
|
|
1295
|
+
},
|
|
1296
|
+
sequence: account.getSequence().toString(),
|
|
1297
|
+
}),
|
|
1298
|
+
],
|
|
1299
|
+
fee: Fee.fromPartial({
|
|
1300
|
+
amount: fee.amount.map((amount) => {
|
|
1301
|
+
return { amount: amount.amount, denom: amount.denom };
|
|
1302
|
+
}),
|
|
1303
|
+
}),
|
|
1304
|
+
}).finish(),
|
|
1305
|
+
// Because of the validation of tx itself, the signature must exist.
|
|
1306
|
+
// However, since they do not actually verify the signature, it is okay to use any value.
|
|
1307
|
+
signatures: [new Uint8Array(64)],
|
|
1308
|
+
}).finish();
|
|
1309
|
+
|
|
1310
|
+
// TODO: Add response type
|
|
1311
|
+
const result = await simpleFetch<any>(
|
|
1312
|
+
this.chainsService.getChainInfoOrThrow(chainId).rest,
|
|
1313
|
+
"/cosmos/tx/v1beta1/simulate",
|
|
1314
|
+
{
|
|
1315
|
+
method: "POST",
|
|
1316
|
+
headers: {
|
|
1317
|
+
"content-type": "application/json",
|
|
1318
|
+
},
|
|
1319
|
+
body: JSON.stringify({
|
|
1320
|
+
tx_bytes: Buffer.from(unsignedTx).toString("base64"),
|
|
1321
|
+
}),
|
|
1322
|
+
}
|
|
1323
|
+
);
|
|
1324
|
+
|
|
1325
|
+
const gasUsed = parseInt(result.data.gas_info.gas_used);
|
|
1326
|
+
if (Number.isNaN(gasUsed)) {
|
|
1327
|
+
throw new Error(`Invalid integer gas: ${result.data.gas_info.gas_used}`);
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
return {
|
|
1331
|
+
gasUsed,
|
|
1332
|
+
};
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1053
1335
|
/**
|
|
1054
1336
|
* Sign a direct-encoded transaction with pre-authorization
|
|
1055
1337
|
* @dev only sign the transaction, not simulate or broadcast
|
|
@@ -1459,6 +1741,70 @@ export class KeyRingCosmosService {
|
|
|
1459
1741
|
);
|
|
1460
1742
|
}
|
|
1461
1743
|
|
|
1744
|
+
async signFigureMarketsAuth(
|
|
1745
|
+
_env: Env,
|
|
1746
|
+
origin: string,
|
|
1747
|
+
chainId: string,
|
|
1748
|
+
signer: string,
|
|
1749
|
+
// base64 encoded.
|
|
1750
|
+
message: string
|
|
1751
|
+
): Promise<{
|
|
1752
|
+
signedMessage: string;
|
|
1753
|
+
signature: StdSignature;
|
|
1754
|
+
}> {
|
|
1755
|
+
const parsed = JSON.parse(Buffer.from(message, "base64").toString());
|
|
1756
|
+
if (
|
|
1757
|
+
parsed.chainId !== this.chainsService.getChainInfoOrThrow(chainId).chainId
|
|
1758
|
+
) {
|
|
1759
|
+
throw new Error("chain id unmatched");
|
|
1760
|
+
}
|
|
1761
|
+
if (new URL(parsed.domain).origin !== new URL(origin).origin) {
|
|
1762
|
+
throw new Error("domain and origin unmatched");
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
const vaultId = this.keyRingService.selectedVaultId;
|
|
1766
|
+
|
|
1767
|
+
const chainInfo = this.chainsService.getChainInfoOrThrow(chainId);
|
|
1768
|
+
const isEthermintLike = KeyRingService.isEthermintLike(chainInfo);
|
|
1769
|
+
const forceEVMLedger = chainInfo.features?.includes(
|
|
1770
|
+
"force-enable-evm-ledger"
|
|
1771
|
+
);
|
|
1772
|
+
|
|
1773
|
+
const keyInfo = this.keyRingService.getKeyInfo(vaultId);
|
|
1774
|
+
if (!keyInfo) {
|
|
1775
|
+
throw new Error("Null key info");
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
if (isEthermintLike && keyInfo.type === "ledger" && !forceEVMLedger) {
|
|
1779
|
+
KeyRingCosmosService.throwErrorIfEthermintWithLedgerButNotSupported(
|
|
1780
|
+
chainId
|
|
1781
|
+
);
|
|
1782
|
+
}
|
|
1783
|
+
|
|
1784
|
+
const key = await this.getKey(vaultId, chainId);
|
|
1785
|
+
const bech32Prefix =
|
|
1786
|
+
this.chainsService.getChainInfoOrThrow(chainId).bech32Config
|
|
1787
|
+
?.bech32PrefixAccAddr ?? "";
|
|
1788
|
+
const bech32Address = new Bech32Address(key.address).toBech32(bech32Prefix);
|
|
1789
|
+
if (signer !== bech32Address || parsed.address !== bech32Address) {
|
|
1790
|
+
throw new Error("Signer mismatched");
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
const signature = await this.keyRingService.sign(
|
|
1794
|
+
chainId,
|
|
1795
|
+
vaultId,
|
|
1796
|
+
Buffer.from(message, "base64"),
|
|
1797
|
+
isEthermintLike ? "keccak256" : "sha256"
|
|
1798
|
+
);
|
|
1799
|
+
return {
|
|
1800
|
+
signedMessage: message,
|
|
1801
|
+
signature: encodeSecp256k1Signature(
|
|
1802
|
+
key.pubKey,
|
|
1803
|
+
new Uint8Array([...signature.r, ...signature.s])
|
|
1804
|
+
),
|
|
1805
|
+
};
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1462
1808
|
async requestICNSAdr36SignaturesSelected(
|
|
1463
1809
|
env: Env,
|
|
1464
1810
|
origin: string,
|