@0xkey-io/core 0.1.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/LICENSE +201 -0
- package/README.MD +7 -0
- package/dist/0xkey-helpers.d.ts +68 -0
- package/dist/0xkey-helpers.d.ts.map +1 -0
- package/dist/0xkey-helpers.js +466 -0
- package/dist/0xkey-helpers.js.map +1 -0
- package/dist/0xkey-helpers.mjs +399 -0
- package/dist/0xkey-helpers.mjs.map +1 -0
- package/dist/__clients__/core.d.ts +1201 -0
- package/dist/__clients__/core.d.ts.map +1 -0
- package/dist/__clients__/core.js +3489 -0
- package/dist/__clients__/core.js.map +1 -0
- package/dist/__clients__/core.mjs +3487 -0
- package/dist/__clients__/core.mjs.map +1 -0
- package/dist/__generated__/sdk-client-base.d.ts +281 -0
- package/dist/__generated__/sdk-client-base.d.ts.map +1 -0
- package/dist/__generated__/sdk-client-base.js +3906 -0
- package/dist/__generated__/sdk-client-base.js.map +1 -0
- package/dist/__generated__/sdk-client-base.mjs +3904 -0
- package/dist/__generated__/sdk-client-base.mjs.map +1 -0
- package/dist/__generated__/version.d.ts +2 -0
- package/dist/__generated__/version.d.ts.map +1 -0
- package/dist/__generated__/version.js +6 -0
- package/dist/__generated__/version.js.map +1 -0
- package/dist/__generated__/version.mjs +4 -0
- package/dist/__generated__/version.mjs.map +1 -0
- package/dist/__inputs__/public_api.types.d.ts +6014 -0
- package/dist/__inputs__/public_api.types.d.ts.map +1 -0
- package/dist/__polyfills__/jest.setup.webcrypto.d.ts +2 -0
- package/dist/__polyfills__/jest.setup.webcrypto.d.ts.map +1 -0
- package/dist/__polyfills__/window.d.ts +15 -0
- package/dist/__polyfills__/window.d.ts.map +1 -0
- package/dist/__polyfills__/window.js +30 -0
- package/dist/__polyfills__/window.js.map +1 -0
- package/dist/__polyfills__/window.mjs +28 -0
- package/dist/__polyfills__/window.mjs.map +1 -0
- package/dist/__stampers__/api/base.d.ts +27 -0
- package/dist/__stampers__/api/base.d.ts.map +1 -0
- package/dist/__stampers__/api/base.js +102 -0
- package/dist/__stampers__/api/base.js.map +1 -0
- package/dist/__stampers__/api/base.mjs +100 -0
- package/dist/__stampers__/api/base.mjs.map +1 -0
- package/dist/__stampers__/api/mobile/stamper.d.ts +15 -0
- package/dist/__stampers__/api/mobile/stamper.d.ts.map +1 -0
- package/dist/__stampers__/api/mobile/stamper.js +119 -0
- package/dist/__stampers__/api/mobile/stamper.js.map +1 -0
- package/dist/__stampers__/api/mobile/stamper.mjs +117 -0
- package/dist/__stampers__/api/mobile/stamper.mjs.map +1 -0
- package/dist/__stampers__/api/web/stamper.d.ts +14 -0
- package/dist/__stampers__/api/web/stamper.d.ts.map +1 -0
- package/dist/__stampers__/api/web/stamper.js +201 -0
- package/dist/__stampers__/api/web/stamper.js.map +1 -0
- package/dist/__stampers__/api/web/stamper.mjs +199 -0
- package/dist/__stampers__/api/web/stamper.mjs.map +1 -0
- package/dist/__stampers__/passkey/base.d.ts +16 -0
- package/dist/__stampers__/passkey/base.d.ts.map +1 -0
- package/dist/__stampers__/passkey/base.js +138 -0
- package/dist/__stampers__/passkey/base.js.map +1 -0
- package/dist/__stampers__/passkey/base.mjs +134 -0
- package/dist/__stampers__/passkey/base.mjs.map +1 -0
- package/dist/__storage__/base.d.ts +3 -0
- package/dist/__storage__/base.d.ts.map +1 -0
- package/dist/__storage__/base.js +27 -0
- package/dist/__storage__/base.js.map +1 -0
- package/dist/__storage__/base.mjs +25 -0
- package/dist/__storage__/base.mjs.map +1 -0
- package/dist/__storage__/mobile/storage.d.ts +18 -0
- package/dist/__storage__/mobile/storage.d.ts.map +1 -0
- package/dist/__storage__/mobile/storage.js +76 -0
- package/dist/__storage__/mobile/storage.js.map +1 -0
- package/dist/__storage__/mobile/storage.mjs +74 -0
- package/dist/__storage__/mobile/storage.mjs.map +1 -0
- package/dist/__storage__/web/storage.d.ts +19 -0
- package/dist/__storage__/web/storage.d.ts.map +1 -0
- package/dist/__storage__/web/storage.js +79 -0
- package/dist/__storage__/web/storage.js.map +1 -0
- package/dist/__storage__/web/storage.mjs +77 -0
- package/dist/__storage__/web/storage.mjs.map +1 -0
- package/dist/__typedoc-entry__/index.d.ts +3 -0
- package/dist/__typedoc-entry__/index.d.ts.map +1 -0
- package/dist/__types__/auth.d.ts +120 -0
- package/dist/__types__/auth.d.ts.map +1 -0
- package/dist/__types__/auth.js +7 -0
- package/dist/__types__/auth.js.map +1 -0
- package/dist/__types__/auth.mjs +5 -0
- package/dist/__types__/auth.mjs.map +1 -0
- package/dist/__types__/config.d.ts +145 -0
- package/dist/__types__/config.d.ts.map +1 -0
- package/dist/__types__/enums.d.ts +59 -0
- package/dist/__types__/enums.d.ts.map +1 -0
- package/dist/__types__/enums.js +72 -0
- package/dist/__types__/enums.js.map +1 -0
- package/dist/__types__/enums.mjs +70 -0
- package/dist/__types__/enums.mjs.map +1 -0
- package/dist/__types__/error.d.ts +13 -0
- package/dist/__types__/error.d.ts.map +1 -0
- package/dist/__types__/error.js +18 -0
- package/dist/__types__/error.js.map +1 -0
- package/dist/__types__/error.mjs +16 -0
- package/dist/__types__/error.mjs.map +1 -0
- package/dist/__types__/export.d.ts +10 -0
- package/dist/__types__/export.d.ts.map +1 -0
- package/dist/__types__/external-wallets.d.ts +203 -0
- package/dist/__types__/external-wallets.d.ts.map +1 -0
- package/dist/__types__/http.d.ts +17 -0
- package/dist/__types__/http.d.ts.map +1 -0
- package/dist/__types__/http.js +11 -0
- package/dist/__types__/http.js.map +1 -0
- package/dist/__types__/http.mjs +9 -0
- package/dist/__types__/http.mjs.map +1 -0
- package/dist/__types__/index.d.ts +10 -0
- package/dist/__types__/index.d.ts.map +1 -0
- package/dist/__types__/method-types/import-export-params.d.ts +38 -0
- package/dist/__types__/method-types/import-export-params.d.ts.map +1 -0
- package/dist/__types__/method-types/shared.d.ts +378 -0
- package/dist/__types__/method-types/shared.d.ts.map +1 -0
- package/dist/__wallet__/base.d.ts +14 -0
- package/dist/__wallet__/base.d.ts.map +1 -0
- package/dist/__wallet__/base.js +35 -0
- package/dist/__wallet__/base.js.map +1 -0
- package/dist/__wallet__/base.mjs +33 -0
- package/dist/__wallet__/base.mjs.map +1 -0
- package/dist/__wallet__/connector.d.ts +60 -0
- package/dist/__wallet__/connector.d.ts.map +1 -0
- package/dist/__wallet__/connector.js +93 -0
- package/dist/__wallet__/connector.js.map +1 -0
- package/dist/__wallet__/connector.mjs +91 -0
- package/dist/__wallet__/connector.mjs.map +1 -0
- package/dist/__wallet__/mobile/manager.d.ts +51 -0
- package/dist/__wallet__/mobile/manager.d.ts.map +1 -0
- package/dist/__wallet__/mobile/manager.js +115 -0
- package/dist/__wallet__/mobile/manager.js.map +1 -0
- package/dist/__wallet__/mobile/manager.mjs +113 -0
- package/dist/__wallet__/mobile/manager.mjs.map +1 -0
- package/dist/__wallet__/stamper.d.ts +90 -0
- package/dist/__wallet__/stamper.d.ts.map +1 -0
- package/dist/__wallet__/stamper.js +183 -0
- package/dist/__wallet__/stamper.js.map +1 -0
- package/dist/__wallet__/stamper.mjs +180 -0
- package/dist/__wallet__/stamper.mjs.map +1 -0
- package/dist/__wallet__/wallet-connect/base.d.ts +182 -0
- package/dist/__wallet__/wallet-connect/base.d.ts.map +1 -0
- package/dist/__wallet__/wallet-connect/base.js +606 -0
- package/dist/__wallet__/wallet-connect/base.js.map +1 -0
- package/dist/__wallet__/wallet-connect/base.mjs +604 -0
- package/dist/__wallet__/wallet-connect/base.mjs.map +1 -0
- package/dist/__wallet__/wallet-connect/client.d.ts +132 -0
- package/dist/__wallet__/wallet-connect/client.d.ts.map +1 -0
- package/dist/__wallet__/wallet-connect/client.js +262 -0
- package/dist/__wallet__/wallet-connect/client.js.map +1 -0
- package/dist/__wallet__/wallet-connect/client.mjs +260 -0
- package/dist/__wallet__/wallet-connect/client.mjs.map +1 -0
- package/dist/__wallet__/web/manager.d.ts +70 -0
- package/dist/__wallet__/web/manager.d.ts.map +1 -0
- package/dist/__wallet__/web/manager.js +177 -0
- package/dist/__wallet__/web/manager.js.map +1 -0
- package/dist/__wallet__/web/manager.mjs +175 -0
- package/dist/__wallet__/web/manager.mjs.map +1 -0
- package/dist/__wallet__/web/native/ethereum.d.ts +101 -0
- package/dist/__wallet__/web/native/ethereum.d.ts.map +1 -0
- package/dist/__wallet__/web/native/ethereum.js +339 -0
- package/dist/__wallet__/web/native/ethereum.js.map +1 -0
- package/dist/__wallet__/web/native/ethereum.mjs +336 -0
- package/dist/__wallet__/web/native/ethereum.mjs.map +1 -0
- package/dist/__wallet__/web/native/solana.d.ts +72 -0
- package/dist/__wallet__/web/native/solana.d.ts.map +1 -0
- package/dist/__wallet__/web/native/solana.js +215 -0
- package/dist/__wallet__/web/native/solana.js.map +1 -0
- package/dist/__wallet__/web/native/solana.mjs +212 -0
- package/dist/__wallet__/web/native/solana.mjs.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +10 -0
- package/dist/index.mjs.map +1 -0
- package/dist/utils.d.ts +160 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +1047 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.mjs +1007 -0
- package/dist/utils.mjs.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { isWeb, isReactNative } from '../../utils.mjs';
|
|
2
|
+
import { IndexedDbStamper } from './web/stamper.mjs';
|
|
3
|
+
import { ZeroXKeyError, ZeroXKeyErrorCodes } from '@0xkey-io/sdk-types';
|
|
4
|
+
import { SignatureFormat } from '@0xkey-io/api-key-stamper';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Cross-platform API key stamper.
|
|
8
|
+
*
|
|
9
|
+
* - This stamper uses indexedDB on web and keychain on react-native to securely stamp ZeroXKey requests.
|
|
10
|
+
* - ***Only supports P-256 ECDSA key pairs.***
|
|
11
|
+
*/
|
|
12
|
+
class CrossPlatformApiKeyStamper {
|
|
13
|
+
constructor(storageManager) {
|
|
14
|
+
this.storageManager = storageManager;
|
|
15
|
+
// Use init method to set up the stamper based on the platform. It's async, so can't be done in the constructor.
|
|
16
|
+
}
|
|
17
|
+
async init() {
|
|
18
|
+
if (isWeb()) {
|
|
19
|
+
this.stamper = new IndexedDbStamper();
|
|
20
|
+
}
|
|
21
|
+
else if (isReactNative()) {
|
|
22
|
+
try {
|
|
23
|
+
// Dynamic import to prevent bundling the native module in web environments.
|
|
24
|
+
const { ReactNativeKeychainStamper } = await import('./mobile/stamper.mjs');
|
|
25
|
+
this.stamper = new ReactNativeKeychainStamper();
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
throw new ZeroXKeyError(`Failed to load keychain stamper for react-native`, ZeroXKeyErrorCodes.INITIALIZE_CLIENT_ERROR, error);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
throw new ZeroXKeyError("Unsupported platform for API key stamper", ZeroXKeyErrorCodes.UNSUPPORTED_PLATFORM);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
listKeyPairs() {
|
|
36
|
+
if (!this.stamper) {
|
|
37
|
+
throw new ZeroXKeyError("Stamper is not initialized. Please call .init() before calling this method.", ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
38
|
+
}
|
|
39
|
+
return this.stamper.listKeyPairs();
|
|
40
|
+
}
|
|
41
|
+
createKeyPair(externalKeyPair) {
|
|
42
|
+
if (!this.stamper) {
|
|
43
|
+
throw new ZeroXKeyError("Stamper is not initialized. Please call .init() before calling this method.", ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
44
|
+
}
|
|
45
|
+
return this.stamper.createKeyPair(externalKeyPair);
|
|
46
|
+
}
|
|
47
|
+
deleteKeyPair(publicKeyHex) {
|
|
48
|
+
if (!this.stamper) {
|
|
49
|
+
throw new ZeroXKeyError("Stamper is not initialized. Please call .init() before calling this method.", ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
50
|
+
}
|
|
51
|
+
// If the deleted key pair is the temporary one, clear it.
|
|
52
|
+
if (this.temporaryPublicKey === publicKeyHex) {
|
|
53
|
+
this.temporaryPublicKey = undefined;
|
|
54
|
+
}
|
|
55
|
+
return this.stamper.deleteKeyPair(publicKeyHex);
|
|
56
|
+
}
|
|
57
|
+
// This allows forcing a specific public key to find the key pair for stamping. The key pair must already exist in indexedDB / Keychain.
|
|
58
|
+
// This is useful if you need to stamp with a specific key pair without having an active session.
|
|
59
|
+
// See "signUpWithPasskey" function in core.ts for usage
|
|
60
|
+
setTemporaryPublicKey(publicKeyHex) {
|
|
61
|
+
this.temporaryPublicKey = publicKeyHex;
|
|
62
|
+
}
|
|
63
|
+
getTemporaryPublicKey() {
|
|
64
|
+
return this.temporaryPublicKey;
|
|
65
|
+
}
|
|
66
|
+
clearTemporaryPublicKey() {
|
|
67
|
+
this.temporaryPublicKey = undefined;
|
|
68
|
+
}
|
|
69
|
+
async stamp(payload) {
|
|
70
|
+
if (!this.stamper) {
|
|
71
|
+
throw new ZeroXKeyError("Stamper is not initialized. Please call .init() before calling this method.", ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
72
|
+
}
|
|
73
|
+
let publicKeyHex = this.temporaryPublicKey;
|
|
74
|
+
if (!publicKeyHex) {
|
|
75
|
+
const session = await this.storageManager.getActiveSession();
|
|
76
|
+
if (!session) {
|
|
77
|
+
throw new ZeroXKeyError("No active session or token available.", ZeroXKeyErrorCodes.NO_SESSION_FOUND);
|
|
78
|
+
}
|
|
79
|
+
publicKeyHex = session.publicKey;
|
|
80
|
+
}
|
|
81
|
+
return this.stamper.stamp(payload, publicKeyHex);
|
|
82
|
+
}
|
|
83
|
+
async sign(payload, format = SignatureFormat.Der) {
|
|
84
|
+
if (!this.stamper) {
|
|
85
|
+
throw new ZeroXKeyError("Stamper is not initialized. Please call .init() before calling this method.", ZeroXKeyErrorCodes.CLIENT_NOT_INITIALIZED);
|
|
86
|
+
}
|
|
87
|
+
let publicKeyHex = this.temporaryPublicKey;
|
|
88
|
+
if (!publicKeyHex) {
|
|
89
|
+
const session = await this.storageManager.getActiveSession();
|
|
90
|
+
if (!session) {
|
|
91
|
+
throw new ZeroXKeyError("No active session or token available.", ZeroXKeyErrorCodes.NO_SESSION_FOUND);
|
|
92
|
+
}
|
|
93
|
+
publicKeyHex = session.publicKey;
|
|
94
|
+
}
|
|
95
|
+
return this.stamper.sign(payload, publicKeyHex, format);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export { CrossPlatformApiKeyStamper };
|
|
100
|
+
//# sourceMappingURL=base.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.mjs","sources":["../../../src/__stampers__/api/base.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { SignatureFormat } from "@0xkey-io/api-key-stamper";
|
|
2
|
+
import type { TStamp, ApiKeyStamperBase } from "../../../__types__";
|
|
3
|
+
export declare class ReactNativeKeychainStamper implements ApiKeyStamperBase {
|
|
4
|
+
private serviceName;
|
|
5
|
+
listKeyPairs(): Promise<string[]>;
|
|
6
|
+
createKeyPair(externalKeyPair?: {
|
|
7
|
+
publicKey: string;
|
|
8
|
+
privateKey: string;
|
|
9
|
+
}): Promise<string>;
|
|
10
|
+
deleteKeyPair(publicKeyHex: string): Promise<void>;
|
|
11
|
+
private getPrivateKey;
|
|
12
|
+
stamp(payload: string, publicKeyHex: string): Promise<TStamp>;
|
|
13
|
+
sign(payload: string, publicKeyHex: string, format: SignatureFormat): Promise<string>;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=stamper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stamper.d.ts","sourceRoot":"","sources":["../../../../src/__stampers__/api/mobile/stamper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE3E,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAsBpE,qBAAa,0BAA2B,YAAW,iBAAiB;IAClE,OAAO,CAAC,WAAW;IAIb,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAOjC,aAAa,CAAC,eAAe,CAAC,EAAE;QACpC,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;KACpB,GAAG,OAAO,CAAC,MAAM,CAAC;IAsBb,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAY1C,aAAa;IAyBrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAa7D,IAAI,CACR,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,MAAM,CAAC;CAoBnB"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var apiKeyStamper = require('@0xkey-io/api-key-stamper');
|
|
4
|
+
var crypto = require('@0xkey-io/crypto');
|
|
5
|
+
|
|
6
|
+
let Keychain;
|
|
7
|
+
try {
|
|
8
|
+
Keychain = require("react-native-keychain");
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
throw new Error("Please install react-native-keychain in your app to use ReactNativeKeychainStamper");
|
|
12
|
+
}
|
|
13
|
+
// In versions <=1.8.0, keys were stored using just the publicKey as the keychain service name
|
|
14
|
+
// This caused `listKeyPairs()` to return ALL keychain entries (including non-ZeroXKey ones),
|
|
15
|
+
// which meant `clearUnusedKeyPairs()` would delete the user's own keychain data
|
|
16
|
+
//
|
|
17
|
+
// To fix this, we now prefix all ZeroXKey-managed keys with this constant to scope them
|
|
18
|
+
// properly to ZeroXKey. Methods that read or delete keys still fall back to the unprefixed
|
|
19
|
+
// service name to migrate legacy keys. This fallback can be removed once we're confident
|
|
20
|
+
// all users have migrated to the prefixed format
|
|
21
|
+
const ZEROXKEY_KEY_PREFIX = "com.0xkey.keypair:";
|
|
22
|
+
class ReactNativeKeychainStamper {
|
|
23
|
+
serviceName(publicKeyHex) {
|
|
24
|
+
return `${ZEROXKEY_KEY_PREFIX}${publicKeyHex}`;
|
|
25
|
+
}
|
|
26
|
+
async listKeyPairs() {
|
|
27
|
+
const allServices = await Keychain.getAllGenericPasswordServices();
|
|
28
|
+
return allServices
|
|
29
|
+
.filter((service) => service.startsWith(ZEROXKEY_KEY_PREFIX))
|
|
30
|
+
.map((service) => service.slice(ZEROXKEY_KEY_PREFIX.length));
|
|
31
|
+
}
|
|
32
|
+
async createKeyPair(externalKeyPair) {
|
|
33
|
+
let privateKey;
|
|
34
|
+
let publicKey;
|
|
35
|
+
if (externalKeyPair) {
|
|
36
|
+
privateKey = externalKeyPair.privateKey;
|
|
37
|
+
publicKey = externalKeyPair.publicKey;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
const pair = crypto.generateP256KeyPair();
|
|
41
|
+
privateKey = pair.privateKey;
|
|
42
|
+
publicKey = pair.publicKey;
|
|
43
|
+
}
|
|
44
|
+
// we store in Keychain with a
|
|
45
|
+
// ZeroXKey-specific service prefix
|
|
46
|
+
await Keychain.setGenericPassword(publicKey, privateKey, {
|
|
47
|
+
service: this.serviceName(publicKey),
|
|
48
|
+
});
|
|
49
|
+
return publicKey;
|
|
50
|
+
}
|
|
51
|
+
async deleteKeyPair(publicKeyHex) {
|
|
52
|
+
// we check if the key exists under the prefixed service name
|
|
53
|
+
// - if it exists, we delete that
|
|
54
|
+
// - otherwise, we assume it's a legacy (unprefixed) key and try to delete that
|
|
55
|
+
const hasPrefixed = await Keychain.getGenericPassword({
|
|
56
|
+
service: this.serviceName(publicKeyHex),
|
|
57
|
+
});
|
|
58
|
+
await Keychain.resetGenericPassword({
|
|
59
|
+
service: hasPrefixed ? this.serviceName(publicKeyHex) : publicKeyHex,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
async getPrivateKey(publicKeyHex) {
|
|
63
|
+
// we check if the key exists under the prefixed service name
|
|
64
|
+
// - if it exists, we return the private key
|
|
65
|
+
// - otherwise, we assume it's a legacy (unprefixed) key, migrate it
|
|
66
|
+
// to the prefixed format, and return the private key
|
|
67
|
+
const prefixedCreds = await Keychain.getGenericPassword({
|
|
68
|
+
service: this.serviceName(publicKeyHex),
|
|
69
|
+
});
|
|
70
|
+
if (prefixedCreds)
|
|
71
|
+
return prefixedCreds.password;
|
|
72
|
+
// we fall back to the unprefixed (legacy) service name
|
|
73
|
+
const creds = await Keychain.getGenericPassword({
|
|
74
|
+
service: publicKeyHex,
|
|
75
|
+
});
|
|
76
|
+
if (!creds)
|
|
77
|
+
return null;
|
|
78
|
+
// migrate the legacy key to the prefixed format so it's properly scoped going forward
|
|
79
|
+
await Keychain.setGenericPassword(creds.username, creds.password, {
|
|
80
|
+
service: this.serviceName(publicKeyHex),
|
|
81
|
+
});
|
|
82
|
+
await Keychain.resetGenericPassword({ service: publicKeyHex });
|
|
83
|
+
return creds.password;
|
|
84
|
+
}
|
|
85
|
+
async stamp(payload, publicKeyHex) {
|
|
86
|
+
const privateKey = await this.getPrivateKey(publicKeyHex);
|
|
87
|
+
if (!privateKey) {
|
|
88
|
+
throw new Error(`No private key found for public key: ${publicKeyHex}`);
|
|
89
|
+
}
|
|
90
|
+
const stamper = new apiKeyStamper.ApiKeyStamper({
|
|
91
|
+
apiPublicKey: publicKeyHex,
|
|
92
|
+
apiPrivateKey: privateKey,
|
|
93
|
+
});
|
|
94
|
+
const { stampHeaderName, stampHeaderValue } = await stamper.stamp(payload);
|
|
95
|
+
return { stampHeaderName, stampHeaderValue };
|
|
96
|
+
}
|
|
97
|
+
async sign(payload, publicKeyHex, format) {
|
|
98
|
+
const privateKey = await this.getPrivateKey(publicKeyHex);
|
|
99
|
+
if (!privateKey) {
|
|
100
|
+
throw new Error(`No private key found for public key: ${publicKeyHex}`);
|
|
101
|
+
}
|
|
102
|
+
const stamper = new apiKeyStamper.ApiKeyStamper({
|
|
103
|
+
apiPublicKey: publicKeyHex,
|
|
104
|
+
apiPrivateKey: privateKey,
|
|
105
|
+
});
|
|
106
|
+
switch (format) {
|
|
107
|
+
case apiKeyStamper.SignatureFormat.Raw: {
|
|
108
|
+
return stamper.sign(payload, apiKeyStamper.SignatureFormat.Raw);
|
|
109
|
+
}
|
|
110
|
+
case apiKeyStamper.SignatureFormat.Der:
|
|
111
|
+
return stamper.sign(payload, apiKeyStamper.SignatureFormat.Der);
|
|
112
|
+
default:
|
|
113
|
+
throw new Error(`Unsupported signature format: ${format}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
exports.ReactNativeKeychainStamper = ReactNativeKeychainStamper;
|
|
119
|
+
//# sourceMappingURL=stamper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stamper.js","sources":["../../../../src/__stampers__/api/mobile/stamper.ts"],"sourcesContent":[null],"names":["generateP256KeyPair","ApiKeyStamper","SignatureFormat"],"mappings":";;;;;AAIA,IAAI,QAAgD;AAEpD,IAAI;AACF,IAAA,QAAQ,GAAG,OAAO,CAAC,uBAAuB,CAAC;AAC7C;AAAE,MAAM;AACN,IAAA,MAAM,IAAI,KAAK,CACb,oFAAoF,CACrF;AACH;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,mBAAmB,GAAG,oBAAoB;MAEnC,0BAA0B,CAAA;AAC7B,IAAA,WAAW,CAAC,YAAoB,EAAA;AACtC,QAAA,OAAO,CAAA,EAAG,mBAAmB,CAAA,EAAG,YAAY,EAAE;IAChD;AAEA,IAAA,MAAM,YAAY,GAAA;AAChB,QAAA,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,6BAA6B,EAAE;AAClE,QAAA,OAAO;AACJ,aAAA,MAAM,CAAC,CAAC,OAAe,KAAK,OAAO,CAAC,UAAU,CAAC,mBAAmB,CAAC;AACnE,aAAA,GAAG,CAAC,CAAC,OAAe,KAAK,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACxE;IAEA,MAAM,aAAa,CAAC,eAGnB,EAAA;AACC,QAAA,IAAI,UAAkB;AACtB,QAAA,IAAI,SAAiB;QAErB,IAAI,eAAe,EAAE;AACnB,YAAA,UAAU,GAAG,eAAe,CAAC,UAAU;AACvC,YAAA,SAAS,GAAG,eAAe,CAAC,SAAS;QACvC;aAAO;AACL,YAAA,MAAM,IAAI,GAAGA,0BAAmB,EAAE;AAClC,YAAA,UAAU,GAAG,IAAI,CAAC,UAAU;AAC5B,YAAA,SAAS,GAAG,IAAI,CAAC,SAAS;QAC5B;;;AAIA,QAAA,MAAM,QAAQ,CAAC,kBAAkB,CAAC,SAAS,EAAE,UAAU,EAAE;AACvD,YAAA,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC;AACrC,SAAA,CAAC;AAEF,QAAA,OAAO,SAAS;IAClB;IAEA,MAAM,aAAa,CAAC,YAAoB,EAAA;;;;AAItC,QAAA,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC;AACpD,YAAA,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC;AACxC,SAAA,CAAC;QACF,MAAM,QAAQ,CAAC,oBAAoB,CAAC;AAClC,YAAA,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,GAAG,YAAY;AACrE,SAAA,CAAC;IACJ;IAEQ,MAAM,aAAa,CAAC,YAAoB,EAAA;;;;;AAK9C,QAAA,MAAM,aAAa,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC;AACtD,YAAA,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC;AACxC,SAAA,CAAC;AACF,QAAA,IAAI,aAAa;YAAE,OAAO,aAAa,CAAC,QAAQ;;AAGhD,QAAA,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC;AAC9C,YAAA,OAAO,EAAE,YAAY;AACtB,SAAA,CAAC;AACF,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,IAAI;;QAGvB,MAAM,QAAQ,CAAC,kBAAkB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE;AAChE,YAAA,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC;AACxC,SAAA,CAAC;QACF,MAAM,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC;QAE9D,OAAO,KAAK,CAAC,QAAQ;IACvB;AAEA,IAAA,MAAM,KAAK,CAAC,OAAe,EAAE,YAAoB,EAAA;QAC/C,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC;QACzD,IAAI,CAAC,UAAU,EAAE;AACf,YAAA,MAAM,IAAI,KAAK,CAAC,wCAAwC,YAAY,CAAA,CAAE,CAAC;QACzE;AACA,QAAA,MAAM,OAAO,GAAG,IAAIC,2BAAa,CAAC;AAChC,YAAA,YAAY,EAAE,YAAY;AAC1B,YAAA,aAAa,EAAE,UAAU;AAC1B,SAAA,CAAC;AACF,QAAA,MAAM,EAAE,eAAe,EAAE,gBAAgB,EAAE,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC;AAC1E,QAAA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE;IAC9C;AAEA,IAAA,MAAM,IAAI,CACR,OAAe,EACf,YAAoB,EACpB,MAAuB,EAAA;QAEvB,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC;QACzD,IAAI,CAAC,UAAU,EAAE;AACf,YAAA,MAAM,IAAI,KAAK,CAAC,wCAAwC,YAAY,CAAA,CAAE,CAAC;QACzE;AACA,QAAA,MAAM,OAAO,GAAG,IAAIA,2BAAa,CAAC;AAChC,YAAA,YAAY,EAAE,YAAY;AAC1B,YAAA,aAAa,EAAE,UAAU;AAC1B,SAAA,CAAC;QAEF,QAAQ,MAAM;AACZ,YAAA,KAAKC,6BAAe,CAAC,GAAG,EAAE;gBACxB,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,EAAEA,6BAAe,CAAC,GAAG,CAAC;YACnD;YACA,KAAKA,6BAAe,CAAC,GAAG;gBACtB,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,EAAEA,6BAAe,CAAC,GAAG,CAAC;AACnD,YAAA;AACE,gBAAA,MAAM,IAAI,KAAK,CAAC,iCAAiC,MAAM,CAAA,CAAE,CAAC;;IAEhE;AACD;;;;"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { ApiKeyStamper, SignatureFormat } from '@0xkey-io/api-key-stamper';
|
|
2
|
+
import { generateP256KeyPair } from '@0xkey-io/crypto';
|
|
3
|
+
|
|
4
|
+
let Keychain;
|
|
5
|
+
try {
|
|
6
|
+
Keychain = require("react-native-keychain");
|
|
7
|
+
}
|
|
8
|
+
catch {
|
|
9
|
+
throw new Error("Please install react-native-keychain in your app to use ReactNativeKeychainStamper");
|
|
10
|
+
}
|
|
11
|
+
// In versions <=1.8.0, keys were stored using just the publicKey as the keychain service name
|
|
12
|
+
// This caused `listKeyPairs()` to return ALL keychain entries (including non-ZeroXKey ones),
|
|
13
|
+
// which meant `clearUnusedKeyPairs()` would delete the user's own keychain data
|
|
14
|
+
//
|
|
15
|
+
// To fix this, we now prefix all ZeroXKey-managed keys with this constant to scope them
|
|
16
|
+
// properly to ZeroXKey. Methods that read or delete keys still fall back to the unprefixed
|
|
17
|
+
// service name to migrate legacy keys. This fallback can be removed once we're confident
|
|
18
|
+
// all users have migrated to the prefixed format
|
|
19
|
+
const ZEROXKEY_KEY_PREFIX = "com.0xkey.keypair:";
|
|
20
|
+
class ReactNativeKeychainStamper {
|
|
21
|
+
serviceName(publicKeyHex) {
|
|
22
|
+
return `${ZEROXKEY_KEY_PREFIX}${publicKeyHex}`;
|
|
23
|
+
}
|
|
24
|
+
async listKeyPairs() {
|
|
25
|
+
const allServices = await Keychain.getAllGenericPasswordServices();
|
|
26
|
+
return allServices
|
|
27
|
+
.filter((service) => service.startsWith(ZEROXKEY_KEY_PREFIX))
|
|
28
|
+
.map((service) => service.slice(ZEROXKEY_KEY_PREFIX.length));
|
|
29
|
+
}
|
|
30
|
+
async createKeyPair(externalKeyPair) {
|
|
31
|
+
let privateKey;
|
|
32
|
+
let publicKey;
|
|
33
|
+
if (externalKeyPair) {
|
|
34
|
+
privateKey = externalKeyPair.privateKey;
|
|
35
|
+
publicKey = externalKeyPair.publicKey;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const pair = generateP256KeyPair();
|
|
39
|
+
privateKey = pair.privateKey;
|
|
40
|
+
publicKey = pair.publicKey;
|
|
41
|
+
}
|
|
42
|
+
// we store in Keychain with a
|
|
43
|
+
// ZeroXKey-specific service prefix
|
|
44
|
+
await Keychain.setGenericPassword(publicKey, privateKey, {
|
|
45
|
+
service: this.serviceName(publicKey),
|
|
46
|
+
});
|
|
47
|
+
return publicKey;
|
|
48
|
+
}
|
|
49
|
+
async deleteKeyPair(publicKeyHex) {
|
|
50
|
+
// we check if the key exists under the prefixed service name
|
|
51
|
+
// - if it exists, we delete that
|
|
52
|
+
// - otherwise, we assume it's a legacy (unprefixed) key and try to delete that
|
|
53
|
+
const hasPrefixed = await Keychain.getGenericPassword({
|
|
54
|
+
service: this.serviceName(publicKeyHex),
|
|
55
|
+
});
|
|
56
|
+
await Keychain.resetGenericPassword({
|
|
57
|
+
service: hasPrefixed ? this.serviceName(publicKeyHex) : publicKeyHex,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async getPrivateKey(publicKeyHex) {
|
|
61
|
+
// we check if the key exists under the prefixed service name
|
|
62
|
+
// - if it exists, we return the private key
|
|
63
|
+
// - otherwise, we assume it's a legacy (unprefixed) key, migrate it
|
|
64
|
+
// to the prefixed format, and return the private key
|
|
65
|
+
const prefixedCreds = await Keychain.getGenericPassword({
|
|
66
|
+
service: this.serviceName(publicKeyHex),
|
|
67
|
+
});
|
|
68
|
+
if (prefixedCreds)
|
|
69
|
+
return prefixedCreds.password;
|
|
70
|
+
// we fall back to the unprefixed (legacy) service name
|
|
71
|
+
const creds = await Keychain.getGenericPassword({
|
|
72
|
+
service: publicKeyHex,
|
|
73
|
+
});
|
|
74
|
+
if (!creds)
|
|
75
|
+
return null;
|
|
76
|
+
// migrate the legacy key to the prefixed format so it's properly scoped going forward
|
|
77
|
+
await Keychain.setGenericPassword(creds.username, creds.password, {
|
|
78
|
+
service: this.serviceName(publicKeyHex),
|
|
79
|
+
});
|
|
80
|
+
await Keychain.resetGenericPassword({ service: publicKeyHex });
|
|
81
|
+
return creds.password;
|
|
82
|
+
}
|
|
83
|
+
async stamp(payload, publicKeyHex) {
|
|
84
|
+
const privateKey = await this.getPrivateKey(publicKeyHex);
|
|
85
|
+
if (!privateKey) {
|
|
86
|
+
throw new Error(`No private key found for public key: ${publicKeyHex}`);
|
|
87
|
+
}
|
|
88
|
+
const stamper = new ApiKeyStamper({
|
|
89
|
+
apiPublicKey: publicKeyHex,
|
|
90
|
+
apiPrivateKey: privateKey,
|
|
91
|
+
});
|
|
92
|
+
const { stampHeaderName, stampHeaderValue } = await stamper.stamp(payload);
|
|
93
|
+
return { stampHeaderName, stampHeaderValue };
|
|
94
|
+
}
|
|
95
|
+
async sign(payload, publicKeyHex, format) {
|
|
96
|
+
const privateKey = await this.getPrivateKey(publicKeyHex);
|
|
97
|
+
if (!privateKey) {
|
|
98
|
+
throw new Error(`No private key found for public key: ${publicKeyHex}`);
|
|
99
|
+
}
|
|
100
|
+
const stamper = new ApiKeyStamper({
|
|
101
|
+
apiPublicKey: publicKeyHex,
|
|
102
|
+
apiPrivateKey: privateKey,
|
|
103
|
+
});
|
|
104
|
+
switch (format) {
|
|
105
|
+
case SignatureFormat.Raw: {
|
|
106
|
+
return stamper.sign(payload, SignatureFormat.Raw);
|
|
107
|
+
}
|
|
108
|
+
case SignatureFormat.Der:
|
|
109
|
+
return stamper.sign(payload, SignatureFormat.Der);
|
|
110
|
+
default:
|
|
111
|
+
throw new Error(`Unsupported signature format: ${format}`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export { ReactNativeKeychainStamper };
|
|
117
|
+
//# sourceMappingURL=stamper.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stamper.mjs","sources":["../../../../src/__stampers__/api/mobile/stamper.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { TStamp, ApiKeyStamperBase } from "../../../__types__";
|
|
2
|
+
import { SignatureFormat } from "@0xkey-io/api-key-stamper";
|
|
3
|
+
export declare class IndexedDbStamper implements ApiKeyStamperBase {
|
|
4
|
+
constructor();
|
|
5
|
+
private openDb;
|
|
6
|
+
private storeKeyPair;
|
|
7
|
+
private getPrivateKey;
|
|
8
|
+
listKeyPairs(): Promise<string[]>;
|
|
9
|
+
createKeyPair(externalKeyPair?: CryptoKeyPair): Promise<string>;
|
|
10
|
+
deleteKeyPair(publicKeyHex: string): Promise<void>;
|
|
11
|
+
sign(payload: string, publicKeyHex: string, format: SignatureFormat): Promise<string>;
|
|
12
|
+
stamp(payload: string, publicKeyHex: string): Promise<TStamp>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=stamper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stamper.d.ts","sourceRoot":"","sources":["../../../../src/__stampers__/api/web/stamper.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAyE5D,qBAAa,gBAAiB,YAAW,iBAAiB;;YAO1C,MAAM;YAcN,YAAY;YAkBZ,aAAa;IAiBrB,YAAY,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAiBjC,aAAa,CAAC,eAAe,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAyB/D,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAclD,IAAI,CACR,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,MAAM,CAAC;IAoBZ,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAgBpE"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var encoding = require('@0xkey-io/encoding');
|
|
4
|
+
var utils = require('../../../utils.js');
|
|
5
|
+
var apiKeyStamper = require('@0xkey-io/api-key-stamper');
|
|
6
|
+
|
|
7
|
+
const DB_NAME = "ZeroXKeyStamperDB";
|
|
8
|
+
const DB_STORE = "KeyStore";
|
|
9
|
+
const stampHeaderName = "X-Stamp";
|
|
10
|
+
/**
|
|
11
|
+
* `SubtleCrypto.sign(...)` outputs signature in IEEE P1363 format:
|
|
12
|
+
* - https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/sign#ecdsa
|
|
13
|
+
*
|
|
14
|
+
* ZeroXKey expects the signature encoding to be DER-encoded ASN.1.
|
|
15
|
+
*
|
|
16
|
+
* Code modified from https://github.com/google/tink/blob/6f74b99a2bfe6677e3670799116a57268fd067fa/javascript/subtle/elliptic_curves.ts#L114
|
|
17
|
+
*
|
|
18
|
+
* Transform an ECDSA signature in IEEE 1363 encoding to DER encoding.
|
|
19
|
+
*
|
|
20
|
+
* @param ieee the ECDSA signature in IEEE encoding
|
|
21
|
+
* @return ECDSA signature in DER encoding
|
|
22
|
+
*/
|
|
23
|
+
function convertEcdsaIeee1363ToDer(ieee) {
|
|
24
|
+
if (ieee.length % 2 != 0 || ieee.length == 0 || ieee.length > 132) {
|
|
25
|
+
throw new Error("Invalid IEEE P1363 signature encoding. Length: " + ieee.length);
|
|
26
|
+
}
|
|
27
|
+
const r = toUnsignedBigNum(ieee.subarray(0, ieee.length / 2));
|
|
28
|
+
const s = toUnsignedBigNum(ieee.subarray(ieee.length / 2, ieee.length));
|
|
29
|
+
let offset = 0;
|
|
30
|
+
const length = 1 + 1 + r.length + 1 + 1 + s.length;
|
|
31
|
+
let der;
|
|
32
|
+
if (length >= 128) {
|
|
33
|
+
der = new Uint8Array(length + 3);
|
|
34
|
+
der[offset++] = 48;
|
|
35
|
+
der[offset++] = 128 + 1;
|
|
36
|
+
der[offset++] = length;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
der = new Uint8Array(length + 2);
|
|
40
|
+
der[offset++] = 48;
|
|
41
|
+
der[offset++] = length;
|
|
42
|
+
}
|
|
43
|
+
der[offset++] = 2;
|
|
44
|
+
der[offset++] = r.length;
|
|
45
|
+
der.set(r, offset);
|
|
46
|
+
offset += r.length;
|
|
47
|
+
der[offset++] = 2;
|
|
48
|
+
der[offset++] = s.length;
|
|
49
|
+
der.set(s, offset);
|
|
50
|
+
return der;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Code modified from https://github.com/google/tink/blob/6f74b99a2bfe6677e3670799116a57268fd067fa/javascript/subtle/elliptic_curves.ts#L311
|
|
54
|
+
*
|
|
55
|
+
* Transform a big integer in big endian to minimal unsigned form which has
|
|
56
|
+
* no extra zero at the beginning except when the highest bit is set.
|
|
57
|
+
*/
|
|
58
|
+
function toUnsignedBigNum(bytes) {
|
|
59
|
+
let start = 0;
|
|
60
|
+
while (start < bytes.length && bytes[start] == 0) {
|
|
61
|
+
start++;
|
|
62
|
+
}
|
|
63
|
+
if (start == bytes.length) {
|
|
64
|
+
start = bytes.length - 1;
|
|
65
|
+
}
|
|
66
|
+
let extraZero = 0;
|
|
67
|
+
if ((bytes[start] & 128) == 128) {
|
|
68
|
+
extraZero = 1;
|
|
69
|
+
}
|
|
70
|
+
const res = new Uint8Array(bytes.length - start + extraZero);
|
|
71
|
+
res.set(bytes.subarray(start), extraZero);
|
|
72
|
+
return res;
|
|
73
|
+
}
|
|
74
|
+
class IndexedDbStamper {
|
|
75
|
+
constructor() {
|
|
76
|
+
if (typeof window === "undefined") {
|
|
77
|
+
throw new Error("IndexedDB is only available in the browser");
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async openDb() {
|
|
81
|
+
return new Promise((resolve, reject) => {
|
|
82
|
+
const request = indexedDB.open(DB_NAME, 1);
|
|
83
|
+
request.onupgradeneeded = (event) => {
|
|
84
|
+
const db = event.target.result;
|
|
85
|
+
if (!db.objectStoreNames.contains(DB_STORE)) {
|
|
86
|
+
db.createObjectStore(DB_STORE);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
request.onsuccess = () => resolve(request.result);
|
|
90
|
+
request.onerror = () => reject(request.error);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async storeKeyPair(publicKeyHex, privateKey) {
|
|
94
|
+
const db = await this.openDb();
|
|
95
|
+
return new Promise((resolve, reject) => {
|
|
96
|
+
const tx = db.transaction(DB_STORE, "readwrite");
|
|
97
|
+
const store = tx.objectStore(DB_STORE);
|
|
98
|
+
store.put(privateKey, publicKeyHex);
|
|
99
|
+
tx.oncomplete = () => {
|
|
100
|
+
db.close();
|
|
101
|
+
resolve();
|
|
102
|
+
};
|
|
103
|
+
tx.onerror = () => reject(tx.error);
|
|
104
|
+
tx.onabort = () => reject(tx.error);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
async getPrivateKey(publicKeyHex) {
|
|
108
|
+
const db = await this.openDb();
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
const tx = db.transaction(DB_STORE, "readonly");
|
|
111
|
+
const store = tx.objectStore(DB_STORE);
|
|
112
|
+
const request = store.get(publicKeyHex);
|
|
113
|
+
request.onsuccess = () => {
|
|
114
|
+
db.close();
|
|
115
|
+
resolve(request.result || null);
|
|
116
|
+
};
|
|
117
|
+
request.onerror = () => {
|
|
118
|
+
db.close();
|
|
119
|
+
reject(request.error);
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
async listKeyPairs() {
|
|
124
|
+
const db = await this.openDb();
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
const tx = db.transaction(DB_STORE, "readonly");
|
|
127
|
+
const store = tx.objectStore(DB_STORE);
|
|
128
|
+
const request = store.getAllKeys();
|
|
129
|
+
request.onsuccess = () => {
|
|
130
|
+
db.close();
|
|
131
|
+
resolve(request.result);
|
|
132
|
+
};
|
|
133
|
+
request.onerror = () => {
|
|
134
|
+
db.close();
|
|
135
|
+
reject(request.error);
|
|
136
|
+
};
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
async createKeyPair(externalKeyPair) {
|
|
140
|
+
let privateKey;
|
|
141
|
+
let publicKey;
|
|
142
|
+
if (externalKeyPair) {
|
|
143
|
+
await utils.assertValidP256ECDSAKeyPair(externalKeyPair);
|
|
144
|
+
privateKey = externalKeyPair.privateKey;
|
|
145
|
+
publicKey = externalKeyPair.publicKey;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
const keyPair = await crypto.subtle.generateKey({ name: "ECDSA", namedCurve: "P-256" }, false, // Non-extractable private key
|
|
149
|
+
["sign", "verify"]);
|
|
150
|
+
privateKey = keyPair.privateKey;
|
|
151
|
+
publicKey = keyPair.publicKey;
|
|
152
|
+
}
|
|
153
|
+
const rawPubKey = new Uint8Array(await crypto.subtle.exportKey("raw", publicKey));
|
|
154
|
+
const compressedPubKey = encoding.pointEncode(rawPubKey);
|
|
155
|
+
const compressedHex = encoding.uint8ArrayToHexString(compressedPubKey);
|
|
156
|
+
await this.storeKeyPair(compressedHex, privateKey);
|
|
157
|
+
return compressedHex;
|
|
158
|
+
}
|
|
159
|
+
async deleteKeyPair(publicKeyHex) {
|
|
160
|
+
const db = await this.openDb();
|
|
161
|
+
return new Promise((resolve, reject) => {
|
|
162
|
+
const tx = db.transaction(DB_STORE, "readwrite");
|
|
163
|
+
const store = tx.objectStore(DB_STORE);
|
|
164
|
+
store.delete(publicKeyHex);
|
|
165
|
+
tx.oncomplete = () => {
|
|
166
|
+
db.close();
|
|
167
|
+
resolve();
|
|
168
|
+
};
|
|
169
|
+
tx.onerror = () => reject(tx.error);
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
async sign(payload, publicKeyHex, format) {
|
|
173
|
+
const privateKey = await this.getPrivateKey(publicKeyHex);
|
|
174
|
+
if (!privateKey) {
|
|
175
|
+
throw new Error("Key not found for publicKey: " + publicKeyHex);
|
|
176
|
+
}
|
|
177
|
+
const encodedPayload = new TextEncoder().encode(payload);
|
|
178
|
+
const signatureIeee1363 = await crypto.subtle.sign({ name: "ECDSA", hash: { name: "SHA-256" } }, privateKey, encodedPayload);
|
|
179
|
+
if (format === apiKeyStamper.SignatureFormat.Raw) {
|
|
180
|
+
return encoding.uint8ArrayToHexString(new Uint8Array(signatureIeee1363));
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
return encoding.uint8ArrayToHexString(convertEcdsaIeee1363ToDer(new Uint8Array(signatureIeee1363)));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
async stamp(payload, publicKeyHex) {
|
|
187
|
+
const signature = await this.sign(payload, publicKeyHex, apiKeyStamper.SignatureFormat.Der);
|
|
188
|
+
const stamp = {
|
|
189
|
+
publicKey: publicKeyHex,
|
|
190
|
+
scheme: "SIGNATURE_SCHEME_TK_API_P256",
|
|
191
|
+
signature,
|
|
192
|
+
};
|
|
193
|
+
return {
|
|
194
|
+
stampHeaderName,
|
|
195
|
+
stampHeaderValue: encoding.stringToBase64urlString(JSON.stringify(stamp)),
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
exports.IndexedDbStamper = IndexedDbStamper;
|
|
201
|
+
//# sourceMappingURL=stamper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stamper.js","sources":["../../../../src/__stampers__/api/web/stamper.ts"],"sourcesContent":[null],"names":["assertValidP256ECDSAKeyPair","pointEncode","uint8ArrayToHexString","SignatureFormat","stringToBase64urlString"],"mappings":"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"}
|