@zerodev/sdk 4.3.2 → 4.3.3

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.
@@ -1,11 +1,11 @@
1
1
  import type { SmartAccountSigner } from "@alchemy/aa-core";
2
- type GetCustodialOwnerParams = {
2
+ type GetCustodialOwnerParams = Readonly<{
3
3
  apiUrl?: string;
4
4
  turnKeyClient?: unknown;
5
5
  privateKey?: string;
6
6
  publicKey?: string;
7
7
  keyId?: string;
8
8
  custodialFilePath?: string;
9
- };
9
+ }>;
10
10
  export declare function getCustodialOwner(identifier: string, { custodialFilePath, privateKey, publicKey, keyId, apiUrl, turnKeyClient, }: GetCustodialOwnerParams): Promise<SmartAccountSigner | undefined>;
11
11
  export {};
@@ -1,4 +1,27 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
27
  };
@@ -6,62 +29,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
29
  exports.getCustodialOwner = void 0;
7
30
  const constants_js_1 = require("../constants.js");
8
31
  const axios_1 = __importDefault(require("axios"));
32
+ const radash_1 = require("radash");
9
33
  async function getCustodialOwner(identifier, { custodialFilePath, privateKey, publicKey, keyId, apiUrl = constants_js_1.API_URL, turnKeyClient, }) {
10
34
  if (custodialFilePath) {
11
- let fsModule;
12
- try {
13
- fsModule = require.resolve("fs") && require("fs");
14
- }
15
- catch (error) {
16
- console.log("FS module not available. Skipping FS operation...");
17
- return;
18
- }
19
- const data = fsModule.readFileSync(custodialFilePath, "utf8");
20
- const values = data.split("\n");
21
- [privateKey, publicKey, keyId] = values;
35
+ [privateKey, publicKey, keyId] = await loadSignDataFromCustodialFile(custodialFilePath);
22
36
  }
23
- if (!privateKey || !publicKey || !keyId) {
24
- throw new Error("Must provide custodialFilePath or privateKey, publicKey, and keyId.");
37
+ if (!keyId) {
38
+ throw new Error("You must provide custodialFilePath or a keyId.");
25
39
  }
26
- if (!turnKeyClient) {
27
- let TurnkeyClient;
28
- let ApiKeyStamper;
29
- try {
30
- TurnkeyClient =
31
- require.resolve("@turnkey/http") &&
32
- require("@turnkey/http").TurnkeyClient;
33
- ApiKeyStamper =
34
- require.resolve("@turnkey/api-key-stamper") &&
35
- require("@turnkey/api-key-stamper").ApiKeyStamper;
36
- }
37
- catch (error) {
38
- console.log("@turnkey/http or @turnkey/api-key-stamper module not available. Skipping FS operation...");
39
- return;
40
- }
41
- turnKeyClient = new TurnkeyClient({
42
- baseUrl: "https://api.turnkey.com",
43
- }, new ApiKeyStamper({
44
- apiPublicKey: publicKey,
45
- apiPrivateKey: privateKey,
46
- }));
40
+ let ensuredTurnkeyClient = turnKeyClient;
41
+ if (!ensuredTurnkeyClient && privateKey && publicKey) {
42
+ ensuredTurnkeyClient = await getDefaultTurnkeyClient({
43
+ privateKey,
44
+ publicKey,
45
+ });
47
46
  }
48
- const response = await axios_1.default.post(`${apiUrl}/wallets/${identifier}`, {
49
- keyId,
50
- });
51
- let createAccount;
52
- try {
53
- createAccount =
54
- require.resolve("@turnkey/viem") &&
55
- require("@turnkey/viem").createAccount;
47
+ else {
48
+ throw new Error("No turnkey client available, if you don't provide one you should provide private and public key or a custodial file path");
56
49
  }
57
- catch (error) {
58
- console.log("@turnkey/viem module not available. Skipping FS operation...");
59
- return;
50
+ const response = await fetchWallet({ identifier, keyId, apiUrl });
51
+ if (!response?.data?.walletId) {
52
+ throw new Error(`No wallet id found for ${identifier}`);
60
53
  }
61
- const turnkeySigner = await createAccount({
62
- client: turnKeyClient,
63
- organizationId: keyId,
54
+ const turnkeySigner = await getTurnkeySigner({
55
+ keyId,
64
56
  privateKeyId: response.data.walletId,
57
+ turnkeyClient: ensuredTurnkeyClient,
65
58
  });
66
59
  return {
67
60
  getAddress: async () => turnkeySigner.address,
@@ -77,4 +70,56 @@ async function getCustodialOwner(identifier, { custodialFilePath, privateKey, pu
77
70
  };
78
71
  }
79
72
  exports.getCustodialOwner = getCustodialOwner;
73
+ const loadSignDataFromCustodialFile = (0, radash_1.memo)(async (custodialFilePath) => {
74
+ const [, fsModule] = await (0, radash_1.tryit)(() => Promise.resolve().then(() => __importStar(require("fs"))))();
75
+ if (!fsModule) {
76
+ console.error("FS module not available");
77
+ throw new Error("FS module not available, you must provide each keys or install this module");
78
+ }
79
+ const data = fsModule.readFileSync(custodialFilePath, "utf8");
80
+ return data.split("\n");
81
+ }, {
82
+ ttl: 1000 * 60,
83
+ key: (custodialFilePath) => `${custodialFilePath}`,
84
+ });
85
+ const getDefaultTurnkeyClient = (0, radash_1.memo)(async ({ privateKey, publicKey, }) => {
86
+ const [, turnkeyHttp] = await (0, radash_1.tryit)(() => Promise.resolve().then(() => __importStar(require("@turnkey/http"))))();
87
+ const [, turnkeyApiKeyStamper] = await (0, radash_1.tryit)(() => Promise.resolve().then(() => __importStar(require("@turnkey/api-key-stamper"))))();
88
+ if (!turnkeyHttp || !turnkeyApiKeyStamper) {
89
+ console.error("@turnkey/http or @turnkey/api-key-stamper module not available.");
90
+ throw new Error("Turnkey http or api-key-stamper modules not available, you must provide a turnkey client or install this modules");
91
+ }
92
+ return new turnkeyHttp.TurnkeyClient({
93
+ baseUrl: "https://api.turnkey.com",
94
+ }, new turnkeyApiKeyStamper.ApiKeyStamper({
95
+ apiPublicKey: publicKey,
96
+ apiPrivateKey: privateKey,
97
+ }));
98
+ }, {
99
+ ttl: 1000 * 60,
100
+ key: ({ privateKey, publicKey, }) => `${privateKey}-${publicKey}`,
101
+ });
102
+ const fetchWallet = (0, radash_1.memo)(({ identifier, keyId, apiUrl, }) => {
103
+ return axios_1.default.post(`${apiUrl}/wallets/${identifier}`, {
104
+ keyId,
105
+ });
106
+ }, {
107
+ ttl: 1000 * 60,
108
+ key: ({ identifier, keyId, apiUrl, }) => `${identifier}-${keyId}-${apiUrl}`,
109
+ });
110
+ const getTurnkeySigner = (0, radash_1.memo)(async ({ keyId, privateKeyId, turnkeyClient, }) => {
111
+ const [, turnkeyViem] = await (0, radash_1.tryit)(() => Promise.resolve().then(() => __importStar(require("@turnkey/viem"))))();
112
+ if (!turnkeyViem) {
113
+ console.error("@turnkey/viem module not available");
114
+ throw new Error("Turnkey viem module not available, can't create a turnkey signer for the custodial owner");
115
+ }
116
+ return turnkeyViem.createAccount({
117
+ client: turnkeyClient,
118
+ organizationId: keyId,
119
+ privateKeyId,
120
+ });
121
+ }, {
122
+ ttl: 1000 * 60,
123
+ key: ({ keyId, privateKeyId, }) => `${keyId}-${privateKeyId}`,
124
+ });
80
125
  //# sourceMappingURL=getCustodialOwner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getCustodialOwner.js","sourceRoot":"","sources":["../../../../src/kernel-zerodev/owner/getCustodialOwner.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SignTypedDataParams, SmartAccountSigner } from \"@alchemy/aa-core\";\nimport { API_URL } from \"../constants.js\";\nimport axios from \"axios\";\n\n/**\n * Params to get a custodial owner\n * Priv / pub key combo or custodial file path should be in different types\n */\ntype GetCustodialOwnerParams = {\n // ZeroDev api url\n apiUrl?: string;\n // Turnkey client (if the client want to reuse it\n turnKeyClient?: unknown;\n\n // Direct access to priv / pub key\n privateKey?: string;\n publicKey?: string;\n keyId?: string;\n\n // Or read them from the custodial file path\n custodialFilePath?: string;\n};\n\n/**\n * Returns a signer for a custodial wallet via TurnKey\n */\nexport async function getCustodialOwner(\n identifier: string,\n {\n custodialFilePath,\n privateKey,\n publicKey,\n keyId,\n apiUrl = API_URL,\n turnKeyClient,\n }: GetCustodialOwnerParams\n): Promise<SmartAccountSigner | undefined> {\n // Extract data from the custodial file path if provided\n if (custodialFilePath) {\n let fsModule;\n try {\n fsModule = require.resolve(\"fs\") && require(\"fs\");\n } catch (error) {\n console.log(\"FS module not available. Skipping FS operation...\");\n return;\n }\n const data = fsModule.readFileSync(custodialFilePath, \"utf8\");\n const values = data.split(\"\\n\");\n // Override the values, if they are provided, to the one from the custodial file\n [privateKey, publicKey, keyId] = values;\n }\n\n // Ensure we have the required values\n if (!privateKey || !publicKey || !keyId) {\n throw new Error(\n \"Must provide custodialFilePath or privateKey, publicKey, and keyId.\"\n );\n }\n\n // Get our turnkey client (build it if needed)\n if (!turnKeyClient) {\n // Try to fetch turnkey client & api key stamper\n let TurnkeyClient;\n let ApiKeyStamper;\n // TODO: Would be cleaner with something like radash and a tryit function?\n try {\n TurnkeyClient =\n require.resolve(\"@turnkey/http\") &&\n require(\"@turnkey/http\").TurnkeyClient;\n ApiKeyStamper =\n require.resolve(\"@turnkey/api-key-stamper\") &&\n require(\"@turnkey/api-key-stamper\").ApiKeyStamper;\n } catch (error) {\n console.log(\n \"@turnkey/http or @turnkey/api-key-stamper module not available. Skipping FS operation...\"\n );\n return;\n }\n\n // Build the turnkey client\n turnKeyClient = new TurnkeyClient(\n {\n baseUrl: \"https://api.turnkey.com\",\n },\n new ApiKeyStamper({\n apiPublicKey: publicKey,\n apiPrivateKey: privateKey,\n })\n );\n }\n\n // Get the wallet identifier from the API\n const response = await axios.post<any, { data: { walletId: string } }>(\n `${apiUrl}/wallets/${identifier}`,\n {\n keyId,\n }\n );\n\n // Build the turnkey viem account\n let createAccount;\n try {\n createAccount =\n require.resolve(\"@turnkey/viem\") &&\n require(\"@turnkey/viem\").createAccount;\n } catch (error) {\n console.log(\"@turnkey/viem module not available. Skipping FS operation...\");\n return;\n }\n const turnkeySigner = await createAccount({\n client: turnKeyClient,\n organizationId: keyId,\n privateKeyId: response.data.walletId,\n });\n\n // Return an alchemy AA signer from the turnkey signer\n return {\n getAddress: async () => turnkeySigner.address,\n signMessage: async (msg: Uint8Array | string) => {\n if (typeof msg === \"string\") {\n // If the msg is a string, sign it directly\n return turnkeySigner.signMessage({ message: msg });\n } else {\n // Otherwise, sign the raw data\n return turnkeySigner.signMessage({ message: { raw: msg } });\n }\n },\n signTypedData: async (params: SignTypedDataParams) =>\n turnkeySigner.signTypedData(params),\n };\n}\n"]}
1
+ {"version":3,"file":"getCustodialOwner.js","sourceRoot":"","sources":["../../../../src/kernel-zerodev/owner/getCustodialOwner.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SignTypedDataParams, SmartAccountSigner } from \"@alchemy/aa-core\";\nimport { API_URL } from \"../constants.js\";\nimport axios from \"axios\";\nimport { memo, tryit } from \"radash\";\n\n/**\n * Params to get a custodial owner\n * Priv / pub key combo or custodial file path should be in different types\n */\ntype GetCustodialOwnerParams = Readonly<{\n // ZeroDev api url\n apiUrl?: string;\n // Turnkey client (if the client want to reuse it\n turnKeyClient?: unknown;\n\n // Direct access to priv / pub key\n privateKey?: string;\n publicKey?: string;\n keyId?: string;\n\n // Or read them from the custodial file path\n custodialFilePath?: string;\n}>;\n\n/**\n * Returns a signer for a custodial wallet via TurnKey\n */\nexport async function getCustodialOwner(\n identifier: string,\n {\n custodialFilePath,\n privateKey,\n publicKey,\n keyId,\n apiUrl = API_URL,\n turnKeyClient,\n }: GetCustodialOwnerParams\n): Promise<SmartAccountSigner | undefined> {\n // Extract data from the custodial file path if provided\n if (custodialFilePath) {\n [privateKey, publicKey, keyId] = await loadSignDataFromCustodialFile(\n custodialFilePath\n );\n }\n\n // Ensure we have the required values\n if (!keyId) {\n throw new Error(\"You must provide custodialFilePath or a keyId.\");\n }\n\n // Get our turnkey client (build it if needed)\n let ensuredTurnkeyClient = turnKeyClient;\n if (!ensuredTurnkeyClient && privateKey && publicKey) {\n ensuredTurnkeyClient = await getDefaultTurnkeyClient({\n privateKey,\n publicKey,\n });\n } else {\n throw new Error(\n \"No turnkey client available, if you don't provide one you should provide private and public key or a custodial file path\"\n );\n }\n\n // Get the wallet identifier from the API\n const response = await fetchWallet({ identifier, keyId, apiUrl });\n if (!response?.data?.walletId) {\n throw new Error(`No wallet id found for ${identifier}`);\n }\n\n // Build the turnkey viem account\n const turnkeySigner = await getTurnkeySigner({\n keyId,\n privateKeyId: response.data.walletId,\n turnkeyClient: ensuredTurnkeyClient,\n });\n\n // Return an alchemy AA signer from the turnkey signer\n return {\n getAddress: async () => turnkeySigner.address,\n signMessage: async (msg: Uint8Array | string) => {\n if (typeof msg === \"string\") {\n // If the msg is a string, sign it directly\n return turnkeySigner.signMessage({ message: msg });\n } else {\n // Otherwise, sign the raw data\n return turnkeySigner.signMessage({ message: { raw: msg } });\n }\n },\n signTypedData: async (params: SignTypedDataParams) =>\n turnkeySigner.signTypedData(params),\n };\n}\n\n/**\n * Try to load sign data from a local custodial file path\n */\nconst loadSignDataFromCustodialFile = memo(\n async (custodialFilePath: string) => {\n const [, fsModule] = await tryit(() => import(\"fs\"))();\n if (!fsModule) {\n console.error(\"FS module not available\");\n throw new Error(\n \"FS module not available, you must provide each keys or install this module\"\n );\n }\n const data = fsModule.readFileSync(custodialFilePath, \"utf8\");\n return data.split(\"\\n\");\n },\n {\n // TTL of 1min in the memory cache\n ttl: 1000 * 60,\n // The key in the cache\n key: (custodialFilePath: string) => `${custodialFilePath}`,\n }\n);\n\n/**\n * Get our default turnkey client\n */\nconst getDefaultTurnkeyClient = memo(\n async ({\n privateKey,\n publicKey,\n }: {\n privateKey: string;\n publicKey: string;\n }) => {\n // Try to fetch turnkey client & api key stamper\n const [, turnkeyHttp] = await tryit(() => import(\"@turnkey/http\"))();\n const [, turnkeyApiKeyStamper] = await tryit(\n () => import(\"@turnkey/api-key-stamper\")\n )();\n if (!turnkeyHttp || !turnkeyApiKeyStamper) {\n console.error(\n \"@turnkey/http or @turnkey/api-key-stamper module not available.\"\n );\n throw new Error(\n \"Turnkey http or api-key-stamper modules not available, you must provide a turnkey client or install this modules\"\n );\n }\n\n // Build the turnkey client\n return new turnkeyHttp.TurnkeyClient(\n {\n baseUrl: \"https://api.turnkey.com\",\n },\n new turnkeyApiKeyStamper.ApiKeyStamper({\n apiPublicKey: publicKey,\n apiPrivateKey: privateKey,\n })\n );\n },\n {\n // TTL of 1min in the memory cache\n ttl: 1000 * 60,\n // The key in the cache\n key: ({\n privateKey,\n publicKey,\n }: {\n privateKey: string;\n publicKey: string;\n }) => `${privateKey}-${publicKey}`,\n }\n);\n\n/**\n * Simple function used to fetch the wallet id from the API using an identifier\n */\nconst fetchWallet = memo(\n ({\n identifier,\n keyId,\n apiUrl,\n }: {\n identifier: string;\n keyId: string;\n apiUrl: string;\n }) => {\n return axios.post<any, { data: { walletId: string } }>(\n `${apiUrl}/wallets/${identifier}`,\n {\n keyId,\n }\n );\n },\n {\n // TTL of 1min in the memory cache\n ttl: 1000 * 60,\n // The key in the cache\n key: ({\n identifier,\n keyId,\n apiUrl,\n }: {\n identifier: string;\n keyId: string;\n apiUrl: string;\n }) => `${identifier}-${keyId}-${apiUrl}`,\n }\n);\n\n/**\n * Get a turnkey signer\n */\nconst getTurnkeySigner = memo(\n async ({\n keyId,\n privateKeyId,\n turnkeyClient,\n }: {\n keyId: string;\n privateKeyId: string;\n turnkeyClient: unknown;\n }) => {\n // Get the turnkey viem account\n const [, turnkeyViem] = await tryit(() => import(\"@turnkey/viem\"))();\n if (!turnkeyViem) {\n console.error(\"@turnkey/viem module not available\");\n throw new Error(\n \"Turnkey viem module not available, can't create a turnkey signer for the custodial owner\"\n );\n }\n return turnkeyViem.createAccount({\n client: turnkeyClient as any,\n organizationId: keyId,\n privateKeyId,\n });\n },\n {\n // TTL of 1min in the memory cache\n ttl: 1000 * 60,\n // The key in the cache\n key: ({\n keyId,\n privateKeyId,\n }: {\n keyId: string;\n privateKeyId: string;\n turnkeyClient: unknown;\n }) => `${keyId}-${privateKeyId}`,\n }\n);\n"]}
@@ -39,10 +39,10 @@ const signMessageImplementation = async (msg, id, walletId, projectId, credentia
39
39
  abortWebauthn();
40
40
  const signedRequest = await http_1.TurnkeyApi.signSignRawPayload({
41
41
  body: {
42
- type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD",
42
+ type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2",
43
43
  organizationId: id,
44
44
  parameters: {
45
- privateKeyId: walletId,
45
+ signWith: walletId,
46
46
  payload: msg,
47
47
  encoding: "PAYLOAD_ENCODING_HEXADECIMAL",
48
48
  hashFunction: "HASH_FUNCTION_NO_OP",
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../src/kernel-zerodev/owner/passkey/utils.ts"],"names":[],"mappings":";;;;;;AAAA,wCAAwD;AACxD,kDAA0B;AAC1B,qDAA6C;AAE7C,+BAAkE;AAElE,IAAA,kBAAW,EAAC;IACV,OAAO,EAAE,yBAAyB;CACnC,CAAC,CAAC;AAEU,QAAA,eAAe,GAAG;IAC7B,UAAU,EAAE,IAAI,eAAe,EAAE;CAClC,CAAC;AAEF,SAAgB,aAAa;IAC3B,uBAAe,CAAC,UAAU,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC7E,uBAAe,CAAC,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;AACrD,CAAC;AAHD,sCAGC;AAEY,QAAA,SAAS,GAAG,YAAY,CAAC;AAEzB,QAAA,KAAK,GAAG,CAAC,CAAC,CAAC;AAEjB,MAAM,oBAAoB,GAAG,GAAgB,EAAE;IACpD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IAC/B,MAAM,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC5B,OAAO,GAAG,CAAC,MAAM,CAAC;AACpB,CAAC,CAAC;AAJW,QAAA,oBAAoB,wBAI/B;AAEK,MAAM,eAAe,GAAG,CAAC,SAAsB,EAAU,EAAE;IAChE,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC;SAC1B,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AACvB,CAAC,CAAC;AANW,QAAA,eAAe,mBAM1B;AAEK,MAAM,yBAAyB,GAAG,KAAK,EAC5C,GAAW,EACX,EAAU,EACV,QAAgB,EAChB,SAAiB,EACjB,YAAoB,EACpB,MAAM,GAAG,sBAAO,EAChB,EAAE;IACF,aAAa,EAAE,CAAC;IAChB,MAAM,aAAa,GAAG,MAAM,iBAAU,CAAC,kBAAkB,CACvD;QACE,IAAI,EAAE;YACJ,IAAI,EAAE,gCAAgC;YACtC,cAAc,EAAE,EAAE;YAClB,UAAU,EAAE;gBACV,YAAY,EAAE,QAAQ;gBACtB,OAAO,EAAE,GAAG;gBACZ,QAAQ,EAAE,8BAA8B;gBACxC,YAAY,EAAE,qBAAqB;aACpC;YACD,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;SAChC;KACF,EACD;QACE,SAAS,EAAE;YACT,gBAAgB,EAAE;gBAChB;oBACE,EAAE,EAAE,uBAAuB,CAAC,YAAY,CAAC;oBACzC,IAAI,EAAE,iBAAS;iBAChB;aACF;SACF;KACF,CACF,CAAC;IACF,MAAM,aAAa,GAAG,MAAM,eAAK,CAAC,IAAI,CACpC,GAAG,MAAM,aAAa,SAAS,gBAAgB,EAC/C;QACE,aAAa;KACd,CACF,CAAC;IACF,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC;IAC9C,IAAI,QAAQ,CAAC,MAAM,KAAK,2BAA2B,EAAE;QACnD,IAAI,MAAM,GAAG,QAAQ,EAAE,MAAM,EAAE,oBAAoB,CAAC;QAEpD,IAAI,MAAM,EAAE;YACV,MAAM,YAAY,GAAG,IAAA,qBAAc,EAAC;gBAClC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,EAAE;gBAClB,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,EAAE;gBAClB,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;aACjC,CAAC,CAAC;YACH,IAAI,YAAY,EAAE;gBAChB,OAAO,YAAY,CAAC;aACrB;SACF;KACF;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAxDW,QAAA,yBAAyB,6BAwDpC;AAEK,MAAM,WAAW,GAAG,KAAK,EAC9B,GAAwB,EACxB,EAAU,EACV,QAAgB,EAChB,SAAiB,EACjB,YAAoB,EACpB,MAAM,GAAG,sBAAO,EAChB,EAAE;IACF,OAAO,MAAM,IAAA,iCAAyB,EACpC,IAAA,kBAAW,EAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,EACzD,EAAE,EACF,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,MAAM,CACP,CAAC;AACJ,CAAC,CAAC;AAhBW,QAAA,WAAW,eAgBtB;AAEK,MAAM,aAAa,GAAG,KAAK,EAChC,MAA2B,EAC3B,EAAU,EACV,QAAgB,EAChB,SAAiB,EACjB,YAAoB,EACpB,MAAM,GAAG,sBAAO,EAChB,EAAE;IACF,MAAM,UAAU,GAAG,IAAA,oBAAa,EAAC,MAAM,CAAC,CAAC;IACzC,OAAO,MAAM,IAAA,iCAAyB,EACpC,UAAU,EACV,EAAE,EACF,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,MAAM,CACP,CAAC;AACJ,CAAC,CAAC;AAjBW,QAAA,aAAa,iBAiBxB;AAEK,MAAM,cAAc,GAAG,KAAK,EACjC,SAAiB,EACjB,IAAa,EACb,MAAM,GAAG,sBAAO,EAChB,EAAE;IACF,MAAM,GAAG,GACP,GAAG,MAAM,aAAa,SAAS,UAAU,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACvE,MAAM,QAAQ,GAAG,MAAM,eAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,WAAW,GAAG,QAAQ,CAAC,IAAI,CAAC;IAClC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,UAAkB,EAAE,EAAE,CAAC,CAAC;QAC9C,EAAE,EAAE,uBAAuB,CAAC,UAAU,CAAC;QACvC,IAAI,EAAE,YAAY;KACnB,CAAC,CAAC,CAAC;AACN,CAAC,CAAC;AAbW,QAAA,cAAc,kBAazB;AAGF,SAAgB,uBAAuB,CAAC,eAAuB;IAE7D,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAQrE,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE,GAAG,CAAC,CAAC;IAG7D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAG5B,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC;IAErC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACtC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;KACjC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAzBD,0DAyBC","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 function abortWebauthn() {\n abortController.controller.abort(\"ZeroDev: Reset previous Webauthn request\");\n abortController.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 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 abortWebauthn();\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 (\n projectId: string,\n name?: string,\n apiUrl = API_URL\n) => {\n const url =\n `${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
+ {"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 function abortWebauthn() {\n abortController.controller.abort(\"ZeroDev: Reset previous Webauthn request\");\n abortController.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 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 abortWebauthn();\n const signedRequest = await TurnkeyApi.signSignRawPayload(\n {\n body: {\n type: \"ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2\",\n organizationId: id,\n parameters: {\n signWith: 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 (\n projectId: string,\n name?: string,\n apiUrl = API_URL\n) => {\n const url =\n `${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,11 +1,11 @@
1
1
  import type { SmartAccountSigner } from "@alchemy/aa-core";
2
- type GetCustodialOwnerParams = {
2
+ type GetCustodialOwnerParams = Readonly<{
3
3
  apiUrl?: string;
4
4
  turnKeyClient?: unknown;
5
5
  privateKey?: string;
6
6
  publicKey?: string;
7
7
  keyId?: string;
8
8
  custodialFilePath?: string;
9
- };
9
+ }>;
10
10
  export declare function getCustodialOwner(identifier: string, { custodialFilePath, privateKey, publicKey, keyId, apiUrl, turnKeyClient, }: GetCustodialOwnerParams): Promise<SmartAccountSigner | undefined>;
11
11
  export {};
@@ -1,61 +1,31 @@
1
1
  import { API_URL } from "../constants.js";
2
2
  import axios from "axios";
3
+ import { memo, tryit } from "radash";
3
4
  export async function getCustodialOwner(identifier, { custodialFilePath, privateKey, publicKey, keyId, apiUrl = API_URL, turnKeyClient, }) {
4
5
  if (custodialFilePath) {
5
- let fsModule;
6
- try {
7
- fsModule = require.resolve("fs") && require("fs");
8
- }
9
- catch (error) {
10
- console.log("FS module not available. Skipping FS operation...");
11
- return;
12
- }
13
- const data = fsModule.readFileSync(custodialFilePath, "utf8");
14
- const values = data.split("\n");
15
- [privateKey, publicKey, keyId] = values;
6
+ [privateKey, publicKey, keyId] = await loadSignDataFromCustodialFile(custodialFilePath);
16
7
  }
17
- if (!privateKey || !publicKey || !keyId) {
18
- throw new Error("Must provide custodialFilePath or privateKey, publicKey, and keyId.");
8
+ if (!keyId) {
9
+ throw new Error("You must provide custodialFilePath or a keyId.");
19
10
  }
20
- if (!turnKeyClient) {
21
- let TurnkeyClient;
22
- let ApiKeyStamper;
23
- try {
24
- TurnkeyClient =
25
- require.resolve("@turnkey/http") &&
26
- require("@turnkey/http").TurnkeyClient;
27
- ApiKeyStamper =
28
- require.resolve("@turnkey/api-key-stamper") &&
29
- require("@turnkey/api-key-stamper").ApiKeyStamper;
30
- }
31
- catch (error) {
32
- console.log("@turnkey/http or @turnkey/api-key-stamper module not available. Skipping FS operation...");
33
- return;
34
- }
35
- turnKeyClient = new TurnkeyClient({
36
- baseUrl: "https://api.turnkey.com",
37
- }, new ApiKeyStamper({
38
- apiPublicKey: publicKey,
39
- apiPrivateKey: privateKey,
40
- }));
11
+ let ensuredTurnkeyClient = turnKeyClient;
12
+ if (!ensuredTurnkeyClient && privateKey && publicKey) {
13
+ ensuredTurnkeyClient = await getDefaultTurnkeyClient({
14
+ privateKey,
15
+ publicKey,
16
+ });
41
17
  }
42
- const response = await axios.post(`${apiUrl}/wallets/${identifier}`, {
43
- keyId,
44
- });
45
- let createAccount;
46
- try {
47
- createAccount =
48
- require.resolve("@turnkey/viem") &&
49
- require("@turnkey/viem").createAccount;
18
+ else {
19
+ throw new Error("No turnkey client available, if you don't provide one you should provide private and public key or a custodial file path");
50
20
  }
51
- catch (error) {
52
- console.log("@turnkey/viem module not available. Skipping FS operation...");
53
- return;
21
+ const response = await fetchWallet({ identifier, keyId, apiUrl });
22
+ if (!response?.data?.walletId) {
23
+ throw new Error(`No wallet id found for ${identifier}`);
54
24
  }
55
- const turnkeySigner = await createAccount({
56
- client: turnKeyClient,
57
- organizationId: keyId,
25
+ const turnkeySigner = await getTurnkeySigner({
26
+ keyId,
58
27
  privateKeyId: response.data.walletId,
28
+ turnkeyClient: ensuredTurnkeyClient,
59
29
  });
60
30
  return {
61
31
  getAddress: async () => turnkeySigner.address,
@@ -70,4 +40,56 @@ export async function getCustodialOwner(identifier, { custodialFilePath, private
70
40
  signTypedData: async (params) => turnkeySigner.signTypedData(params),
71
41
  };
72
42
  }
43
+ const loadSignDataFromCustodialFile = memo(async (custodialFilePath) => {
44
+ const [, fsModule] = await tryit(() => import("fs"))();
45
+ if (!fsModule) {
46
+ console.error("FS module not available");
47
+ throw new Error("FS module not available, you must provide each keys or install this module");
48
+ }
49
+ const data = fsModule.readFileSync(custodialFilePath, "utf8");
50
+ return data.split("\n");
51
+ }, {
52
+ ttl: 1000 * 60,
53
+ key: (custodialFilePath) => `${custodialFilePath}`,
54
+ });
55
+ const getDefaultTurnkeyClient = memo(async ({ privateKey, publicKey, }) => {
56
+ const [, turnkeyHttp] = await tryit(() => import("@turnkey/http"))();
57
+ const [, turnkeyApiKeyStamper] = await tryit(() => import("@turnkey/api-key-stamper"))();
58
+ if (!turnkeyHttp || !turnkeyApiKeyStamper) {
59
+ console.error("@turnkey/http or @turnkey/api-key-stamper module not available.");
60
+ throw new Error("Turnkey http or api-key-stamper modules not available, you must provide a turnkey client or install this modules");
61
+ }
62
+ return new turnkeyHttp.TurnkeyClient({
63
+ baseUrl: "https://api.turnkey.com",
64
+ }, new turnkeyApiKeyStamper.ApiKeyStamper({
65
+ apiPublicKey: publicKey,
66
+ apiPrivateKey: privateKey,
67
+ }));
68
+ }, {
69
+ ttl: 1000 * 60,
70
+ key: ({ privateKey, publicKey, }) => `${privateKey}-${publicKey}`,
71
+ });
72
+ const fetchWallet = memo(({ identifier, keyId, apiUrl, }) => {
73
+ return axios.post(`${apiUrl}/wallets/${identifier}`, {
74
+ keyId,
75
+ });
76
+ }, {
77
+ ttl: 1000 * 60,
78
+ key: ({ identifier, keyId, apiUrl, }) => `${identifier}-${keyId}-${apiUrl}`,
79
+ });
80
+ const getTurnkeySigner = memo(async ({ keyId, privateKeyId, turnkeyClient, }) => {
81
+ const [, turnkeyViem] = await tryit(() => import("@turnkey/viem"))();
82
+ if (!turnkeyViem) {
83
+ console.error("@turnkey/viem module not available");
84
+ throw new Error("Turnkey viem module not available, can't create a turnkey signer for the custodial owner");
85
+ }
86
+ return turnkeyViem.createAccount({
87
+ client: turnkeyClient,
88
+ organizationId: keyId,
89
+ privateKeyId,
90
+ });
91
+ }, {
92
+ ttl: 1000 * 60,
93
+ key: ({ keyId, privateKeyId, }) => `${keyId}-${privateKeyId}`,
94
+ });
73
95
  //# sourceMappingURL=getCustodialOwner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"getCustodialOwner.js","sourceRoot":"","sources":["../../../../src/kernel-zerodev/owner/getCustodialOwner.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SignTypedDataParams, SmartAccountSigner } from \"@alchemy/aa-core\";\nimport { API_URL } from \"../constants.js\";\nimport axios from \"axios\";\n\n/**\n * Params to get a custodial owner\n * Priv / pub key combo or custodial file path should be in different types\n */\ntype GetCustodialOwnerParams = {\n // ZeroDev api url\n apiUrl?: string;\n // Turnkey client (if the client want to reuse it\n turnKeyClient?: unknown;\n\n // Direct access to priv / pub key\n privateKey?: string;\n publicKey?: string;\n keyId?: string;\n\n // Or read them from the custodial file path\n custodialFilePath?: string;\n};\n\n/**\n * Returns a signer for a custodial wallet via TurnKey\n */\nexport async function getCustodialOwner(\n identifier: string,\n {\n custodialFilePath,\n privateKey,\n publicKey,\n keyId,\n apiUrl = API_URL,\n turnKeyClient,\n }: GetCustodialOwnerParams\n): Promise<SmartAccountSigner | undefined> {\n // Extract data from the custodial file path if provided\n if (custodialFilePath) {\n let fsModule;\n try {\n fsModule = require.resolve(\"fs\") && require(\"fs\");\n } catch (error) {\n console.log(\"FS module not available. Skipping FS operation...\");\n return;\n }\n const data = fsModule.readFileSync(custodialFilePath, \"utf8\");\n const values = data.split(\"\\n\");\n // Override the values, if they are provided, to the one from the custodial file\n [privateKey, publicKey, keyId] = values;\n }\n\n // Ensure we have the required values\n if (!privateKey || !publicKey || !keyId) {\n throw new Error(\n \"Must provide custodialFilePath or privateKey, publicKey, and keyId.\"\n );\n }\n\n // Get our turnkey client (build it if needed)\n if (!turnKeyClient) {\n // Try to fetch turnkey client & api key stamper\n let TurnkeyClient;\n let ApiKeyStamper;\n // TODO: Would be cleaner with something like radash and a tryit function?\n try {\n TurnkeyClient =\n require.resolve(\"@turnkey/http\") &&\n require(\"@turnkey/http\").TurnkeyClient;\n ApiKeyStamper =\n require.resolve(\"@turnkey/api-key-stamper\") &&\n require(\"@turnkey/api-key-stamper\").ApiKeyStamper;\n } catch (error) {\n console.log(\n \"@turnkey/http or @turnkey/api-key-stamper module not available. Skipping FS operation...\"\n );\n return;\n }\n\n // Build the turnkey client\n turnKeyClient = new TurnkeyClient(\n {\n baseUrl: \"https://api.turnkey.com\",\n },\n new ApiKeyStamper({\n apiPublicKey: publicKey,\n apiPrivateKey: privateKey,\n })\n );\n }\n\n // Get the wallet identifier from the API\n const response = await axios.post<any, { data: { walletId: string } }>(\n `${apiUrl}/wallets/${identifier}`,\n {\n keyId,\n }\n );\n\n // Build the turnkey viem account\n let createAccount;\n try {\n createAccount =\n require.resolve(\"@turnkey/viem\") &&\n require(\"@turnkey/viem\").createAccount;\n } catch (error) {\n console.log(\"@turnkey/viem module not available. Skipping FS operation...\");\n return;\n }\n const turnkeySigner = await createAccount({\n client: turnKeyClient,\n organizationId: keyId,\n privateKeyId: response.data.walletId,\n });\n\n // Return an alchemy AA signer from the turnkey signer\n return {\n getAddress: async () => turnkeySigner.address,\n signMessage: async (msg: Uint8Array | string) => {\n if (typeof msg === \"string\") {\n // If the msg is a string, sign it directly\n return turnkeySigner.signMessage({ message: msg });\n } else {\n // Otherwise, sign the raw data\n return turnkeySigner.signMessage({ message: { raw: msg } });\n }\n },\n signTypedData: async (params: SignTypedDataParams) =>\n turnkeySigner.signTypedData(params),\n };\n}\n"]}
1
+ {"version":3,"file":"getCustodialOwner.js","sourceRoot":"","sources":["../../../../src/kernel-zerodev/owner/getCustodialOwner.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SignTypedDataParams, SmartAccountSigner } from \"@alchemy/aa-core\";\nimport { API_URL } from \"../constants.js\";\nimport axios from \"axios\";\nimport { memo, tryit } from \"radash\";\n\n/**\n * Params to get a custodial owner\n * Priv / pub key combo or custodial file path should be in different types\n */\ntype GetCustodialOwnerParams = Readonly<{\n // ZeroDev api url\n apiUrl?: string;\n // Turnkey client (if the client want to reuse it\n turnKeyClient?: unknown;\n\n // Direct access to priv / pub key\n privateKey?: string;\n publicKey?: string;\n keyId?: string;\n\n // Or read them from the custodial file path\n custodialFilePath?: string;\n}>;\n\n/**\n * Returns a signer for a custodial wallet via TurnKey\n */\nexport async function getCustodialOwner(\n identifier: string,\n {\n custodialFilePath,\n privateKey,\n publicKey,\n keyId,\n apiUrl = API_URL,\n turnKeyClient,\n }: GetCustodialOwnerParams\n): Promise<SmartAccountSigner | undefined> {\n // Extract data from the custodial file path if provided\n if (custodialFilePath) {\n [privateKey, publicKey, keyId] = await loadSignDataFromCustodialFile(\n custodialFilePath\n );\n }\n\n // Ensure we have the required values\n if (!keyId) {\n throw new Error(\"You must provide custodialFilePath or a keyId.\");\n }\n\n // Get our turnkey client (build it if needed)\n let ensuredTurnkeyClient = turnKeyClient;\n if (!ensuredTurnkeyClient && privateKey && publicKey) {\n ensuredTurnkeyClient = await getDefaultTurnkeyClient({\n privateKey,\n publicKey,\n });\n } else {\n throw new Error(\n \"No turnkey client available, if you don't provide one you should provide private and public key or a custodial file path\"\n );\n }\n\n // Get the wallet identifier from the API\n const response = await fetchWallet({ identifier, keyId, apiUrl });\n if (!response?.data?.walletId) {\n throw new Error(`No wallet id found for ${identifier}`);\n }\n\n // Build the turnkey viem account\n const turnkeySigner = await getTurnkeySigner({\n keyId,\n privateKeyId: response.data.walletId,\n turnkeyClient: ensuredTurnkeyClient,\n });\n\n // Return an alchemy AA signer from the turnkey signer\n return {\n getAddress: async () => turnkeySigner.address,\n signMessage: async (msg: Uint8Array | string) => {\n if (typeof msg === \"string\") {\n // If the msg is a string, sign it directly\n return turnkeySigner.signMessage({ message: msg });\n } else {\n // Otherwise, sign the raw data\n return turnkeySigner.signMessage({ message: { raw: msg } });\n }\n },\n signTypedData: async (params: SignTypedDataParams) =>\n turnkeySigner.signTypedData(params),\n };\n}\n\n/**\n * Try to load sign data from a local custodial file path\n */\nconst loadSignDataFromCustodialFile = memo(\n async (custodialFilePath: string) => {\n const [, fsModule] = await tryit(() => import(\"fs\"))();\n if (!fsModule) {\n console.error(\"FS module not available\");\n throw new Error(\n \"FS module not available, you must provide each keys or install this module\"\n );\n }\n const data = fsModule.readFileSync(custodialFilePath, \"utf8\");\n return data.split(\"\\n\");\n },\n {\n // TTL of 1min in the memory cache\n ttl: 1000 * 60,\n // The key in the cache\n key: (custodialFilePath: string) => `${custodialFilePath}`,\n }\n);\n\n/**\n * Get our default turnkey client\n */\nconst getDefaultTurnkeyClient = memo(\n async ({\n privateKey,\n publicKey,\n }: {\n privateKey: string;\n publicKey: string;\n }) => {\n // Try to fetch turnkey client & api key stamper\n const [, turnkeyHttp] = await tryit(() => import(\"@turnkey/http\"))();\n const [, turnkeyApiKeyStamper] = await tryit(\n () => import(\"@turnkey/api-key-stamper\")\n )();\n if (!turnkeyHttp || !turnkeyApiKeyStamper) {\n console.error(\n \"@turnkey/http or @turnkey/api-key-stamper module not available.\"\n );\n throw new Error(\n \"Turnkey http or api-key-stamper modules not available, you must provide a turnkey client or install this modules\"\n );\n }\n\n // Build the turnkey client\n return new turnkeyHttp.TurnkeyClient(\n {\n baseUrl: \"https://api.turnkey.com\",\n },\n new turnkeyApiKeyStamper.ApiKeyStamper({\n apiPublicKey: publicKey,\n apiPrivateKey: privateKey,\n })\n );\n },\n {\n // TTL of 1min in the memory cache\n ttl: 1000 * 60,\n // The key in the cache\n key: ({\n privateKey,\n publicKey,\n }: {\n privateKey: string;\n publicKey: string;\n }) => `${privateKey}-${publicKey}`,\n }\n);\n\n/**\n * Simple function used to fetch the wallet id from the API using an identifier\n */\nconst fetchWallet = memo(\n ({\n identifier,\n keyId,\n apiUrl,\n }: {\n identifier: string;\n keyId: string;\n apiUrl: string;\n }) => {\n return axios.post<any, { data: { walletId: string } }>(\n `${apiUrl}/wallets/${identifier}`,\n {\n keyId,\n }\n );\n },\n {\n // TTL of 1min in the memory cache\n ttl: 1000 * 60,\n // The key in the cache\n key: ({\n identifier,\n keyId,\n apiUrl,\n }: {\n identifier: string;\n keyId: string;\n apiUrl: string;\n }) => `${identifier}-${keyId}-${apiUrl}`,\n }\n);\n\n/**\n * Get a turnkey signer\n */\nconst getTurnkeySigner = memo(\n async ({\n keyId,\n privateKeyId,\n turnkeyClient,\n }: {\n keyId: string;\n privateKeyId: string;\n turnkeyClient: unknown;\n }) => {\n // Get the turnkey viem account\n const [, turnkeyViem] = await tryit(() => import(\"@turnkey/viem\"))();\n if (!turnkeyViem) {\n console.error(\"@turnkey/viem module not available\");\n throw new Error(\n \"Turnkey viem module not available, can't create a turnkey signer for the custodial owner\"\n );\n }\n return turnkeyViem.createAccount({\n client: turnkeyClient as any,\n organizationId: keyId,\n privateKeyId,\n });\n },\n {\n // TTL of 1min in the memory cache\n ttl: 1000 * 60,\n // The key in the cache\n key: ({\n keyId,\n privateKeyId,\n }: {\n keyId: string;\n privateKeyId: string;\n turnkeyClient: unknown;\n }) => `${keyId}-${privateKeyId}`,\n }\n);\n"]}
@@ -30,10 +30,10 @@ export const signMessageImplementation = async (msg, id, walletId, projectId, cr
30
30
  abortWebauthn();
31
31
  const signedRequest = await TurnkeyApi.signSignRawPayload({
32
32
  body: {
33
- type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD",
33
+ type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2",
34
34
  organizationId: id,
35
35
  parameters: {
36
- privateKeyId: walletId,
36
+ signWith: walletId,
37
37
  payload: msg,
38
38
  encoding: "PAYLOAD_ENCODING_HEXADECIMAL",
39
39
  hashFunction: "HASH_FUNCTION_NO_OP",
@@ -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 abortController = {\n controller: new AbortController(),\n};\n\nexport function abortWebauthn() {\n abortController.controller.abort(\"ZeroDev: Reset previous Webauthn request\");\n abortController.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 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 abortWebauthn();\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 (\n projectId: string,\n name?: string,\n apiUrl = API_URL\n) => {\n const url =\n `${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
+ {"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 function abortWebauthn() {\n abortController.controller.abort(\"ZeroDev: Reset previous Webauthn request\");\n abortController.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 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 abortWebauthn();\n const signedRequest = await TurnkeyApi.signSignRawPayload(\n {\n body: {\n type: \"ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2\",\n organizationId: id,\n parameters: {\n signWith: 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 (\n projectId: string,\n name?: string,\n apiUrl = API_URL\n) => {\n const url =\n `${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,12 +1,12 @@
1
1
  import type { SmartAccountSigner } from "@alchemy/aa-core";
2
- type GetCustodialOwnerParams = {
2
+ type GetCustodialOwnerParams = Readonly<{
3
3
  apiUrl?: string;
4
4
  turnKeyClient?: unknown;
5
5
  privateKey?: string;
6
6
  publicKey?: string;
7
7
  keyId?: string;
8
8
  custodialFilePath?: string;
9
- };
9
+ }>;
10
10
  export declare function getCustodialOwner(identifier: string, { custodialFilePath, privateKey, publicKey, keyId, apiUrl, turnKeyClient, }: GetCustodialOwnerParams): Promise<SmartAccountSigner | undefined>;
11
11
  export {};
12
12
  //# sourceMappingURL=getCustodialOwner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"getCustodialOwner.d.ts","sourceRoot":"","sources":["../../../../src/kernel-zerodev/owner/getCustodialOwner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAQhF,KAAK,uBAAuB,GAAG;IAE7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAKF,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,EACE,iBAAiB,EACjB,UAAU,EACV,SAAS,EACT,KAAK,EACL,MAAgB,EAChB,aAAa,GACd,EAAE,uBAAuB,GACzB,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CA8FzC"}
1
+ {"version":3,"file":"getCustodialOwner.d.ts","sourceRoot":"","sources":["../../../../src/kernel-zerodev/owner/getCustodialOwner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAuB,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAShF,KAAK,uBAAuB,GAAG,QAAQ,CAAC;IAEtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,aAAa,CAAC,EAAE,OAAO,CAAC;IAGxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC,CAAC;AAKH,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,EACE,iBAAiB,EACjB,UAAU,EACV,SAAS,EACT,KAAK,EACL,MAAgB,EAChB,aAAa,GACd,EAAE,uBAAuB,GACzB,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAsDzC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zerodev/sdk",
3
- "version": "4.3.2",
3
+ "version": "4.3.3",
4
4
  "description": "A collection of ERC-4337 compliant smart contract account interfaces",
5
5
  "author": "ZeroDev",
6
6
  "license": "MIT",
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "devDependencies": {
47
47
  "@turnkey/api-key-stamper": "^0.1.1",
48
- "@turnkey/http": "^1.2.0",
48
+ "@turnkey/http": "^2.1.0",
49
49
  "@turnkey/viem": "^0.2.4",
50
50
  "typescript": "^5.0.4",
51
51
  "typescript-template": "*",
@@ -70,6 +70,7 @@
70
70
  "@openzeppelin/merkle-tree": "^1.0.5",
71
71
  "axios": "^1.4.0",
72
72
  "merkletreejs": "^0.3.10",
73
+ "radash": "^11.0.0",
73
74
  "viem": "^1.5.3"
74
75
  }
75
76
  }
@@ -1,12 +1,13 @@
1
1
  import type { SignTypedDataParams, SmartAccountSigner } from "@alchemy/aa-core";
2
2
  import { API_URL } from "../constants.js";
3
3
  import axios from "axios";
4
+ import { memo, tryit } from "radash";
4
5
 
5
6
  /**
6
7
  * Params to get a custodial owner
7
8
  * Priv / pub key combo or custodial file path should be in different types
8
9
  */
9
- type GetCustodialOwnerParams = {
10
+ type GetCustodialOwnerParams = Readonly<{
10
11
  // ZeroDev api url
11
12
  apiUrl?: string;
12
13
  // Turnkey client (if the client want to reuse it
@@ -19,7 +20,7 @@ type GetCustodialOwnerParams = {
19
20
 
20
21
  // Or read them from the custodial file path
21
22
  custodialFilePath?: string;
22
- };
23
+ }>;
23
24
 
24
25
  /**
25
26
  * Returns a signer for a custodial wallet via TurnKey
@@ -37,80 +38,40 @@ export async function getCustodialOwner(
37
38
  ): Promise<SmartAccountSigner | undefined> {
38
39
  // Extract data from the custodial file path if provided
39
40
  if (custodialFilePath) {
40
- let fsModule;
41
- try {
42
- fsModule = require.resolve("fs") && require("fs");
43
- } catch (error) {
44
- console.log("FS module not available. Skipping FS operation...");
45
- return;
46
- }
47
- const data = fsModule.readFileSync(custodialFilePath, "utf8");
48
- const values = data.split("\n");
49
- // Override the values, if they are provided, to the one from the custodial file
50
- [privateKey, publicKey, keyId] = values;
41
+ [privateKey, publicKey, keyId] = await loadSignDataFromCustodialFile(
42
+ custodialFilePath
43
+ );
51
44
  }
52
45
 
53
46
  // Ensure we have the required values
54
- if (!privateKey || !publicKey || !keyId) {
55
- throw new Error(
56
- "Must provide custodialFilePath or privateKey, publicKey, and keyId."
57
- );
47
+ if (!keyId) {
48
+ throw new Error("You must provide custodialFilePath or a keyId.");
58
49
  }
59
50
 
60
51
  // Get our turnkey client (build it if needed)
61
- if (!turnKeyClient) {
62
- // Try to fetch turnkey client & api key stamper
63
- let TurnkeyClient;
64
- let ApiKeyStamper;
65
- // TODO: Would be cleaner with something like radash and a tryit function?
66
- try {
67
- TurnkeyClient =
68
- require.resolve("@turnkey/http") &&
69
- require("@turnkey/http").TurnkeyClient;
70
- ApiKeyStamper =
71
- require.resolve("@turnkey/api-key-stamper") &&
72
- require("@turnkey/api-key-stamper").ApiKeyStamper;
73
- } catch (error) {
74
- console.log(
75
- "@turnkey/http or @turnkey/api-key-stamper module not available. Skipping FS operation..."
76
- );
77
- return;
78
- }
79
-
80
- // Build the turnkey client
81
- turnKeyClient = new TurnkeyClient(
82
- {
83
- baseUrl: "https://api.turnkey.com",
84
- },
85
- new ApiKeyStamper({
86
- apiPublicKey: publicKey,
87
- apiPrivateKey: privateKey,
88
- })
52
+ let ensuredTurnkeyClient = turnKeyClient;
53
+ if (!ensuredTurnkeyClient && privateKey && publicKey) {
54
+ ensuredTurnkeyClient = await getDefaultTurnkeyClient({
55
+ privateKey,
56
+ publicKey,
57
+ });
58
+ } else {
59
+ throw new Error(
60
+ "No turnkey client available, if you don't provide one you should provide private and public key or a custodial file path"
89
61
  );
90
62
  }
91
63
 
92
64
  // Get the wallet identifier from the API
93
- const response = await axios.post<any, { data: { walletId: string } }>(
94
- `${apiUrl}/wallets/${identifier}`,
95
- {
96
- keyId,
97
- }
98
- );
65
+ const response = await fetchWallet({ identifier, keyId, apiUrl });
66
+ if (!response?.data?.walletId) {
67
+ throw new Error(`No wallet id found for ${identifier}`);
68
+ }
99
69
 
100
70
  // Build the turnkey viem account
101
- let createAccount;
102
- try {
103
- createAccount =
104
- require.resolve("@turnkey/viem") &&
105
- require("@turnkey/viem").createAccount;
106
- } catch (error) {
107
- console.log("@turnkey/viem module not available. Skipping FS operation...");
108
- return;
109
- }
110
- const turnkeySigner = await createAccount({
111
- client: turnKeyClient,
112
- organizationId: keyId,
71
+ const turnkeySigner = await getTurnkeySigner({
72
+ keyId,
113
73
  privateKeyId: response.data.walletId,
74
+ turnkeyClient: ensuredTurnkeyClient,
114
75
  });
115
76
 
116
77
  // Return an alchemy AA signer from the turnkey signer
@@ -129,3 +90,154 @@ export async function getCustodialOwner(
129
90
  turnkeySigner.signTypedData(params),
130
91
  };
131
92
  }
93
+
94
+ /**
95
+ * Try to load sign data from a local custodial file path
96
+ */
97
+ const loadSignDataFromCustodialFile = memo(
98
+ async (custodialFilePath: string) => {
99
+ const [, fsModule] = await tryit(() => import("fs"))();
100
+ if (!fsModule) {
101
+ console.error("FS module not available");
102
+ throw new Error(
103
+ "FS module not available, you must provide each keys or install this module"
104
+ );
105
+ }
106
+ const data = fsModule.readFileSync(custodialFilePath, "utf8");
107
+ return data.split("\n");
108
+ },
109
+ {
110
+ // TTL of 1min in the memory cache
111
+ ttl: 1000 * 60,
112
+ // The key in the cache
113
+ key: (custodialFilePath: string) => `${custodialFilePath}`,
114
+ }
115
+ );
116
+
117
+ /**
118
+ * Get our default turnkey client
119
+ */
120
+ const getDefaultTurnkeyClient = memo(
121
+ async ({
122
+ privateKey,
123
+ publicKey,
124
+ }: {
125
+ privateKey: string;
126
+ publicKey: string;
127
+ }) => {
128
+ // Try to fetch turnkey client & api key stamper
129
+ const [, turnkeyHttp] = await tryit(() => import("@turnkey/http"))();
130
+ const [, turnkeyApiKeyStamper] = await tryit(
131
+ () => import("@turnkey/api-key-stamper")
132
+ )();
133
+ if (!turnkeyHttp || !turnkeyApiKeyStamper) {
134
+ console.error(
135
+ "@turnkey/http or @turnkey/api-key-stamper module not available."
136
+ );
137
+ throw new Error(
138
+ "Turnkey http or api-key-stamper modules not available, you must provide a turnkey client or install this modules"
139
+ );
140
+ }
141
+
142
+ // Build the turnkey client
143
+ return new turnkeyHttp.TurnkeyClient(
144
+ {
145
+ baseUrl: "https://api.turnkey.com",
146
+ },
147
+ new turnkeyApiKeyStamper.ApiKeyStamper({
148
+ apiPublicKey: publicKey,
149
+ apiPrivateKey: privateKey,
150
+ })
151
+ );
152
+ },
153
+ {
154
+ // TTL of 1min in the memory cache
155
+ ttl: 1000 * 60,
156
+ // The key in the cache
157
+ key: ({
158
+ privateKey,
159
+ publicKey,
160
+ }: {
161
+ privateKey: string;
162
+ publicKey: string;
163
+ }) => `${privateKey}-${publicKey}`,
164
+ }
165
+ );
166
+
167
+ /**
168
+ * Simple function used to fetch the wallet id from the API using an identifier
169
+ */
170
+ const fetchWallet = memo(
171
+ ({
172
+ identifier,
173
+ keyId,
174
+ apiUrl,
175
+ }: {
176
+ identifier: string;
177
+ keyId: string;
178
+ apiUrl: string;
179
+ }) => {
180
+ return axios.post<any, { data: { walletId: string } }>(
181
+ `${apiUrl}/wallets/${identifier}`,
182
+ {
183
+ keyId,
184
+ }
185
+ );
186
+ },
187
+ {
188
+ // TTL of 1min in the memory cache
189
+ ttl: 1000 * 60,
190
+ // The key in the cache
191
+ key: ({
192
+ identifier,
193
+ keyId,
194
+ apiUrl,
195
+ }: {
196
+ identifier: string;
197
+ keyId: string;
198
+ apiUrl: string;
199
+ }) => `${identifier}-${keyId}-${apiUrl}`,
200
+ }
201
+ );
202
+
203
+ /**
204
+ * Get a turnkey signer
205
+ */
206
+ const getTurnkeySigner = memo(
207
+ async ({
208
+ keyId,
209
+ privateKeyId,
210
+ turnkeyClient,
211
+ }: {
212
+ keyId: string;
213
+ privateKeyId: string;
214
+ turnkeyClient: unknown;
215
+ }) => {
216
+ // Get the turnkey viem account
217
+ const [, turnkeyViem] = await tryit(() => import("@turnkey/viem"))();
218
+ if (!turnkeyViem) {
219
+ console.error("@turnkey/viem module not available");
220
+ throw new Error(
221
+ "Turnkey viem module not available, can't create a turnkey signer for the custodial owner"
222
+ );
223
+ }
224
+ return turnkeyViem.createAccount({
225
+ client: turnkeyClient as any,
226
+ organizationId: keyId,
227
+ privateKeyId,
228
+ });
229
+ },
230
+ {
231
+ // TTL of 1min in the memory cache
232
+ ttl: 1000 * 60,
233
+ // The key in the cache
234
+ key: ({
235
+ keyId,
236
+ privateKeyId,
237
+ }: {
238
+ keyId: string;
239
+ privateKeyId: string;
240
+ turnkeyClient: unknown;
241
+ }) => `${keyId}-${privateKeyId}`,
242
+ }
243
+ );
@@ -47,10 +47,10 @@ export const signMessageImplementation = async (
47
47
  const signedRequest = await TurnkeyApi.signSignRawPayload(
48
48
  {
49
49
  body: {
50
- type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD",
50
+ type: "ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2",
51
51
  organizationId: id,
52
52
  parameters: {
53
- privateKeyId: walletId,
53
+ signWith: walletId,
54
54
  payload: msg,
55
55
  encoding: "PAYLOAD_ENCODING_HEXADECIMAL",
56
56
  hashFunction: "HASH_FUNCTION_NO_OP",