@zerodev/wallet-core 0.0.1-alpha.10

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.
Files changed (292) hide show
  1. package/README.md +310 -0
  2. package/dist/_cjs/actions/auth/authenticateWithEmail.js +17 -0
  3. package/dist/_cjs/actions/auth/authenticateWithEmail.js.map +1 -0
  4. package/dist/_cjs/actions/auth/authenticateWithOAuth.js +13 -0
  5. package/dist/_cjs/actions/auth/authenticateWithOAuth.js.map +1 -0
  6. package/dist/_cjs/actions/auth/getAuthProxyConfigId.js +10 -0
  7. package/dist/_cjs/actions/auth/getAuthProxyConfigId.js.map +1 -0
  8. package/dist/_cjs/actions/auth/getUserEmail.js +19 -0
  9. package/dist/_cjs/actions/auth/getUserEmail.js.map +1 -0
  10. package/dist/_cjs/actions/auth/getWhoami.js +15 -0
  11. package/dist/_cjs/actions/auth/getWhoami.js.map +1 -0
  12. package/dist/_cjs/actions/auth/index.js +22 -0
  13. package/dist/_cjs/actions/auth/index.js.map +1 -0
  14. package/dist/_cjs/actions/auth/loginWithOTP.js +15 -0
  15. package/dist/_cjs/actions/auth/loginWithOTP.js.map +1 -0
  16. package/dist/_cjs/actions/auth/loginWithStamp.js +39 -0
  17. package/dist/_cjs/actions/auth/loginWithStamp.js.map +1 -0
  18. package/dist/_cjs/actions/auth/registerWithOTP.js +16 -0
  19. package/dist/_cjs/actions/auth/registerWithOTP.js.map +1 -0
  20. package/dist/_cjs/actions/auth/registerWithPasskey.js +17 -0
  21. package/dist/_cjs/actions/auth/registerWithPasskey.js.map +1 -0
  22. package/dist/_cjs/actions/index.js +17 -0
  23. package/dist/_cjs/actions/index.js.map +1 -0
  24. package/dist/_cjs/actions/wallet/getUserWallet.js +18 -0
  25. package/dist/_cjs/actions/wallet/getUserWallet.js.map +1 -0
  26. package/dist/_cjs/actions/wallet/index.js +10 -0
  27. package/dist/_cjs/actions/wallet/index.js.map +1 -0
  28. package/dist/_cjs/actions/wallet/signRawPayload.js +27 -0
  29. package/dist/_cjs/actions/wallet/signRawPayload.js.map +1 -0
  30. package/dist/_cjs/actions/wallet/signTransaction.js +26 -0
  31. package/dist/_cjs/actions/wallet/signTransaction.js.map +1 -0
  32. package/dist/_cjs/adapters/viem.js +92 -0
  33. package/dist/_cjs/adapters/viem.js.map +1 -0
  34. package/dist/_cjs/client/authProxy.js +31 -0
  35. package/dist/_cjs/client/authProxy.js.map +1 -0
  36. package/dist/_cjs/client/createClient.js +49 -0
  37. package/dist/_cjs/client/createClient.js.map +1 -0
  38. package/dist/_cjs/client/decorators/client.js +23 -0
  39. package/dist/_cjs/client/decorators/client.js.map +1 -0
  40. package/dist/_cjs/client/index.js +11 -0
  41. package/dist/_cjs/client/index.js.map +1 -0
  42. package/dist/_cjs/client/transports/createTransport.js +31 -0
  43. package/dist/_cjs/client/transports/createTransport.js.map +1 -0
  44. package/dist/_cjs/client/transports/rest.js +104 -0
  45. package/dist/_cjs/client/transports/rest.js.map +1 -0
  46. package/dist/_cjs/client/types.js +3 -0
  47. package/dist/_cjs/client/types.js.map +1 -0
  48. package/dist/_cjs/constants.js +9 -0
  49. package/dist/_cjs/constants.js.map +1 -0
  50. package/dist/_cjs/core/createZeroDevWallet.js +302 -0
  51. package/dist/_cjs/core/createZeroDevWallet.js.map +1 -0
  52. package/dist/_cjs/errors/request.js +61 -0
  53. package/dist/_cjs/errors/request.js.map +1 -0
  54. package/dist/_cjs/index.js +35 -0
  55. package/dist/_cjs/index.js.map +1 -0
  56. package/dist/_cjs/package.json +1 -0
  57. package/dist/_cjs/polyfills/window.js +26 -0
  58. package/dist/_cjs/polyfills/window.js.map +1 -0
  59. package/dist/_cjs/stampers/iframeStamper.js +35 -0
  60. package/dist/_cjs/stampers/iframeStamper.js.map +1 -0
  61. package/dist/_cjs/stampers/index.js +10 -0
  62. package/dist/_cjs/stampers/index.js.map +1 -0
  63. package/dist/_cjs/stampers/indexedDbStamper.js +23 -0
  64. package/dist/_cjs/stampers/indexedDbStamper.js.map +1 -0
  65. package/dist/_cjs/stampers/types.js +3 -0
  66. package/dist/_cjs/stampers/types.js.map +1 -0
  67. package/dist/_cjs/stampers/webauthnStamper.js +17 -0
  68. package/dist/_cjs/stampers/webauthnStamper.js.map +1 -0
  69. package/dist/_cjs/storage/adapters.js +18 -0
  70. package/dist/_cjs/storage/adapters.js.map +1 -0
  71. package/dist/_cjs/storage/manager.js +108 -0
  72. package/dist/_cjs/storage/manager.js.map +1 -0
  73. package/dist/_cjs/types/session.js +9 -0
  74. package/dist/_cjs/types/session.js.map +1 -0
  75. package/dist/_cjs/utils/buildClientSignature.js +39 -0
  76. package/dist/_cjs/utils/buildClientSignature.js.map +1 -0
  77. package/dist/_cjs/utils/derToRawSignature.js +63 -0
  78. package/dist/_cjs/utils/derToRawSignature.js.map +1 -0
  79. package/dist/_cjs/utils/exportPrivateKey.js +55 -0
  80. package/dist/_cjs/utils/exportPrivateKey.js.map +1 -0
  81. package/dist/_cjs/utils/exportWallet.js +70 -0
  82. package/dist/_cjs/utils/exportWallet.js.map +1 -0
  83. package/dist/_cjs/utils/utils.js +75 -0
  84. package/dist/_cjs/utils/utils.js.map +1 -0
  85. package/dist/_esm/actions/auth/authenticateWithEmail.js +18 -0
  86. package/dist/_esm/actions/auth/authenticateWithEmail.js.map +1 -0
  87. package/dist/_esm/actions/auth/authenticateWithOAuth.js +29 -0
  88. package/dist/_esm/actions/auth/authenticateWithOAuth.js.map +1 -0
  89. package/dist/_esm/actions/auth/getAuthProxyConfigId.js +13 -0
  90. package/dist/_esm/actions/auth/getAuthProxyConfigId.js.map +1 -0
  91. package/dist/_esm/actions/auth/getUserEmail.js +33 -0
  92. package/dist/_esm/actions/auth/getUserEmail.js.map +1 -0
  93. package/dist/_esm/actions/auth/getWhoami.js +28 -0
  94. package/dist/_esm/actions/auth/getWhoami.js.map +1 -0
  95. package/dist/_esm/actions/auth/index.js +10 -0
  96. package/dist/_esm/actions/auth/index.js.map +1 -0
  97. package/dist/_esm/actions/auth/loginWithOTP.js +38 -0
  98. package/dist/_esm/actions/auth/loginWithOTP.js.map +1 -0
  99. package/dist/_esm/actions/auth/loginWithStamp.js +52 -0
  100. package/dist/_esm/actions/auth/loginWithStamp.js.map +1 -0
  101. package/dist/_esm/actions/auth/registerWithOTP.js +35 -0
  102. package/dist/_esm/actions/auth/registerWithOTP.js.map +1 -0
  103. package/dist/_esm/actions/auth/registerWithPasskey.js +36 -0
  104. package/dist/_esm/actions/auth/registerWithPasskey.js.map +1 -0
  105. package/dist/_esm/actions/index.js +5 -0
  106. package/dist/_esm/actions/index.js.map +1 -0
  107. package/dist/_esm/actions/wallet/getUserWallet.js +31 -0
  108. package/dist/_esm/actions/wallet/getUserWallet.js.map +1 -0
  109. package/dist/_esm/actions/wallet/index.js +4 -0
  110. package/dist/_esm/actions/wallet/index.js.map +1 -0
  111. package/dist/_esm/actions/wallet/signRawPayload.js +42 -0
  112. package/dist/_esm/actions/wallet/signRawPayload.js.map +1 -0
  113. package/dist/_esm/actions/wallet/signTransaction.js +41 -0
  114. package/dist/_esm/actions/wallet/signTransaction.js.map +1 -0
  115. package/dist/_esm/adapters/viem.js +94 -0
  116. package/dist/_esm/adapters/viem.js.map +1 -0
  117. package/dist/_esm/client/authProxy.js +41 -0
  118. package/dist/_esm/client/authProxy.js.map +1 -0
  119. package/dist/_esm/client/createClient.js +60 -0
  120. package/dist/_esm/client/createClient.js.map +1 -0
  121. package/dist/_esm/client/decorators/client.js +44 -0
  122. package/dist/_esm/client/decorators/client.js.map +1 -0
  123. package/dist/_esm/client/index.js +4 -0
  124. package/dist/_esm/client/index.js.map +1 -0
  125. package/dist/_esm/client/transports/createTransport.js +33 -0
  126. package/dist/_esm/client/transports/createTransport.js.map +1 -0
  127. package/dist/_esm/client/transports/rest.js +103 -0
  128. package/dist/_esm/client/transports/rest.js.map +1 -0
  129. package/dist/_esm/client/types.js +2 -0
  130. package/dist/_esm/client/types.js.map +1 -0
  131. package/dist/_esm/constants.js +6 -0
  132. package/dist/_esm/constants.js.map +1 -0
  133. package/dist/_esm/core/createZeroDevWallet.js +308 -0
  134. package/dist/_esm/core/createZeroDevWallet.js.map +1 -0
  135. package/dist/_esm/errors/request.js +60 -0
  136. package/dist/_esm/errors/request.js.map +1 -0
  137. package/dist/_esm/index.js +23 -0
  138. package/dist/_esm/index.js.map +1 -0
  139. package/dist/_esm/package.json +1 -0
  140. package/dist/_esm/polyfills/window.js +24 -0
  141. package/dist/_esm/polyfills/window.js.map +1 -0
  142. package/dist/_esm/stampers/iframeStamper.js +32 -0
  143. package/dist/_esm/stampers/iframeStamper.js.map +1 -0
  144. package/dist/_esm/stampers/index.js +4 -0
  145. package/dist/_esm/stampers/index.js.map +1 -0
  146. package/dist/_esm/stampers/indexedDbStamper.js +20 -0
  147. package/dist/_esm/stampers/indexedDbStamper.js.map +1 -0
  148. package/dist/_esm/stampers/types.js +2 -0
  149. package/dist/_esm/stampers/types.js.map +1 -0
  150. package/dist/_esm/stampers/webauthnStamper.js +15 -0
  151. package/dist/_esm/stampers/webauthnStamper.js.map +1 -0
  152. package/dist/_esm/storage/adapters.js +15 -0
  153. package/dist/_esm/storage/adapters.js.map +1 -0
  154. package/dist/_esm/storage/manager.js +118 -0
  155. package/dist/_esm/storage/manager.js.map +1 -0
  156. package/dist/_esm/types/session.js +6 -0
  157. package/dist/_esm/types/session.js.map +1 -0
  158. package/dist/_esm/utils/buildClientSignature.js +64 -0
  159. package/dist/_esm/utils/buildClientSignature.js.map +1 -0
  160. package/dist/_esm/utils/derToRawSignature.js +89 -0
  161. package/dist/_esm/utils/derToRawSignature.js.map +1 -0
  162. package/dist/_esm/utils/exportPrivateKey.js +83 -0
  163. package/dist/_esm/utils/exportPrivateKey.js.map +1 -0
  164. package/dist/_esm/utils/exportWallet.js +98 -0
  165. package/dist/_esm/utils/exportWallet.js.map +1 -0
  166. package/dist/_esm/utils/utils.js +105 -0
  167. package/dist/_esm/utils/utils.js.map +1 -0
  168. package/dist/_types/actions/auth/authenticateWithEmail.d.ts +33 -0
  169. package/dist/_types/actions/auth/authenticateWithEmail.d.ts.map +1 -0
  170. package/dist/_types/actions/auth/authenticateWithOAuth.d.ts +38 -0
  171. package/dist/_types/actions/auth/authenticateWithOAuth.d.ts.map +1 -0
  172. package/dist/_types/actions/auth/getAuthProxyConfigId.d.ts +12 -0
  173. package/dist/_types/actions/auth/getAuthProxyConfigId.d.ts.map +1 -0
  174. package/dist/_types/actions/auth/getUserEmail.d.ts +32 -0
  175. package/dist/_types/actions/auth/getUserEmail.d.ts.map +1 -0
  176. package/dist/_types/actions/auth/getWhoami.d.ts +35 -0
  177. package/dist/_types/actions/auth/getWhoami.d.ts.map +1 -0
  178. package/dist/_types/actions/auth/index.d.ts +10 -0
  179. package/dist/_types/actions/auth/index.d.ts.map +1 -0
  180. package/dist/_types/actions/auth/loginWithOTP.d.ts +41 -0
  181. package/dist/_types/actions/auth/loginWithOTP.d.ts.map +1 -0
  182. package/dist/_types/actions/auth/loginWithStamp.d.ts +37 -0
  183. package/dist/_types/actions/auth/loginWithStamp.d.ts.map +1 -0
  184. package/dist/_types/actions/auth/registerWithOTP.d.ts +46 -0
  185. package/dist/_types/actions/auth/registerWithOTP.d.ts.map +1 -0
  186. package/dist/_types/actions/auth/registerWithPasskey.d.ts +53 -0
  187. package/dist/_types/actions/auth/registerWithPasskey.d.ts.map +1 -0
  188. package/dist/_types/actions/index.d.ts +3 -0
  189. package/dist/_types/actions/index.d.ts.map +1 -0
  190. package/dist/_types/actions/wallet/getUserWallet.d.ts +34 -0
  191. package/dist/_types/actions/wallet/getUserWallet.d.ts.map +1 -0
  192. package/dist/_types/actions/wallet/index.d.ts +4 -0
  193. package/dist/_types/actions/wallet/index.d.ts.map +1 -0
  194. package/dist/_types/actions/wallet/signRawPayload.d.ts +39 -0
  195. package/dist/_types/actions/wallet/signRawPayload.d.ts.map +1 -0
  196. package/dist/_types/actions/wallet/signTransaction.d.ts +35 -0
  197. package/dist/_types/actions/wallet/signTransaction.d.ts.map +1 -0
  198. package/dist/_types/adapters/viem.d.ts +10 -0
  199. package/dist/_types/adapters/viem.d.ts.map +1 -0
  200. package/dist/_types/client/authProxy.d.ts +36 -0
  201. package/dist/_types/client/authProxy.d.ts.map +1 -0
  202. package/dist/_types/client/createClient.d.ts +17 -0
  203. package/dist/_types/client/createClient.d.ts.map +1 -0
  204. package/dist/_types/client/decorators/client.d.ts +81 -0
  205. package/dist/_types/client/decorators/client.d.ts.map +1 -0
  206. package/dist/_types/client/index.d.ts +5 -0
  207. package/dist/_types/client/index.d.ts.map +1 -0
  208. package/dist/_types/client/transports/createTransport.d.ts +17 -0
  209. package/dist/_types/client/transports/createTransport.d.ts.map +1 -0
  210. package/dist/_types/client/transports/rest.d.ts +35 -0
  211. package/dist/_types/client/transports/rest.d.ts.map +1 -0
  212. package/dist/_types/client/types.d.ts +59 -0
  213. package/dist/_types/client/types.d.ts.map +1 -0
  214. package/dist/_types/constants.d.ts +6 -0
  215. package/dist/_types/constants.d.ts.map +1 -0
  216. package/dist/_types/core/createZeroDevWallet.d.ts +52 -0
  217. package/dist/_types/core/createZeroDevWallet.d.ts.map +1 -0
  218. package/dist/_types/errors/request.d.ts +12 -0
  219. package/dist/_types/errors/request.d.ts.map +1 -0
  220. package/dist/_types/index.d.ts +20 -0
  221. package/dist/_types/index.d.ts.map +1 -0
  222. package/dist/_types/polyfills/window.d.ts +15 -0
  223. package/dist/_types/polyfills/window.d.ts.map +1 -0
  224. package/dist/_types/stampers/iframeStamper.d.ts +7 -0
  225. package/dist/_types/stampers/iframeStamper.d.ts.map +1 -0
  226. package/dist/_types/stampers/index.d.ts +5 -0
  227. package/dist/_types/stampers/index.d.ts.map +1 -0
  228. package/dist/_types/stampers/indexedDbStamper.d.ts +3 -0
  229. package/dist/_types/stampers/indexedDbStamper.d.ts.map +1 -0
  230. package/dist/_types/stampers/types.d.ts +25 -0
  231. package/dist/_types/stampers/types.d.ts.map +1 -0
  232. package/dist/_types/stampers/webauthnStamper.d.ts +5 -0
  233. package/dist/_types/stampers/webauthnStamper.d.ts.map +1 -0
  234. package/dist/_types/storage/adapters.d.ts +3 -0
  235. package/dist/_types/storage/adapters.d.ts.map +1 -0
  236. package/dist/_types/storage/manager.d.ts +19 -0
  237. package/dist/_types/storage/manager.d.ts.map +1 -0
  238. package/dist/_types/types/session.d.ts +17 -0
  239. package/dist/_types/types/session.d.ts.map +1 -0
  240. package/dist/_types/utils/buildClientSignature.d.ts +25 -0
  241. package/dist/_types/utils/buildClientSignature.d.ts.map +1 -0
  242. package/dist/_types/utils/derToRawSignature.d.ts +11 -0
  243. package/dist/_types/utils/derToRawSignature.d.ts.map +1 -0
  244. package/dist/_types/utils/exportPrivateKey.d.ts +47 -0
  245. package/dist/_types/utils/exportPrivateKey.d.ts.map +1 -0
  246. package/dist/_types/utils/exportWallet.d.ts +44 -0
  247. package/dist/_types/utils/exportWallet.d.ts.map +1 -0
  248. package/dist/_types/utils/utils.d.ts +52 -0
  249. package/dist/_types/utils/utils.d.ts.map +1 -0
  250. package/dist/tsconfig.build.tsbuildinfo +1 -0
  251. package/package.json +74 -0
  252. package/src/actions/auth/authenticateWithEmail.ts +52 -0
  253. package/src/actions/auth/authenticateWithOAuth.ts +52 -0
  254. package/src/actions/auth/getAuthProxyConfigId.ts +20 -0
  255. package/src/actions/auth/getUserEmail.ts +52 -0
  256. package/src/actions/auth/getWhoami.ts +51 -0
  257. package/src/actions/auth/index.ts +47 -0
  258. package/src/actions/auth/loginWithOTP.ts +57 -0
  259. package/src/actions/auth/loginWithStamp.ts +79 -0
  260. package/src/actions/auth/registerWithOTP.ts +64 -0
  261. package/src/actions/auth/registerWithPasskey.ts +72 -0
  262. package/src/actions/index.ts +41 -0
  263. package/src/actions/wallet/getUserWallet.ts +53 -0
  264. package/src/actions/wallet/index.ts +17 -0
  265. package/src/actions/wallet/signRawPayload.ts +75 -0
  266. package/src/actions/wallet/signTransaction.ts +64 -0
  267. package/src/adapters/viem.ts +162 -0
  268. package/src/client/authProxy.ts +78 -0
  269. package/src/client/createClient.ts +90 -0
  270. package/src/client/decorators/client.ts +171 -0
  271. package/src/client/index.ts +19 -0
  272. package/src/client/transports/createTransport.ts +54 -0
  273. package/src/client/transports/rest.ts +138 -0
  274. package/src/client/types.ts +64 -0
  275. package/src/constants.ts +5 -0
  276. package/src/core/createZeroDevWallet.ts +447 -0
  277. package/src/errors/request.ts +36 -0
  278. package/src/index.ts +79 -0
  279. package/src/polyfills/window.ts +24 -0
  280. package/src/stampers/iframeStamper.ts +49 -0
  281. package/src/stampers/index.ts +8 -0
  282. package/src/stampers/indexedDbStamper.ts +22 -0
  283. package/src/stampers/types.ts +35 -0
  284. package/src/stampers/webauthnStamper.ts +21 -0
  285. package/src/storage/adapters.ts +20 -0
  286. package/src/storage/manager.ts +170 -0
  287. package/src/types/session.ts +18 -0
  288. package/src/utils/buildClientSignature.ts +86 -0
  289. package/src/utils/derToRawSignature.ts +103 -0
  290. package/src/utils/exportPrivateKey.ts +116 -0
  291. package/src/utils/exportWallet.ts +130 -0
  292. package/src/utils/utils.ts +136 -0
