@keplr-wallet/background 0.12.20 → 0.12.21-rc.0
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/analytics/handler.js +5 -0
- package/build/analytics/handler.js.map +1 -1
- package/build/analytics/init.js +1 -0
- package/build/analytics/init.js.map +1 -1
- package/build/analytics/messages.d.ts +9 -0
- package/build/analytics/messages.js +23 -1
- package/build/analytics/messages.js.map +1 -1
- package/build/index.d.ts +2 -2
- package/build/index.js +4 -4
- package/build/index.js.map +1 -1
- package/build/keyring-cosmos/handler.js +9 -2
- package/build/keyring-cosmos/handler.js.map +1 -1
- package/build/keyring-cosmos/init.js +1 -0
- package/build/keyring-cosmos/init.js.map +1 -1
- package/build/keyring-cosmos/messages.d.ts +12 -0
- package/build/keyring-cosmos/messages.js +45 -1
- package/build/keyring-cosmos/messages.js.map +1 -1
- package/build/keyring-cosmos/service.d.ts +7 -2
- package/build/keyring-cosmos/service.js +72 -4
- package/build/keyring-cosmos/service.js.map +1 -1
- package/build/phishing-list/handler.js +4 -0
- package/build/phishing-list/handler.js.map +1 -1
- package/build/phishing-list/messages.d.ts +1 -0
- package/build/phishing-list/messages.js +3 -0
- package/build/phishing-list/messages.js.map +1 -1
- package/build/phishing-list/service.d.ts +2 -1
- package/build/phishing-list/service.js +2 -1
- package/build/phishing-list/service.js.map +1 -1
- package/build/phishing-list/service.spec.js +7 -7
- package/build/phishing-list/service.spec.js.map +1 -1
- package/package.json +13 -13
- package/src/analytics/handler.ts +16 -1
- package/src/analytics/init.ts +6 -1
- package/src/analytics/messages.ts +29 -0
- package/src/index.ts +16 -10
- package/src/keyring-cosmos/handler.ts +23 -1
- package/src/keyring-cosmos/init.ts +2 -0
- package/src/keyring-cosmos/messages.ts +57 -0
- package/src/keyring-cosmos/service.ts +107 -3
- package/src/phishing-list/handler.ts +5 -0
- package/src/phishing-list/messages.ts +4 -0
- package/src/phishing-list/service.spec.ts +63 -42
- package/src/phishing-list/service.ts +2 -1
|
@@ -255,6 +255,10 @@ export class PrivilegeCosmosSignAminoWithdrawRewardsMsg extends Message<AminoSig
|
|
|
255
255
|
}
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
+
override approveExternal(): boolean {
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
|
|
258
262
|
route(): string {
|
|
259
263
|
return ROUTE;
|
|
260
264
|
}
|
|
@@ -264,6 +268,59 @@ export class PrivilegeCosmosSignAminoWithdrawRewardsMsg extends Message<AminoSig
|
|
|
264
268
|
}
|
|
265
269
|
}
|
|
266
270
|
|
|
271
|
+
export class PrivilegeCosmosSignAminoDelegateMsg extends Message<AminoSignResponse> {
|
|
272
|
+
public static type() {
|
|
273
|
+
return "PrivilegeCosmosSignAminoDelegate";
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
constructor(
|
|
277
|
+
public readonly chainId: string,
|
|
278
|
+
public readonly signer: string,
|
|
279
|
+
public readonly signDoc: StdSignDoc
|
|
280
|
+
) {
|
|
281
|
+
super();
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
validateBasic(): void {
|
|
285
|
+
if (!this.chainId) {
|
|
286
|
+
throw new KeplrError("keyring", 270, "chain id not set");
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (!this.signer) {
|
|
290
|
+
throw new KeplrError("keyring", 230, "signer not set");
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Validate bech32 address.
|
|
294
|
+
Bech32Address.validate(this.signer);
|
|
295
|
+
|
|
296
|
+
// Check and validate the ADR-36 sign doc.
|
|
297
|
+
// ADR-36 sign doc doesn't have the chain id
|
|
298
|
+
if (!checkAndValidateADR36AminoSignDoc(this.signDoc)) {
|
|
299
|
+
if (this.signDoc.chain_id !== this.chainId) {
|
|
300
|
+
throw new KeplrError(
|
|
301
|
+
"keyring",
|
|
302
|
+
234,
|
|
303
|
+
"Chain id in the message is not matched with the requested chain id"
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
} else {
|
|
307
|
+
throw new Error("Can't use ADR-36 sign doc");
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
override approveExternal(): boolean {
|
|
312
|
+
return true;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
route(): string {
|
|
316
|
+
return ROUTE;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
type(): string {
|
|
320
|
+
return PrivilegeCosmosSignAminoDelegateMsg.type();
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
267
324
|
export class RequestCosmosSignAminoADR36Msg extends Message<StdSignature> {
|
|
268
325
|
public static type() {
|
|
269
326
|
return "request-cosmos-sign-amino-adr-36";
|
|
@@ -37,7 +37,8 @@ export class KeyRingCosmosService {
|
|
|
37
37
|
protected readonly keyRingService: KeyRingService,
|
|
38
38
|
protected readonly interactionService: InteractionService,
|
|
39
39
|
protected readonly chainsUIService: ChainsUIService,
|
|
40
|
-
protected readonly analyticsService: AnalyticsService
|
|
40
|
+
protected readonly analyticsService: AnalyticsService,
|
|
41
|
+
protected readonly msgPrivilegedOrigins: string[]
|
|
41
42
|
) {}
|
|
42
43
|
|
|
43
44
|
async init() {
|
|
@@ -283,12 +284,18 @@ export class KeyRingCosmosService {
|
|
|
283
284
|
}
|
|
284
285
|
|
|
285
286
|
async privilegeSignAminoWithdrawRewards(
|
|
287
|
+
env: Env,
|
|
288
|
+
origin: string,
|
|
286
289
|
chainId: string,
|
|
287
290
|
signer: string,
|
|
288
291
|
signDoc: StdSignDoc
|
|
289
292
|
) {
|
|
290
293
|
// TODO: 이 기능은 ledger에서는 사용할 수 없고 어케 이 문제를 해결할지도 아직 명확하지 않음.
|
|
291
294
|
|
|
295
|
+
if (!env.isInternalMsg && !this.msgPrivilegedOrigins.includes(origin)) {
|
|
296
|
+
throw new Error("Permission Rejected");
|
|
297
|
+
}
|
|
298
|
+
|
|
292
299
|
const chainInfo = this.chainsService.getChainInfoOrThrow(chainId);
|
|
293
300
|
|
|
294
301
|
const vaultId = this.keyRingService.selectedVaultId;
|
|
@@ -358,8 +365,8 @@ export class KeyRingCosmosService {
|
|
|
358
365
|
|
|
359
366
|
this.analyticsService.logEventIgnoreError("tx_signed", {
|
|
360
367
|
chainId,
|
|
361
|
-
isInternal:
|
|
362
|
-
origin
|
|
368
|
+
isInternal: env.isInternalMsg,
|
|
369
|
+
origin,
|
|
363
370
|
signMode: "amino",
|
|
364
371
|
privileged: "withdrawRewards",
|
|
365
372
|
});
|
|
@@ -373,6 +380,103 @@ export class KeyRingCosmosService {
|
|
|
373
380
|
}
|
|
374
381
|
}
|
|
375
382
|
|
|
383
|
+
async privilegeSignAminoDelegate(
|
|
384
|
+
env: Env,
|
|
385
|
+
origin: string,
|
|
386
|
+
chainId: string,
|
|
387
|
+
signer: string,
|
|
388
|
+
signDoc: StdSignDoc
|
|
389
|
+
) {
|
|
390
|
+
// TODO: 이 기능은 ledger에서는 사용할 수 없고 어케 이 문제를 해결할지도 아직 명확하지 않음.
|
|
391
|
+
|
|
392
|
+
if (!env.isInternalMsg && !this.msgPrivilegedOrigins.includes(origin)) {
|
|
393
|
+
throw new Error("Permission Rejected");
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const chainInfo = this.chainsService.getChainInfoOrThrow(chainId);
|
|
397
|
+
|
|
398
|
+
const vaultId = this.keyRingService.selectedVaultId;
|
|
399
|
+
|
|
400
|
+
const isEthermintLike = KeyRingService.isEthermintLike(chainInfo);
|
|
401
|
+
|
|
402
|
+
const keyInfo = this.keyRingService.getKeyInfo(vaultId);
|
|
403
|
+
if (!keyInfo) {
|
|
404
|
+
throw new Error("Null key info");
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (isEthermintLike && keyInfo.type === "ledger") {
|
|
408
|
+
KeyRingCosmosService.throwErrorIfEthermintWithLedgerButNotSupported(
|
|
409
|
+
chainId
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
signDoc = {
|
|
414
|
+
...signDoc,
|
|
415
|
+
memo: escapeHTML(signDoc.memo),
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
signDoc = trimAminoSignDoc(signDoc);
|
|
419
|
+
signDoc = sortObjectByKey(signDoc);
|
|
420
|
+
|
|
421
|
+
const key = await this.getKey(vaultId, chainId);
|
|
422
|
+
const bech32Prefix =
|
|
423
|
+
this.chainsService.getChainInfoOrThrow(chainId).bech32Config
|
|
424
|
+
.bech32PrefixAccAddr;
|
|
425
|
+
const bech32Address = new Bech32Address(key.address).toBech32(bech32Prefix);
|
|
426
|
+
if (signer !== bech32Address) {
|
|
427
|
+
throw new Error("Signer mismatched");
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const isADR36SignDoc = checkAndValidateADR36AminoSignDoc(
|
|
431
|
+
signDoc,
|
|
432
|
+
bech32Prefix
|
|
433
|
+
);
|
|
434
|
+
if (isADR36SignDoc) {
|
|
435
|
+
throw new Error("Can't use ADR-36 sign doc");
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
if (!signDoc.msgs || signDoc.msgs.length === 0) {
|
|
439
|
+
throw new Error("No msgs");
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
for (const msg of signDoc.msgs) {
|
|
443
|
+
// Some chains modify types for obscure reasons. For now, treat it like this:
|
|
444
|
+
const i = msg.type.indexOf("/");
|
|
445
|
+
if (i < 0) {
|
|
446
|
+
throw new Error("Invalid msg type");
|
|
447
|
+
}
|
|
448
|
+
const action = msg.type.slice(i + 1);
|
|
449
|
+
if (action !== "MsgDelegate") {
|
|
450
|
+
throw new Error("Invalid msg type");
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
try {
|
|
455
|
+
const _sig = await this.keyRingService.sign(
|
|
456
|
+
chainId,
|
|
457
|
+
vaultId,
|
|
458
|
+
serializeSignDoc(signDoc),
|
|
459
|
+
isEthermintLike ? "keccak256" : "sha256"
|
|
460
|
+
);
|
|
461
|
+
const signature = new Uint8Array([..._sig.r, ..._sig.s]);
|
|
462
|
+
|
|
463
|
+
this.analyticsService.logEventIgnoreError("tx_signed", {
|
|
464
|
+
chainId,
|
|
465
|
+
isInternal: env.isInternalMsg,
|
|
466
|
+
origin,
|
|
467
|
+
signMode: "amino",
|
|
468
|
+
privileged: "delegate",
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
return {
|
|
472
|
+
signed: signDoc,
|
|
473
|
+
signature: encodeSecp256k1Signature(key.pubKey, signature),
|
|
474
|
+
};
|
|
475
|
+
} finally {
|
|
476
|
+
this.interactionService.dispatchEvent(APP_PORT, "request-sign-end", {});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
376
480
|
async signAminoADR36Selected(
|
|
377
481
|
env: Env,
|
|
378
482
|
origin: string,
|
|
@@ -40,6 +40,11 @@ const handleURLTempAllow: (
|
|
|
40
40
|
service: PhishingListService
|
|
41
41
|
) => InternalHandler<URLTempAllowMsg> =
|
|
42
42
|
(service: PhishingListService) => (_, msg) => {
|
|
43
|
+
const blocklistPageURL = new URL(msg.origin);
|
|
44
|
+
if (blocklistPageURL.origin !== new URL(service.blocklistPageURL).origin) {
|
|
45
|
+
throw new Error("Permission rejected");
|
|
46
|
+
}
|
|
47
|
+
|
|
43
48
|
service.allowUrlTemp(msg.url);
|
|
44
49
|
};
|
|
45
50
|
|
|
@@ -266,12 +266,15 @@ describe("Test phishing list service", () => {
|
|
|
266
266
|
};
|
|
267
267
|
|
|
268
268
|
test("Test basic PhishingListService with valid cases", async () => {
|
|
269
|
-
const service = new PhishingListService(
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
269
|
+
const service = new PhishingListService(
|
|
270
|
+
{
|
|
271
|
+
blockListUrl: `http://127.0.0.1:${port}/list1`,
|
|
272
|
+
fetchingIntervalMs: 3600,
|
|
273
|
+
retryIntervalMs: 3600,
|
|
274
|
+
allowTimeoutMs: 100,
|
|
275
|
+
},
|
|
276
|
+
"http://noop.com"
|
|
277
|
+
);
|
|
275
278
|
eachService = service;
|
|
276
279
|
|
|
277
280
|
service.init();
|
|
@@ -282,12 +285,15 @@ describe("Test phishing list service", () => {
|
|
|
282
285
|
});
|
|
283
286
|
|
|
284
287
|
test("Test basic PhishingListService with strange separators", async () => {
|
|
285
|
-
const service = new PhishingListService(
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
288
|
+
const service = new PhishingListService(
|
|
289
|
+
{
|
|
290
|
+
blockListUrl: `http://127.0.0.1:${port}/list2`,
|
|
291
|
+
fetchingIntervalMs: 3600,
|
|
292
|
+
retryIntervalMs: 3600,
|
|
293
|
+
allowTimeoutMs: 100,
|
|
294
|
+
},
|
|
295
|
+
"http://noop.com"
|
|
296
|
+
);
|
|
291
297
|
eachService = service;
|
|
292
298
|
|
|
293
299
|
service.init();
|
|
@@ -298,12 +304,15 @@ describe("Test phishing list service", () => {
|
|
|
298
304
|
});
|
|
299
305
|
|
|
300
306
|
test("Test basic PhishingListService with strange cases", async () => {
|
|
301
|
-
const service = new PhishingListService(
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
+
const service = new PhishingListService(
|
|
308
|
+
{
|
|
309
|
+
blockListUrl: `http://127.0.0.1:${port}/list3`,
|
|
310
|
+
fetchingIntervalMs: 3600,
|
|
311
|
+
retryIntervalMs: 3600,
|
|
312
|
+
allowTimeoutMs: 100,
|
|
313
|
+
},
|
|
314
|
+
"http://noop.com"
|
|
315
|
+
);
|
|
307
316
|
eachService = service;
|
|
308
317
|
|
|
309
318
|
service.init();
|
|
@@ -314,12 +323,15 @@ describe("Test phishing list service", () => {
|
|
|
314
323
|
});
|
|
315
324
|
|
|
316
325
|
test("Test basic PhishingListService fetching interval", async () => {
|
|
317
|
-
const service = new PhishingListService(
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
326
|
+
const service = new PhishingListService(
|
|
327
|
+
{
|
|
328
|
+
blockListUrl: `http://127.0.0.1:${port}/list3`,
|
|
329
|
+
fetchingIntervalMs: 200,
|
|
330
|
+
retryIntervalMs: 3600,
|
|
331
|
+
allowTimeoutMs: 100,
|
|
332
|
+
},
|
|
333
|
+
"http://noop.com"
|
|
334
|
+
);
|
|
323
335
|
const spyFetch = jest.spyOn(service.urlFetcher, "fetch");
|
|
324
336
|
eachService = service;
|
|
325
337
|
|
|
@@ -357,12 +369,15 @@ describe("Test phishing list service", () => {
|
|
|
357
369
|
});
|
|
358
370
|
|
|
359
371
|
test("Test basic PhishingListService fetching interval with retry interval", async () => {
|
|
360
|
-
const service = new PhishingListService(
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
372
|
+
const service = new PhishingListService(
|
|
373
|
+
{
|
|
374
|
+
blockListUrl: `http://127.0.0.1:${port}/test-retry`,
|
|
375
|
+
fetchingIntervalMs: 200,
|
|
376
|
+
retryIntervalMs: 100,
|
|
377
|
+
allowTimeoutMs: 100,
|
|
378
|
+
},
|
|
379
|
+
"http://noop.com"
|
|
380
|
+
);
|
|
366
381
|
const spyFetch = jest.spyOn(service.urlFetcher, "fetch");
|
|
367
382
|
eachService = service;
|
|
368
383
|
|
|
@@ -433,12 +448,15 @@ describe("Test phishing list service", () => {
|
|
|
433
448
|
});
|
|
434
449
|
|
|
435
450
|
test("Test addUrlTemp allow blocked url", async () => {
|
|
436
|
-
const service = new PhishingListService(
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
451
|
+
const service = new PhishingListService(
|
|
452
|
+
{
|
|
453
|
+
blockListUrl: `http://127.0.0.1:${port}/list1`,
|
|
454
|
+
fetchingIntervalMs: 200,
|
|
455
|
+
retryIntervalMs: 100,
|
|
456
|
+
allowTimeoutMs: 100,
|
|
457
|
+
},
|
|
458
|
+
"http://noop.com"
|
|
459
|
+
);
|
|
442
460
|
eachService = service;
|
|
443
461
|
|
|
444
462
|
service.init();
|
|
@@ -476,12 +494,15 @@ describe("Test phishing list service", () => {
|
|
|
476
494
|
});
|
|
477
495
|
|
|
478
496
|
test("Test subdomains", async () => {
|
|
479
|
-
const service = new PhishingListService(
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
497
|
+
const service = new PhishingListService(
|
|
498
|
+
{
|
|
499
|
+
blockListUrl: `http://127.0.0.1:${port}/subdomains`,
|
|
500
|
+
fetchingIntervalMs: 200,
|
|
501
|
+
retryIntervalMs: 100,
|
|
502
|
+
allowTimeoutMs: 100,
|
|
503
|
+
},
|
|
504
|
+
"http://noop.com"
|
|
505
|
+
);
|
|
485
506
|
eachService = service;
|
|
486
507
|
|
|
487
508
|
service.init();
|