@mentaproject/signer-react-native 0.0.1 → 0.0.6
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/dist/signer.d.ts +27 -5
- package/dist/signer.d.ts.map +1 -1
- package/dist/signer.js +31 -3
- package/dist/signer.js.map +1 -1
- package/dist/utils/cose.d.ts +2 -0
- package/dist/utils/cose.d.ts.map +1 -1
- package/dist/utils/cose.js +177 -14
- package/dist/utils/cose.js.map +1 -1
- package/package.json +1 -1
- package/src/signer.ts +39 -5
- package/src/utils/cose.ts +297 -33
package/dist/signer.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Address, type Hex, type TypedData, type TypedDataDefinition } from "viem";
|
|
2
|
-
import type {
|
|
2
|
+
import type { PasskeyCredential, P256PublicKey, ReactNativePasskeySignerConfig, SignableMessage, SignatureEncodingFormat } from "./types/index.js";
|
|
3
3
|
/**
|
|
4
4
|
* Error thrown when passkey operations fail.
|
|
5
5
|
*/
|
|
@@ -8,10 +8,10 @@ export declare class PasskeySignerError extends Error {
|
|
|
8
8
|
constructor(message: string, cause?: unknown | undefined);
|
|
9
9
|
}
|
|
10
10
|
/**
|
|
11
|
-
* ReactNativePasskeySigner
|
|
11
|
+
* ReactNativePasskeySigner is compatible with Viem LocalAccount and SmartAccountSigner interfaces.
|
|
12
12
|
*
|
|
13
13
|
* This signer uses the device's biometric authentication (Face ID, Touch ID, fingerprint)
|
|
14
|
-
* to sign messages and
|
|
14
|
+
* to sign messages and typed data for ERC-4337 smart accounts via WebAuthn/Passkeys.
|
|
15
15
|
*
|
|
16
16
|
* The public key is a P-256 (secp256r1) key stored in the device's secure enclave.
|
|
17
17
|
*
|
|
@@ -29,8 +29,21 @@ export declare class PasskeySignerError extends Error {
|
|
|
29
29
|
* });
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
|
-
export declare class ReactNativePasskeySigner
|
|
33
|
-
|
|
32
|
+
export declare class ReactNativePasskeySigner {
|
|
33
|
+
/**
|
|
34
|
+
* Type identifier for Viem LocalAccount compatibility.
|
|
35
|
+
*/
|
|
36
|
+
readonly type: "local";
|
|
37
|
+
/**
|
|
38
|
+
* Source identifier for debugging and compatibility.
|
|
39
|
+
*/
|
|
40
|
+
readonly source: "react-native-passkey";
|
|
41
|
+
/**
|
|
42
|
+
* Deterministic address derived from the public key.
|
|
43
|
+
* Required for Viem LocalAccount compatibility.
|
|
44
|
+
* Note: This is not a real EOA address, but a pseudo-address derived from the P-256 public key.
|
|
45
|
+
*/
|
|
46
|
+
readonly address: Address;
|
|
34
47
|
/**
|
|
35
48
|
* The credential ID in Base64URL format.
|
|
36
49
|
*/
|
|
@@ -105,6 +118,15 @@ export declare class ReactNativePasskeySigner implements SmartAccountSigner<"pas
|
|
|
105
118
|
* @throws PasskeySignerError if signing fails
|
|
106
119
|
*/
|
|
107
120
|
signTypedData<const TTypedData extends TypedData | Record<string, unknown>, TPrimaryType extends keyof TTypedData | "EIP712Domain" = keyof TTypedData>(typedData: TypedDataDefinition<TTypedData, TPrimaryType>): Promise<Hex>;
|
|
121
|
+
/**
|
|
122
|
+
* Signs a transaction.
|
|
123
|
+
*
|
|
124
|
+
* This method is required for Viem LocalAccount compatibility but is not supported
|
|
125
|
+
* for smart account signers. Smart accounts sign UserOperations, not transactions directly.
|
|
126
|
+
*
|
|
127
|
+
* @throws PasskeySignerError always - smart account signers cannot sign transactions
|
|
128
|
+
*/
|
|
129
|
+
signTransaction(): Promise<Hex>;
|
|
108
130
|
/**
|
|
109
131
|
* Returns the address derived from the public key.
|
|
110
132
|
*
|
package/dist/signer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,GAAG,EACR,KAAK,SAAS,EACd,KAAK,mBAAmB,EAGzB,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EACV,
|
|
1
|
+
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"AACA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,GAAG,EACR,KAAK,SAAS,EACd,KAAK,mBAAmB,EAGzB,MAAM,MAAM,CAAC;AAEd,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,EACb,8BAA8B,EAC9B,eAAe,EACf,uBAAuB,EACxB,MAAM,kBAAkB,CAAC;AAe1B;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;aAGzB,KAAK,CAAC,EAAE,OAAO;gBAD/B,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,OAAO,YAAA;CAKlC;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,wBAAwB;IACnC;;OAEG;IACH,SAAgB,IAAI,EAAG,OAAO,CAAU;IAExC;;OAEG;IACH,SAAgB,MAAM,EAAG,sBAAsB,CAAU;IAEzD;;;;OAIG;IACH,SAAgB,OAAO,EAAE,OAAO,CAAC;IAEjC;;OAEG;IACH,SAAgB,YAAY,EAAE,MAAM,CAAC;IAErC;;OAEG;IACH,SAAgB,eAAe,EAAE,GAAG,CAAC;IAErC;;OAEG;IACH,SAAgB,oBAAoB,EAAE,aAAa,CAAC;IAEpD;;OAEG;IACH,SAAgB,SAAS,EAAE,GAAG,CAAC;IAE/B;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IAExD;;;;;;OAMG;IACH,OAAO;IAsBP;;;;;;;;;;;;;OAaG;WACiB,QAAQ,CAC1B,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,8BAA8B,GACrC,OAAO,CAAC,wBAAwB,CAAC;IA2FpC;;;;;;;;OAQG;WACW,cAAc,CAC1B,UAAU,EAAE,iBAAiB,EAC7B,MAAM,EAAE,8BAA8B,GACrC,wBAAwB;IAQ3B;;;;;;;;;OASG;IACU,WAAW,CAAC,EACvB,OAAO,GACR,EAAE;QACD,OAAO,EAAE,eAAe,CAAC;KAC1B,GAAG,OAAO,CAAC,GAAG,CAAC;IAmChB;;;;;;OAMG;IACU,aAAa,CACxB,KAAK,CAAC,UAAU,SAAS,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5D,YAAY,SAAS,MAAM,UAAU,GAAG,cAAc,GAAG,MAAM,UAAU,EACzE,SAAS,EAAE,mBAAmB,CAAC,UAAU,EAAE,YAAY,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAWzE;;;;;;;OAOG;IACU,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC;IAM5C;;;;;;;;OAQG;IACU,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC;IAQ3C;;OAEG;IACI,aAAa,IAAI,GAAG;IAI3B;;OAEG;IACI,aAAa,IAAI,GAAG;IAI3B;;OAEG;IACI,aAAa,IAAI,iBAAiB;IASzC;;;;;OAKG;IACI,mBAAmB,CACxB,MAAM,EAAE,uBAAuB,GAC9B,wBAAwB;IAO3B;;;;;OAKG;YACW,eAAe;IAwC7B;;OAEG;IACH,OAAO,CAAC,UAAU;CAQnB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,iBAAiB,CAkB5B;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,iBAAiB,GAC5B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,iBAAiB,CAoBnB"}
|
package/dist/signer.js
CHANGED
|
@@ -15,10 +15,10 @@ export class PasskeySignerError extends Error {
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
/**
|
|
18
|
-
* ReactNativePasskeySigner
|
|
18
|
+
* ReactNativePasskeySigner is compatible with Viem LocalAccount and SmartAccountSigner interfaces.
|
|
19
19
|
*
|
|
20
20
|
* This signer uses the device's biometric authentication (Face ID, Touch ID, fingerprint)
|
|
21
|
-
* to sign messages and
|
|
21
|
+
* to sign messages and typed data for ERC-4337 smart accounts via WebAuthn/Passkeys.
|
|
22
22
|
*
|
|
23
23
|
* The public key is a P-256 (secp256r1) key stored in the device's secure enclave.
|
|
24
24
|
*
|
|
@@ -37,7 +37,20 @@ export class PasskeySignerError extends Error {
|
|
|
37
37
|
* ```
|
|
38
38
|
*/
|
|
39
39
|
export class ReactNativePasskeySigner {
|
|
40
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Type identifier for Viem LocalAccount compatibility.
|
|
42
|
+
*/
|
|
43
|
+
type = "local";
|
|
44
|
+
/**
|
|
45
|
+
* Source identifier for debugging and compatibility.
|
|
46
|
+
*/
|
|
47
|
+
source = "react-native-passkey";
|
|
48
|
+
/**
|
|
49
|
+
* Deterministic address derived from the public key.
|
|
50
|
+
* Required for Viem LocalAccount compatibility.
|
|
51
|
+
* Note: This is not a real EOA address, but a pseudo-address derived from the P-256 public key.
|
|
52
|
+
*/
|
|
53
|
+
address;
|
|
41
54
|
/**
|
|
42
55
|
* The credential ID in Base64URL format.
|
|
43
56
|
*/
|
|
@@ -70,6 +83,10 @@ export class ReactNativePasskeySigner {
|
|
|
70
83
|
this.credentialIdHex = credential.credentialIdHex;
|
|
71
84
|
this.publicKeyCoordinates = credential.publicKey;
|
|
72
85
|
this.publicKey = credential.publicKeyHex;
|
|
86
|
+
// Derive a deterministic address from the public key
|
|
87
|
+
// This is required for Viem LocalAccount compatibility
|
|
88
|
+
const hash = keccak256(credential.publicKeyHex);
|
|
89
|
+
this.address = `0x${hash.slice(-40)}`;
|
|
73
90
|
this.config = {
|
|
74
91
|
...config,
|
|
75
92
|
timeout: config.timeout ?? 60000,
|
|
@@ -233,6 +250,17 @@ export class ReactNativePasskeySigner {
|
|
|
233
250
|
const challenge = bytesToBase64Url(messageBytes);
|
|
234
251
|
return this.signWithPasskey(challenge);
|
|
235
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* Signs a transaction.
|
|
255
|
+
*
|
|
256
|
+
* This method is required for Viem LocalAccount compatibility but is not supported
|
|
257
|
+
* for smart account signers. Smart accounts sign UserOperations, not transactions directly.
|
|
258
|
+
*
|
|
259
|
+
* @throws PasskeySignerError always - smart account signers cannot sign transactions
|
|
260
|
+
*/
|
|
261
|
+
async signTransaction() {
|
|
262
|
+
throw new PasskeySignerError("Smart Account Signer cannot sign transactions directly. Use signMessage to sign UserOperation hashes instead.");
|
|
263
|
+
}
|
|
236
264
|
/**
|
|
237
265
|
* Returns the address derived from the public key.
|
|
238
266
|
*
|
package/dist/signer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signer.js","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC/C,OAAO,EAKL,aAAa,EACb,SAAS,GACV,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"signer.js","sourceRoot":"","sources":["../src/signer.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/cose.d.ts
CHANGED
|
@@ -69,6 +69,8 @@ export declare function parseAuthenticatorData(authenticatorData: Uint8Array): {
|
|
|
69
69
|
export declare function extractP256PublicKey(coseBytes: Uint8Array): P256PublicKey;
|
|
70
70
|
/**
|
|
71
71
|
* Extracts the public key from a WebAuthn attestation response.
|
|
72
|
+
* Handles both Map and Object returns from cbor-x, and supports
|
|
73
|
+
* both Base64URL and standard Base64 encoded attestation objects.
|
|
72
74
|
*
|
|
73
75
|
* @param attestationObject - Base64URL encoded attestation object from registration
|
|
74
76
|
* @returns The P256 public key coordinates
|
package/dist/utils/cose.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cose.d.ts","sourceRoot":"","sources":["../../src/utils/cose.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"cose.d.ts","sourceRoot":"","sources":["../../src/utils/cose.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAChC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAkHvD;;;GAGG;AACH,QAAA,MAAM,aAAa;;;;;CAKT,CAAC;AAEX;;;GAGG;AACH,QAAA,MAAM,cAAc;;;;;CAKV,CAAC;AAEX;;;GAGG;AACH,QAAA,MAAM,UAAU;;;;;CAKN,CAAC;AAaX;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AA6ID;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CAAC,iBAAiB,EAAE,UAAU,GAAG;IACrE,YAAY,EAAE,UAAU,CAAC;IACzB,cAAc,EAAE,UAAU,CAAC;CAC5B,CA0DA;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,UAAU,GAAG,aAAa,CAwCzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,+BAA+B,CAAC,iBAAiB,EAAE,MAAM,GAAG;IAC1E,YAAY,EAAE,UAAU,CAAC;IACzB,SAAS,EAAE,aAAa,CAAC;CAC1B,CA8GA;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,aAAa,GAAG,GAAG,CAOzE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,aAAa,GAAG,OAAO,CA8BtE;AAED,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,CAAC"}
|
package/dist/utils/cose.js
CHANGED
|
@@ -1,5 +1,88 @@
|
|
|
1
1
|
import { decode as cborDecode } from "cbor-x";
|
|
2
|
-
import { base64UrlToBytes, bytesToHex, padHex, concatHex } from "./base64url.js";
|
|
2
|
+
import { base64UrlToBytes, bytesToHex, padHex, concatHex, } from "./base64url.js";
|
|
3
|
+
/**
|
|
4
|
+
* Helper to convert Uint8Array to hex string for debug logging.
|
|
5
|
+
*/
|
|
6
|
+
function uint8ArrayToHexForDebug(arr) {
|
|
7
|
+
if (arr instanceof Uint8Array) {
|
|
8
|
+
return `Uint8Array(${arr.length})[${Array.from(arr.slice(0, 20))
|
|
9
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
10
|
+
.join(" ")}${arr.length > 20 ? "..." : ""}]`;
|
|
11
|
+
}
|
|
12
|
+
return String(arr);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Helper to safely stringify objects with Uint8Array for debug logging.
|
|
16
|
+
*/
|
|
17
|
+
function safeStringify(obj, depth = 0) {
|
|
18
|
+
if (depth > 3)
|
|
19
|
+
return "[max depth]";
|
|
20
|
+
if (obj instanceof Uint8Array) {
|
|
21
|
+
return uint8ArrayToHexForDebug(obj);
|
|
22
|
+
}
|
|
23
|
+
if (obj instanceof Map) {
|
|
24
|
+
const entries = [];
|
|
25
|
+
obj.forEach((value, key) => {
|
|
26
|
+
entries.push(`${safeStringify(key, depth + 1)} => ${safeStringify(value, depth + 1)}`);
|
|
27
|
+
});
|
|
28
|
+
return `Map(${obj.size}){${entries.join(", ")}}`;
|
|
29
|
+
}
|
|
30
|
+
if (Array.isArray(obj)) {
|
|
31
|
+
return `[${obj.map((v) => safeStringify(v, depth + 1)).join(", ")}]`;
|
|
32
|
+
}
|
|
33
|
+
if (obj !== null && typeof obj === "object") {
|
|
34
|
+
const entries = Object.entries(obj).map(([k, v]) => `${k}: ${safeStringify(v, depth + 1)}`);
|
|
35
|
+
return `{${entries.join(", ")}}`;
|
|
36
|
+
}
|
|
37
|
+
return String(obj);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Helper to get a value from either a Map or an Object.
|
|
41
|
+
*/
|
|
42
|
+
function getFromMapOrObject(data, key) {
|
|
43
|
+
if (data instanceof Map) {
|
|
44
|
+
return data.get(key);
|
|
45
|
+
}
|
|
46
|
+
if (data !== null && typeof data === "object") {
|
|
47
|
+
return data[key];
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Decodes Base64URL with fallback to standard Base64.
|
|
53
|
+
* Some implementations may send standard Base64 instead of Base64URL.
|
|
54
|
+
*/
|
|
55
|
+
function base64UrlToBytesWithFallback(input) {
|
|
56
|
+
// First, try Base64URL decoding
|
|
57
|
+
try {
|
|
58
|
+
return base64UrlToBytes(input);
|
|
59
|
+
}
|
|
60
|
+
catch (base64UrlError) {
|
|
61
|
+
console.log("[COSE] Base64URL decode failed, trying standard Base64 fallback");
|
|
62
|
+
console.log("[COSE] Base64URL error:", base64UrlError instanceof Error ? base64UrlError.message : base64UrlError);
|
|
63
|
+
// Fallback: try standard Base64 (in case the input is already standard Base64)
|
|
64
|
+
try {
|
|
65
|
+
// Add padding if needed
|
|
66
|
+
let base64 = input;
|
|
67
|
+
const padding = base64.length % 4;
|
|
68
|
+
if (padding) {
|
|
69
|
+
base64 += "=".repeat(4 - padding);
|
|
70
|
+
}
|
|
71
|
+
const binaryString = atob(base64);
|
|
72
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
73
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
74
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
75
|
+
}
|
|
76
|
+
console.log("[COSE] Standard Base64 fallback succeeded");
|
|
77
|
+
return bytes;
|
|
78
|
+
}
|
|
79
|
+
catch (base64Error) {
|
|
80
|
+
console.log("[COSE] Standard Base64 fallback also failed:", base64Error instanceof Error ? base64Error.message : base64Error);
|
|
81
|
+
// Throw the original error
|
|
82
|
+
throw base64UrlError;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
3
86
|
/**
|
|
4
87
|
* COSE Key Types (kty)
|
|
5
88
|
* @see https://www.iana.org/assignments/cose/cose.xhtml#key-type
|
|
@@ -51,6 +134,7 @@ export class COSEParseError extends Error {
|
|
|
51
134
|
}
|
|
52
135
|
/**
|
|
53
136
|
* Parses a COSE key from CBOR-encoded bytes.
|
|
137
|
+
* Handles both Map (ES6) and plain Object returns from cbor-x.
|
|
54
138
|
*
|
|
55
139
|
* @param coseBytes - The CBOR-encoded COSE key bytes
|
|
56
140
|
* @returns The parsed COSE key structure
|
|
@@ -64,35 +148,81 @@ function parseCOSEKey(coseBytes) {
|
|
|
64
148
|
catch (error) {
|
|
65
149
|
throw new COSEParseError(`Failed to decode CBOR: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
66
150
|
}
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
151
|
+
// Debug logging
|
|
152
|
+
console.log("[COSE] parseCOSEKey - decoded type:", typeof decoded);
|
|
153
|
+
console.log("[COSE] parseCOSEKey - is Map:", decoded instanceof Map);
|
|
154
|
+
console.log("[COSE] parseCOSEKey - is Object:", decoded !== null &&
|
|
155
|
+
typeof decoded === "object" &&
|
|
156
|
+
!(decoded instanceof Map));
|
|
157
|
+
console.log("[COSE] parseCOSEKey - decoded content:", safeStringify(decoded));
|
|
158
|
+
// COSE keys are encoded as CBOR maps - cbor-x may return either Map or Object
|
|
159
|
+
const isMap = decoded instanceof Map;
|
|
160
|
+
const isObject = decoded !== null &&
|
|
161
|
+
typeof decoded === "object" &&
|
|
162
|
+
!isMap &&
|
|
163
|
+
!Array.isArray(decoded);
|
|
164
|
+
if (!isMap && !isObject) {
|
|
165
|
+
throw new COSEParseError(`Invalid COSE key format: expected CBOR map, got ${typeof decoded}${Array.isArray(decoded) ? " (array)" : ""}`);
|
|
70
166
|
}
|
|
71
|
-
|
|
167
|
+
// Get kty (key type) - try both numeric and string keys
|
|
168
|
+
let kty = getFromMapOrObject(decoded, COSE_KEY_PARAMS.KTY);
|
|
169
|
+
if (kty === undefined) {
|
|
170
|
+
// Some implementations might use string keys
|
|
171
|
+
kty = getFromMapOrObject(decoded, "1");
|
|
172
|
+
}
|
|
173
|
+
console.log("[COSE] parseCOSEKey - kty value:", kty, "type:", typeof kty);
|
|
72
174
|
if (typeof kty !== "number") {
|
|
175
|
+
// Log available keys for debugging
|
|
176
|
+
if (isMap) {
|
|
177
|
+
console.log("[COSE] parseCOSEKey - Map keys:", Array.from(decoded.keys()));
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
console.log("[COSE] parseCOSEKey - Object keys:", Object.keys(decoded));
|
|
181
|
+
}
|
|
73
182
|
throw new COSEParseError("Invalid COSE key: missing or invalid kty");
|
|
74
183
|
}
|
|
75
184
|
const result = { kty };
|
|
76
185
|
// Optional algorithm
|
|
77
|
-
|
|
186
|
+
let alg = getFromMapOrObject(decoded, COSE_KEY_PARAMS.ALG);
|
|
187
|
+
if (alg === undefined) {
|
|
188
|
+
alg = getFromMapOrObject(decoded, "3");
|
|
189
|
+
}
|
|
78
190
|
if (typeof alg === "number") {
|
|
79
191
|
result.alg = alg;
|
|
80
192
|
}
|
|
81
193
|
// For EC2 keys, extract curve and coordinates
|
|
82
194
|
if (kty === COSE_KEY_TYPE.EC2) {
|
|
83
|
-
|
|
195
|
+
let crv = getFromMapOrObject(decoded, COSE_KEY_PARAMS.CRV);
|
|
196
|
+
if (crv === undefined) {
|
|
197
|
+
crv = getFromMapOrObject(decoded, "-1");
|
|
198
|
+
}
|
|
84
199
|
if (typeof crv === "number") {
|
|
85
200
|
result.crv = crv;
|
|
86
201
|
}
|
|
87
|
-
|
|
202
|
+
let x = getFromMapOrObject(decoded, COSE_KEY_PARAMS.X);
|
|
203
|
+
if (x === undefined) {
|
|
204
|
+
x = getFromMapOrObject(decoded, "-2");
|
|
205
|
+
}
|
|
88
206
|
if (x instanceof Uint8Array) {
|
|
89
207
|
result.x = x;
|
|
90
208
|
}
|
|
91
|
-
|
|
209
|
+
console.log("[COSE] parseCOSEKey - x coordinate:", x instanceof Uint8Array ? `Uint8Array(${x.length})` : x);
|
|
210
|
+
let y = getFromMapOrObject(decoded, COSE_KEY_PARAMS.Y);
|
|
211
|
+
if (y === undefined) {
|
|
212
|
+
y = getFromMapOrObject(decoded, "-3");
|
|
213
|
+
}
|
|
92
214
|
if (y instanceof Uint8Array) {
|
|
93
215
|
result.y = y;
|
|
94
216
|
}
|
|
217
|
+
console.log("[COSE] parseCOSEKey - y coordinate:", y instanceof Uint8Array ? `Uint8Array(${y.length})` : y);
|
|
95
218
|
}
|
|
219
|
+
console.log("[COSE] parseCOSEKey - result:", JSON.stringify({
|
|
220
|
+
kty: result.kty,
|
|
221
|
+
alg: result.alg,
|
|
222
|
+
crv: result.crv,
|
|
223
|
+
hasX: !!result.x,
|
|
224
|
+
hasY: !!result.y,
|
|
225
|
+
}));
|
|
96
226
|
return result;
|
|
97
227
|
}
|
|
98
228
|
/**
|
|
@@ -185,14 +315,19 @@ export function extractP256PublicKey(coseBytes) {
|
|
|
185
315
|
}
|
|
186
316
|
/**
|
|
187
317
|
* Extracts the public key from a WebAuthn attestation response.
|
|
318
|
+
* Handles both Map and Object returns from cbor-x, and supports
|
|
319
|
+
* both Base64URL and standard Base64 encoded attestation objects.
|
|
188
320
|
*
|
|
189
321
|
* @param attestationObject - Base64URL encoded attestation object from registration
|
|
190
322
|
* @returns The P256 public key coordinates
|
|
191
323
|
* @throws COSEParseError if extraction fails
|
|
192
324
|
*/
|
|
193
325
|
export function extractPublicKeyFromAttestation(attestationObject) {
|
|
194
|
-
|
|
195
|
-
|
|
326
|
+
console.log("[COSE] extractPublicKeyFromAttestation - input length:", attestationObject.length);
|
|
327
|
+
console.log("[COSE] extractPublicKeyFromAttestation - input preview:", attestationObject.substring(0, 50) + "...");
|
|
328
|
+
// Decode the attestation object (with Base64 fallback)
|
|
329
|
+
const attestationBytes = base64UrlToBytesWithFallback(attestationObject);
|
|
330
|
+
console.log("[COSE] extractPublicKeyFromAttestation - decoded bytes length:", attestationBytes.length);
|
|
196
331
|
let attestation;
|
|
197
332
|
try {
|
|
198
333
|
attestation = cborDecode(attestationBytes);
|
|
@@ -200,14 +335,42 @@ export function extractPublicKeyFromAttestation(attestationObject) {
|
|
|
200
335
|
catch (error) {
|
|
201
336
|
throw new COSEParseError(`Failed to decode attestation object: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
202
337
|
}
|
|
203
|
-
//
|
|
204
|
-
|
|
338
|
+
// Debug logging for attestation object
|
|
339
|
+
console.log("[COSE] extractPublicKeyFromAttestation - attestation type:", typeof attestation);
|
|
340
|
+
console.log("[COSE] extractPublicKeyFromAttestation - is Map:", attestation instanceof Map);
|
|
341
|
+
console.log("[COSE] extractPublicKeyFromAttestation - is Object:", attestation !== null &&
|
|
342
|
+
typeof attestation === "object" &&
|
|
343
|
+
!(attestation instanceof Map));
|
|
344
|
+
console.log("[COSE] extractPublicKeyFromAttestation - attestation content:", safeStringify(attestation));
|
|
345
|
+
// Extract authData from attestation - handle both Map and Object
|
|
346
|
+
let authData;
|
|
347
|
+
// Try object-style access first (most common with cbor-x default config)
|
|
348
|
+
authData = getFromMapOrObject(attestation, "authData");
|
|
349
|
+
console.log("[COSE] extractPublicKeyFromAttestation - authData from 'authData' key:", authData instanceof Uint8Array
|
|
350
|
+
? `Uint8Array(${authData.length})`
|
|
351
|
+
: authData);
|
|
352
|
+
// If not found, log available keys for debugging
|
|
353
|
+
if (!authData) {
|
|
354
|
+
if (attestation instanceof Map) {
|
|
355
|
+
console.log("[COSE] extractPublicKeyFromAttestation - Map keys:", Array.from(attestation.keys()));
|
|
356
|
+
}
|
|
357
|
+
else if (attestation !== null && typeof attestation === "object") {
|
|
358
|
+
console.log("[COSE] extractPublicKeyFromAttestation - Object keys:", Object.keys(attestation));
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
if (!authData || !(authData instanceof Uint8Array)) {
|
|
205
362
|
throw new COSEParseError("Invalid attestation object: missing or invalid authData");
|
|
206
363
|
}
|
|
364
|
+
console.log("[COSE] extractPublicKeyFromAttestation - authData length:", authData.length);
|
|
207
365
|
// Parse the authenticator data to get the public key
|
|
208
|
-
const { credentialId, publicKeyBytes } = parseAuthenticatorData(
|
|
366
|
+
const { credentialId, publicKeyBytes } = parseAuthenticatorData(authData);
|
|
367
|
+
console.log("[COSE] extractPublicKeyFromAttestation - credentialId length:", credentialId.length);
|
|
368
|
+
console.log("[COSE] extractPublicKeyFromAttestation - publicKeyBytes length:", publicKeyBytes.length);
|
|
209
369
|
// Extract the P256 coordinates from the COSE key
|
|
210
370
|
const publicKey = extractP256PublicKey(publicKeyBytes);
|
|
371
|
+
console.log("[COSE] extractPublicKeyFromAttestation - extraction successful");
|
|
372
|
+
console.log("[COSE] extractPublicKeyFromAttestation - publicKey.x:", publicKey.x);
|
|
373
|
+
console.log("[COSE] extractPublicKeyFromAttestation - publicKey.y:", publicKey.y);
|
|
211
374
|
return { credentialId, publicKey };
|
|
212
375
|
}
|
|
213
376
|
/**
|
package/dist/utils/cose.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cose.js","sourceRoot":"","sources":["../../src/utils/cose.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cose.js","sourceRoot":"","sources":["../../src/utils/cose.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/signer.ts
CHANGED
|
@@ -9,7 +9,6 @@ import {
|
|
|
9
9
|
} from "viem";
|
|
10
10
|
|
|
11
11
|
import type {
|
|
12
|
-
SmartAccountSigner,
|
|
13
12
|
PasskeyCredential,
|
|
14
13
|
P256PublicKey,
|
|
15
14
|
ReactNativePasskeySignerConfig,
|
|
@@ -44,10 +43,10 @@ export class PasskeySignerError extends Error {
|
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
/**
|
|
47
|
-
* ReactNativePasskeySigner
|
|
46
|
+
* ReactNativePasskeySigner is compatible with Viem LocalAccount and SmartAccountSigner interfaces.
|
|
48
47
|
*
|
|
49
48
|
* This signer uses the device's biometric authentication (Face ID, Touch ID, fingerprint)
|
|
50
|
-
* to sign messages and
|
|
49
|
+
* to sign messages and typed data for ERC-4337 smart accounts via WebAuthn/Passkeys.
|
|
51
50
|
*
|
|
52
51
|
* The public key is a P-256 (secp256r1) key stored in the device's secure enclave.
|
|
53
52
|
*
|
|
@@ -65,8 +64,23 @@ export class PasskeySignerError extends Error {
|
|
|
65
64
|
* });
|
|
66
65
|
* ```
|
|
67
66
|
*/
|
|
68
|
-
export class ReactNativePasskeySigner
|
|
69
|
-
|
|
67
|
+
export class ReactNativePasskeySigner {
|
|
68
|
+
/**
|
|
69
|
+
* Type identifier for Viem LocalAccount compatibility.
|
|
70
|
+
*/
|
|
71
|
+
public readonly type = "local" as const;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Source identifier for debugging and compatibility.
|
|
75
|
+
*/
|
|
76
|
+
public readonly source = "react-native-passkey" as const;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Deterministic address derived from the public key.
|
|
80
|
+
* Required for Viem LocalAccount compatibility.
|
|
81
|
+
* Note: This is not a real EOA address, but a pseudo-address derived from the P-256 public key.
|
|
82
|
+
*/
|
|
83
|
+
public readonly address: Address;
|
|
70
84
|
|
|
71
85
|
/**
|
|
72
86
|
* The credential ID in Base64URL format.
|
|
@@ -108,6 +122,12 @@ export class ReactNativePasskeySigner implements SmartAccountSigner<"passkey"> {
|
|
|
108
122
|
this.credentialIdHex = credential.credentialIdHex;
|
|
109
123
|
this.publicKeyCoordinates = credential.publicKey;
|
|
110
124
|
this.publicKey = credential.publicKeyHex;
|
|
125
|
+
|
|
126
|
+
// Derive a deterministic address from the public key
|
|
127
|
+
// This is required for Viem LocalAccount compatibility
|
|
128
|
+
const hash = keccak256(credential.publicKeyHex);
|
|
129
|
+
this.address = `0x${hash.slice(-40)}` as Address;
|
|
130
|
+
|
|
111
131
|
this.config = {
|
|
112
132
|
...config,
|
|
113
133
|
timeout: config.timeout ?? 60000,
|
|
@@ -314,6 +334,20 @@ export class ReactNativePasskeySigner implements SmartAccountSigner<"passkey"> {
|
|
|
314
334
|
return this.signWithPasskey(challenge);
|
|
315
335
|
}
|
|
316
336
|
|
|
337
|
+
/**
|
|
338
|
+
* Signs a transaction.
|
|
339
|
+
*
|
|
340
|
+
* This method is required for Viem LocalAccount compatibility but is not supported
|
|
341
|
+
* for smart account signers. Smart accounts sign UserOperations, not transactions directly.
|
|
342
|
+
*
|
|
343
|
+
* @throws PasskeySignerError always - smart account signers cannot sign transactions
|
|
344
|
+
*/
|
|
345
|
+
public async signTransaction(): Promise<Hex> {
|
|
346
|
+
throw new PasskeySignerError(
|
|
347
|
+
"Smart Account Signer cannot sign transactions directly. Use signMessage to sign UserOperation hashes instead.",
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
317
351
|
/**
|
|
318
352
|
* Returns the address derived from the public key.
|
|
319
353
|
*
|
package/src/utils/cose.ts
CHANGED
|
@@ -1,7 +1,118 @@
|
|
|
1
1
|
import { decode as cborDecode } from "cbor-x";
|
|
2
2
|
import type { Hex } from "viem";
|
|
3
3
|
import type { P256PublicKey } from "../types/index.js";
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
base64UrlToBytes,
|
|
6
|
+
bytesToHex,
|
|
7
|
+
padHex,
|
|
8
|
+
concatHex,
|
|
9
|
+
} from "./base64url.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Helper to convert Uint8Array to hex string for debug logging.
|
|
13
|
+
*/
|
|
14
|
+
function uint8ArrayToHexForDebug(arr: unknown): string {
|
|
15
|
+
if (arr instanceof Uint8Array) {
|
|
16
|
+
return `Uint8Array(${arr.length})[${Array.from(arr.slice(0, 20))
|
|
17
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
18
|
+
.join(" ")}${arr.length > 20 ? "..." : ""}]`;
|
|
19
|
+
}
|
|
20
|
+
return String(arr);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Helper to safely stringify objects with Uint8Array for debug logging.
|
|
25
|
+
*/
|
|
26
|
+
function safeStringify(obj: unknown, depth = 0): string {
|
|
27
|
+
if (depth > 3) return "[max depth]";
|
|
28
|
+
|
|
29
|
+
if (obj instanceof Uint8Array) {
|
|
30
|
+
return uint8ArrayToHexForDebug(obj);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (obj instanceof Map) {
|
|
34
|
+
const entries: string[] = [];
|
|
35
|
+
obj.forEach((value, key) => {
|
|
36
|
+
entries.push(
|
|
37
|
+
`${safeStringify(key, depth + 1)} => ${safeStringify(value, depth + 1)}`,
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
return `Map(${obj.size}){${entries.join(", ")}}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (Array.isArray(obj)) {
|
|
44
|
+
return `[${obj.map((v) => safeStringify(v, depth + 1)).join(", ")}]`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (obj !== null && typeof obj === "object") {
|
|
48
|
+
const entries = Object.entries(obj).map(
|
|
49
|
+
([k, v]) => `${k}: ${safeStringify(v, depth + 1)}`,
|
|
50
|
+
);
|
|
51
|
+
return `{${entries.join(", ")}}`;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return String(obj);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Helper to get a value from either a Map or an Object.
|
|
59
|
+
*/
|
|
60
|
+
function getFromMapOrObject<T>(
|
|
61
|
+
data: unknown,
|
|
62
|
+
key: string | number,
|
|
63
|
+
): T | undefined {
|
|
64
|
+
if (data instanceof Map) {
|
|
65
|
+
return data.get(key) as T | undefined;
|
|
66
|
+
}
|
|
67
|
+
if (data !== null && typeof data === "object") {
|
|
68
|
+
return (data as Record<string | number, unknown>)[key] as T | undefined;
|
|
69
|
+
}
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Decodes Base64URL with fallback to standard Base64.
|
|
75
|
+
* Some implementations may send standard Base64 instead of Base64URL.
|
|
76
|
+
*/
|
|
77
|
+
function base64UrlToBytesWithFallback(input: string): Uint8Array {
|
|
78
|
+
// First, try Base64URL decoding
|
|
79
|
+
try {
|
|
80
|
+
return base64UrlToBytes(input);
|
|
81
|
+
} catch (base64UrlError) {
|
|
82
|
+
console.log(
|
|
83
|
+
"[COSE] Base64URL decode failed, trying standard Base64 fallback",
|
|
84
|
+
);
|
|
85
|
+
console.log(
|
|
86
|
+
"[COSE] Base64URL error:",
|
|
87
|
+
base64UrlError instanceof Error ? base64UrlError.message : base64UrlError,
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
// Fallback: try standard Base64 (in case the input is already standard Base64)
|
|
91
|
+
try {
|
|
92
|
+
// Add padding if needed
|
|
93
|
+
let base64 = input;
|
|
94
|
+
const padding = base64.length % 4;
|
|
95
|
+
if (padding) {
|
|
96
|
+
base64 += "=".repeat(4 - padding);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const binaryString = atob(base64);
|
|
100
|
+
const bytes = new Uint8Array(binaryString.length);
|
|
101
|
+
for (let i = 0; i < binaryString.length; i++) {
|
|
102
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
103
|
+
}
|
|
104
|
+
console.log("[COSE] Standard Base64 fallback succeeded");
|
|
105
|
+
return bytes;
|
|
106
|
+
} catch (base64Error) {
|
|
107
|
+
console.log(
|
|
108
|
+
"[COSE] Standard Base64 fallback also failed:",
|
|
109
|
+
base64Error instanceof Error ? base64Error.message : base64Error,
|
|
110
|
+
);
|
|
111
|
+
// Throw the original error
|
|
112
|
+
throw base64UrlError;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
5
116
|
|
|
6
117
|
/**
|
|
7
118
|
* COSE Key Types (kty)
|
|
@@ -70,60 +181,129 @@ interface COSEKey {
|
|
|
70
181
|
|
|
71
182
|
/**
|
|
72
183
|
* Parses a COSE key from CBOR-encoded bytes.
|
|
184
|
+
* Handles both Map (ES6) and plain Object returns from cbor-x.
|
|
73
185
|
*
|
|
74
186
|
* @param coseBytes - The CBOR-encoded COSE key bytes
|
|
75
187
|
* @returns The parsed COSE key structure
|
|
76
188
|
* @throws COSEParseError if parsing fails
|
|
77
189
|
*/
|
|
78
190
|
function parseCOSEKey(coseBytes: Uint8Array): COSEKey {
|
|
79
|
-
let decoded:
|
|
191
|
+
let decoded: unknown;
|
|
80
192
|
|
|
81
193
|
try {
|
|
82
194
|
decoded = cborDecode(coseBytes);
|
|
83
195
|
} catch (error) {
|
|
84
196
|
throw new COSEParseError(
|
|
85
|
-
`Failed to decode CBOR: ${error instanceof Error ? error.message : "Unknown error"}
|
|
197
|
+
`Failed to decode CBOR: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
86
198
|
);
|
|
87
199
|
}
|
|
88
200
|
|
|
89
|
-
//
|
|
90
|
-
|
|
201
|
+
// Debug logging
|
|
202
|
+
console.log("[COSE] parseCOSEKey - decoded type:", typeof decoded);
|
|
203
|
+
console.log("[COSE] parseCOSEKey - is Map:", decoded instanceof Map);
|
|
204
|
+
console.log(
|
|
205
|
+
"[COSE] parseCOSEKey - is Object:",
|
|
206
|
+
decoded !== null &&
|
|
207
|
+
typeof decoded === "object" &&
|
|
208
|
+
!(decoded instanceof Map),
|
|
209
|
+
);
|
|
210
|
+
console.log("[COSE] parseCOSEKey - decoded content:", safeStringify(decoded));
|
|
211
|
+
|
|
212
|
+
// COSE keys are encoded as CBOR maps - cbor-x may return either Map or Object
|
|
213
|
+
const isMap = decoded instanceof Map;
|
|
214
|
+
const isObject =
|
|
215
|
+
decoded !== null &&
|
|
216
|
+
typeof decoded === "object" &&
|
|
217
|
+
!isMap &&
|
|
218
|
+
!Array.isArray(decoded);
|
|
219
|
+
|
|
220
|
+
if (!isMap && !isObject) {
|
|
91
221
|
throw new COSEParseError(
|
|
92
|
-
|
|
222
|
+
`Invalid COSE key format: expected CBOR map, got ${typeof decoded}${Array.isArray(decoded) ? " (array)" : ""}`,
|
|
93
223
|
);
|
|
94
224
|
}
|
|
95
225
|
|
|
96
|
-
|
|
226
|
+
// Get kty (key type) - try both numeric and string keys
|
|
227
|
+
let kty = getFromMapOrObject<number>(decoded, COSE_KEY_PARAMS.KTY);
|
|
228
|
+
if (kty === undefined) {
|
|
229
|
+
// Some implementations might use string keys
|
|
230
|
+
kty = getFromMapOrObject<number>(decoded, "1");
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
console.log("[COSE] parseCOSEKey - kty value:", kty, "type:", typeof kty);
|
|
234
|
+
|
|
97
235
|
if (typeof kty !== "number") {
|
|
236
|
+
// Log available keys for debugging
|
|
237
|
+
if (isMap) {
|
|
238
|
+
console.log(
|
|
239
|
+
"[COSE] parseCOSEKey - Map keys:",
|
|
240
|
+
Array.from((decoded as Map<unknown, unknown>).keys()),
|
|
241
|
+
);
|
|
242
|
+
} else {
|
|
243
|
+
console.log(
|
|
244
|
+
"[COSE] parseCOSEKey - Object keys:",
|
|
245
|
+
Object.keys(decoded as object),
|
|
246
|
+
);
|
|
247
|
+
}
|
|
98
248
|
throw new COSEParseError("Invalid COSE key: missing or invalid kty");
|
|
99
249
|
}
|
|
100
250
|
|
|
101
251
|
const result: COSEKey = { kty };
|
|
102
252
|
|
|
103
253
|
// Optional algorithm
|
|
104
|
-
|
|
254
|
+
let alg = getFromMapOrObject<number>(decoded, COSE_KEY_PARAMS.ALG);
|
|
255
|
+
if (alg === undefined) {
|
|
256
|
+
alg = getFromMapOrObject<number>(decoded, "3");
|
|
257
|
+
}
|
|
105
258
|
if (typeof alg === "number") {
|
|
106
259
|
result.alg = alg;
|
|
107
260
|
}
|
|
108
261
|
|
|
109
262
|
// For EC2 keys, extract curve and coordinates
|
|
110
263
|
if (kty === COSE_KEY_TYPE.EC2) {
|
|
111
|
-
|
|
264
|
+
let crv = getFromMapOrObject<number>(decoded, COSE_KEY_PARAMS.CRV);
|
|
265
|
+
if (crv === undefined) {
|
|
266
|
+
crv = getFromMapOrObject<number>(decoded, "-1");
|
|
267
|
+
}
|
|
112
268
|
if (typeof crv === "number") {
|
|
113
269
|
result.crv = crv;
|
|
114
270
|
}
|
|
115
271
|
|
|
116
|
-
|
|
272
|
+
let x = getFromMapOrObject<Uint8Array>(decoded, COSE_KEY_PARAMS.X);
|
|
273
|
+
if (x === undefined) {
|
|
274
|
+
x = getFromMapOrObject<Uint8Array>(decoded, "-2");
|
|
275
|
+
}
|
|
117
276
|
if (x instanceof Uint8Array) {
|
|
118
277
|
result.x = x;
|
|
119
278
|
}
|
|
279
|
+
console.log(
|
|
280
|
+
"[COSE] parseCOSEKey - x coordinate:",
|
|
281
|
+
x instanceof Uint8Array ? `Uint8Array(${x.length})` : x,
|
|
282
|
+
);
|
|
120
283
|
|
|
121
|
-
|
|
284
|
+
let y = getFromMapOrObject<Uint8Array>(decoded, COSE_KEY_PARAMS.Y);
|
|
285
|
+
if (y === undefined) {
|
|
286
|
+
y = getFromMapOrObject<Uint8Array>(decoded, "-3");
|
|
287
|
+
}
|
|
122
288
|
if (y instanceof Uint8Array) {
|
|
123
289
|
result.y = y;
|
|
124
290
|
}
|
|
291
|
+
console.log(
|
|
292
|
+
"[COSE] parseCOSEKey - y coordinate:",
|
|
293
|
+
y instanceof Uint8Array ? `Uint8Array(${y.length})` : y,
|
|
294
|
+
);
|
|
125
295
|
}
|
|
126
296
|
|
|
297
|
+
console.log(
|
|
298
|
+
"[COSE] parseCOSEKey - result:",
|
|
299
|
+
JSON.stringify({
|
|
300
|
+
kty: result.kty,
|
|
301
|
+
alg: result.alg,
|
|
302
|
+
crv: result.crv,
|
|
303
|
+
hasX: !!result.x,
|
|
304
|
+
hasY: !!result.y,
|
|
305
|
+
}),
|
|
306
|
+
);
|
|
127
307
|
return result;
|
|
128
308
|
}
|
|
129
309
|
|
|
@@ -152,7 +332,7 @@ export function parseAuthenticatorData(authenticatorData: Uint8Array): {
|
|
|
152
332
|
// Minimum length: 37 bytes (rpIdHash + flags + signCount)
|
|
153
333
|
if (authenticatorData.length < 37) {
|
|
154
334
|
throw new COSEParseError(
|
|
155
|
-
"Authenticator data too short: minimum 37 bytes required"
|
|
335
|
+
"Authenticator data too short: minimum 37 bytes required",
|
|
156
336
|
);
|
|
157
337
|
}
|
|
158
338
|
|
|
@@ -162,7 +342,7 @@ export function parseAuthenticatorData(authenticatorData: Uint8Array): {
|
|
|
162
342
|
|
|
163
343
|
if (!hasAttestedCredData) {
|
|
164
344
|
throw new COSEParseError(
|
|
165
|
-
"Authenticator data does not contain attested credential data"
|
|
345
|
+
"Authenticator data does not contain attested credential data",
|
|
166
346
|
);
|
|
167
347
|
}
|
|
168
348
|
|
|
@@ -174,7 +354,7 @@ export function parseAuthenticatorData(authenticatorData: Uint8Array): {
|
|
|
174
354
|
|
|
175
355
|
if (authenticatorData.length < offset + 2) {
|
|
176
356
|
throw new COSEParseError(
|
|
177
|
-
"Authenticator data too short: missing credentialIdLength"
|
|
357
|
+
"Authenticator data too short: missing credentialIdLength",
|
|
178
358
|
);
|
|
179
359
|
}
|
|
180
360
|
|
|
@@ -185,12 +365,15 @@ export function parseAuthenticatorData(authenticatorData: Uint8Array): {
|
|
|
185
365
|
|
|
186
366
|
if (authenticatorData.length < offset + credentialIdLength) {
|
|
187
367
|
throw new COSEParseError(
|
|
188
|
-
"Authenticator data too short: missing credentialId"
|
|
368
|
+
"Authenticator data too short: missing credentialId",
|
|
189
369
|
);
|
|
190
370
|
}
|
|
191
371
|
|
|
192
372
|
// Read credentialId
|
|
193
|
-
const credentialId = authenticatorData.slice(
|
|
373
|
+
const credentialId = authenticatorData.slice(
|
|
374
|
+
offset,
|
|
375
|
+
offset + credentialIdLength,
|
|
376
|
+
);
|
|
194
377
|
offset += credentialIdLength;
|
|
195
378
|
|
|
196
379
|
// Remaining bytes are the CBOR-encoded public key
|
|
@@ -198,7 +381,7 @@ export function parseAuthenticatorData(authenticatorData: Uint8Array): {
|
|
|
198
381
|
|
|
199
382
|
if (publicKeyBytes.length === 0) {
|
|
200
383
|
throw new COSEParseError(
|
|
201
|
-
"Authenticator data too short: missing public key"
|
|
384
|
+
"Authenticator data too short: missing public key",
|
|
202
385
|
);
|
|
203
386
|
}
|
|
204
387
|
|
|
@@ -219,21 +402,21 @@ export function extractP256PublicKey(coseBytes: Uint8Array): P256PublicKey {
|
|
|
219
402
|
// Validate key type
|
|
220
403
|
if (coseKey.kty !== COSE_KEY_TYPE.EC2) {
|
|
221
404
|
throw new COSEParseError(
|
|
222
|
-
`Invalid key type: expected EC2 (${COSE_KEY_TYPE.EC2}), got ${coseKey.kty}
|
|
405
|
+
`Invalid key type: expected EC2 (${COSE_KEY_TYPE.EC2}), got ${coseKey.kty}`,
|
|
223
406
|
);
|
|
224
407
|
}
|
|
225
408
|
|
|
226
409
|
// Validate curve (if present)
|
|
227
410
|
if (coseKey.crv !== undefined && coseKey.crv !== COSE_CURVE.P256) {
|
|
228
411
|
throw new COSEParseError(
|
|
229
|
-
`Invalid curve: expected P-256 (${COSE_CURVE.P256}), got ${coseKey.crv}
|
|
412
|
+
`Invalid curve: expected P-256 (${COSE_CURVE.P256}), got ${coseKey.crv}`,
|
|
230
413
|
);
|
|
231
414
|
}
|
|
232
415
|
|
|
233
416
|
// Validate algorithm (if present)
|
|
234
417
|
if (coseKey.alg !== undefined && coseKey.alg !== COSE_ALGORITHM.ES256) {
|
|
235
418
|
throw new COSEParseError(
|
|
236
|
-
`Invalid algorithm: expected ES256 (${COSE_ALGORITHM.ES256}), got ${coseKey.alg}
|
|
419
|
+
`Invalid algorithm: expected ES256 (${COSE_ALGORITHM.ES256}), got ${coseKey.alg}`,
|
|
237
420
|
);
|
|
238
421
|
}
|
|
239
422
|
|
|
@@ -257,44 +440,125 @@ export function extractP256PublicKey(coseBytes: Uint8Array): P256PublicKey {
|
|
|
257
440
|
|
|
258
441
|
/**
|
|
259
442
|
* Extracts the public key from a WebAuthn attestation response.
|
|
443
|
+
* Handles both Map and Object returns from cbor-x, and supports
|
|
444
|
+
* both Base64URL and standard Base64 encoded attestation objects.
|
|
260
445
|
*
|
|
261
446
|
* @param attestationObject - Base64URL encoded attestation object from registration
|
|
262
447
|
* @returns The P256 public key coordinates
|
|
263
448
|
* @throws COSEParseError if extraction fails
|
|
264
449
|
*/
|
|
265
|
-
export function extractPublicKeyFromAttestation(
|
|
266
|
-
attestationObject: string
|
|
267
|
-
): {
|
|
450
|
+
export function extractPublicKeyFromAttestation(attestationObject: string): {
|
|
268
451
|
credentialId: Uint8Array;
|
|
269
452
|
publicKey: P256PublicKey;
|
|
270
453
|
} {
|
|
271
|
-
|
|
272
|
-
|
|
454
|
+
console.log(
|
|
455
|
+
"[COSE] extractPublicKeyFromAttestation - input length:",
|
|
456
|
+
attestationObject.length,
|
|
457
|
+
);
|
|
458
|
+
console.log(
|
|
459
|
+
"[COSE] extractPublicKeyFromAttestation - input preview:",
|
|
460
|
+
attestationObject.substring(0, 50) + "...",
|
|
461
|
+
);
|
|
462
|
+
|
|
463
|
+
// Decode the attestation object (with Base64 fallback)
|
|
464
|
+
const attestationBytes = base64UrlToBytesWithFallback(attestationObject);
|
|
465
|
+
console.log(
|
|
466
|
+
"[COSE] extractPublicKeyFromAttestation - decoded bytes length:",
|
|
467
|
+
attestationBytes.length,
|
|
468
|
+
);
|
|
273
469
|
|
|
274
|
-
let attestation:
|
|
470
|
+
let attestation: unknown;
|
|
275
471
|
try {
|
|
276
472
|
attestation = cborDecode(attestationBytes);
|
|
277
473
|
} catch (error) {
|
|
278
474
|
throw new COSEParseError(
|
|
279
|
-
`Failed to decode attestation object: ${error instanceof Error ? error.message : "Unknown error"}
|
|
475
|
+
`Failed to decode attestation object: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
280
476
|
);
|
|
281
477
|
}
|
|
282
478
|
|
|
283
|
-
//
|
|
284
|
-
|
|
479
|
+
// Debug logging for attestation object
|
|
480
|
+
console.log(
|
|
481
|
+
"[COSE] extractPublicKeyFromAttestation - attestation type:",
|
|
482
|
+
typeof attestation,
|
|
483
|
+
);
|
|
484
|
+
console.log(
|
|
485
|
+
"[COSE] extractPublicKeyFromAttestation - is Map:",
|
|
486
|
+
attestation instanceof Map,
|
|
487
|
+
);
|
|
488
|
+
console.log(
|
|
489
|
+
"[COSE] extractPublicKeyFromAttestation - is Object:",
|
|
490
|
+
attestation !== null &&
|
|
491
|
+
typeof attestation === "object" &&
|
|
492
|
+
!(attestation instanceof Map),
|
|
493
|
+
);
|
|
494
|
+
console.log(
|
|
495
|
+
"[COSE] extractPublicKeyFromAttestation - attestation content:",
|
|
496
|
+
safeStringify(attestation),
|
|
497
|
+
);
|
|
498
|
+
|
|
499
|
+
// Extract authData from attestation - handle both Map and Object
|
|
500
|
+
let authData: Uint8Array | undefined;
|
|
501
|
+
|
|
502
|
+
// Try object-style access first (most common with cbor-x default config)
|
|
503
|
+
authData = getFromMapOrObject<Uint8Array>(attestation, "authData");
|
|
504
|
+
console.log(
|
|
505
|
+
"[COSE] extractPublicKeyFromAttestation - authData from 'authData' key:",
|
|
506
|
+
authData instanceof Uint8Array
|
|
507
|
+
? `Uint8Array(${authData.length})`
|
|
508
|
+
: authData,
|
|
509
|
+
);
|
|
510
|
+
|
|
511
|
+
// If not found, log available keys for debugging
|
|
512
|
+
if (!authData) {
|
|
513
|
+
if (attestation instanceof Map) {
|
|
514
|
+
console.log(
|
|
515
|
+
"[COSE] extractPublicKeyFromAttestation - Map keys:",
|
|
516
|
+
Array.from(attestation.keys()),
|
|
517
|
+
);
|
|
518
|
+
} else if (attestation !== null && typeof attestation === "object") {
|
|
519
|
+
console.log(
|
|
520
|
+
"[COSE] extractPublicKeyFromAttestation - Object keys:",
|
|
521
|
+
Object.keys(attestation),
|
|
522
|
+
);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
if (!authData || !(authData instanceof Uint8Array)) {
|
|
285
527
|
throw new COSEParseError(
|
|
286
|
-
"Invalid attestation object: missing or invalid authData"
|
|
528
|
+
"Invalid attestation object: missing or invalid authData",
|
|
287
529
|
);
|
|
288
530
|
}
|
|
289
531
|
|
|
532
|
+
console.log(
|
|
533
|
+
"[COSE] extractPublicKeyFromAttestation - authData length:",
|
|
534
|
+
authData.length,
|
|
535
|
+
);
|
|
536
|
+
|
|
290
537
|
// Parse the authenticator data to get the public key
|
|
291
|
-
const { credentialId, publicKeyBytes } = parseAuthenticatorData(
|
|
292
|
-
|
|
538
|
+
const { credentialId, publicKeyBytes } = parseAuthenticatorData(authData);
|
|
539
|
+
|
|
540
|
+
console.log(
|
|
541
|
+
"[COSE] extractPublicKeyFromAttestation - credentialId length:",
|
|
542
|
+
credentialId.length,
|
|
543
|
+
);
|
|
544
|
+
console.log(
|
|
545
|
+
"[COSE] extractPublicKeyFromAttestation - publicKeyBytes length:",
|
|
546
|
+
publicKeyBytes.length,
|
|
293
547
|
);
|
|
294
548
|
|
|
295
549
|
// Extract the P256 coordinates from the COSE key
|
|
296
550
|
const publicKey = extractP256PublicKey(publicKeyBytes);
|
|
297
551
|
|
|
552
|
+
console.log("[COSE] extractPublicKeyFromAttestation - extraction successful");
|
|
553
|
+
console.log(
|
|
554
|
+
"[COSE] extractPublicKeyFromAttestation - publicKey.x:",
|
|
555
|
+
publicKey.x,
|
|
556
|
+
);
|
|
557
|
+
console.log(
|
|
558
|
+
"[COSE] extractPublicKeyFromAttestation - publicKey.y:",
|
|
559
|
+
publicKey.y,
|
|
560
|
+
);
|
|
561
|
+
|
|
298
562
|
return { credentialId, publicKey };
|
|
299
563
|
}
|
|
300
564
|
|
|
@@ -342,7 +606,7 @@ export function isValidP256PublicKey(publicKey: P256PublicKey): boolean {
|
|
|
342
606
|
|
|
343
607
|
// P-256 prime
|
|
344
608
|
const p = BigInt(
|
|
345
|
-
"0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff"
|
|
609
|
+
"0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
|
|
346
610
|
);
|
|
347
611
|
|
|
348
612
|
// Coordinates should be less than the prime
|