@@ -0,0 +1,21 @@
1
+ import { WebauthnStamper as TurnkeyWebauthnStamper } from '@turnkey/webauthn-stamper'
2
+ import type { WebauthnStamper } from './types.js'
3
+
4
+ export async function createWebauthnStamper({
5
+ rpId,
6
+ }: {
7
+ rpId: string
8
+ }): Promise<WebauthnStamper> {
9
+ const inner = new TurnkeyWebauthnStamper({ rpId })
10
+
11
+ return {
12
+ async getPublicKey() {
13
+ // return await inner.();
14
+ return null
15
+ },
16
+ async stamp(payload: string) {
17
+ return await inner.stamp(payload)
18
+ },
19
+ async clear() {},
20
+ }
21
+ }
@@ -0,0 +1,20 @@
1
+ import WindowWrapper from '../polyfills/window.js'
2
+ import type { StorageAdapter } from './manager.js'
3
+
4
+ export function createWebStorageAdapter(
5
+ storage: Storage = WindowWrapper.localStorage,
6
+ ): StorageAdapter {
7
+ return {
8
+ getItem(key: string): string | null {
9
+ return storage.getItem(key)
10
+ },
11
+
12
+ setItem(key: string, value: string): void {
13
+ storage.setItem(key, value)
14
+ },
15
+
16
+ removeItem(key: string): void {
17
+ storage.removeItem(key)
18
+ },
19
+ }
20
+ }
@@ -0,0 +1,170 @@
1
+ import type { ZeroDevWalletSession } from '../types/session.js'
2
+ import { normalizeTimestamp } from '../utils/utils.js'
3
+
4
+ export type StorageAdapter = {
5
+ getItem(key: string): string | null | Promise<string | null>
6
+ setItem(key: string, value: string): void | Promise<void>
7
+ removeItem(key: string): void | Promise<void>
8
+ }
9
+
10
+ export type StorageManager = {
11
+ storeSession(
12
+ sessionData: ZeroDevWalletSession,
13
+ sessionKey: string,
14
+ ): Promise<void>
15
+ getActiveSession(): Promise<ZeroDevWalletSession | undefined>
16
+ getActiveSessionKey(): Promise<string | undefined>
17
+ getSession(sessionKey: string): Promise<ZeroDevWalletSession | undefined>
18
+ listSessionKeys(): Promise<string[]>
19
+ listSessions(): Promise<ZeroDevWalletSession[]>
20
+ setActiveSession(sessionKey: string): Promise<void>
21
+ clearSession(sessionKey: string): Promise<void>
22
+ clearAllSessions(): Promise<void>
23
+ }
24
+
25
+ export function createStorageManager(adapter: StorageAdapter): StorageManager {
26
+ const ACTIVE_SESSION_KEY = '@zerodev/active_session'
27
+ const ALL_SESSIONS_KEY = '@zerodev/sessions'
28
+
29
+ const storeSession = async (
30
+ sessionData: ZeroDevWalletSession,
31
+ sessionKey: string,
32
+ ): Promise<void> => {
33
+ // Store the session data
34
+ await adapter.setItem(sessionKey, JSON.stringify(sessionData))
35
+
36
+ // Add to sessions list if not already present
37
+ const sessionsStr = await adapter.getItem(ALL_SESSIONS_KEY)
38
+ const sessions = JSON.parse(sessionsStr || '[]')
39
+ if (!sessions.includes(sessionKey)) {
40
+ sessions.push(sessionKey)
41
+ await adapter.setItem(ALL_SESSIONS_KEY, JSON.stringify(sessions))
42
+ }
43
+
44
+ // Set as active session
45
+ await adapter.setItem(ACTIVE_SESSION_KEY, sessionKey)
46
+ }
47
+
48
+ const getActiveSession = async (): Promise<
49
+ ZeroDevWalletSession | undefined
50
+ > => {
51
+ const activeKey = await adapter.getItem(ACTIVE_SESSION_KEY)
52
+ if (!activeKey) return undefined
53
+
54
+ return getSession(activeKey)
55
+ }
56
+
57
+ const getActiveSessionKey = async (): Promise<string | undefined> => {
58
+ const key = await adapter.getItem(ACTIVE_SESSION_KEY)
59
+ return key || undefined
60
+ }
61
+
62
+ const getSession = async (
63
+ sessionKey: string,
64
+ ): Promise<ZeroDevWalletSession | undefined> => {
65
+ const sessionStr = await adapter.getItem(sessionKey)
66
+ if (!sessionStr) return undefined
67
+
68
+ try {
69
+ const session: ZeroDevWalletSession = JSON.parse(sessionStr)
70
+
71
+ // Check if session is expired
72
+ if (session.expiry && normalizeTimestamp(session.expiry) < Date.now()) {
73
+ await clearSession(sessionKey)
74
+ return undefined
75
+ }
76
+
77
+ return session
78
+ } catch (_error) {
79
+ // Invalid JSON, clean up
80
+ await clearSession(sessionKey)
81
+ return undefined
82
+ }
83
+ }
84
+
85
+ const listSessionKeys = async (): Promise<string[]> => {
86
+ const sessionsStr = await adapter.getItem(ALL_SESSIONS_KEY)
87
+ const sessionKeys = JSON.parse(sessionsStr || '[]')
88
+
89
+ // Clean up any keys that don't have corresponding sessions
90
+ const validKeys: string[] = []
91
+ for (const key of sessionKeys) {
92
+ const exists = await adapter.getItem(key)
93
+ if (exists) {
94
+ validKeys.push(key)
95
+ }
96
+ }
97
+
98
+ // Update the list if we found invalid keys
99
+ if (validKeys.length !== sessionKeys.length) {
100
+ await adapter.setItem(ALL_SESSIONS_KEY, JSON.stringify(validKeys))
101
+ }
102
+
103
+ return validKeys
104
+ }
105
+
106
+ const listSessions = async (): Promise<ZeroDevWalletSession[]> => {
107
+ const sessionKeys = await listSessionKeys()
108
+ const sessions: ZeroDevWalletSession[] = []
109
+
110
+ for (const key of sessionKeys) {
111
+ const session = await getSession(key)
112
+ if (session) {
113
+ sessions.push(session)
114
+ }
115
+ }
116
+
117
+ return sessions
118
+ }
119
+
120
+ const setActiveSession = async (sessionKey: string): Promise<void> => {
121
+ // Verify the session exists
122
+ const session = await getSession(sessionKey)
123
+ if (!session) {
124
+ throw new Error(`Session not found: ${sessionKey}`)
125
+ }
126
+
127
+ await adapter.setItem(ACTIVE_SESSION_KEY, sessionKey)
128
+ }
129
+
130
+ const clearSession = async (sessionKey: string): Promise<void> => {
131
+ // Remove the session data
132
+ await adapter.removeItem(sessionKey)
133
+
134
+ // Remove from sessions list
135
+ const sessions = await listSessionKeys()
136
+ const updated = sessions.filter((k) => k !== sessionKey)
137
+ await adapter.setItem(ALL_SESSIONS_KEY, JSON.stringify(updated))
138
+
139
+ // Clear active session if it was the cleared one
140
+ const activeKey = await adapter.getItem(ACTIVE_SESSION_KEY)
141
+ if (activeKey === sessionKey) {
142
+ await adapter.removeItem(ACTIVE_SESSION_KEY)
143
+ }
144
+ }
145
+
146
+ const clearAllSessions = async (): Promise<void> => {
147
+ const sessions = await listSessionKeys()
148
+
149
+ // Remove all session data
150
+ for (const key of sessions) {
151
+ await adapter.removeItem(key)
152
+ }
153
+
154
+ // Clear the metadata
155
+ await adapter.removeItem(ALL_SESSIONS_KEY)
156
+ await adapter.removeItem(ACTIVE_SESSION_KEY)
157
+ }
158
+
159
+ return {
160
+ storeSession,
161
+ getActiveSession,
162
+ getActiveSessionKey,
163
+ getSession,
164
+ listSessionKeys,
165
+ listSessions,
166
+ setActiveSession,
167
+ clearSession,
168
+ clearAllSessions,
169
+ }
170
+ }
@@ -0,0 +1,18 @@
1
+ export enum SessionType {
2
+ READ_ONLY = 'SESSION_TYPE_READ_ONLY',
3
+ READ_WRITE = 'SESSION_TYPE_READ_WRITE',
4
+ }
5
+
6
+ export type StamperType = 'iframe' | 'indexedDb' | 'passkey'
7
+
8
+ export type ZeroDevWalletSession = {
9
+ id: string
10
+ userId: string
11
+ organizationId: string
12
+ stamperType: StamperType
13
+ sessionType?: SessionType
14
+ token?: string
15
+ publicKey?: string
16
+ expiry: number
17
+ createdAt: number
18
+ }
@@ -0,0 +1,86 @@
1
+ import type { IndexedDbStamper } from '../stampers/types.js'
2
+ import { derToRawSignature } from './derToRawSignature.js'
3
+
4
+ export type BuildClientSignatureParams = {
5
+ /** The verification token JWT from Auth Proxy's verifyOtp */
6
+ verificationToken: string
7
+ /** The compressed public key hex */
8
+ publicKey: string
9
+ /** The IndexedDB stamper for signing */
10
+ stamper: IndexedDbStamper
11
+ }
12
+
13
+ /**
14
+ * Builds a client signature for OTP login.
15
+ *
16
+ * Steps:
17
+ * 1. Decode verificationToken JWT to extract `id` field as tokenId
18
+ * 2. Build message: JSON.stringify({ login: { publicKey }, tokenId, type: "USAGE_TYPE_LOGIN" })
19
+ * 3. Sign message with stamper → get stampHeaderValue
20
+ * 4. Parse stampHeaderValue → extract DER signature hex
21
+ * 5. Convert DER to raw r||s format
22
+ * 6. Return raw signature hex
23
+ *
24
+ * @param params - The parameters for building the client signature
25
+ * @returns The raw r||s signature hex (64 bytes = 128 chars)
26
+ */
27
+ export async function buildClientSignature(
28
+ params: BuildClientSignatureParams,
29
+ ): Promise<string> {
30
+ const { verificationToken, publicKey, stamper } = params
31
+
32
+ // Step 1: Extract tokenId from verification token JWT payload
33
+ const tokenId = extractTokenIdFromJwt(verificationToken)
34
+
35
+ // Step 2: Build the signature payload message
36
+ const signaturePayload = {
37
+ login: { publicKey },
38
+ tokenId,
39
+ type: 'USAGE_TYPE_LOGIN',
40
+ }
41
+ const message = JSON.stringify(signaturePayload)
42
+
43
+ // Step 3: Sign the message using the stamper
44
+ const stamp = await stamper.stamp(message)
45
+
46
+ // Step 4: Parse the stamp to extract the DER signature
47
+ // The stampHeaderValue is base64url encoded JSON containing the signature
48
+ const stampData = JSON.parse(base64UrlDecode(stamp.stampHeaderValue))
49
+ const derSignatureHex: string = stampData.signature
50
+
51
+ // Step 5: Convert DER signature to raw r||s format
52
+ const rawSignature = derToRawSignature(derSignatureHex)
53
+
54
+ // Step 6: Return raw signature hex
55
+ return rawSignature
56
+ }
57
+
58
+ /**
59
+ * Extracts the token ID (id field) from a JWT's payload
60
+ */
61
+ function extractTokenIdFromJwt(jwt: string): string {
62
+ const parts = jwt.split('.')
63
+ if (parts.length !== 3) {
64
+ throw new Error('Invalid JWT format')
65
+ }
66
+
67
+ const payload = JSON.parse(base64UrlDecode(parts[1]!))
68
+ if (!payload.id) {
69
+ throw new Error('JWT payload missing id field')
70
+ }
71
+
72
+ return payload.id
73
+ }
74
+
75
+ /**
76
+ * Decodes a base64url encoded string
77
+ */
78
+ function base64UrlDecode(str: string): string {
79
+ // Add padding if necessary
80
+ let base64 = str.replace(/-/g, '+').replace(/_/g, '/')
81
+ const padding = base64.length % 4
82
+ if (padding) {
83
+ base64 += '='.repeat(4 - padding)
84
+ }
85
+ return atob(base64)
86
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Converts a DER-encoded ECDSA signature to raw r||s format.
3
+ *
4
+ * DER format: 0x30 [length] 0x02 [r-length] [r] 0x02 [s-length] [s]
5
+ * Raw format: [r (32 bytes)] [s (32 bytes)]
6
+ *
7
+ * @param derHex - The DER-encoded signature as a hex string
8
+ * @returns The raw signature as a hex string (r||s, 64 bytes = 128 chars)
9
+ */
10
+ export function derToRawSignature(derHex: string): string {
11
+ const der = hexToBytes(derHex)
12
+
13
+ // Verify SEQUENCE tag (0x30)
14
+ if (der[0] !== 0x30) {
15
+ throw new Error('Invalid DER signature: expected SEQUENCE tag (0x30)')
16
+ }
17
+
18
+ let offset = 2 // Skip SEQUENCE tag and length
19
+
20
+ // Parse r INTEGER
21
+ if (der[offset] !== 0x02) {
22
+ throw new Error('Invalid DER signature: expected INTEGER tag (0x02) for r')
23
+ }
24
+ offset++ // Skip INTEGER tag
25
+
26
+ const rLength = der[offset]!
27
+ offset++ // Skip length byte
28
+
29
+ const rBytes = der.slice(offset, offset + rLength)
30
+ offset += rLength
31
+
32
+ // Parse s INTEGER
33
+ if (der[offset] !== 0x02) {
34
+ throw new Error('Invalid DER signature: expected INTEGER tag (0x02) for s')
35
+ }
36
+ offset++ // Skip INTEGER tag
37
+
38
+ const sLength = der[offset]!
39
+ offset++ // Skip length byte
40
+
41
+ const sBytes = der.slice(offset, offset + sLength)
42
+
43
+ // Remove leading zero bytes if present (DER uses signed integers)
44
+ // and pad to 32 bytes
45
+ const r = padTo32Bytes(stripLeadingZeros(rBytes))
46
+ const s = padTo32Bytes(stripLeadingZeros(sBytes))
47
+
48
+ // Concatenate r || s
49
+ const raw = new Uint8Array(64)
50
+ raw.set(r, 0)
51
+ raw.set(s, 32)
52
+
53
+ return bytesToHex(raw)
54
+ }
55
+
56
+ /**
57
+ * Converts a hex string to a Uint8Array
58
+ */
59
+ function hexToBytes(hex: string): Uint8Array {
60
+ const cleanHex = hex.startsWith('0x') ? hex.slice(2) : hex
61
+ const bytes = new Uint8Array(cleanHex.length / 2)
62
+ for (let i = 0; i < bytes.length; i++) {
63
+ bytes[i] = parseInt(cleanHex.slice(i * 2, i * 2 + 2), 16)
64
+ }
65
+ return bytes
66
+ }
67
+
68
+ /**
69
+ * Converts a Uint8Array to a hex string (no 0x prefix)
70
+ */
71
+ function bytesToHex(bytes: Uint8Array): string {
72
+ return Array.from(bytes)
73
+ .map((b) => b.toString(16).padStart(2, '0'))
74
+ .join('')
75
+ }
76
+
77
+ /**
78
+ * Strips leading zero bytes from a byte array
79
+ * DER integers are signed, so positive numbers may have a leading 0x00
80
+ */
81
+ function stripLeadingZeros(bytes: Uint8Array): Uint8Array {
82
+ let start = 0
83
+ while (start < bytes.length - 1 && bytes[start] === 0) {
84
+ start++
85
+ }
86
+ return bytes.slice(start)
87
+ }
88
+
89
+ /**
90
+ * Pads a byte array to 32 bytes (left-padded with zeros)
91
+ */
92
+ function padTo32Bytes(bytes: Uint8Array): Uint8Array {
93
+ if (bytes.length === 32) {
94
+ return bytes
95
+ }
96
+ if (bytes.length > 32) {
97
+ // This shouldn't happen for P-256, but handle it gracefully
98
+ return bytes.slice(bytes.length - 32)
99
+ }
100
+ const padded = new Uint8Array(32)
101
+ padded.set(bytes, 32 - bytes.length)
102
+ return padded
103
+ }
@@ -0,0 +1,116 @@
1
+ import type { ZeroDevWalletSDK } from '../core/createZeroDevWallet.js'
2
+ import type { KeyFormat } from '../stampers/types.js'
3
+
4
+ export type ExportPrivateKeyParameters = {
5
+ /** Wallet to use for the export */
6
+ wallet: ZeroDevWalletSDK
7
+ /** Target public key from export iframe for encryption */
8
+ targetPublicKey: string
9
+ /** Wallet address to export (optional, defaults to wallet's account address) */
10
+ address?: string
11
+ }
12
+
13
+ /**
14
+ * Export a wallet account's private key
15
+ *
16
+ * This calls Turnkey's export_wallet_account API to get an encrypted bundle
17
+ * containing the account's private key. The bundle is encrypted with the
18
+ * targetPublicKey (from Turnkey's export iframe).
19
+ *
20
+ * @param params - Export parameters
21
+ * @returns Encrypted export bundle and metadata
22
+ *
23
+ * @example
24
+ * ```ts
25
+ * // In UI: Initialize export iframe first
26
+ * const iframeStamper = await createIframeStamper({
27
+ * iframeUrl: 'https://export.turnkey.com',
28
+ * iframeContainer: document.getElementById('export-container'),
29
+ * iframeElementId: 'export-iframe'
30
+ * });
31
+ * const targetPublicKey = await iframeStamper.init();
32
+ *
33
+ * // Call SDK to get encrypted bundle
34
+ * const { exportBundle, address, organizationId } = await exportPrivateKey({
35
+ * wallet,
36
+ * targetPublicKey
37
+ * });
38
+ *
39
+ * // Inject into iframe to display private key
40
+ * await iframeStamper.injectKeyExportBundle(exportBundle, organizationId, 'Hexadecimal');
41
+ * ```
42
+ */
43
+ export async function exportPrivateKey(
44
+ params: ExportPrivateKeyParameters,
45
+ ): Promise<{ exportBundle: string; address: string; organizationId: string }> {
46
+ const { targetPublicKey, wallet, address: addressParam } = params
47
+
48
+ const session = await wallet.getSession()
49
+ if (!session) {
50
+ throw new Error('Session not found')
51
+ }
52
+ const { organizationId } = session
53
+
54
+ // If address not provided, get it from the wallet's account
55
+ let address = addressParam
56
+ if (!address) {
57
+ const account = await wallet.toAccount()
58
+ if (!account?.address) {
59
+ throw new Error('Could not get address from wallet account')
60
+ }
61
+ address = account.address
62
+ }
63
+
64
+ const exportBody = JSON.stringify({
65
+ type: 'ACTIVITY_TYPE_EXPORT_WALLET_ACCOUNT',
66
+ timestampMs: Date.now().toString(),
67
+ organizationId: organizationId,
68
+ parameters: {
69
+ address: address,
70
+ targetPublicKey,
71
+ },
72
+ })
73
+
74
+ const stamperKey =
75
+ session.stamperType === 'indexedDb' ? 'indexedDbStamper' : 'webauthnStamper'
76
+ const stamper = wallet.client[stamperKey]
77
+ if (!stamper) {
78
+ throw new Error(`Stamper '${stamperKey}' not found on wallet.client`)
79
+ }
80
+
81
+ const exportStamp = await stamper.stamp(exportBody)
82
+ if (!exportStamp) {
83
+ throw new Error('Failed to stamp export body')
84
+ }
85
+
86
+ const exportResponse = await fetch(
87
+ 'https://api.turnkey.com/public/v1/submit/export_wallet_account',
88
+ {
89
+ method: 'POST',
90
+ body: exportBody,
91
+ headers: {
92
+ [exportStamp.stampHeaderName]: exportStamp.stampHeaderValue,
93
+ },
94
+ },
95
+ )
96
+ if (!exportResponse.ok) {
97
+ const errorText = await exportResponse.text()
98
+ throw new Error(
99
+ `Failed to export wallet account: ${exportResponse.status} ${errorText}`,
100
+ )
101
+ }
102
+ const exportData = await exportResponse.json()
103
+
104
+ const exportBundle =
105
+ exportData?.activity?.result?.exportWalletAccountResult?.exportBundle
106
+
107
+ if (!exportBundle) {
108
+ throw new Error(
109
+ `Export bundle not found in response: ${JSON.stringify(exportData)}`,
110
+ )
111
+ }
112
+
113
+ return { exportBundle, address: address!, organizationId }
114
+ }
115
+
116
+ export type { KeyFormat }
@@ -0,0 +1,130 @@
1
+ import type { ZeroDevWalletSDK } from '../core/createZeroDevWallet.js'
2
+
3
+ export type ExportWalletParameters = {
4
+ /** Wallet to use for the export */
5
+ wallet: ZeroDevWalletSDK
6
+ /** Target public key from export iframe for encryption */
7
+ targetPublicKey: string
8
+ }
9
+
10
+ /**
11
+ * TODO: Add it as standard action in the SDK when backend is ready
12
+ * Export a wallet's seed phrase
13
+ *
14
+ * This calls Turnkey's export_wallet API to get an encrypted bundle
15
+ * containing the wallet's mnemonic. The bundle is encrypted with the
16
+ * targetPublicKey (from Turnkey's export iframe).
17
+ *
18
+ * @param params - Export parameters
19
+ * @returns Encrypted export bundle
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * // In UI: Initialize export iframe first
24
+ * const iframeStamper = await createIframeStamper({
25
+ * iframeUrl: 'https://export.turnkey.com',
26
+ * iframeContainer: document.getElementById('export-container'),
27
+ * iframeElementId: 'export-iframe'
28
+ * });
29
+ * const targetPublicKey = await iframeStamper.init();
30
+ *
31
+ * // Call SDK to get encrypted bundle
32
+ * const exportBundle = await exportWallet({
33
+ * wallet,
34
+ * targetPublicKey
35
+ * });
36
+ *
37
+ * // Inject into iframe to display seed phrase
38
+ * await iframeStamper.injectWalletExportBundle(exportBundle, organizationId);
39
+ * ```
40
+ */
41
+ export async function exportWallet(
42
+ params: ExportWalletParameters,
43
+ ): Promise<{ exportBundle: string; walletId: string; organizationId: string }> {
44
+ const { targetPublicKey, wallet } = params
45
+
46
+ try {
47
+ const session = await wallet.getSession()
48
+ if (!session) {
49
+ throw new Error('Session not found')
50
+ }
51
+ const { organizationId } = session
52
+
53
+ const listWalletsBody = JSON.stringify({
54
+ organizationId,
55
+ })
56
+
57
+ const listWalletsStamp =
58
+ await wallet.client[
59
+ session.stamperType === 'indexedDb'
60
+ ? 'indexedDbStamper'
61
+ : 'webauthnStamper'
62
+ ].stamp(listWalletsBody)
63
+ if (!listWalletsStamp) {
64
+ throw new Error('Failed to stamp list wallets body')
65
+ }
66
+
67
+ const listWalletsResponse = await fetch(
68
+ 'https://api.turnkey.com/public/v1/query/list_wallets',
69
+ {
70
+ method: 'POST',
71
+ body: listWalletsBody,
72
+ headers: {
73
+ [listWalletsStamp.stampHeaderName]: listWalletsStamp.stampHeaderValue,
74
+ },
75
+ },
76
+ )
77
+ if (!listWalletsResponse.ok) {
78
+ throw new Error('Failed to list wallets')
79
+ }
80
+ const listWalletsData = await listWalletsResponse.json()
81
+
82
+ const walletId = listWalletsData.wallets[0].walletId
83
+
84
+ const exportWalletBody = JSON.stringify({
85
+ type: 'ACTIVITY_TYPE_EXPORT_WALLET',
86
+ timestampMs: Date.now().toString(),
87
+ organizationId: organizationId,
88
+ parameters: {
89
+ walletId: walletId,
90
+ targetPublicKey,
91
+ language: 'MNEMONIC_LANGUAGE_ENGLISH',
92
+ },
93
+ })
94
+ const exportWalletStamp =
95
+ await wallet.client[
96
+ session.stamperType === 'indexedDb'
97
+ ? 'indexedDbStamper'
98
+ : 'webauthnStamper'
99
+ ].stamp(exportWalletBody)
100
+ if (!exportWalletStamp) {
101
+ throw new Error('Failed to stamp export wallet body')
102
+ }
103
+ const exportWalletResponse = await fetch(
104
+ 'https://api.turnkey.com/public/v1/submit/export_wallet',
105
+ {
106
+ method: 'POST',
107
+ body: exportWalletBody,
108
+ headers: {
109
+ [exportWalletStamp.stampHeaderName]:
110
+ exportWalletStamp.stampHeaderValue,
111
+ },
112
+ },
113
+ )
114
+ if (!exportWalletResponse.ok) {
115
+ throw new Error('Failed to export wallet')
116
+ }
117
+ const exportWalletData = await exportWalletResponse.json()
118
+
119
+ const exportBundle =
120
+ exportWalletData?.activity?.result?.exportWalletResult?.exportBundle
121
+
122
+ if (!exportBundle) {
123
+ throw new Error('Export bundle not found in response')
124
+ }
125
+
126
+ return { exportBundle, walletId, organizationId }
127
+ } catch (_) {
128
+ throw new Error('Error exporting wallet')
129
+ }
130
+ }