@zerodev/sdk 4.0.22 → 4.0.24
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/cjs/kernel-zerodev/owner/passkey/createPasskeyOwner.d.ts +2 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/createPasskeyOwner.js +13 -3
- package/dist/cjs/kernel-zerodev/owner/passkey/createPasskeyOwner.js.map +1 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/exceptions.d.ts +3 -0
- package/dist/cjs/kernel-zerodev/owner/passkey/exceptions.js +16 -0
- package/dist/cjs/kernel-zerodev/owner/passkey/exceptions.js.map +1 -0
- package/dist/cjs/kernel-zerodev/owner/passkey/{getOrCreatePasskeyOwner.d.ts → getAutocompletePasskeyOwner.d.ts} +2 -2
- package/dist/cjs/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.js +46 -0
- package/dist/cjs/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.js.map +1 -0
- package/dist/cjs/kernel-zerodev/owner/passkey/getPasskeyOwner.d.ts +3 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/getPasskeyOwner.js +4 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/getPasskeyOwner.js.map +1 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/index.d.ts +1 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/index.js +3 -3
- package/dist/cjs/kernel-zerodev/owner/passkey/index.js.map +1 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/utils.d.ts +5 -0
- package/dist/cjs/kernel-zerodev/owner/passkey/utils.js +14 -1
- package/dist/cjs/kernel-zerodev/owner/passkey/utils.js.map +1 -1
- package/dist/esm/kernel-zerodev/owner/passkey/createPasskeyOwner.d.ts +2 -1
- package/dist/esm/kernel-zerodev/owner/passkey/createPasskeyOwner.js +14 -4
- package/dist/esm/kernel-zerodev/owner/passkey/createPasskeyOwner.js.map +1 -1
- package/dist/esm/kernel-zerodev/owner/passkey/exceptions.d.ts +3 -0
- package/dist/esm/kernel-zerodev/owner/passkey/exceptions.js +12 -0
- package/dist/esm/kernel-zerodev/owner/passkey/exceptions.js.map +1 -0
- package/dist/esm/kernel-zerodev/owner/passkey/{getOrCreatePasskeyOwner.d.ts → getAutocompletePasskeyOwner.d.ts} +2 -2
- package/dist/esm/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.js +39 -0
- package/dist/esm/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.js.map +1 -0
- package/dist/esm/kernel-zerodev/owner/passkey/getPasskeyOwner.d.ts +3 -1
- package/dist/esm/kernel-zerodev/owner/passkey/getPasskeyOwner.js +5 -2
- package/dist/esm/kernel-zerodev/owner/passkey/getPasskeyOwner.js.map +1 -1
- package/dist/esm/kernel-zerodev/owner/passkey/index.d.ts +1 -1
- package/dist/esm/kernel-zerodev/owner/passkey/index.js +1 -1
- package/dist/esm/kernel-zerodev/owner/passkey/index.js.map +1 -1
- package/dist/esm/kernel-zerodev/owner/passkey/utils.d.ts +5 -0
- package/dist/esm/kernel-zerodev/owner/passkey/utils.js +12 -0
- package/dist/esm/kernel-zerodev/owner/passkey/utils.js.map +1 -1
- package/dist/types/kernel-zerodev/owner/passkey/createPasskeyOwner.d.ts +2 -1
- package/dist/types/kernel-zerodev/owner/passkey/createPasskeyOwner.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/owner/passkey/exceptions.d.ts +4 -0
- package/dist/types/kernel-zerodev/owner/passkey/exceptions.d.ts.map +1 -0
- package/dist/types/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.d.ts +7 -0
- package/dist/types/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.d.ts.map +1 -0
- package/dist/types/kernel-zerodev/owner/passkey/getPasskeyOwner.d.ts +3 -1
- package/dist/types/kernel-zerodev/owner/passkey/getPasskeyOwner.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/owner/passkey/index.d.ts +1 -1
- package/dist/types/kernel-zerodev/owner/passkey/index.d.ts.map +1 -1
- package/dist/types/kernel-zerodev/owner/passkey/utils.d.ts +5 -0
- package/dist/types/kernel-zerodev/owner/passkey/utils.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/kernel-zerodev/owner/passkey/createPasskeyOwner.ts +17 -3
- package/src/kernel-zerodev/owner/passkey/exceptions.ts +3 -0
- package/src/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.ts +78 -0
- package/src/kernel-zerodev/owner/passkey/getPasskeyOwner.ts +9 -1
- package/src/kernel-zerodev/owner/passkey/index.ts +1 -1
- package/src/kernel-zerodev/owner/passkey/utils.ts +14 -0
- package/dist/cjs/kernel-zerodev/owner/passkey/getOrCreatePasskeyOwner.js +0 -16
- package/dist/cjs/kernel-zerodev/owner/passkey/getOrCreatePasskeyOwner.js.map +0 -1
- package/dist/esm/kernel-zerodev/owner/passkey/getOrCreatePasskeyOwner.js +0 -12
- package/dist/esm/kernel-zerodev/owner/passkey/getOrCreatePasskeyOwner.js.map +0 -1
- package/dist/types/kernel-zerodev/owner/passkey/getOrCreatePasskeyOwner.d.ts +0 -7
- package/dist/types/kernel-zerodev/owner/passkey/getOrCreatePasskeyOwner.d.ts.map +0 -1
- package/src/kernel-zerodev/owner/passkey/getOrCreatePasskeyOwner.ts +0 -22
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { SmartAccountSigner } from "@alchemy/aa-core";
|
|
2
|
-
export declare function createPasskeyOwner({ name, projectId, fallback, apiUrl, }: {
|
|
2
|
+
export declare function createPasskeyOwner({ name, projectId, withCredentials, fallback, apiUrl, }: {
|
|
3
3
|
name: string;
|
|
4
4
|
projectId: string;
|
|
5
|
+
withCredentials?: boolean;
|
|
5
6
|
fallback?: () => Promise<SmartAccountSigner | undefined>;
|
|
6
7
|
apiUrl?: string;
|
|
7
8
|
}): Promise<SmartAccountSigner | undefined>;
|
|
@@ -8,11 +8,20 @@ const http_1 = require("@turnkey/http");
|
|
|
8
8
|
const axios_1 = __importDefault(require("axios"));
|
|
9
9
|
const utils_js_1 = require("./utils.js");
|
|
10
10
|
const constants_js_1 = require("../../constants.js");
|
|
11
|
-
|
|
11
|
+
const exceptions_js_1 = require("./exceptions.js");
|
|
12
|
+
async function createPasskeyOwner({ name, projectId, withCredentials = false, fallback, apiUrl = constants_js_1.API_URL, }) {
|
|
12
13
|
if (typeof window !== "undefined") {
|
|
13
14
|
const challenge = (0, utils_js_1.generateRandomBuffer)();
|
|
14
|
-
|
|
15
|
+
let credentials = undefined;
|
|
16
|
+
if (withCredentials) {
|
|
17
|
+
credentials = await (0, utils_js_1.getCredentials)(projectId, name);
|
|
18
|
+
}
|
|
19
|
+
if (credentials.length >= 64) {
|
|
20
|
+
throw new exceptions_js_1.UsernameIsAlreadyUsed();
|
|
21
|
+
}
|
|
15
22
|
try {
|
|
23
|
+
utils_js_1.abortController.controller.abort();
|
|
24
|
+
utils_js_1.abortController.controller = new AbortController();
|
|
16
25
|
const attestation = await (0, http_1.getWebAuthnAttestation)({
|
|
17
26
|
publicKey: {
|
|
18
27
|
rp: {
|
|
@@ -23,6 +32,7 @@ async function createPasskeyOwner({ name, projectId, fallback, apiUrl = constant
|
|
|
23
32
|
residentKey: "required",
|
|
24
33
|
userVerification: "required",
|
|
25
34
|
},
|
|
35
|
+
excludeCredentials: credentials,
|
|
26
36
|
extensions: { credProps: true },
|
|
27
37
|
challenge,
|
|
28
38
|
pubKeyCredParams: [
|
|
@@ -32,7 +42,7 @@ async function createPasskeyOwner({ name, projectId, fallback, apiUrl = constant
|
|
|
32
42
|
},
|
|
33
43
|
],
|
|
34
44
|
user: {
|
|
35
|
-
id:
|
|
45
|
+
id: Uint8Array.from(name, (c) => c.charCodeAt(0)),
|
|
36
46
|
name,
|
|
37
47
|
displayName: name,
|
|
38
48
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPasskeyOwner.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/createPasskeyOwner.ts"],"names":[],"mappings":";;;;;;AAAA,wCAAuD;AACvD,kDAA0B;AAE1B,
|
|
1
|
+
{"version":3,"file":"createPasskeyOwner.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/createPasskeyOwner.ts"],"names":[],"mappings":";;;;;;AAAA,wCAAuD;AACvD,kDAA0B;AAE1B,yCASoB;AACpB,qDAA6C;AAC7C,mDAAwD;AAEjD,KAAK,UAAU,kBAAkB,CAAC,EACvC,IAAI,EACJ,SAAS,EACT,eAAe,GAAG,KAAK,EACvB,QAAQ,EACR,MAAM,GAAG,sBAAO,GAOjB;IAEC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,MAAM,SAAS,GAAG,IAAA,+BAAoB,GAAE,CAAC;QACzC,IAAI,WAAW,GAAG,SAAS,CAAA;QAC3B,IAAI,eAAe,EAAE;YACnB,WAAW,GAAG,MAAM,IAAA,yBAAc,EAAC,SAAS,EAAE,IAAI,CAAC,CAAA;SACpD;QACD,IAAI,WAAW,CAAC,MAAM,IAAI,EAAE,EAAE;YAC5B,MAAM,IAAI,qCAAqB,EAAE,CAAA;SAClC;QAED,IAAI;YACF,0BAAe,CAAC,UAAU,CAAC,KAAK,EAAE,CAAA;YAClC,0BAAe,CAAC,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;YAClD,MAAM,WAAW,GAAG,MAAM,IAAA,6BAAsB,EAAC;gBAC/C,SAAS,EAAE;oBACT,EAAE,EAAE;wBAEF,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;wBAE5B,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;qBAC/B;oBACD,sBAAsB,EAAE;wBACtB,WAAW,EAAE,UAAU;wBACvB,gBAAgB,EAAE,UAAU;qBAC7B;oBACD,kBAAkB,EAAE,WAAW;oBAC/B,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE;oBAC/B,SAAS;oBACT,gBAAgB,EAAE;wBAChB;4BACE,IAAI,EAAE,oBAAS;4BACf,GAAG,EAAE,gBAAK;yBACX;qBACF;oBACD,IAAI,EAAE;wBACJ,EAAE,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;wBACjD,IAAI;wBACJ,WAAW,EAAE,IAAI;qBAClB;iBACF;aACF,CAAC,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,eAAK,CAAC,IAAI,CAC/B,GAAG,MAAM,aAAa,SAAS,UAAU,EACzC;gBACE,SAAS,EAAE,IAAA,0BAAe,EAAC,SAAS,CAAC;gBACrC,IAAI;gBACJ,WAAW;aACZ,CACF,CAAC;YACF,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC;YACtD,MAAM,KAAK,GAAuB;gBAChC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO;gBAC/B,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CACnB,IAAA,sBAAW,EACT,GAAG,EACH,EAAE,EACF,QAAQ,EACR,SAAS,EACT,WAAW,CAAC,YAAY,EACxB,MAAM,CACP;gBACH,aAAa,EAAE,CAAC,MAA2B,EAAE,EAAE,CAC7C,IAAA,wBAAa,EACX,MAAM,EACN,EAAE,EACF,QAAQ,EACR,SAAS,EACT,WAAW,CAAC,YAAY,EACxB,MAAM,CACP;aACJ,CAAC;YACF,OAAO,KAAK,CAAC;SACd;QAAC,OAAO,CAAC,EAAE;YAEV,IAAI,CAAC,YAAY,YAAY,IAAI,CAAC,CAAC,IAAI,KAAK,mBAAmB,EAAE;gBAC/D,IAAI,QAAQ;oBAAE,OAAO,MAAM,QAAQ,EAAE,CAAC;aACvC;YACD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SAChB;KACF;IACD,OAAO;AACT,CAAC;AA/FD,gDA+FC","sourcesContent":["import { getWebAuthnAttestation } from \"@turnkey/http\";\nimport axios from \"axios\";\nimport type { SignTypedDataParams, SmartAccountSigner } from \"@alchemy/aa-core\";\nimport {\n abortController,\n base64UrlEncode,\n es256,\n generateRandomBuffer,\n getCredentials,\n publicKey,\n signMessage,\n signTypedData,\n} from \"./utils.js\";\nimport { API_URL } from \"../../constants.js\";\nimport { UsernameIsAlreadyUsed } from \"./exceptions.js\";\n\nexport async function createPasskeyOwner({\n name,\n projectId,\n withCredentials = false,\n fallback,\n apiUrl = API_URL,\n}: {\n name: string;\n projectId: string;\n withCredentials?: boolean;\n fallback?: () => Promise<SmartAccountSigner | undefined>;\n apiUrl?: string;\n}): Promise<SmartAccountSigner | undefined> {\n //@ts-expect-error\n if (typeof window !== \"undefined\") {\n const challenge = generateRandomBuffer();\n let credentials = undefined\n if (withCredentials) {\n credentials = await getCredentials(projectId, name)\n }\n if (credentials.length >= 64) {\n throw new UsernameIsAlreadyUsed()\n }\n\n try {\n abortController.controller.abort()\n abortController.controller = new AbortController()\n const attestation = await getWebAuthnAttestation({\n publicKey: {\n rp: {\n //@ts-expect-error\n id: window.location.hostname,\n //@ts-expect-error\n name: window.location.hostname,\n },\n authenticatorSelection: {\n residentKey: \"required\", // or 'preferred', 'discouraged'\n userVerification: \"required\",\n },\n excludeCredentials: credentials,\n extensions: { credProps: true },\n challenge,\n pubKeyCredParams: [\n {\n type: publicKey,\n alg: es256,\n },\n ],\n user: {\n id: Uint8Array.from(name, (c) => c.charCodeAt(0)),\n name,\n displayName: name,\n },\n },\n });\n const response = await axios.post(\n `${apiUrl}/projects/${projectId}/wallets`,\n {\n challenge: base64UrlEncode(challenge),\n name,\n attestation,\n }\n );\n const { id, walletId, address } = await response.data;\n const owner: SmartAccountSigner = {\n getAddress: async () => address,\n signMessage: (msg) =>\n signMessage(\n msg,\n id,\n walletId,\n projectId,\n attestation.credentialId,\n apiUrl\n ),\n signTypedData: (params: SignTypedDataParams) =>\n signTypedData(\n params,\n id,\n walletId,\n projectId,\n attestation.credentialId,\n apiUrl\n ),\n };\n return owner;\n } catch (e) {\n //@ts-expect-error\n if (e instanceof DOMException && e.name === \"InvalidStateError\") {\n if (fallback) return await fallback();\n }\n console.log(e);\n }\n }\n return;\n}\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UsernameIsAlreadyUsed = void 0;
|
|
4
|
+
class UsernameIsAlreadyUsed extends Error {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
Object.defineProperty(this, "message", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
configurable: true,
|
|
10
|
+
writable: true,
|
|
11
|
+
value: 'Username is already used.'
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.UsernameIsAlreadyUsed = UsernameIsAlreadyUsed;
|
|
16
|
+
//# sourceMappingURL=exceptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exceptions.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/exceptions.ts"],"names":[],"mappings":";;;AAAA,MAAa,qBAAsB,SAAQ,KAAK;IAAhD;;QACI;;;;mBAAkB,2BAA2B;WAAA;IACjD,CAAC;CAAA;AAFD,sDAEC","sourcesContent":["export class UsernameIsAlreadyUsed extends Error {\n message: string = 'Username is already used.'\n}"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SmartAccountSigner } from "@alchemy/aa-core";
|
|
2
|
-
export declare function
|
|
3
|
-
name: string;
|
|
2
|
+
export declare function getAutocompletePasskeyOwner({ projectId, apiUrl, }: {
|
|
4
3
|
projectId: string;
|
|
4
|
+
name?: string;
|
|
5
5
|
apiUrl?: string;
|
|
6
6
|
}): Promise<SmartAccountSigner | undefined>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getAutocompletePasskeyOwner = void 0;
|
|
7
|
+
const webauthn_1 = require("@turnkey/http/dist/webauthn");
|
|
8
|
+
const axios_1 = __importDefault(require("axios"));
|
|
9
|
+
const utils_js_1 = require("./utils.js");
|
|
10
|
+
const constants_js_1 = require("../../constants.js");
|
|
11
|
+
async function getAutocompletePasskeyOwner({ projectId, apiUrl = constants_js_1.API_URL, }) {
|
|
12
|
+
if (!PublicKeyCredential?.isConditionalMediationAvailable ||
|
|
13
|
+
!PublicKeyCredential?.isConditionalMediationAvailable()) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (typeof window !== "undefined") {
|
|
17
|
+
const challenge = (0, utils_js_1.generateRandomBuffer)();
|
|
18
|
+
try {
|
|
19
|
+
const assertion = JSON.parse(await (0, webauthn_1.getWebAuthnAssertion)((0, utils_js_1.base64UrlEncode)(challenge), {
|
|
20
|
+
mediation: 'conditional',
|
|
21
|
+
publicKey: {
|
|
22
|
+
rpId: window.location.hostname,
|
|
23
|
+
userVerification: "required",
|
|
24
|
+
},
|
|
25
|
+
signal: utils_js_1.abortController.controller.signal
|
|
26
|
+
}));
|
|
27
|
+
const response = await axios_1.default.post(`${apiUrl}/projects/${projectId}/wallets/${assertion.credentialId}`, {
|
|
28
|
+
challenge: (0, utils_js_1.base64UrlEncode)(challenge),
|
|
29
|
+
assertion,
|
|
30
|
+
});
|
|
31
|
+
const { id, walletId, address } = await response.data;
|
|
32
|
+
const owner = {
|
|
33
|
+
getAddress: async () => address,
|
|
34
|
+
signMessage: (msg) => (0, utils_js_1.signMessage)(msg, id, walletId, projectId, assertion.credentialId, apiUrl),
|
|
35
|
+
signTypedData: (params) => (0, utils_js_1.signTypedData)(params, id, walletId, projectId, assertion.credentialId, apiUrl),
|
|
36
|
+
};
|
|
37
|
+
return owner;
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
console.log(e);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
exports.getAutocompletePasskeyOwner = getAutocompletePasskeyOwner;
|
|
46
|
+
//# sourceMappingURL=getAutocompletePasskeyOwner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getAutocompletePasskeyOwner.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.ts"],"names":[],"mappings":";;;;;;AAAA,0DAAmE;AACnE,kDAA0B;AAE1B,yCAMoB;AACpB,qDAA6C;AAEtC,KAAK,UAAU,2BAA2B,CAAC,EAChD,SAAS,EACT,MAAM,GAAG,sBAAO,GAKjB;IAEC,IAAI,CAAC,mBAAmB,EAAE,+BAA+B;QAEnD,CAAC,mBAAmB,EAAE,+BAA+B,EAAE,EAAE;QAC3D,OAAO;KACR;IAGH,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,MAAM,SAAS,GAAG,IAAA,+BAAoB,GAAE,CAAC;QACzC,IAAI;YACF,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAC1B,MAAM,IAAA,+BAAoB,EAAC,IAAA,0BAAe,EAAC,SAAS,CAAC,EAAE;gBACrD,SAAS,EAAE,aAAa;gBACxB,SAAS,EAAE;oBAET,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;oBAC9B,gBAAgB,EAAE,UAAU;iBAC7B;gBACD,MAAM,EAAE,0BAAe,CAAC,UAAU,CAAC,MAAM;aAC1C,CAAC,CACH,CAAC;YACF,MAAM,QAAQ,GAAG,MAAM,eAAK,CAAC,IAAI,CAC/B,GAAG,MAAM,aAAa,SAAS,YAAY,SAAS,CAAC,YAAY,EAAE,EACnE;gBACE,SAAS,EAAE,IAAA,0BAAe,EAAC,SAAS,CAAC;gBACrC,SAAS;aACV,CACF,CAAC;YACF,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC;YACtD,MAAM,KAAK,GAAuB;gBAChC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO;gBAC/B,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CACnB,IAAA,sBAAW,EACT,GAAG,EACH,EAAE,EACF,QAAQ,EACR,SAAS,EACT,SAAS,CAAC,YAAY,EACtB,MAAM,CACP;gBACH,aAAa,EAAE,CAAC,MAA2B,EAAE,EAAE,CAC7C,IAAA,wBAAa,EACX,MAAM,EACN,EAAE,EACF,QAAQ,EACR,SAAS,EACT,SAAS,CAAC,YAAY,EACtB,MAAM,CACP;aACJ,CAAC;YACF,OAAO,KAAK,CAAC;SACd;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SAChB;KACF;IACD,OAAO;AACT,CAAC;AAjED,kEAiEC","sourcesContent":["import { getWebAuthnAssertion } from \"@turnkey/http/dist/webauthn\";\nimport axios from \"axios\";\nimport type { SignTypedDataParams, SmartAccountSigner } from \"@alchemy/aa-core\";\nimport {\n abortController,\n base64UrlEncode,\n generateRandomBuffer,\n signMessage,\n signTypedData,\n} from \"./utils.js\";\nimport { API_URL } from \"../../constants.js\";\n\nexport async function getAutocompletePasskeyOwner({\n projectId,\n apiUrl = API_URL,\n}: {\n projectId: string;\n name?: string;\n apiUrl?: string;\n}): Promise<SmartAccountSigner | undefined> {\n //@ts-ignore\n if (!PublicKeyCredential?.isConditionalMediationAvailable ||\n //@ts-ignore\n !PublicKeyCredential?.isConditionalMediationAvailable()) {\n return;\n }\n\n //@ts-expect-error\n if (typeof window !== \"undefined\") {\n const challenge = generateRandomBuffer();\n try {\n const assertion = JSON.parse(\n await getWebAuthnAssertion(base64UrlEncode(challenge), {\n mediation: 'conditional',\n publicKey: {\n //@ts-expect-error\n rpId: window.location.hostname,\n userVerification: \"required\",\n },\n signal: abortController.controller.signal\n })\n );\n const response = await axios.post(\n `${apiUrl}/projects/${projectId}/wallets/${assertion.credentialId}`,\n {\n challenge: base64UrlEncode(challenge),\n assertion,\n }\n );\n const { id, walletId, address } = await response.data;\n const owner: SmartAccountSigner = {\n getAddress: async () => address,\n signMessage: (msg) =>\n signMessage(\n msg,\n id,\n walletId,\n projectId,\n assertion.credentialId,\n apiUrl\n ),\n signTypedData: (params: SignTypedDataParams) =>\n signTypedData(\n params,\n id,\n walletId,\n projectId,\n assertion.credentialId,\n apiUrl\n ),\n };\n return owner;\n } catch (e) {\n console.log(e);\n }\n }\n return;\n}\n"]}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { SmartAccountSigner } from "@alchemy/aa-core";
|
|
2
|
-
export declare function getPasskeyOwner({ projectId, apiUrl, }: {
|
|
2
|
+
export declare function getPasskeyOwner({ projectId, name, apiUrl, withCredentials }: {
|
|
3
3
|
projectId: string;
|
|
4
|
+
name?: string;
|
|
4
5
|
apiUrl?: string;
|
|
6
|
+
withCredentials?: boolean;
|
|
5
7
|
}): Promise<SmartAccountSigner | undefined>;
|
|
@@ -8,14 +8,17 @@ const webauthn_1 = require("@turnkey/http/dist/webauthn");
|
|
|
8
8
|
const axios_1 = __importDefault(require("axios"));
|
|
9
9
|
const utils_js_1 = require("./utils.js");
|
|
10
10
|
const constants_js_1 = require("../../constants.js");
|
|
11
|
-
async function getPasskeyOwner({ projectId, apiUrl = constants_js_1.API_URL, }) {
|
|
11
|
+
async function getPasskeyOwner({ projectId, name, apiUrl = constants_js_1.API_URL, withCredentials = false }) {
|
|
12
12
|
if (typeof window !== "undefined") {
|
|
13
13
|
const challenge = (0, utils_js_1.generateRandomBuffer)();
|
|
14
14
|
try {
|
|
15
|
+
utils_js_1.abortController.controller.abort();
|
|
16
|
+
utils_js_1.abortController.controller = new AbortController();
|
|
15
17
|
const assertion = JSON.parse(await (0, webauthn_1.getWebAuthnAssertion)((0, utils_js_1.base64UrlEncode)(challenge), {
|
|
16
18
|
publicKey: {
|
|
17
19
|
rpId: window.location.hostname,
|
|
18
20
|
userVerification: "required",
|
|
21
|
+
allowCredentials: withCredentials ? await (0, utils_js_1.getCredentials)(projectId, name) : undefined,
|
|
19
22
|
},
|
|
20
23
|
}));
|
|
21
24
|
const response = await axios_1.default.post(`${apiUrl}/projects/${projectId}/wallets/${assertion.credentialId}`, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPasskeyOwner.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/getPasskeyOwner.ts"],"names":[],"mappings":";;;;;;AAAA,0DAAmE;AACnE,kDAA0B;AAE1B,
|
|
1
|
+
{"version":3,"file":"getPasskeyOwner.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/getPasskeyOwner.ts"],"names":[],"mappings":";;;;;;AAAA,0DAAmE;AACnE,kDAA0B;AAE1B,yCAOoB;AACpB,qDAA6C;AAEtC,KAAK,UAAU,eAAe,CAAC,EACpC,SAAS,EACT,IAAI,EACJ,MAAM,GAAG,sBAAO,EAChB,eAAe,GAAG,KAAK,EAMxB;IAEC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,MAAM,SAAS,GAAG,IAAA,+BAAoB,GAAE,CAAC;QACzC,IAAI;YACF,0BAAe,CAAC,UAAU,CAAC,KAAK,EAAE,CAAA;YAClC,0BAAe,CAAC,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;YAClD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAC1B,MAAM,IAAA,+BAAoB,EAAC,IAAA,0BAAe,EAAC,SAAS,CAAC,EAAE;gBACrD,SAAS,EAAE;oBAET,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;oBAC9B,gBAAgB,EAAE,UAAU;oBAC5B,gBAAgB,EAAE,eAAe,CAAC,CAAC,CAAC,MAAM,IAAA,yBAAc,EAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;iBACtF;aACF,CAAC,CACH,CAAC;YACF,MAAM,QAAQ,GAAG,MAAM,eAAK,CAAC,IAAI,CAC/B,GAAG,MAAM,aAAa,SAAS,YAAY,SAAS,CAAC,YAAY,EAAE,EACnE;gBACE,SAAS,EAAE,IAAA,0BAAe,EAAC,SAAS,CAAC;gBACrC,SAAS;aACV,CACF,CAAC;YACF,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC;YACtD,MAAM,KAAK,GAAuB;gBAChC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO;gBAC/B,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CACnB,IAAA,sBAAW,EACT,GAAG,EACH,EAAE,EACF,QAAQ,EACR,SAAS,EACT,SAAS,CAAC,YAAY,EACtB,MAAM,CACP;gBACH,aAAa,EAAE,CAAC,MAA2B,EAAE,EAAE,CAC7C,IAAA,wBAAa,EACX,MAAM,EACN,EAAE,EACF,QAAQ,EACR,SAAS,EACT,SAAS,CAAC,YAAY,EACtB,MAAM,CACP;aACJ,CAAC;YACF,OAAO,KAAK,CAAC;SACd;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SAChB;KACF;IACD,OAAO;AACT,CAAC;AA9DD,0CA8DC","sourcesContent":["import { getWebAuthnAssertion } from \"@turnkey/http/dist/webauthn\";\nimport axios from \"axios\";\nimport type { SignTypedDataParams, SmartAccountSigner } from \"@alchemy/aa-core\";\nimport {\n abortController,\n base64UrlEncode,\n generateRandomBuffer,\n getCredentials,\n signMessage,\n signTypedData,\n} from \"./utils.js\";\nimport { API_URL } from \"../../constants.js\";\n\nexport async function getPasskeyOwner({\n projectId,\n name,\n apiUrl = API_URL,\n withCredentials = false\n}: {\n projectId: string;\n name?: string;\n apiUrl?: string;\n withCredentials?: boolean;\n}): Promise<SmartAccountSigner | undefined> {\n //@ts-expect-error\n if (typeof window !== \"undefined\") {\n const challenge = generateRandomBuffer();\n try {\n abortController.controller.abort()\n abortController.controller = new AbortController()\n const assertion = JSON.parse(\n await getWebAuthnAssertion(base64UrlEncode(challenge), {\n publicKey: {\n //@ts-expect-error\n rpId: window.location.hostname,\n userVerification: \"required\",\n allowCredentials: withCredentials ? await getCredentials(projectId, name) : undefined,\n },\n })\n );\n const response = await axios.post(\n `${apiUrl}/projects/${projectId}/wallets/${assertion.credentialId}`,\n {\n challenge: base64UrlEncode(challenge),\n assertion,\n }\n );\n const { id, walletId, address } = await response.data;\n const owner: SmartAccountSigner = {\n getAddress: async () => address,\n signMessage: (msg) =>\n signMessage(\n msg,\n id,\n walletId,\n projectId,\n assertion.credentialId,\n apiUrl\n ),\n signTypedData: (params: SignTypedDataParams) =>\n signTypedData(\n params,\n id,\n walletId,\n projectId,\n assertion.credentialId,\n apiUrl\n ),\n };\n return owner;\n } catch (e) {\n console.log(e);\n }\n }\n return;\n}\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { getPasskeyOwner } from "./getPasskeyOwner.js";
|
|
2
2
|
export { createPasskeyOwner } from "./createPasskeyOwner.js";
|
|
3
|
-
export {
|
|
3
|
+
export { getAutocompletePasskeyOwner } from "./getAutocompletePasskeyOwner.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getAutocompletePasskeyOwner = exports.createPasskeyOwner = exports.getPasskeyOwner = void 0;
|
|
4
4
|
var getPasskeyOwner_js_1 = require("./getPasskeyOwner.js");
|
|
5
5
|
Object.defineProperty(exports, "getPasskeyOwner", { enumerable: true, get: function () { return getPasskeyOwner_js_1.getPasskeyOwner; } });
|
|
6
6
|
var createPasskeyOwner_js_1 = require("./createPasskeyOwner.js");
|
|
7
7
|
Object.defineProperty(exports, "createPasskeyOwner", { enumerable: true, get: function () { return createPasskeyOwner_js_1.createPasskeyOwner; } });
|
|
8
|
-
var
|
|
9
|
-
Object.defineProperty(exports, "
|
|
8
|
+
var getAutocompletePasskeyOwner_js_1 = require("./getAutocompletePasskeyOwner.js");
|
|
9
|
+
Object.defineProperty(exports, "getAutocompletePasskeyOwner", { enumerable: true, get: function () { return getAutocompletePasskeyOwner_js_1.getAutocompletePasskeyOwner; } });
|
|
10
10
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/index.ts"],"names":[],"mappings":";;;AAAA,2DAAuD;AAA9C,qHAAA,eAAe,OAAA;AACxB,iEAA6D;AAApD,2HAAA,kBAAkB,OAAA;AAC3B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/index.ts"],"names":[],"mappings":";;;AAAA,2DAAuD;AAA9C,qHAAA,eAAe,OAAA;AACxB,iEAA6D;AAApD,2HAAA,kBAAkB,OAAA;AAC3B,mFAA+E;AAAtE,6IAAA,2BAA2B,OAAA","sourcesContent":["export { getPasskeyOwner } from \"./getPasskeyOwner.js\";\nexport { createPasskeyOwner } from \"./createPasskeyOwner.js\";\nexport { getAutocompletePasskeyOwner } from \"./getAutocompletePasskeyOwner.js\";\n"]}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import type { SignTypedDataParams } from "@alchemy/aa-core";
|
|
3
|
+
export declare const abortController: {
|
|
4
|
+
controller: AbortController;
|
|
5
|
+
};
|
|
2
6
|
export declare const publicKey = "public-key";
|
|
3
7
|
export declare const es256 = -7;
|
|
4
8
|
export declare const generateRandomBuffer: () => ArrayBuffer;
|
|
@@ -6,4 +10,5 @@ export declare const base64UrlEncode: (challenge: ArrayBuffer) => string;
|
|
|
6
10
|
export declare const signMessageImplementation: (msg: string, id: string, walletId: string, projectId: string, credentialId: string, apiUrl?: string) => Promise<`0x${string}`>;
|
|
7
11
|
export declare const signMessage: (msg: string | Uint8Array, id: string, walletId: string, projectId: string, credentialId: string, apiUrl?: string) => Promise<`0x${string}`>;
|
|
8
12
|
export declare const signTypedData: (params: SignTypedDataParams, id: string, walletId: string, projectId: string, credentialId: string, apiUrl?: string) => Promise<`0x${string}`>;
|
|
13
|
+
export declare const getCredentials: (projectId: string, name?: string, apiUrl?: string) => Promise<any>;
|
|
9
14
|
export declare function base64URLStringToBuffer(base64URLString: string): ArrayBuffer;
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.base64URLStringToBuffer = exports.signTypedData = exports.signMessage = exports.signMessageImplementation = exports.base64UrlEncode = exports.generateRandomBuffer = exports.es256 = exports.publicKey = void 0;
|
|
6
|
+
exports.base64URLStringToBuffer = exports.getCredentials = exports.signTypedData = exports.signMessage = exports.signMessageImplementation = exports.base64UrlEncode = exports.generateRandomBuffer = exports.es256 = exports.publicKey = exports.abortController = void 0;
|
|
7
7
|
const http_1 = require("@turnkey/http");
|
|
8
8
|
const axios_1 = __importDefault(require("axios"));
|
|
9
9
|
const constants_js_1 = require("../../constants.js");
|
|
@@ -11,6 +11,9 @@ const viem_1 = require("viem");
|
|
|
11
11
|
(0, http_1.browserInit)({
|
|
12
12
|
baseUrl: "https://api.turnkey.com",
|
|
13
13
|
});
|
|
14
|
+
exports.abortController = {
|
|
15
|
+
controller: new AbortController(),
|
|
16
|
+
};
|
|
14
17
|
exports.publicKey = "public-key";
|
|
15
18
|
exports.es256 = -7;
|
|
16
19
|
const generateRandomBuffer = () => {
|
|
@@ -80,6 +83,16 @@ const signTypedData = async (params, id, walletId, projectId, credentialId, apiU
|
|
|
80
83
|
return await (0, exports.signMessageImplementation)(hashToSign, id, walletId, projectId, credentialId, apiUrl);
|
|
81
84
|
};
|
|
82
85
|
exports.signTypedData = signTypedData;
|
|
86
|
+
const getCredentials = async (projectId, name, apiUrl = constants_js_1.API_URL) => {
|
|
87
|
+
const url = `${apiUrl}/projects/${projectId}/wallets` + (name ? `/${name}` : '');
|
|
88
|
+
const response = await axios_1.default.get(url);
|
|
89
|
+
const credentials = response.data;
|
|
90
|
+
return credentials.map((credential) => ({
|
|
91
|
+
id: base64URLStringToBuffer(credential),
|
|
92
|
+
type: "public-key",
|
|
93
|
+
}));
|
|
94
|
+
};
|
|
95
|
+
exports.getCredentials = getCredentials;
|
|
83
96
|
function base64URLStringToBuffer(base64URLString) {
|
|
84
97
|
const base64 = base64URLString.replace(/-/g, "+").replace(/_/g, "/");
|
|
85
98
|
const padLength = (4 - (base64.length % 4)) % 4;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { browserInit, TurnkeyApi } from \"@turnkey/http\";\nimport axios from \"axios\";\nimport { API_URL } from \"../../constants.js\";\nimport type { SignTypedDataParams } from \"@alchemy/aa-core\";\nimport { hashTypedData, signatureToHex, hashMessage } from \"viem\";\n\nbrowserInit({\n baseUrl: \"https://api.turnkey.com\",\n});\n\nexport const publicKey = \"public-key\";\n\nexport const es256 = -7;\n\nexport const generateRandomBuffer = (): ArrayBuffer => {\n const arr = new Uint8Array(32);\n //@ts-expect-error\n crypto.getRandomValues(arr);\n return arr.buffer;\n};\n\nexport const base64UrlEncode = (challenge: ArrayBuffer): string => {\n return Buffer.from(challenge)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\");\n};\n\nexport const signMessageImplementation = async (\n msg: string,\n id: string,\n walletId: string,\n projectId: string,\n credentialId: string,\n apiUrl = API_URL\n) => {\n console.log(\"SIGN MESSAGE IMPLEMENTATION\");\n const signedRequest = await TurnkeyApi.signSignRawPayload(\n {\n body: {\n type: \"ACTIVITY_TYPE_SIGN_RAW_PAYLOAD\",\n organizationId: id,\n parameters: {\n privateKeyId: walletId,\n payload: msg,\n encoding: \"PAYLOAD_ENCODING_HEXADECIMAL\",\n hashFunction: \"HASH_FUNCTION_NO_OP\",\n },\n timestampMs: String(Date.now()),\n },\n },\n {\n publicKey: {\n allowCredentials: [\n {\n id: base64URLStringToBuffer(credentialId),\n type: publicKey,\n },\n ],\n },\n }\n );\n const proxyResponse = await axios.post(\n `${apiUrl}/projects/${projectId}/wallets/proxy`,\n {\n signedRequest,\n }\n );\n const { activity } = await proxyResponse.data;\n if (activity.status === \"ACTIVITY_STATUS_COMPLETED\") {\n let result = activity?.result?.signRawPayloadResult;\n\n if (result) {\n const signatureHex = signatureToHex({\n r: `0x${result.r}`,\n s: `0x${result.s}`,\n v: result.v === \"00\" ? 27n : 28n,\n });\n if (signatureHex) {\n return signatureHex;\n }\n }\n }\n return \"0x\";\n};\n\nexport const signMessage = async (\n msg: string | Uint8Array,\n id: string,\n walletId: string,\n projectId: string,\n credentialId: string,\n apiUrl = API_URL\n) => {\n return await signMessageImplementation(\n hashMessage(typeof msg === \"string\" ? msg : { raw: msg }),\n id,\n walletId,\n projectId,\n credentialId,\n apiUrl\n );\n};\n\nexport const signTypedData = async (\n params: SignTypedDataParams,\n id: string,\n walletId: string,\n projectId: string,\n credentialId: string,\n apiUrl = API_URL\n) => {\n const hashToSign = hashTypedData(params);\n return await signMessageImplementation(\n hashToSign,\n id,\n walletId,\n projectId,\n credentialId,\n apiUrl\n );\n};\n\n// https://github.com/MasterKale/SimpleWebAuthn/blob/master/packages/browser/src/helpers/base64URLStringToBuffer.ts#L8\nexport function base64URLStringToBuffer(base64URLString: string): ArrayBuffer {\n // Convert from Base64URL to Base64\n const base64 = base64URLString.replace(/-/g, \"+\").replace(/_/g, \"/\");\n /**\n * Pad with '=' until it's a multiple of four\n * (4 - (85 % 4 = 1) = 3) % 4 = 3 padding\n * (4 - (86 % 4 = 2) = 2) % 4 = 2 padding\n * (4 - (87 % 4 = 3) = 1) % 4 = 1 padding\n * (4 - (88 % 4 = 0) = 4) % 4 = 0 padding\n */\n const padLength = (4 - (base64.length % 4)) % 4;\n const padded = base64.padEnd(base64.length + padLength, \"=\");\n\n // Convert to a binary string\n const binary = atob(padded);\n\n // Convert binary string to buffer\n const buffer = new ArrayBuffer(binary.length);\n const bytes = new Uint8Array(buffer);\n\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n\n return buffer;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { browserInit, TurnkeyApi } from \"@turnkey/http\";\nimport axios from \"axios\";\nimport { API_URL } from \"../../constants.js\";\nimport type { SignTypedDataParams } from \"@alchemy/aa-core\";\nimport { hashTypedData, signatureToHex, hashMessage } from \"viem\";\n\nbrowserInit({\n baseUrl: \"https://api.turnkey.com\",\n});\n\nexport const abortController = {\n controller: new AbortController(),\n}\n\nexport const publicKey = \"public-key\";\n\nexport const es256 = -7;\n\nexport const generateRandomBuffer = (): ArrayBuffer => {\n const arr = new Uint8Array(32);\n //@ts-expect-error\n crypto.getRandomValues(arr);\n return arr.buffer;\n};\n\nexport const base64UrlEncode = (challenge: ArrayBuffer): string => {\n return Buffer.from(challenge)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\");\n};\n\nexport const signMessageImplementation = async (\n msg: string,\n id: string,\n walletId: string,\n projectId: string,\n credentialId: string,\n apiUrl = API_URL\n) => {\n console.log(\"SIGN MESSAGE IMPLEMENTATION\");\n const signedRequest = await TurnkeyApi.signSignRawPayload(\n {\n body: {\n type: \"ACTIVITY_TYPE_SIGN_RAW_PAYLOAD\",\n organizationId: id,\n parameters: {\n privateKeyId: walletId,\n payload: msg,\n encoding: \"PAYLOAD_ENCODING_HEXADECIMAL\",\n hashFunction: \"HASH_FUNCTION_NO_OP\",\n },\n timestampMs: String(Date.now()),\n },\n },\n {\n publicKey: {\n allowCredentials: [\n {\n id: base64URLStringToBuffer(credentialId),\n type: publicKey,\n },\n ],\n },\n }\n );\n const proxyResponse = await axios.post(\n `${apiUrl}/projects/${projectId}/wallets/proxy`,\n {\n signedRequest,\n }\n );\n const { activity } = await proxyResponse.data;\n if (activity.status === \"ACTIVITY_STATUS_COMPLETED\") {\n let result = activity?.result?.signRawPayloadResult;\n\n if (result) {\n const signatureHex = signatureToHex({\n r: `0x${result.r}`,\n s: `0x${result.s}`,\n v: result.v === \"00\" ? 27n : 28n,\n });\n if (signatureHex) {\n return signatureHex;\n }\n }\n }\n return \"0x\";\n};\n\nexport const signMessage = async (\n msg: string | Uint8Array,\n id: string,\n walletId: string,\n projectId: string,\n credentialId: string,\n apiUrl = API_URL\n) => {\n return await signMessageImplementation(\n hashMessage(typeof msg === \"string\" ? msg : { raw: msg }),\n id,\n walletId,\n projectId,\n credentialId,\n apiUrl\n );\n};\n\nexport const signTypedData = async (\n params: SignTypedDataParams,\n id: string,\n walletId: string,\n projectId: string,\n credentialId: string,\n apiUrl = API_URL\n) => {\n const hashToSign = hashTypedData(params);\n return await signMessageImplementation(\n hashToSign,\n id,\n walletId,\n projectId,\n credentialId,\n apiUrl\n );\n};\n\nexport const getCredentials = async (projectId: string, name?: string, apiUrl = API_URL) => {\n const url = `${apiUrl}/projects/${projectId}/wallets` + (name ? `/${name}` : '')\n const response = await axios.get(url);\n const credentials = response.data;\n return credentials.map((credential: string) => ({\n id: base64URLStringToBuffer(credential),\n type: \"public-key\",\n }));\n};\n\n// https://github.com/MasterKale/SimpleWebAuthn/blob/master/packages/browser/src/helpers/base64URLStringToBuffer.ts#L8\nexport function base64URLStringToBuffer(base64URLString: string): ArrayBuffer {\n // Convert from Base64URL to Base64\n const base64 = base64URLString.replace(/-/g, \"+\").replace(/_/g, \"/\");\n /**\n * Pad with '=' until it's a multiple of four\n * (4 - (85 % 4 = 1) = 3) % 4 = 3 padding\n * (4 - (86 % 4 = 2) = 2) % 4 = 2 padding\n * (4 - (87 % 4 = 3) = 1) % 4 = 1 padding\n * (4 - (88 % 4 = 0) = 4) % 4 = 0 padding\n */\n const padLength = (4 - (base64.length % 4)) % 4;\n const padded = base64.padEnd(base64.length + padLength, \"=\");\n\n // Convert to a binary string\n const binary = atob(padded);\n\n // Convert binary string to buffer\n const buffer = new ArrayBuffer(binary.length);\n const bytes = new Uint8Array(buffer);\n\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n\n return buffer;\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { SmartAccountSigner } from "@alchemy/aa-core";
|
|
2
|
-
export declare function createPasskeyOwner({ name, projectId, fallback, apiUrl, }: {
|
|
2
|
+
export declare function createPasskeyOwner({ name, projectId, withCredentials, fallback, apiUrl, }: {
|
|
3
3
|
name: string;
|
|
4
4
|
projectId: string;
|
|
5
|
+
withCredentials?: boolean;
|
|
5
6
|
fallback?: () => Promise<SmartAccountSigner | undefined>;
|
|
6
7
|
apiUrl?: string;
|
|
7
8
|
}): Promise<SmartAccountSigner | undefined>;
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
import { getWebAuthnAttestation } from "@turnkey/http";
|
|
2
2
|
import axios from "axios";
|
|
3
|
-
import { base64UrlEncode, es256, generateRandomBuffer, publicKey, signMessage, signTypedData, } from "./utils.js";
|
|
3
|
+
import { abortController, base64UrlEncode, es256, generateRandomBuffer, getCredentials, publicKey, signMessage, signTypedData, } from "./utils.js";
|
|
4
4
|
import { API_URL } from "../../constants.js";
|
|
5
|
-
|
|
5
|
+
import { UsernameIsAlreadyUsed } from "./exceptions.js";
|
|
6
|
+
export async function createPasskeyOwner({ name, projectId, withCredentials = false, fallback, apiUrl = API_URL, }) {
|
|
6
7
|
if (typeof window !== "undefined") {
|
|
7
8
|
const challenge = generateRandomBuffer();
|
|
8
|
-
|
|
9
|
+
let credentials = undefined;
|
|
10
|
+
if (withCredentials) {
|
|
11
|
+
credentials = await getCredentials(projectId, name);
|
|
12
|
+
}
|
|
13
|
+
if (credentials.length >= 64) {
|
|
14
|
+
throw new UsernameIsAlreadyUsed();
|
|
15
|
+
}
|
|
9
16
|
try {
|
|
17
|
+
abortController.controller.abort();
|
|
18
|
+
abortController.controller = new AbortController();
|
|
10
19
|
const attestation = await getWebAuthnAttestation({
|
|
11
20
|
publicKey: {
|
|
12
21
|
rp: {
|
|
@@ -17,6 +26,7 @@ export async function createPasskeyOwner({ name, projectId, fallback, apiUrl = A
|
|
|
17
26
|
residentKey: "required",
|
|
18
27
|
userVerification: "required",
|
|
19
28
|
},
|
|
29
|
+
excludeCredentials: credentials,
|
|
20
30
|
extensions: { credProps: true },
|
|
21
31
|
challenge,
|
|
22
32
|
pubKeyCredParams: [
|
|
@@ -26,7 +36,7 @@ export async function createPasskeyOwner({ name, projectId, fallback, apiUrl = A
|
|
|
26
36
|
},
|
|
27
37
|
],
|
|
28
38
|
user: {
|
|
29
|
-
id:
|
|
39
|
+
id: Uint8Array.from(name, (c) => c.charCodeAt(0)),
|
|
30
40
|
name,
|
|
31
41
|
displayName: name,
|
|
32
42
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPasskeyOwner.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/createPasskeyOwner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,eAAe,EACf,KAAK,EACL,oBAAoB,EACpB,SAAS,EACT,WAAW,EACX,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"createPasskeyOwner.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/createPasskeyOwner.ts"],"names":[],"mappings":"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","sourcesContent":["import { getWebAuthnAttestation } from \"@turnkey/http\";\nimport axios from \"axios\";\nimport type { SignTypedDataParams, SmartAccountSigner } from \"@alchemy/aa-core\";\nimport {\n abortController,\n base64UrlEncode,\n es256,\n generateRandomBuffer,\n getCredentials,\n publicKey,\n signMessage,\n signTypedData,\n} from \"./utils.js\";\nimport { API_URL } from \"../../constants.js\";\nimport { UsernameIsAlreadyUsed } from \"./exceptions.js\";\n\nexport async function createPasskeyOwner({\n name,\n projectId,\n withCredentials = false,\n fallback,\n apiUrl = API_URL,\n}: {\n name: string;\n projectId: string;\n withCredentials?: boolean;\n fallback?: () => Promise<SmartAccountSigner | undefined>;\n apiUrl?: string;\n}): Promise<SmartAccountSigner | undefined> {\n //@ts-expect-error\n if (typeof window !== \"undefined\") {\n const challenge = generateRandomBuffer();\n let credentials = undefined\n if (withCredentials) {\n credentials = await getCredentials(projectId, name)\n }\n if (credentials.length >= 64) {\n throw new UsernameIsAlreadyUsed()\n }\n\n try {\n abortController.controller.abort()\n abortController.controller = new AbortController()\n const attestation = await getWebAuthnAttestation({\n publicKey: {\n rp: {\n //@ts-expect-error\n id: window.location.hostname,\n //@ts-expect-error\n name: window.location.hostname,\n },\n authenticatorSelection: {\n residentKey: \"required\", // or 'preferred', 'discouraged'\n userVerification: \"required\",\n },\n excludeCredentials: credentials,\n extensions: { credProps: true },\n challenge,\n pubKeyCredParams: [\n {\n type: publicKey,\n alg: es256,\n },\n ],\n user: {\n id: Uint8Array.from(name, (c) => c.charCodeAt(0)),\n name,\n displayName: name,\n },\n },\n });\n const response = await axios.post(\n `${apiUrl}/projects/${projectId}/wallets`,\n {\n challenge: base64UrlEncode(challenge),\n name,\n attestation,\n }\n );\n const { id, walletId, address } = await response.data;\n const owner: SmartAccountSigner = {\n getAddress: async () => address,\n signMessage: (msg) =>\n signMessage(\n msg,\n id,\n walletId,\n projectId,\n attestation.credentialId,\n apiUrl\n ),\n signTypedData: (params: SignTypedDataParams) =>\n signTypedData(\n params,\n id,\n walletId,\n projectId,\n attestation.credentialId,\n apiUrl\n ),\n };\n return owner;\n } catch (e) {\n //@ts-expect-error\n if (e instanceof DOMException && e.name === \"InvalidStateError\") {\n if (fallback) return await fallback();\n }\n console.log(e);\n }\n }\n return;\n}\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export class UsernameIsAlreadyUsed extends Error {
|
|
2
|
+
constructor() {
|
|
3
|
+
super(...arguments);
|
|
4
|
+
Object.defineProperty(this, "message", {
|
|
5
|
+
enumerable: true,
|
|
6
|
+
configurable: true,
|
|
7
|
+
writable: true,
|
|
8
|
+
value: 'Username is already used.'
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=exceptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exceptions.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/exceptions.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAAhD;;QACI;;;;mBAAkB,2BAA2B;WAAA;IACjD,CAAC;CAAA","sourcesContent":["export class UsernameIsAlreadyUsed extends Error {\n message: string = 'Username is already used.'\n}"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SmartAccountSigner } from "@alchemy/aa-core";
|
|
2
|
-
export declare function
|
|
3
|
-
name: string;
|
|
2
|
+
export declare function getAutocompletePasskeyOwner({ projectId, apiUrl, }: {
|
|
4
3
|
projectId: string;
|
|
4
|
+
name?: string;
|
|
5
5
|
apiUrl?: string;
|
|
6
6
|
}): Promise<SmartAccountSigner | undefined>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { getWebAuthnAssertion } from "@turnkey/http/dist/webauthn";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import { abortController, base64UrlEncode, generateRandomBuffer, signMessage, signTypedData, } from "./utils.js";
|
|
4
|
+
import { API_URL } from "../../constants.js";
|
|
5
|
+
export async function getAutocompletePasskeyOwner({ projectId, apiUrl = API_URL, }) {
|
|
6
|
+
if (!PublicKeyCredential?.isConditionalMediationAvailable ||
|
|
7
|
+
!PublicKeyCredential?.isConditionalMediationAvailable()) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (typeof window !== "undefined") {
|
|
11
|
+
const challenge = generateRandomBuffer();
|
|
12
|
+
try {
|
|
13
|
+
const assertion = JSON.parse(await getWebAuthnAssertion(base64UrlEncode(challenge), {
|
|
14
|
+
mediation: 'conditional',
|
|
15
|
+
publicKey: {
|
|
16
|
+
rpId: window.location.hostname,
|
|
17
|
+
userVerification: "required",
|
|
18
|
+
},
|
|
19
|
+
signal: abortController.controller.signal
|
|
20
|
+
}));
|
|
21
|
+
const response = await axios.post(`${apiUrl}/projects/${projectId}/wallets/${assertion.credentialId}`, {
|
|
22
|
+
challenge: base64UrlEncode(challenge),
|
|
23
|
+
assertion,
|
|
24
|
+
});
|
|
25
|
+
const { id, walletId, address } = await response.data;
|
|
26
|
+
const owner = {
|
|
27
|
+
getAddress: async () => address,
|
|
28
|
+
signMessage: (msg) => signMessage(msg, id, walletId, projectId, assertion.credentialId, apiUrl),
|
|
29
|
+
signTypedData: (params) => signTypedData(params, id, walletId, projectId, assertion.credentialId, apiUrl),
|
|
30
|
+
};
|
|
31
|
+
return owner;
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
console.log(e);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=getAutocompletePasskeyOwner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getAutocompletePasskeyOwner.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,WAAW,EACX,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAAC,EAChD,SAAS,EACT,MAAM,GAAG,OAAO,GAKjB;IAEC,IAAI,CAAC,mBAAmB,EAAE,+BAA+B;QAEnD,CAAC,mBAAmB,EAAE,+BAA+B,EAAE,EAAE;QAC3D,OAAO;KACR;IAGH,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,MAAM,SAAS,GAAG,oBAAoB,EAAE,CAAC;QACzC,IAAI;YACF,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAC1B,MAAM,oBAAoB,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE;gBACrD,SAAS,EAAE,aAAa;gBACxB,SAAS,EAAE;oBAET,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;oBAC9B,gBAAgB,EAAE,UAAU;iBAC7B;gBACD,MAAM,EAAE,eAAe,CAAC,UAAU,CAAC,MAAM;aAC1C,CAAC,CACH,CAAC;YACF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAC/B,GAAG,MAAM,aAAa,SAAS,YAAY,SAAS,CAAC,YAAY,EAAE,EACnE;gBACE,SAAS,EAAE,eAAe,CAAC,SAAS,CAAC;gBACrC,SAAS;aACV,CACF,CAAC;YACF,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC;YACtD,MAAM,KAAK,GAAuB;gBAChC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO;gBAC/B,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CACnB,WAAW,CACT,GAAG,EACH,EAAE,EACF,QAAQ,EACR,SAAS,EACT,SAAS,CAAC,YAAY,EACtB,MAAM,CACP;gBACH,aAAa,EAAE,CAAC,MAA2B,EAAE,EAAE,CAC7C,aAAa,CACX,MAAM,EACN,EAAE,EACF,QAAQ,EACR,SAAS,EACT,SAAS,CAAC,YAAY,EACtB,MAAM,CACP;aACJ,CAAC;YACF,OAAO,KAAK,CAAC;SACd;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SAChB;KACF;IACD,OAAO;AACT,CAAC","sourcesContent":["import { getWebAuthnAssertion } from \"@turnkey/http/dist/webauthn\";\nimport axios from \"axios\";\nimport type { SignTypedDataParams, SmartAccountSigner } from \"@alchemy/aa-core\";\nimport {\n abortController,\n base64UrlEncode,\n generateRandomBuffer,\n signMessage,\n signTypedData,\n} from \"./utils.js\";\nimport { API_URL } from \"../../constants.js\";\n\nexport async function getAutocompletePasskeyOwner({\n projectId,\n apiUrl = API_URL,\n}: {\n projectId: string;\n name?: string;\n apiUrl?: string;\n}): Promise<SmartAccountSigner | undefined> {\n //@ts-ignore\n if (!PublicKeyCredential?.isConditionalMediationAvailable ||\n //@ts-ignore\n !PublicKeyCredential?.isConditionalMediationAvailable()) {\n return;\n }\n\n //@ts-expect-error\n if (typeof window !== \"undefined\") {\n const challenge = generateRandomBuffer();\n try {\n const assertion = JSON.parse(\n await getWebAuthnAssertion(base64UrlEncode(challenge), {\n mediation: 'conditional',\n publicKey: {\n //@ts-expect-error\n rpId: window.location.hostname,\n userVerification: \"required\",\n },\n signal: abortController.controller.signal\n })\n );\n const response = await axios.post(\n `${apiUrl}/projects/${projectId}/wallets/${assertion.credentialId}`,\n {\n challenge: base64UrlEncode(challenge),\n assertion,\n }\n );\n const { id, walletId, address } = await response.data;\n const owner: SmartAccountSigner = {\n getAddress: async () => address,\n signMessage: (msg) =>\n signMessage(\n msg,\n id,\n walletId,\n projectId,\n assertion.credentialId,\n apiUrl\n ),\n signTypedData: (params: SignTypedDataParams) =>\n signTypedData(\n params,\n id,\n walletId,\n projectId,\n assertion.credentialId,\n apiUrl\n ),\n };\n return owner;\n } catch (e) {\n console.log(e);\n }\n }\n return;\n}\n"]}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { SmartAccountSigner } from "@alchemy/aa-core";
|
|
2
|
-
export declare function getPasskeyOwner({ projectId, apiUrl, }: {
|
|
2
|
+
export declare function getPasskeyOwner({ projectId, name, apiUrl, withCredentials }: {
|
|
3
3
|
projectId: string;
|
|
4
|
+
name?: string;
|
|
4
5
|
apiUrl?: string;
|
|
6
|
+
withCredentials?: boolean;
|
|
5
7
|
}): Promise<SmartAccountSigner | undefined>;
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import { getWebAuthnAssertion } from "@turnkey/http/dist/webauthn";
|
|
2
2
|
import axios from "axios";
|
|
3
|
-
import { base64UrlEncode, generateRandomBuffer, signMessage, signTypedData, } from "./utils.js";
|
|
3
|
+
import { abortController, base64UrlEncode, generateRandomBuffer, getCredentials, signMessage, signTypedData, } from "./utils.js";
|
|
4
4
|
import { API_URL } from "../../constants.js";
|
|
5
|
-
export async function getPasskeyOwner({ projectId, apiUrl = API_URL, }) {
|
|
5
|
+
export async function getPasskeyOwner({ projectId, name, apiUrl = API_URL, withCredentials = false }) {
|
|
6
6
|
if (typeof window !== "undefined") {
|
|
7
7
|
const challenge = generateRandomBuffer();
|
|
8
8
|
try {
|
|
9
|
+
abortController.controller.abort();
|
|
10
|
+
abortController.controller = new AbortController();
|
|
9
11
|
const assertion = JSON.parse(await getWebAuthnAssertion(base64UrlEncode(challenge), {
|
|
10
12
|
publicKey: {
|
|
11
13
|
rpId: window.location.hostname,
|
|
12
14
|
userVerification: "required",
|
|
15
|
+
allowCredentials: withCredentials ? await getCredentials(projectId, name) : undefined,
|
|
13
16
|
},
|
|
14
17
|
}));
|
|
15
18
|
const response = await axios.post(`${apiUrl}/projects/${projectId}/wallets/${assertion.credentialId}`, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPasskeyOwner.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/getPasskeyOwner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,eAAe,EACf,oBAAoB,EACpB,WAAW,EACX,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EACpC,SAAS,EACT,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"getPasskeyOwner.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/getPasskeyOwner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,WAAW,EACX,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EACpC,SAAS,EACT,IAAI,EACJ,MAAM,GAAG,OAAO,EAChB,eAAe,GAAG,KAAK,EAMxB;IAEC,IAAI,OAAO,MAAM,KAAK,WAAW,EAAE;QACjC,MAAM,SAAS,GAAG,oBAAoB,EAAE,CAAC;QACzC,IAAI;YACF,eAAe,CAAC,UAAU,CAAC,KAAK,EAAE,CAAA;YAClC,eAAe,CAAC,UAAU,GAAG,IAAI,eAAe,EAAE,CAAA;YAClD,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAC1B,MAAM,oBAAoB,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE;gBACrD,SAAS,EAAE;oBAET,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ;oBAC9B,gBAAgB,EAAE,UAAU;oBAC5B,gBAAgB,EAAE,eAAe,CAAC,CAAC,CAAC,MAAM,cAAc,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;iBACtF;aACF,CAAC,CACH,CAAC;YACF,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,IAAI,CAC/B,GAAG,MAAM,aAAa,SAAS,YAAY,SAAS,CAAC,YAAY,EAAE,EACnE;gBACE,SAAS,EAAE,eAAe,CAAC,SAAS,CAAC;gBACrC,SAAS;aACV,CACF,CAAC;YACF,MAAM,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC;YACtD,MAAM,KAAK,GAAuB;gBAChC,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO;gBAC/B,WAAW,EAAE,CAAC,GAAG,EAAE,EAAE,CACnB,WAAW,CACT,GAAG,EACH,EAAE,EACF,QAAQ,EACR,SAAS,EACT,SAAS,CAAC,YAAY,EACtB,MAAM,CACP;gBACH,aAAa,EAAE,CAAC,MAA2B,EAAE,EAAE,CAC7C,aAAa,CACX,MAAM,EACN,EAAE,EACF,QAAQ,EACR,SAAS,EACT,SAAS,CAAC,YAAY,EACtB,MAAM,CACP;aACJ,CAAC;YACF,OAAO,KAAK,CAAC;SACd;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SAChB;KACF;IACD,OAAO;AACT,CAAC","sourcesContent":["import { getWebAuthnAssertion } from \"@turnkey/http/dist/webauthn\";\nimport axios from \"axios\";\nimport type { SignTypedDataParams, SmartAccountSigner } from \"@alchemy/aa-core\";\nimport {\n abortController,\n base64UrlEncode,\n generateRandomBuffer,\n getCredentials,\n signMessage,\n signTypedData,\n} from \"./utils.js\";\nimport { API_URL } from \"../../constants.js\";\n\nexport async function getPasskeyOwner({\n projectId,\n name,\n apiUrl = API_URL,\n withCredentials = false\n}: {\n projectId: string;\n name?: string;\n apiUrl?: string;\n withCredentials?: boolean;\n}): Promise<SmartAccountSigner | undefined> {\n //@ts-expect-error\n if (typeof window !== \"undefined\") {\n const challenge = generateRandomBuffer();\n try {\n abortController.controller.abort()\n abortController.controller = new AbortController()\n const assertion = JSON.parse(\n await getWebAuthnAssertion(base64UrlEncode(challenge), {\n publicKey: {\n //@ts-expect-error\n rpId: window.location.hostname,\n userVerification: \"required\",\n allowCredentials: withCredentials ? await getCredentials(projectId, name) : undefined,\n },\n })\n );\n const response = await axios.post(\n `${apiUrl}/projects/${projectId}/wallets/${assertion.credentialId}`,\n {\n challenge: base64UrlEncode(challenge),\n assertion,\n }\n );\n const { id, walletId, address } = await response.data;\n const owner: SmartAccountSigner = {\n getAddress: async () => address,\n signMessage: (msg) =>\n signMessage(\n msg,\n id,\n walletId,\n projectId,\n assertion.credentialId,\n apiUrl\n ),\n signTypedData: (params: SignTypedDataParams) =>\n signTypedData(\n params,\n id,\n walletId,\n projectId,\n assertion.credentialId,\n apiUrl\n ),\n };\n return owner;\n } catch (e) {\n console.log(e);\n }\n }\n return;\n}\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { getPasskeyOwner } from "./getPasskeyOwner.js";
|
|
2
2
|
export { createPasskeyOwner } from "./createPasskeyOwner.js";
|
|
3
|
-
export {
|
|
3
|
+
export { getAutocompletePasskeyOwner } from "./getAutocompletePasskeyOwner.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { getPasskeyOwner } from "./getPasskeyOwner.js";
|
|
2
2
|
export { createPasskeyOwner } from "./createPasskeyOwner.js";
|
|
3
|
-
export {
|
|
3
|
+
export { getAutocompletePasskeyOwner } from "./getAutocompletePasskeyOwner.js";
|
|
4
4
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC","sourcesContent":["export { getPasskeyOwner } from \"./getPasskeyOwner.js\";\nexport { createPasskeyOwner } from \"./createPasskeyOwner.js\";\nexport { getAutocompletePasskeyOwner } from \"./getAutocompletePasskeyOwner.js\";\n"]}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import type { SignTypedDataParams } from "@alchemy/aa-core";
|
|
3
|
+
export declare const abortController: {
|
|
4
|
+
controller: AbortController;
|
|
5
|
+
};
|
|
2
6
|
export declare const publicKey = "public-key";
|
|
3
7
|
export declare const es256 = -7;
|
|
4
8
|
export declare const generateRandomBuffer: () => ArrayBuffer;
|
|
@@ -6,4 +10,5 @@ export declare const base64UrlEncode: (challenge: ArrayBuffer) => string;
|
|
|
6
10
|
export declare const signMessageImplementation: (msg: string, id: string, walletId: string, projectId: string, credentialId: string, apiUrl?: string) => Promise<`0x${string}`>;
|
|
7
11
|
export declare const signMessage: (msg: string | Uint8Array, id: string, walletId: string, projectId: string, credentialId: string, apiUrl?: string) => Promise<`0x${string}`>;
|
|
8
12
|
export declare const signTypedData: (params: SignTypedDataParams, id: string, walletId: string, projectId: string, credentialId: string, apiUrl?: string) => Promise<`0x${string}`>;
|
|
13
|
+
export declare const getCredentials: (projectId: string, name?: string, apiUrl?: string) => Promise<any>;
|
|
9
14
|
export declare function base64URLStringToBuffer(base64URLString: string): ArrayBuffer;
|
|
@@ -5,6 +5,9 @@ import { hashTypedData, signatureToHex, hashMessage } from "viem";
|
|
|
5
5
|
browserInit({
|
|
6
6
|
baseUrl: "https://api.turnkey.com",
|
|
7
7
|
});
|
|
8
|
+
export const abortController = {
|
|
9
|
+
controller: new AbortController(),
|
|
10
|
+
};
|
|
8
11
|
export const publicKey = "public-key";
|
|
9
12
|
export const es256 = -7;
|
|
10
13
|
export const generateRandomBuffer = () => {
|
|
@@ -69,6 +72,15 @@ export const signTypedData = async (params, id, walletId, projectId, credentialI
|
|
|
69
72
|
const hashToSign = hashTypedData(params);
|
|
70
73
|
return await signMessageImplementation(hashToSign, id, walletId, projectId, credentialId, apiUrl);
|
|
71
74
|
};
|
|
75
|
+
export const getCredentials = async (projectId, name, apiUrl = API_URL) => {
|
|
76
|
+
const url = `${apiUrl}/projects/${projectId}/wallets` + (name ? `/${name}` : '');
|
|
77
|
+
const response = await axios.get(url);
|
|
78
|
+
const credentials = response.data;
|
|
79
|
+
return credentials.map((credential) => ({
|
|
80
|
+
id: base64URLStringToBuffer(credential),
|
|
81
|
+
type: "public-key",
|
|
82
|
+
}));
|
|
83
|
+
};
|
|
72
84
|
export function base64URLStringToBuffer(base64URLString) {
|
|
73
85
|
const base64 = base64URLString.replace(/-/g, "+").replace(/_/g, "/");
|
|
74
86
|
const padLength = (4 - (base64.length % 4)) % 4;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { browserInit, TurnkeyApi } from \"@turnkey/http\";\nimport axios from \"axios\";\nimport { API_URL } from \"../../constants.js\";\nimport type { SignTypedDataParams } from \"@alchemy/aa-core\";\nimport { hashTypedData, signatureToHex, hashMessage } from \"viem\";\n\nbrowserInit({\n baseUrl: \"https://api.turnkey.com\",\n});\n\nexport const publicKey = \"public-key\";\n\nexport const es256 = -7;\n\nexport const generateRandomBuffer = (): ArrayBuffer => {\n const arr = new Uint8Array(32);\n //@ts-expect-error\n crypto.getRandomValues(arr);\n return arr.buffer;\n};\n\nexport const base64UrlEncode = (challenge: ArrayBuffer): string => {\n return Buffer.from(challenge)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\");\n};\n\nexport const signMessageImplementation = async (\n msg: string,\n id: string,\n walletId: string,\n projectId: string,\n credentialId: string,\n apiUrl = API_URL\n) => {\n console.log(\"SIGN MESSAGE IMPLEMENTATION\");\n const signedRequest = await TurnkeyApi.signSignRawPayload(\n {\n body: {\n type: \"ACTIVITY_TYPE_SIGN_RAW_PAYLOAD\",\n organizationId: id,\n parameters: {\n privateKeyId: walletId,\n payload: msg,\n encoding: \"PAYLOAD_ENCODING_HEXADECIMAL\",\n hashFunction: \"HASH_FUNCTION_NO_OP\",\n },\n timestampMs: String(Date.now()),\n },\n },\n {\n publicKey: {\n allowCredentials: [\n {\n id: base64URLStringToBuffer(credentialId),\n type: publicKey,\n },\n ],\n },\n }\n );\n const proxyResponse = await axios.post(\n `${apiUrl}/projects/${projectId}/wallets/proxy`,\n {\n signedRequest,\n }\n );\n const { activity } = await proxyResponse.data;\n if (activity.status === \"ACTIVITY_STATUS_COMPLETED\") {\n let result = activity?.result?.signRawPayloadResult;\n\n if (result) {\n const signatureHex = signatureToHex({\n r: `0x${result.r}`,\n s: `0x${result.s}`,\n v: result.v === \"00\" ? 27n : 28n,\n });\n if (signatureHex) {\n return signatureHex;\n }\n }\n }\n return \"0x\";\n};\n\nexport const signMessage = async (\n msg: string | Uint8Array,\n id: string,\n walletId: string,\n projectId: string,\n credentialId: string,\n apiUrl = API_URL\n) => {\n return await signMessageImplementation(\n hashMessage(typeof msg === \"string\" ? msg : { raw: msg }),\n id,\n walletId,\n projectId,\n credentialId,\n apiUrl\n );\n};\n\nexport const signTypedData = async (\n params: SignTypedDataParams,\n id: string,\n walletId: string,\n projectId: string,\n credentialId: string,\n apiUrl = API_URL\n) => {\n const hashToSign = hashTypedData(params);\n return await signMessageImplementation(\n hashToSign,\n id,\n walletId,\n projectId,\n credentialId,\n apiUrl\n );\n};\n\n// https://github.com/MasterKale/SimpleWebAuthn/blob/master/packages/browser/src/helpers/base64URLStringToBuffer.ts#L8\nexport function base64URLStringToBuffer(base64URLString: string): ArrayBuffer {\n // Convert from Base64URL to Base64\n const base64 = base64URLString.replace(/-/g, \"+\").replace(/_/g, \"/\");\n /**\n * Pad with '=' until it's a multiple of four\n * (4 - (85 % 4 = 1) = 3) % 4 = 3 padding\n * (4 - (86 % 4 = 2) = 2) % 4 = 2 padding\n * (4 - (87 % 4 = 3) = 1) % 4 = 1 padding\n * (4 - (88 % 4 = 0) = 4) % 4 = 0 padding\n */\n const padLength = (4 - (base64.length % 4)) % 4;\n const padded = base64.padEnd(base64.length + padLength, \"=\");\n\n // Convert to a binary string\n const binary = atob(padded);\n\n // Convert binary string to buffer\n const buffer = new ArrayBuffer(binary.length);\n const bytes = new Uint8Array(buffer);\n\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n\n return buffer;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { browserInit, TurnkeyApi } from \"@turnkey/http\";\nimport axios from \"axios\";\nimport { API_URL } from \"../../constants.js\";\nimport type { SignTypedDataParams } from \"@alchemy/aa-core\";\nimport { hashTypedData, signatureToHex, hashMessage } from \"viem\";\n\nbrowserInit({\n baseUrl: \"https://api.turnkey.com\",\n});\n\nexport const abortController = {\n controller: new AbortController(),\n}\n\nexport const publicKey = \"public-key\";\n\nexport const es256 = -7;\n\nexport const generateRandomBuffer = (): ArrayBuffer => {\n const arr = new Uint8Array(32);\n //@ts-expect-error\n crypto.getRandomValues(arr);\n return arr.buffer;\n};\n\nexport const base64UrlEncode = (challenge: ArrayBuffer): string => {\n return Buffer.from(challenge)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=/g, \"\");\n};\n\nexport const signMessageImplementation = async (\n msg: string,\n id: string,\n walletId: string,\n projectId: string,\n credentialId: string,\n apiUrl = API_URL\n) => {\n console.log(\"SIGN MESSAGE IMPLEMENTATION\");\n const signedRequest = await TurnkeyApi.signSignRawPayload(\n {\n body: {\n type: \"ACTIVITY_TYPE_SIGN_RAW_PAYLOAD\",\n organizationId: id,\n parameters: {\n privateKeyId: walletId,\n payload: msg,\n encoding: \"PAYLOAD_ENCODING_HEXADECIMAL\",\n hashFunction: \"HASH_FUNCTION_NO_OP\",\n },\n timestampMs: String(Date.now()),\n },\n },\n {\n publicKey: {\n allowCredentials: [\n {\n id: base64URLStringToBuffer(credentialId),\n type: publicKey,\n },\n ],\n },\n }\n );\n const proxyResponse = await axios.post(\n `${apiUrl}/projects/${projectId}/wallets/proxy`,\n {\n signedRequest,\n }\n );\n const { activity } = await proxyResponse.data;\n if (activity.status === \"ACTIVITY_STATUS_COMPLETED\") {\n let result = activity?.result?.signRawPayloadResult;\n\n if (result) {\n const signatureHex = signatureToHex({\n r: `0x${result.r}`,\n s: `0x${result.s}`,\n v: result.v === \"00\" ? 27n : 28n,\n });\n if (signatureHex) {\n return signatureHex;\n }\n }\n }\n return \"0x\";\n};\n\nexport const signMessage = async (\n msg: string | Uint8Array,\n id: string,\n walletId: string,\n projectId: string,\n credentialId: string,\n apiUrl = API_URL\n) => {\n return await signMessageImplementation(\n hashMessage(typeof msg === \"string\" ? msg : { raw: msg }),\n id,\n walletId,\n projectId,\n credentialId,\n apiUrl\n );\n};\n\nexport const signTypedData = async (\n params: SignTypedDataParams,\n id: string,\n walletId: string,\n projectId: string,\n credentialId: string,\n apiUrl = API_URL\n) => {\n const hashToSign = hashTypedData(params);\n return await signMessageImplementation(\n hashToSign,\n id,\n walletId,\n projectId,\n credentialId,\n apiUrl\n );\n};\n\nexport const getCredentials = async (projectId: string, name?: string, apiUrl = API_URL) => {\n const url = `${apiUrl}/projects/${projectId}/wallets` + (name ? `/${name}` : '')\n const response = await axios.get(url);\n const credentials = response.data;\n return credentials.map((credential: string) => ({\n id: base64URLStringToBuffer(credential),\n type: \"public-key\",\n }));\n};\n\n// https://github.com/MasterKale/SimpleWebAuthn/blob/master/packages/browser/src/helpers/base64URLStringToBuffer.ts#L8\nexport function base64URLStringToBuffer(base64URLString: string): ArrayBuffer {\n // Convert from Base64URL to Base64\n const base64 = base64URLString.replace(/-/g, \"+\").replace(/_/g, \"/\");\n /**\n * Pad with '=' until it's a multiple of four\n * (4 - (85 % 4 = 1) = 3) % 4 = 3 padding\n * (4 - (86 % 4 = 2) = 2) % 4 = 2 padding\n * (4 - (87 % 4 = 3) = 1) % 4 = 1 padding\n * (4 - (88 % 4 = 0) = 4) % 4 = 0 padding\n */\n const padLength = (4 - (base64.length % 4)) % 4;\n const padded = base64.padEnd(base64.length + padLength, \"=\");\n\n // Convert to a binary string\n const binary = atob(padded);\n\n // Convert binary string to buffer\n const buffer = new ArrayBuffer(binary.length);\n const bytes = new Uint8Array(buffer);\n\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n\n return buffer;\n}\n"]}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { SmartAccountSigner } from "@alchemy/aa-core";
|
|
2
|
-
export declare function createPasskeyOwner({ name, projectId, fallback, apiUrl, }: {
|
|
2
|
+
export declare function createPasskeyOwner({ name, projectId, withCredentials, fallback, apiUrl, }: {
|
|
3
3
|
name: string;
|
|
4
4
|
projectId: string;
|
|
5
|
+
withCredentials?: boolean;
|
|
5
6
|
fallback?: () => Promise<SmartAccountSigner | undefined>;
|
|
6
7
|
apiUrl?: string;
|
|
7
8
|
}): Promise<SmartAccountSigner | undefined>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createPasskeyOwner.d.ts","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/createPasskeyOwner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAuB,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"createPasskeyOwner.d.ts","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/createPasskeyOwner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAuB,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAchF,wBAAsB,kBAAkB,CAAC,EACvC,IAAI,EACJ,SAAS,EACT,eAAuB,EACvB,QAAQ,EACR,MAAgB,GACjB,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAAC;IACzD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAmF1C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exceptions.d.ts","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/exceptions.ts"],"names":[],"mappings":"AAAA,qBAAa,qBAAsB,SAAQ,KAAK;IAC5C,OAAO,EAAE,MAAM,CAA8B;CAChD"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { SmartAccountSigner } from "@alchemy/aa-core";
|
|
2
|
+
export declare function getAutocompletePasskeyOwner({ projectId, apiUrl, }: {
|
|
3
|
+
projectId: string;
|
|
4
|
+
name?: string;
|
|
5
|
+
apiUrl?: string;
|
|
6
|
+
}): Promise<SmartAccountSigner | undefined>;
|
|
7
|
+
//# sourceMappingURL=getAutocompletePasskeyOwner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getAutocompletePasskeyOwner.d.ts","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/getAutocompletePasskeyOwner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAuB,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAUhF,wBAAsB,2BAA2B,CAAC,EAChD,SAAS,EACT,MAAgB,GACjB,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CA0D1C"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { SmartAccountSigner } from "@alchemy/aa-core";
|
|
2
|
-
export declare function getPasskeyOwner({ projectId, apiUrl, }: {
|
|
2
|
+
export declare function getPasskeyOwner({ projectId, name, apiUrl, withCredentials }: {
|
|
3
3
|
projectId: string;
|
|
4
|
+
name?: string;
|
|
4
5
|
apiUrl?: string;
|
|
6
|
+
withCredentials?: boolean;
|
|
5
7
|
}): Promise<SmartAccountSigner | undefined>;
|
|
6
8
|
//# sourceMappingURL=getPasskeyOwner.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getPasskeyOwner.d.ts","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/getPasskeyOwner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAuB,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"getPasskeyOwner.d.ts","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/getPasskeyOwner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAuB,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAWhF,wBAAsB,eAAe,CAAC,EACpC,SAAS,EACT,IAAI,EACJ,MAAgB,EAChB,eAAuB,EACxB,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAoD1C"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { getPasskeyOwner } from "./getPasskeyOwner.js";
|
|
2
2
|
export { createPasskeyOwner } from "./createPasskeyOwner.js";
|
|
3
|
-
export {
|
|
3
|
+
export { getAutocompletePasskeyOwner } from "./getAutocompletePasskeyOwner.js";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC"}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import type { SignTypedDataParams } from "@alchemy/aa-core";
|
|
3
|
+
export declare const abortController: {
|
|
4
|
+
controller: AbortController;
|
|
5
|
+
};
|
|
2
6
|
export declare const publicKey = "public-key";
|
|
3
7
|
export declare const es256 = -7;
|
|
4
8
|
export declare const generateRandomBuffer: () => ArrayBuffer;
|
|
@@ -6,5 +10,6 @@ export declare const base64UrlEncode: (challenge: ArrayBuffer) => string;
|
|
|
6
10
|
export declare const signMessageImplementation: (msg: string, id: string, walletId: string, projectId: string, credentialId: string, apiUrl?: string) => Promise<`0x${string}`>;
|
|
7
11
|
export declare const signMessage: (msg: string | Uint8Array, id: string, walletId: string, projectId: string, credentialId: string, apiUrl?: string) => Promise<`0x${string}`>;
|
|
8
12
|
export declare const signTypedData: (params: SignTypedDataParams, id: string, walletId: string, projectId: string, credentialId: string, apiUrl?: string) => Promise<`0x${string}`>;
|
|
13
|
+
export declare const getCredentials: (projectId: string, name?: string, apiUrl?: string) => Promise<any>;
|
|
9
14
|
export declare function base64URLStringToBuffer(base64URLString: string): ArrayBuffer;
|
|
10
15
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/utils.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAO5D,eAAO,MAAM,SAAS,eAAe,CAAC;AAEtC,eAAO,MAAM,KAAK,KAAK,CAAC;AAExB,eAAO,MAAM,oBAAoB,QAAO,WAKvC,CAAC;AAEF,eAAO,MAAM,eAAe,cAAe,WAAW,KAAG,MAMxD,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAC/B,MAAM,MACP,MAAM,YACA,MAAM,aACL,MAAM,gBACH,MAAM,4CAmDrB,CAAC;AAEF,eAAO,MAAM,WAAW,QACjB,MAAM,GAAG,UAAU,MACpB,MAAM,YACA,MAAM,aACL,MAAM,gBACH,MAAM,4CAWrB,CAAC;AAEF,eAAO,MAAM,aAAa,WAChB,mBAAmB,MACvB,MAAM,YACA,MAAM,aACL,MAAM,gBACH,MAAM,4CAYrB,CAAC;AAGF,wBAAgB,uBAAuB,CAAC,eAAe,EAAE,MAAM,GAAG,WAAW,CAyB5E"}
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/utils.ts"],"names":[],"mappings":";AAGA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAO5D,eAAO,MAAM,eAAe;;CAE3B,CAAA;AAED,eAAO,MAAM,SAAS,eAAe,CAAC;AAEtC,eAAO,MAAM,KAAK,KAAK,CAAC;AAExB,eAAO,MAAM,oBAAoB,QAAO,WAKvC,CAAC;AAEF,eAAO,MAAM,eAAe,cAAe,WAAW,KAAG,MAMxD,CAAC;AAEF,eAAO,MAAM,yBAAyB,QAC/B,MAAM,MACP,MAAM,YACA,MAAM,aACL,MAAM,gBACH,MAAM,4CAmDrB,CAAC;AAEF,eAAO,MAAM,WAAW,QACjB,MAAM,GAAG,UAAU,MACpB,MAAM,YACA,MAAM,aACL,MAAM,gBACH,MAAM,4CAWrB,CAAC;AAEF,eAAO,MAAM,aAAa,WAChB,mBAAmB,MACvB,MAAM,YACA,MAAM,aACL,MAAM,gBACH,MAAM,4CAYrB,CAAC;AAEF,eAAO,MAAM,cAAc,cAAqB,MAAM,SAAS,MAAM,kCAQpE,CAAC;AAGF,wBAAgB,uBAAuB,CAAC,eAAe,EAAE,MAAM,GAAG,WAAW,CAyB5E"}
|
package/package.json
CHANGED
|
@@ -2,31 +2,45 @@ import { getWebAuthnAttestation } from "@turnkey/http";
|
|
|
2
2
|
import axios from "axios";
|
|
3
3
|
import type { SignTypedDataParams, SmartAccountSigner } from "@alchemy/aa-core";
|
|
4
4
|
import {
|
|
5
|
+
abortController,
|
|
5
6
|
base64UrlEncode,
|
|
6
7
|
es256,
|
|
7
8
|
generateRandomBuffer,
|
|
9
|
+
getCredentials,
|
|
8
10
|
publicKey,
|
|
9
11
|
signMessage,
|
|
10
12
|
signTypedData,
|
|
11
13
|
} from "./utils.js";
|
|
12
14
|
import { API_URL } from "../../constants.js";
|
|
15
|
+
import { UsernameIsAlreadyUsed } from "./exceptions.js";
|
|
13
16
|
|
|
14
17
|
export async function createPasskeyOwner({
|
|
15
18
|
name,
|
|
16
19
|
projectId,
|
|
20
|
+
withCredentials = false,
|
|
17
21
|
fallback,
|
|
18
22
|
apiUrl = API_URL,
|
|
19
23
|
}: {
|
|
20
24
|
name: string;
|
|
21
25
|
projectId: string;
|
|
26
|
+
withCredentials?: boolean;
|
|
22
27
|
fallback?: () => Promise<SmartAccountSigner | undefined>;
|
|
23
28
|
apiUrl?: string;
|
|
24
29
|
}): Promise<SmartAccountSigner | undefined> {
|
|
25
30
|
//@ts-expect-error
|
|
26
31
|
if (typeof window !== "undefined") {
|
|
27
32
|
const challenge = generateRandomBuffer();
|
|
28
|
-
|
|
33
|
+
let credentials = undefined
|
|
34
|
+
if (withCredentials) {
|
|
35
|
+
credentials = await getCredentials(projectId, name)
|
|
36
|
+
}
|
|
37
|
+
if (credentials.length >= 64) {
|
|
38
|
+
throw new UsernameIsAlreadyUsed()
|
|
39
|
+
}
|
|
40
|
+
|
|
29
41
|
try {
|
|
42
|
+
abortController.controller.abort()
|
|
43
|
+
abortController.controller = new AbortController()
|
|
30
44
|
const attestation = await getWebAuthnAttestation({
|
|
31
45
|
publicKey: {
|
|
32
46
|
rp: {
|
|
@@ -39,7 +53,7 @@ export async function createPasskeyOwner({
|
|
|
39
53
|
residentKey: "required", // or 'preferred', 'discouraged'
|
|
40
54
|
userVerification: "required",
|
|
41
55
|
},
|
|
42
|
-
|
|
56
|
+
excludeCredentials: credentials,
|
|
43
57
|
extensions: { credProps: true },
|
|
44
58
|
challenge,
|
|
45
59
|
pubKeyCredParams: [
|
|
@@ -49,7 +63,7 @@ export async function createPasskeyOwner({
|
|
|
49
63
|
},
|
|
50
64
|
],
|
|
51
65
|
user: {
|
|
52
|
-
id:
|
|
66
|
+
id: Uint8Array.from(name, (c) => c.charCodeAt(0)),
|
|
53
67
|
name,
|
|
54
68
|
displayName: name,
|
|
55
69
|
},
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { getWebAuthnAssertion } from "@turnkey/http/dist/webauthn";
|
|
2
|
+
import axios from "axios";
|
|
3
|
+
import type { SignTypedDataParams, SmartAccountSigner } from "@alchemy/aa-core";
|
|
4
|
+
import {
|
|
5
|
+
abortController,
|
|
6
|
+
base64UrlEncode,
|
|
7
|
+
generateRandomBuffer,
|
|
8
|
+
signMessage,
|
|
9
|
+
signTypedData,
|
|
10
|
+
} from "./utils.js";
|
|
11
|
+
import { API_URL } from "../../constants.js";
|
|
12
|
+
|
|
13
|
+
export async function getAutocompletePasskeyOwner({
|
|
14
|
+
projectId,
|
|
15
|
+
apiUrl = API_URL,
|
|
16
|
+
}: {
|
|
17
|
+
projectId: string;
|
|
18
|
+
name?: string;
|
|
19
|
+
apiUrl?: string;
|
|
20
|
+
}): Promise<SmartAccountSigner | undefined> {
|
|
21
|
+
//@ts-ignore
|
|
22
|
+
if (!PublicKeyCredential?.isConditionalMediationAvailable ||
|
|
23
|
+
//@ts-ignore
|
|
24
|
+
!PublicKeyCredential?.isConditionalMediationAvailable()) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
//@ts-expect-error
|
|
29
|
+
if (typeof window !== "undefined") {
|
|
30
|
+
const challenge = generateRandomBuffer();
|
|
31
|
+
try {
|
|
32
|
+
const assertion = JSON.parse(
|
|
33
|
+
await getWebAuthnAssertion(base64UrlEncode(challenge), {
|
|
34
|
+
mediation: 'conditional',
|
|
35
|
+
publicKey: {
|
|
36
|
+
//@ts-expect-error
|
|
37
|
+
rpId: window.location.hostname,
|
|
38
|
+
userVerification: "required",
|
|
39
|
+
},
|
|
40
|
+
signal: abortController.controller.signal
|
|
41
|
+
})
|
|
42
|
+
);
|
|
43
|
+
const response = await axios.post(
|
|
44
|
+
`${apiUrl}/projects/${projectId}/wallets/${assertion.credentialId}`,
|
|
45
|
+
{
|
|
46
|
+
challenge: base64UrlEncode(challenge),
|
|
47
|
+
assertion,
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
const { id, walletId, address } = await response.data;
|
|
51
|
+
const owner: SmartAccountSigner = {
|
|
52
|
+
getAddress: async () => address,
|
|
53
|
+
signMessage: (msg) =>
|
|
54
|
+
signMessage(
|
|
55
|
+
msg,
|
|
56
|
+
id,
|
|
57
|
+
walletId,
|
|
58
|
+
projectId,
|
|
59
|
+
assertion.credentialId,
|
|
60
|
+
apiUrl
|
|
61
|
+
),
|
|
62
|
+
signTypedData: (params: SignTypedDataParams) =>
|
|
63
|
+
signTypedData(
|
|
64
|
+
params,
|
|
65
|
+
id,
|
|
66
|
+
walletId,
|
|
67
|
+
projectId,
|
|
68
|
+
assertion.credentialId,
|
|
69
|
+
apiUrl
|
|
70
|
+
),
|
|
71
|
+
};
|
|
72
|
+
return owner;
|
|
73
|
+
} catch (e) {
|
|
74
|
+
console.log(e);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
@@ -2,8 +2,10 @@ import { getWebAuthnAssertion } from "@turnkey/http/dist/webauthn";
|
|
|
2
2
|
import axios from "axios";
|
|
3
3
|
import type { SignTypedDataParams, SmartAccountSigner } from "@alchemy/aa-core";
|
|
4
4
|
import {
|
|
5
|
+
abortController,
|
|
5
6
|
base64UrlEncode,
|
|
6
7
|
generateRandomBuffer,
|
|
8
|
+
getCredentials,
|
|
7
9
|
signMessage,
|
|
8
10
|
signTypedData,
|
|
9
11
|
} from "./utils.js";
|
|
@@ -11,22 +13,28 @@ import { API_URL } from "../../constants.js";
|
|
|
11
13
|
|
|
12
14
|
export async function getPasskeyOwner({
|
|
13
15
|
projectId,
|
|
16
|
+
name,
|
|
14
17
|
apiUrl = API_URL,
|
|
18
|
+
withCredentials = false
|
|
15
19
|
}: {
|
|
16
20
|
projectId: string;
|
|
21
|
+
name?: string;
|
|
17
22
|
apiUrl?: string;
|
|
23
|
+
withCredentials?: boolean;
|
|
18
24
|
}): Promise<SmartAccountSigner | undefined> {
|
|
19
25
|
//@ts-expect-error
|
|
20
26
|
if (typeof window !== "undefined") {
|
|
21
27
|
const challenge = generateRandomBuffer();
|
|
22
28
|
try {
|
|
29
|
+
abortController.controller.abort()
|
|
30
|
+
abortController.controller = new AbortController()
|
|
23
31
|
const assertion = JSON.parse(
|
|
24
32
|
await getWebAuthnAssertion(base64UrlEncode(challenge), {
|
|
25
33
|
publicKey: {
|
|
26
34
|
//@ts-expect-error
|
|
27
35
|
rpId: window.location.hostname,
|
|
28
36
|
userVerification: "required",
|
|
29
|
-
|
|
37
|
+
allowCredentials: withCredentials ? await getCredentials(projectId, name) : undefined,
|
|
30
38
|
},
|
|
31
39
|
})
|
|
32
40
|
);
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { getPasskeyOwner } from "./getPasskeyOwner.js";
|
|
2
2
|
export { createPasskeyOwner } from "./createPasskeyOwner.js";
|
|
3
|
-
export {
|
|
3
|
+
export { getAutocompletePasskeyOwner } from "./getAutocompletePasskeyOwner.js";
|
|
@@ -8,6 +8,10 @@ browserInit({
|
|
|
8
8
|
baseUrl: "https://api.turnkey.com",
|
|
9
9
|
});
|
|
10
10
|
|
|
11
|
+
export const abortController = {
|
|
12
|
+
controller: new AbortController(),
|
|
13
|
+
}
|
|
14
|
+
|
|
11
15
|
export const publicKey = "public-key";
|
|
12
16
|
|
|
13
17
|
export const es256 = -7;
|
|
@@ -122,6 +126,16 @@ export const signTypedData = async (
|
|
|
122
126
|
);
|
|
123
127
|
};
|
|
124
128
|
|
|
129
|
+
export const getCredentials = async (projectId: string, name?: string, apiUrl = API_URL) => {
|
|
130
|
+
const url = `${apiUrl}/projects/${projectId}/wallets` + (name ? `/${name}` : '')
|
|
131
|
+
const response = await axios.get(url);
|
|
132
|
+
const credentials = response.data;
|
|
133
|
+
return credentials.map((credential: string) => ({
|
|
134
|
+
id: base64URLStringToBuffer(credential),
|
|
135
|
+
type: "public-key",
|
|
136
|
+
}));
|
|
137
|
+
};
|
|
138
|
+
|
|
125
139
|
// https://github.com/MasterKale/SimpleWebAuthn/blob/master/packages/browser/src/helpers/base64URLStringToBuffer.ts#L8
|
|
126
140
|
export function base64URLStringToBuffer(base64URLString: string): ArrayBuffer {
|
|
127
141
|
// Convert from Base64URL to Base64
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getOrCreatePasskeyOwner = void 0;
|
|
4
|
-
const constants_js_1 = require("../../constants.js");
|
|
5
|
-
const createPasskeyOwner_js_1 = require("./createPasskeyOwner.js");
|
|
6
|
-
const getPasskeyOwner_js_1 = require("./getPasskeyOwner.js");
|
|
7
|
-
async function getOrCreatePasskeyOwner({ name, projectId, apiUrl = constants_js_1.API_URL, }) {
|
|
8
|
-
return await (0, createPasskeyOwner_js_1.createPasskeyOwner)({
|
|
9
|
-
name,
|
|
10
|
-
projectId,
|
|
11
|
-
apiUrl,
|
|
12
|
-
fallback: () => (0, getPasskeyOwner_js_1.getPasskeyOwner)({ projectId, apiUrl }),
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
exports.getOrCreatePasskeyOwner = getOrCreatePasskeyOwner;
|
|
16
|
-
//# sourceMappingURL=getOrCreatePasskeyOwner.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getOrCreatePasskeyOwner.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/getOrCreatePasskeyOwner.ts"],"names":[],"mappings":";;;AACA,qDAA6C;AAE7C,mEAA6D;AAC7D,6DAAuD;AAEhD,KAAK,UAAU,uBAAuB,CAAC,EAC5C,IAAI,EACJ,SAAS,EACT,MAAM,GAAG,sBAAO,GAKjB;IACC,OAAO,MAAM,IAAA,0CAAkB,EAAC;QAC9B,IAAI;QACJ,SAAS;QACT,MAAM;QACN,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAA,oCAAe,EAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;KACvD,CAAC,CAAC;AACL,CAAC;AAfD,0DAeC","sourcesContent":["import type { SmartAccountSigner } from \"@alchemy/aa-core\";\nimport { API_URL } from \"../../constants.js\";\n// import { getPasskeyOwner } from \"./getPasskeyOwner.js\";\nimport { createPasskeyOwner } from \"./createPasskeyOwner.js\";\nimport { getPasskeyOwner } from \"./getPasskeyOwner.js\";\n\nexport async function getOrCreatePasskeyOwner({\n name,\n projectId,\n apiUrl = API_URL,\n}: {\n name: string;\n projectId: string;\n apiUrl?: string;\n}): Promise<SmartAccountSigner | undefined> {\n return await createPasskeyOwner({\n name,\n projectId,\n apiUrl,\n fallback: () => getPasskeyOwner({ projectId, apiUrl }),\n });\n}\n"]}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { API_URL } from "../../constants.js";
|
|
2
|
-
import { createPasskeyOwner } from "./createPasskeyOwner.js";
|
|
3
|
-
import { getPasskeyOwner } from "./getPasskeyOwner.js";
|
|
4
|
-
export async function getOrCreatePasskeyOwner({ name, projectId, apiUrl = API_URL, }) {
|
|
5
|
-
return await createPasskeyOwner({
|
|
6
|
-
name,
|
|
7
|
-
projectId,
|
|
8
|
-
apiUrl,
|
|
9
|
-
fallback: () => getPasskeyOwner({ projectId, apiUrl }),
|
|
10
|
-
});
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=getOrCreatePasskeyOwner.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getOrCreatePasskeyOwner.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/getOrCreatePasskeyOwner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,EAC5C,IAAI,EACJ,SAAS,EACT,MAAM,GAAG,OAAO,GAKjB;IACC,OAAO,MAAM,kBAAkB,CAAC;QAC9B,IAAI;QACJ,SAAS;QACT,MAAM;QACN,QAAQ,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;KACvD,CAAC,CAAC;AACL,CAAC","sourcesContent":["import type { SmartAccountSigner } from \"@alchemy/aa-core\";\nimport { API_URL } from \"../../constants.js\";\n// import { getPasskeyOwner } from \"./getPasskeyOwner.js\";\nimport { createPasskeyOwner } from \"./createPasskeyOwner.js\";\nimport { getPasskeyOwner } from \"./getPasskeyOwner.js\";\n\nexport async function getOrCreatePasskeyOwner({\n name,\n projectId,\n apiUrl = API_URL,\n}: {\n name: string;\n projectId: string;\n apiUrl?: string;\n}): Promise<SmartAccountSigner | undefined> {\n return await createPasskeyOwner({\n name,\n projectId,\n apiUrl,\n fallback: () => getPasskeyOwner({ projectId, apiUrl }),\n });\n}\n"]}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { SmartAccountSigner } from "@alchemy/aa-core";
|
|
2
|
-
export declare function getOrCreatePasskeyOwner({ name, projectId, apiUrl, }: {
|
|
3
|
-
name: string;
|
|
4
|
-
projectId: string;
|
|
5
|
-
apiUrl?: string;
|
|
6
|
-
}): Promise<SmartAccountSigner | undefined>;
|
|
7
|
-
//# sourceMappingURL=getOrCreatePasskeyOwner.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getOrCreatePasskeyOwner.d.ts","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/getOrCreatePasskeyOwner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAM3D,wBAAsB,uBAAuB,CAAC,EAC5C,IAAI,EACJ,SAAS,EACT,MAAgB,GACjB,EAAE;IACD,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAO1C"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { SmartAccountSigner } from "@alchemy/aa-core";
|
|
2
|
-
import { API_URL } from "../../constants.js";
|
|
3
|
-
// import { getPasskeyOwner } from "./getPasskeyOwner.js";
|
|
4
|
-
import { createPasskeyOwner } from "./createPasskeyOwner.js";
|
|
5
|
-
import { getPasskeyOwner } from "./getPasskeyOwner.js";
|
|
6
|
-
|
|
7
|
-
export async function getOrCreatePasskeyOwner({
|
|
8
|
-
name,
|
|
9
|
-
projectId,
|
|
10
|
-
apiUrl = API_URL,
|
|
11
|
-
}: {
|
|
12
|
-
name: string;
|
|
13
|
-
projectId: string;
|
|
14
|
-
apiUrl?: string;
|
|
15
|
-
}): Promise<SmartAccountSigner | undefined> {
|
|
16
|
-
return await createPasskeyOwner({
|
|
17
|
-
name,
|
|
18
|
-
projectId,
|
|
19
|
-
apiUrl,
|
|
20
|
-
fallback: () => getPasskeyOwner({ projectId, apiUrl }),
|
|
21
|
-
});
|
|
22
|
-
}
|