@zerodev/wallet-core 0.0.1-alpha.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.
Files changed (250) hide show
  1. package/README.md +272 -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 +17 -0
  5. package/dist/_cjs/actions/auth/authenticateWithOAuth.js.map +1 -0
  6. package/dist/_cjs/actions/auth/getWhoami.js +15 -0
  7. package/dist/_cjs/actions/auth/getWhoami.js.map +1 -0
  8. package/dist/_cjs/actions/auth/index.js +18 -0
  9. package/dist/_cjs/actions/auth/index.js.map +1 -0
  10. package/dist/_cjs/actions/auth/loginWithOTP.js +17 -0
  11. package/dist/_cjs/actions/auth/loginWithOTP.js.map +1 -0
  12. package/dist/_cjs/actions/auth/loginWithStamp.js +29 -0
  13. package/dist/_cjs/actions/auth/loginWithStamp.js.map +1 -0
  14. package/dist/_cjs/actions/auth/registerWithOTP.js +17 -0
  15. package/dist/_cjs/actions/auth/registerWithOTP.js.map +1 -0
  16. package/dist/_cjs/actions/auth/registerWithPasskey.js +17 -0
  17. package/dist/_cjs/actions/auth/registerWithPasskey.js.map +1 -0
  18. package/dist/_cjs/actions/index.js +15 -0
  19. package/dist/_cjs/actions/index.js.map +1 -0
  20. package/dist/_cjs/actions/wallet/getUserWallet.js +13 -0
  21. package/dist/_cjs/actions/wallet/getUserWallet.js.map +1 -0
  22. package/dist/_cjs/actions/wallet/index.js +10 -0
  23. package/dist/_cjs/actions/wallet/index.js.map +1 -0
  24. package/dist/_cjs/actions/wallet/signRawPayload.js +26 -0
  25. package/dist/_cjs/actions/wallet/signRawPayload.js.map +1 -0
  26. package/dist/_cjs/actions/wallet/signTransaction.js +25 -0
  27. package/dist/_cjs/actions/wallet/signTransaction.js.map +1 -0
  28. package/dist/_cjs/adapters/viem.js +89 -0
  29. package/dist/_cjs/adapters/viem.js.map +1 -0
  30. package/dist/_cjs/client/createClient.js +45 -0
  31. package/dist/_cjs/client/createClient.js.map +1 -0
  32. package/dist/_cjs/client/decorators/client.js +21 -0
  33. package/dist/_cjs/client/decorators/client.js.map +1 -0
  34. package/dist/_cjs/client/index.js +9 -0
  35. package/dist/_cjs/client/index.js.map +1 -0
  36. package/dist/_cjs/client/transports/createTransport.js +29 -0
  37. package/dist/_cjs/client/transports/createTransport.js.map +1 -0
  38. package/dist/_cjs/client/transports/rest.js +86 -0
  39. package/dist/_cjs/client/transports/rest.js.map +1 -0
  40. package/dist/_cjs/client/types.js +3 -0
  41. package/dist/_cjs/client/types.js.map +1 -0
  42. package/dist/_cjs/constants.js +9 -0
  43. package/dist/_cjs/constants.js.map +1 -0
  44. package/dist/_cjs/core/createZeroDevWallet.js +330 -0
  45. package/dist/_cjs/core/createZeroDevWallet.js.map +1 -0
  46. package/dist/_cjs/errors/request.js +61 -0
  47. package/dist/_cjs/errors/request.js.map +1 -0
  48. package/dist/_cjs/index.js +31 -0
  49. package/dist/_cjs/index.js.map +1 -0
  50. package/dist/_cjs/package.json +1 -0
  51. package/dist/_cjs/polyfills/window.js +26 -0
  52. package/dist/_cjs/polyfills/window.js.map +1 -0
  53. package/dist/_cjs/stampers/iframeStamper.js +32 -0
  54. package/dist/_cjs/stampers/iframeStamper.js.map +1 -0
  55. package/dist/_cjs/stampers/index.js +10 -0
  56. package/dist/_cjs/stampers/index.js.map +1 -0
  57. package/dist/_cjs/stampers/indexedDbStamper.js +23 -0
  58. package/dist/_cjs/stampers/indexedDbStamper.js.map +1 -0
  59. package/dist/_cjs/stampers/types.js +3 -0
  60. package/dist/_cjs/stampers/types.js.map +1 -0
  61. package/dist/_cjs/stampers/webauthnStamper.js +17 -0
  62. package/dist/_cjs/stampers/webauthnStamper.js.map +1 -0
  63. package/dist/_cjs/storage/adapters.js +18 -0
  64. package/dist/_cjs/storage/adapters.js.map +1 -0
  65. package/dist/_cjs/storage/manager.js +108 -0
  66. package/dist/_cjs/storage/manager.js.map +1 -0
  67. package/dist/_cjs/types/session.js +9 -0
  68. package/dist/_cjs/types/session.js.map +1 -0
  69. package/dist/_cjs/utils/exportWallet.js +70 -0
  70. package/dist/_cjs/utils/exportWallet.js.map +1 -0
  71. package/dist/_cjs/utils/utils.js +75 -0
  72. package/dist/_cjs/utils/utils.js.map +1 -0
  73. package/dist/_esm/actions/auth/authenticateWithEmail.js +18 -0
  74. package/dist/_esm/actions/auth/authenticateWithEmail.js.map +1 -0
  75. package/dist/_esm/actions/auth/authenticateWithOAuth.js +31 -0
  76. package/dist/_esm/actions/auth/authenticateWithOAuth.js.map +1 -0
  77. package/dist/_esm/actions/auth/getWhoami.js +28 -0
  78. package/dist/_esm/actions/auth/getWhoami.js.map +1 -0
  79. package/dist/_esm/actions/auth/index.js +8 -0
  80. package/dist/_esm/actions/auth/index.js.map +1 -0
  81. package/dist/_esm/actions/auth/loginWithOTP.js +36 -0
  82. package/dist/_esm/actions/auth/loginWithOTP.js.map +1 -0
  83. package/dist/_esm/actions/auth/loginWithStamp.js +42 -0
  84. package/dist/_esm/actions/auth/loginWithStamp.js.map +1 -0
  85. package/dist/_esm/actions/auth/registerWithOTP.js +36 -0
  86. package/dist/_esm/actions/auth/registerWithOTP.js.map +1 -0
  87. package/dist/_esm/actions/auth/registerWithPasskey.js +36 -0
  88. package/dist/_esm/actions/auth/registerWithPasskey.js.map +1 -0
  89. package/dist/_esm/actions/index.js +5 -0
  90. package/dist/_esm/actions/index.js.map +1 -0
  91. package/dist/_esm/actions/wallet/getUserWallet.js +26 -0
  92. package/dist/_esm/actions/wallet/getUserWallet.js.map +1 -0
  93. package/dist/_esm/actions/wallet/index.js +4 -0
  94. package/dist/_esm/actions/wallet/index.js.map +1 -0
  95. package/dist/_esm/actions/wallet/signRawPayload.js +41 -0
  96. package/dist/_esm/actions/wallet/signRawPayload.js.map +1 -0
  97. package/dist/_esm/actions/wallet/signTransaction.js +40 -0
  98. package/dist/_esm/actions/wallet/signTransaction.js.map +1 -0
  99. package/dist/_esm/adapters/viem.js +91 -0
  100. package/dist/_esm/adapters/viem.js.map +1 -0
  101. package/dist/_esm/client/createClient.js +56 -0
  102. package/dist/_esm/client/createClient.js.map +1 -0
  103. package/dist/_esm/client/decorators/client.js +42 -0
  104. package/dist/_esm/client/decorators/client.js.map +1 -0
  105. package/dist/_esm/client/index.js +3 -0
  106. package/dist/_esm/client/index.js.map +1 -0
  107. package/dist/_esm/client/transports/createTransport.js +31 -0
  108. package/dist/_esm/client/transports/createTransport.js.map +1 -0
  109. package/dist/_esm/client/transports/rest.js +85 -0
  110. package/dist/_esm/client/transports/rest.js.map +1 -0
  111. package/dist/_esm/client/types.js +2 -0
  112. package/dist/_esm/client/types.js.map +1 -0
  113. package/dist/_esm/constants.js +6 -0
  114. package/dist/_esm/constants.js.map +1 -0
  115. package/dist/_esm/core/createZeroDevWallet.js +332 -0
  116. package/dist/_esm/core/createZeroDevWallet.js.map +1 -0
  117. package/dist/_esm/errors/request.js +60 -0
  118. package/dist/_esm/errors/request.js.map +1 -0
  119. package/dist/_esm/index.js +20 -0
  120. package/dist/_esm/index.js.map +1 -0
  121. package/dist/_esm/package.json +1 -0
  122. package/dist/_esm/polyfills/window.js +24 -0
  123. package/dist/_esm/polyfills/window.js.map +1 -0
  124. package/dist/_esm/stampers/iframeStamper.js +29 -0
  125. package/dist/_esm/stampers/iframeStamper.js.map +1 -0
  126. package/dist/_esm/stampers/index.js +4 -0
  127. package/dist/_esm/stampers/index.js.map +1 -0
  128. package/dist/_esm/stampers/indexedDbStamper.js +20 -0
  129. package/dist/_esm/stampers/indexedDbStamper.js.map +1 -0
  130. package/dist/_esm/stampers/types.js +2 -0
  131. package/dist/_esm/stampers/types.js.map +1 -0
  132. package/dist/_esm/stampers/webauthnStamper.js +15 -0
  133. package/dist/_esm/stampers/webauthnStamper.js.map +1 -0
  134. package/dist/_esm/storage/adapters.js +15 -0
  135. package/dist/_esm/storage/adapters.js.map +1 -0
  136. package/dist/_esm/storage/manager.js +118 -0
  137. package/dist/_esm/storage/manager.js.map +1 -0
  138. package/dist/_esm/types/session.js +6 -0
  139. package/dist/_esm/types/session.js.map +1 -0
  140. package/dist/_esm/utils/exportWallet.js +98 -0
  141. package/dist/_esm/utils/exportWallet.js.map +1 -0
  142. package/dist/_esm/utils/utils.js +105 -0
  143. package/dist/_esm/utils/utils.js.map +1 -0
  144. package/dist/_types/actions/auth/authenticateWithEmail.d.ts +33 -0
  145. package/dist/_types/actions/auth/authenticateWithEmail.d.ts.map +1 -0
  146. package/dist/_types/actions/auth/authenticateWithOAuth.d.ts +40 -0
  147. package/dist/_types/actions/auth/authenticateWithOAuth.d.ts.map +1 -0
  148. package/dist/_types/actions/auth/getWhoami.d.ts +35 -0
  149. package/dist/_types/actions/auth/getWhoami.d.ts.map +1 -0
  150. package/dist/_types/actions/auth/index.d.ts +8 -0
  151. package/dist/_types/actions/auth/index.d.ts.map +1 -0
  152. package/dist/_types/actions/auth/loginWithOTP.d.ts +41 -0
  153. package/dist/_types/actions/auth/loginWithOTP.d.ts.map +1 -0
  154. package/dist/_types/actions/auth/loginWithStamp.d.ts +35 -0
  155. package/dist/_types/actions/auth/loginWithStamp.d.ts.map +1 -0
  156. package/dist/_types/actions/auth/registerWithOTP.d.ts +52 -0
  157. package/dist/_types/actions/auth/registerWithOTP.d.ts.map +1 -0
  158. package/dist/_types/actions/auth/registerWithPasskey.d.ts +53 -0
  159. package/dist/_types/actions/auth/registerWithPasskey.d.ts.map +1 -0
  160. package/dist/_types/actions/index.d.ts +3 -0
  161. package/dist/_types/actions/index.d.ts.map +1 -0
  162. package/dist/_types/actions/wallet/getUserWallet.d.ts +32 -0
  163. package/dist/_types/actions/wallet/getUserWallet.d.ts.map +1 -0
  164. package/dist/_types/actions/wallet/index.d.ts +4 -0
  165. package/dist/_types/actions/wallet/index.d.ts.map +1 -0
  166. package/dist/_types/actions/wallet/signRawPayload.d.ts +37 -0
  167. package/dist/_types/actions/wallet/signRawPayload.d.ts.map +1 -0
  168. package/dist/_types/actions/wallet/signTransaction.d.ts +33 -0
  169. package/dist/_types/actions/wallet/signTransaction.d.ts.map +1 -0
  170. package/dist/_types/adapters/viem.d.ts +9 -0
  171. package/dist/_types/adapters/viem.d.ts.map +1 -0
  172. package/dist/_types/client/createClient.d.ts +18 -0
  173. package/dist/_types/client/createClient.d.ts.map +1 -0
  174. package/dist/_types/client/decorators/client.d.ts +73 -0
  175. package/dist/_types/client/decorators/client.d.ts.map +1 -0
  176. package/dist/_types/client/index.d.ts +4 -0
  177. package/dist/_types/client/index.d.ts.map +1 -0
  178. package/dist/_types/client/transports/createTransport.d.ts +17 -0
  179. package/dist/_types/client/transports/createTransport.d.ts.map +1 -0
  180. package/dist/_types/client/transports/rest.d.ts +30 -0
  181. package/dist/_types/client/transports/rest.d.ts.map +1 -0
  182. package/dist/_types/client/types.d.ts +60 -0
  183. package/dist/_types/client/types.d.ts.map +1 -0
  184. package/dist/_types/constants.d.ts +6 -0
  185. package/dist/_types/constants.d.ts.map +1 -0
  186. package/dist/_types/core/createZeroDevWallet.d.ts +55 -0
  187. package/dist/_types/core/createZeroDevWallet.d.ts.map +1 -0
  188. package/dist/_types/errors/request.d.ts +12 -0
  189. package/dist/_types/errors/request.d.ts.map +1 -0
  190. package/dist/_types/index.d.ts +17 -0
  191. package/dist/_types/index.d.ts.map +1 -0
  192. package/dist/_types/polyfills/window.d.ts +15 -0
  193. package/dist/_types/polyfills/window.d.ts.map +1 -0
  194. package/dist/_types/stampers/iframeStamper.d.ts +7 -0
  195. package/dist/_types/stampers/iframeStamper.d.ts.map +1 -0
  196. package/dist/_types/stampers/index.d.ts +5 -0
  197. package/dist/_types/stampers/index.d.ts.map +1 -0
  198. package/dist/_types/stampers/indexedDbStamper.d.ts +3 -0
  199. package/dist/_types/stampers/indexedDbStamper.d.ts.map +1 -0
  200. package/dist/_types/stampers/types.d.ts +23 -0
  201. package/dist/_types/stampers/types.d.ts.map +1 -0
  202. package/dist/_types/stampers/webauthnStamper.d.ts +5 -0
  203. package/dist/_types/stampers/webauthnStamper.d.ts.map +1 -0
  204. package/dist/_types/storage/adapters.d.ts +3 -0
  205. package/dist/_types/storage/adapters.d.ts.map +1 -0
  206. package/dist/_types/storage/manager.d.ts +19 -0
  207. package/dist/_types/storage/manager.d.ts.map +1 -0
  208. package/dist/_types/types/session.d.ts +17 -0
  209. package/dist/_types/types/session.d.ts.map +1 -0
  210. package/dist/_types/utils/exportWallet.d.ts +44 -0
  211. package/dist/_types/utils/exportWallet.d.ts.map +1 -0
  212. package/dist/_types/utils/utils.d.ts +52 -0
  213. package/dist/_types/utils/utils.d.ts.map +1 -0
  214. package/dist/tsconfig.build.tsbuildinfo +1 -0
  215. package/package.json +73 -0
  216. package/src/actions/auth/authenticateWithEmail.ts +52 -0
  217. package/src/actions/auth/authenticateWithOAuth.ts +58 -0
  218. package/src/actions/auth/getWhoami.ts +51 -0
  219. package/src/actions/auth/index.ts +40 -0
  220. package/src/actions/auth/loginWithOTP.ts +60 -0
  221. package/src/actions/auth/loginWithStamp.ts +68 -0
  222. package/src/actions/auth/registerWithOTP.ts +71 -0
  223. package/src/actions/auth/registerWithPasskey.ts +72 -0
  224. package/src/actions/index.ts +36 -0
  225. package/src/actions/wallet/getUserWallet.ts +46 -0
  226. package/src/actions/wallet/index.ts +17 -0
  227. package/src/actions/wallet/signRawPayload.ts +71 -0
  228. package/src/actions/wallet/signTransaction.ts +60 -0
  229. package/src/adapters/viem.ts +158 -0
  230. package/src/client/createClient.ts +95 -0
  231. package/src/client/decorators/client.ts +152 -0
  232. package/src/client/index.ts +12 -0
  233. package/src/client/transports/createTransport.ts +52 -0
  234. package/src/client/transports/rest.ts +121 -0
  235. package/src/client/types.ts +66 -0
  236. package/src/constants.ts +5 -0
  237. package/src/core/createZeroDevWallet.ts +477 -0
  238. package/src/errors/request.ts +36 -0
  239. package/src/index.ts +75 -0
  240. package/src/polyfills/window.ts +24 -0
  241. package/src/stampers/iframeStamper.ts +35 -0
  242. package/src/stampers/index.ts +8 -0
  243. package/src/stampers/indexedDbStamper.ts +22 -0
  244. package/src/stampers/types.ts +28 -0
  245. package/src/stampers/webauthnStamper.ts +21 -0
  246. package/src/storage/adapters.ts +20 -0
  247. package/src/storage/manager.ts +170 -0
  248. package/src/types/session.ts +18 -0
  249. package/src/utils/exportWallet.ts +124 -0
  250. package/src/utils/utils.ts +136 -0
@@ -0,0 +1,66 @@
1
+ import type { Stamper } from '../stampers/types.js'
2
+ import type { RestRequestFn } from './transports/rest.js'
3
+
4
+ export type TransportConfig = {
5
+ /** The name of the transport. */
6
+ name: string
7
+ /** The key of the transport. */
8
+ key: string
9
+ /** Base URL for the API */
10
+ url: string
11
+ /** Proxy base URL for auth requests */
12
+ proxyBaseUrl?: string
13
+ /** Request timeout in milliseconds */
14
+ timeoutMs: number
15
+ /** The type of the transport. */
16
+ type: string
17
+ }
18
+
19
+ export type Transport = (options: { stamper: Stamper }) => {
20
+ config: TransportConfig
21
+ request: RestRequestFn
22
+ value?: Record<string, unknown>
23
+ }
24
+
25
+ export type ClientConfig<TStamper extends Stamper = Stamper> = {
26
+ /** Transport for the client */
27
+ transport: Transport
28
+ /** Stamper for authenticated requests */
29
+ stamper: TStamper
30
+ /** Organization ID */
31
+ organizationId?: string
32
+ /** A key for the client. */
33
+ key?: string
34
+ /** A name for the client. */
35
+ name?: string
36
+ }
37
+
38
+ export type Client<
39
+ extended extends Extended | undefined = undefined,
40
+ TStamper extends Stamper = Stamper,
41
+ > = {
42
+ /** Transport configuration */
43
+ transport: TransportConfig & Record<string, unknown>
44
+ /** Request function from transport */
45
+ request: RestRequestFn
46
+ /** Stamper for authenticated requests */
47
+ stamper: TStamper
48
+ /** Organization ID */
49
+ organizationId?: string
50
+ /** A key for the client */
51
+ key: string
52
+ /** A name for the client */
53
+ name: string
54
+ /** The type of client */
55
+ type: string
56
+ /** A unique ID for the client */
57
+ uid: string
58
+ /** Extend the client with additional functionality */
59
+ extend: <const client extends Extended>(
60
+ fn: (client: Client<extended>) => client,
61
+ ) => Client<client & (extended extends Extended ? extended : unknown)>
62
+ } & (extended extends Extended ? extended : unknown)
63
+
64
+ type Extended = {
65
+ [key: string]: unknown
66
+ }
@@ -0,0 +1,5 @@
1
+ export const DEFAULT_SESSION_EXPIRATION_IN_SECONDS = '900' // default to 15 minutes
2
+ export const DEFAULT_IFRAME_CONTAINER_ID = 'turnkey-auth-iframe-container-id'
3
+ export const DEFAULT_IFRAME_ELEMENT_ID = 'turnkey-default-iframe-element-id'
4
+ export const DEFAULT_ORGANIZATION_ID = '6254bb1d-0d0d-4f7e-96b8-77c94fe0b0c1'
5
+ export const KMS_SERVER_URL = 'https://kms.dev.zerodev.app'
@@ -0,0 +1,477 @@
1
+ import { getWebAuthnAttestation } from '@turnkey/http'
2
+ import type { LocalAccount } from 'viem/accounts'
3
+ import type { EmailCustomization } from '../actions/auth/index.js'
4
+ import { toViemAccount } from '../adapters/viem.js'
5
+ import {
6
+ createClient,
7
+ type ZeroDevWalletClient,
8
+ zeroDevWalletTransport,
9
+ } from '../client/index.js'
10
+ import {
11
+ DEFAULT_ORGANIZATION_ID,
12
+ DEFAULT_SESSION_EXPIRATION_IN_SECONDS,
13
+ KMS_SERVER_URL,
14
+ } from '../constants.js'
15
+ import { createIndexedDbStamper } from '../stampers/indexedDbStamper.js'
16
+ import type { IndexedDbStamper } from '../stampers/types.js'
17
+ import { createWebauthnStamper } from '../stampers/webauthnStamper.js'
18
+ import { createWebStorageAdapter } from '../storage/adapters.js'
19
+ import {
20
+ createStorageManager,
21
+ type StorageAdapter,
22
+ } from '../storage/manager.js'
23
+ import { SessionType, type ZeroDevWalletSession } from '../types/session.js'
24
+ import {
25
+ base64UrlEncode,
26
+ generateCompressedPublicKeyFromKeyPair,
27
+ generateRandomBuffer,
28
+ humanReadableDateTime,
29
+ parseSession,
30
+ } from '../utils/utils.js'
31
+ export interface ZeroDevWalletConfig {
32
+ organizationId?: string
33
+ proxyBaseUrl?: string
34
+ projectId: string
35
+ sessionStorage?: StorageAdapter
36
+ rpId?: string
37
+ }
38
+
39
+ // Re-export EmailCustomization for convenience
40
+ export type { EmailCustomization } from '../actions/auth/index.js'
41
+ export type { StorageAdapter, StorageManager } from '../storage/manager.js'
42
+ // Re-export new session types
43
+ export type { StamperType, ZeroDevWalletSession } from '../types/session.js'
44
+
45
+ export type AuthParams =
46
+ | {
47
+ type: 'oauth'
48
+ provider: string
49
+ redirectUrl?: string
50
+ credential: string
51
+ }
52
+ | {
53
+ type: 'passkey'
54
+ email: string
55
+ mode: 'register' | 'login'
56
+ }
57
+ | {
58
+ type: 'otp'
59
+ mode: 'sendOtp'
60
+ email: string
61
+ contact: {
62
+ type: 'email' | 'sms'
63
+ contact: string
64
+ }
65
+ emailCustomization?: EmailCustomization
66
+ }
67
+ | {
68
+ type: 'otp'
69
+ mode: 'verifyOtp'
70
+ otpId: string
71
+ otpCode: string
72
+ subOrganizationId: string
73
+ }
74
+
75
+ export interface ZeroDevWalletSDK {
76
+ client: () => ZeroDevWalletClient | null
77
+ auth: (params: AuthParams) => Promise<any>
78
+
79
+ getPublicKey: () => Promise<string | null>
80
+
81
+ getSession: () => Promise<ZeroDevWalletSession | undefined>
82
+ getAllSessions: () => Promise<Record<string, ZeroDevWalletSession>>
83
+ switchSession: (
84
+ sessionId: string,
85
+ ) => Promise<ZeroDevWalletSession | undefined>
86
+ clearSession: (sessionId: string) => Promise<void>
87
+ clearAllSessions: () => Promise<void>
88
+ refreshSession: (
89
+ sessionId?: string,
90
+ ) => Promise<ZeroDevWalletSession | undefined>
91
+
92
+ logout: () => Promise<boolean>
93
+
94
+ toAccount: () => Promise<LocalAccount>
95
+ }
96
+
97
+ export async function createZeroDevWallet(
98
+ config: ZeroDevWalletConfig,
99
+ ): Promise<ZeroDevWalletSDK> {
100
+ const {
101
+ projectId,
102
+ sessionStorage,
103
+ rpId = window.location.hostname,
104
+ organizationId = DEFAULT_ORGANIZATION_ID,
105
+ } = config
106
+
107
+ const sessionStorageManager = createStorageManager(
108
+ sessionStorage || createWebStorageAdapter(),
109
+ )
110
+
111
+ const indexedDbStamper = await createIndexedDbStamper()
112
+
113
+ const webauthnStamper = await createWebauthnStamper({ rpId })
114
+
115
+ let currentClient: ZeroDevWalletClient | null = null
116
+
117
+ const indexedDbClient = createClient({
118
+ stamper: indexedDbStamper,
119
+ transport: zeroDevWalletTransport({
120
+ baseUrl: config.proxyBaseUrl || `${KMS_SERVER_URL}/api/v1`,
121
+ }),
122
+ })
123
+
124
+ const passkeyClient = createClient({
125
+ stamper: webauthnStamper,
126
+ transport: zeroDevWalletTransport({
127
+ baseUrl: config.proxyBaseUrl || `${KMS_SERVER_URL}/api/v1`,
128
+ }),
129
+ })
130
+
131
+ // Restore active session on initialization
132
+ const activeSession = await sessionStorageManager.getActiveSession()
133
+
134
+ if (activeSession) {
135
+ try {
136
+ if (activeSession.stamperType === 'indexedDb') {
137
+ currentClient = indexedDbClient
138
+ }
139
+ } catch (_error) {}
140
+ }
141
+
142
+ const getClient = () => {
143
+ return currentClient
144
+ }
145
+
146
+ return {
147
+ client: getClient,
148
+ async getPublicKey() {
149
+ await indexedDbClient.stamper.resetKeyPair()
150
+ const compressedPublicKey = await indexedDbClient.stamper.getPublicKey()
151
+ return compressedPublicKey
152
+ },
153
+
154
+ async getSession() {
155
+ return sessionStorageManager.getActiveSession()
156
+ },
157
+
158
+ async getAllSessions() {
159
+ const sessions = await sessionStorageManager.listSessions()
160
+ const sessionMap: Record<string, ZeroDevWalletSession> = {}
161
+ for (const session of sessions) {
162
+ sessionMap[session.id] = session
163
+ }
164
+ return sessionMap
165
+ },
166
+
167
+ async switchSession(sessionId: string) {
168
+ await sessionStorageManager.setActiveSession(sessionId)
169
+ const session = await sessionStorageManager.getActiveSession()
170
+
171
+ if (session) {
172
+ // Update current client based on session's stamper type
173
+ let stamper: IndexedDbStamper | undefined
174
+ if (session.stamperType === 'indexedDb') {
175
+ stamper = indexedDbStamper
176
+ }
177
+
178
+ if (stamper) {
179
+ currentClient = createClient({
180
+ stamper,
181
+ transport: zeroDevWalletTransport({
182
+ baseUrl: config.proxyBaseUrl || `${KMS_SERVER_URL}/api/v1`,
183
+ }),
184
+ })
185
+ }
186
+ }
187
+
188
+ return session
189
+ },
190
+
191
+ async clearSession(sessionId: string) {
192
+ await sessionStorageManager.clearSession(sessionId)
193
+ },
194
+
195
+ async clearAllSessions() {
196
+ await sessionStorageManager.clearAllSessions()
197
+ currentClient = null
198
+ },
199
+
200
+ async refreshSession(sessionId?: string) {
201
+ const activeSession = sessionId
202
+ ? await sessionStorageManager.getSession(sessionId)
203
+ : await sessionStorageManager.getActiveSession()
204
+ if (!activeSession) {
205
+ throw new Error('No active session')
206
+ }
207
+ if (activeSession.stamperType === 'indexedDb') {
208
+ const newKeyPair = await crypto.subtle.generateKey(
209
+ {
210
+ name: 'ECDSA',
211
+ namedCurve: 'P-256',
212
+ },
213
+ false,
214
+ ['sign', 'verify'],
215
+ )
216
+ const compressedPublicKeyHex =
217
+ await generateCompressedPublicKeyFromKeyPair(newKeyPair)
218
+ const data = await indexedDbClient.loginWithStamp({
219
+ targetPublicKey: compressedPublicKeyHex,
220
+ projectId,
221
+ organizationId: activeSession.organizationId,
222
+ })
223
+ await indexedDbClient.stamper.resetKeyPair(newKeyPair)
224
+ const parsedSession = parseSession(data.session)
225
+ const session: ZeroDevWalletSession = {
226
+ id: `session_indexedDb_${Date.now()}`,
227
+ userId: parsedSession.userId,
228
+ organizationId: parsedSession.organizationId,
229
+ stamperType: 'indexedDb',
230
+ sessionType: SessionType.READ_WRITE,
231
+ token: data.session,
232
+ expiry: parsedSession.expiry,
233
+ createdAt: Date.now(),
234
+ }
235
+ await sessionStorageManager.clearSession(activeSession.id)
236
+ await sessionStorageManager.storeSession(session, session.id)
237
+ currentClient = indexedDbClient
238
+ return session
239
+ }
240
+ throw new Error('Invalid session type')
241
+ },
242
+
243
+ // [TODO] refactor to smaller utils/actions
244
+ async auth(params: AuthParams) {
245
+ switch (params.type) {
246
+ case 'oauth': {
247
+ const { credential } = params
248
+ const targetPublicKey = await indexedDbClient.stamper.getPublicKey()
249
+
250
+ if (!targetPublicKey) {
251
+ throw new Error('Failed to get public key')
252
+ }
253
+
254
+ const data = await indexedDbClient.authenticateWithOAuth({
255
+ oidcToken: credential,
256
+ provider: 'google',
257
+ targetPublicKey,
258
+ projectId,
259
+ })
260
+
261
+ if (data.turnkeySession) {
262
+ // Parse the JWT to get session data
263
+ const parsedSession = parseSession(data.turnkeySession)
264
+ const session: ZeroDevWalletSession = {
265
+ id: `session_oauth_${Date.now()}`,
266
+ userId: parsedSession.userId,
267
+ organizationId: parsedSession.organizationId,
268
+ stamperType: 'indexedDb',
269
+ sessionType: parsedSession.sessionType || SessionType.READ_WRITE,
270
+ token: data.turnkeySession,
271
+ expiry: parsedSession.expiry,
272
+ createdAt: Date.now(),
273
+ publicKey: targetPublicKey,
274
+ }
275
+ await sessionStorageManager.storeSession(session, session.id)
276
+ }
277
+ currentClient = indexedDbClient
278
+ return data
279
+ }
280
+ case 'passkey': {
281
+ const { type } = params
282
+ if (
283
+ type === 'passkey' &&
284
+ 'mode' in params &&
285
+ params.mode === 'register'
286
+ ) {
287
+ const { email } = params
288
+ await indexedDbClient.stamper.resetKeyPair()
289
+ const tempPublicKey = await indexedDbClient.stamper.getPublicKey()
290
+ if (!tempPublicKey) {
291
+ throw new Error('Failed to get public key')
292
+ }
293
+ const challenge = generateRandomBuffer()
294
+ const encodedChallenge = base64UrlEncode(challenge)
295
+ const authenticatorUserId = generateRandomBuffer()
296
+ const name = `ZeroDevWallet-${humanReadableDateTime()}-${email}`
297
+ const attestation = await getWebAuthnAttestation({
298
+ publicKey: {
299
+ rp: { id: rpId, name: '' },
300
+ challenge,
301
+ pubKeyCredParams: [
302
+ {
303
+ type: 'public-key',
304
+ alg: -7,
305
+ },
306
+ {
307
+ type: 'public-key',
308
+ alg: -257,
309
+ },
310
+ ],
311
+ user: {
312
+ id: authenticatorUserId,
313
+ name,
314
+ displayName: name,
315
+ },
316
+ },
317
+ })
318
+ const data = await passkeyClient.registerWithPasskey({
319
+ email,
320
+ attestation,
321
+ challenge: encodedChallenge,
322
+ projectId,
323
+ encodedPublicKey: tempPublicKey,
324
+ })
325
+ const newKeyPair = await crypto.subtle.generateKey(
326
+ {
327
+ name: 'ECDSA',
328
+ namedCurve: 'P-256',
329
+ },
330
+ false,
331
+ ['sign', 'verify'],
332
+ )
333
+ const compressedPublicKeyHex =
334
+ await generateCompressedPublicKeyFromKeyPair(newKeyPair)
335
+ const loginData = await indexedDbClient.loginWithStamp({
336
+ projectId,
337
+ targetPublicKey: compressedPublicKeyHex,
338
+ organizationId: data.subOrganizationId,
339
+ })
340
+ await indexedDbClient.stamper.resetKeyPair(newKeyPair)
341
+ const parsedSession = parseSession(loginData.session)
342
+ const session: ZeroDevWalletSession = {
343
+ id: `session_indexedDb_${Date.now()}`,
344
+ stamperType: 'indexedDb',
345
+ createdAt: Date.now(),
346
+ sessionType: SessionType.READ_WRITE,
347
+ userId: parsedSession.userId,
348
+ organizationId: parsedSession.organizationId,
349
+ expiry:
350
+ Date.now() +
351
+ Number(DEFAULT_SESSION_EXPIRATION_IN_SECONDS) * 1000,
352
+ token: loginData.session,
353
+ }
354
+ await sessionStorageManager.storeSession(session, session.id)
355
+ currentClient = indexedDbClient
356
+ return data
357
+ }
358
+ if (
359
+ type === 'passkey' &&
360
+ 'mode' in params &&
361
+ params.mode === 'login'
362
+ ) {
363
+ await indexedDbClient.stamper.resetKeyPair()
364
+ const generatedPublicKey =
365
+ await indexedDbClient.stamper.getPublicKey()
366
+ if (!generatedPublicKey) {
367
+ throw new Error('Failed to get public key')
368
+ }
369
+ const loginData = await passkeyClient.loginWithStamp({
370
+ targetPublicKey: generatedPublicKey,
371
+ projectId,
372
+ organizationId,
373
+ })
374
+ const parsedSession = parseSession(loginData.session)
375
+ const session: ZeroDevWalletSession = {
376
+ id: `session_indexedDb_${Date.now()}`,
377
+ stamperType: 'indexedDb',
378
+ createdAt: Date.now(),
379
+ sessionType: SessionType.READ_WRITE,
380
+ userId: parsedSession.userId,
381
+ organizationId: parsedSession.organizationId,
382
+ expiry:
383
+ Date.now() +
384
+ Number(DEFAULT_SESSION_EXPIRATION_IN_SECONDS) * 1000,
385
+ token: loginData.session,
386
+ }
387
+ await sessionStorageManager.storeSession(session, session.id)
388
+ currentClient = indexedDbClient
389
+ return loginData
390
+ }
391
+ throw new Error('Passkey authentication requires passkey parameter')
392
+ }
393
+ case 'otp': {
394
+ const { type, mode } = params
395
+
396
+ if (type === 'otp' && mode === 'sendOtp') {
397
+ const { email, contact, emailCustomization } = params
398
+
399
+ const data = await indexedDbClient.registerWithOTP({
400
+ email,
401
+ contact,
402
+ projectId,
403
+ ...(emailCustomization && { emailCustomization }),
404
+ })
405
+
406
+ return data
407
+ }
408
+
409
+ if (type === 'otp' && mode === 'verifyOtp') {
410
+ const { otpId, otpCode, subOrganizationId } = params
411
+ await indexedDbClient.stamper.resetKeyPair()
412
+ const targetPublicKey = await indexedDbClient.stamper.getPublicKey()
413
+
414
+ if (!targetPublicKey) {
415
+ throw new Error('Failed to get public key')
416
+ }
417
+
418
+ const data = await indexedDbClient.loginWithOTP({
419
+ otpId,
420
+ otpCode,
421
+ subOrganizationId,
422
+ encodedPublicKey: targetPublicKey,
423
+ projectId,
424
+ })
425
+
426
+ if (data.session) {
427
+ // Parse the JWT to get session data
428
+ const parsedSession = parseSession(data.session)
429
+ const session: ZeroDevWalletSession = {
430
+ id: `session_otp_${Date.now()}`,
431
+ userId: parsedSession.userId,
432
+ organizationId: parsedSession.organizationId,
433
+ stamperType: 'indexedDb',
434
+ sessionType:
435
+ parsedSession.sessionType || SessionType.READ_WRITE,
436
+ token: data.session,
437
+ expiry: parsedSession.expiry,
438
+ createdAt: Date.now(),
439
+ publicKey: targetPublicKey,
440
+ }
441
+ await sessionStorageManager.storeSession(session, session.id)
442
+ }
443
+ currentClient = indexedDbClient
444
+ return data
445
+ }
446
+
447
+ throw new Error('OTP authentication requires mode parameter')
448
+ }
449
+ default:
450
+ throw new Error(`Unknown auth type: ${(params as any).type}`)
451
+ }
452
+ },
453
+
454
+ async logout() {
455
+ await sessionStorageManager.clearAllSessions()
456
+ currentClient = null
457
+ await indexedDbClient.stamper.resetKeyPair()
458
+ return true
459
+ },
460
+
461
+ async toAccount(): Promise<LocalAccount> {
462
+ const session = await sessionStorageManager.getActiveSession()
463
+ if (!session) {
464
+ throw new Error('No active session')
465
+ }
466
+ if (!currentClient) {
467
+ throw new Error('No client')
468
+ }
469
+
470
+ return toViemAccount({
471
+ client: currentClient,
472
+ organizationId: session.organizationId,
473
+ projectId,
474
+ })
475
+ },
476
+ }
477
+ }
@@ -0,0 +1,36 @@
1
+ export class RestRequestError extends Error {
2
+ constructor(
3
+ public url: string,
4
+ public status?: number,
5
+ public body?: unknown,
6
+ public override cause?: unknown,
7
+ ) {
8
+ // Extract error message from backend response format
9
+ // Backend format: { error: "error_code", message: "human readable message" }
10
+ let errorMessage = `Request failed (${status || 'unknown'}): `
11
+
12
+ if (body && typeof body === 'object') {
13
+ const errorBody = body as any
14
+
15
+ // Prefer message (detailed), fallback to error (code)
16
+ if (errorBody.message && errorBody.error) {
17
+ // Both present: show error code + message
18
+ errorMessage += `${errorBody.error} - ${errorBody.message}`
19
+ } else if (errorBody.message) {
20
+ errorMessage += `${errorBody.message}`
21
+ } else if (errorBody.error) {
22
+ errorMessage += `${errorBody.error}`
23
+ }
24
+ }
25
+
26
+ super(errorMessage)
27
+ this.name = 'RestRequestError'
28
+ }
29
+ }
30
+
31
+ export class RestTimeoutError extends Error {
32
+ constructor(public url: string) {
33
+ super(`Request timed out: ${url}`)
34
+ this.name = 'RestTimeoutError'
35
+ }
36
+ }
package/src/index.ts ADDED
@@ -0,0 +1,75 @@
1
+ export type {
2
+ // Auth types
3
+ AuthenticateWithEmailParameters,
4
+ AuthenticateWithEmailReturnType,
5
+ AuthenticateWithOAuthParameters,
6
+ AuthenticateWithOAuthReturnType,
7
+ EmailCustomization,
8
+ // Wallet types
9
+ GetUserWalletParameters,
10
+ GetUserWalletReturnType,
11
+ GetWhoamiParameters,
12
+ GetWhoamiReturnType,
13
+ LoginWithOTPParameters,
14
+ LoginWithOTPReturnType,
15
+ OtpContact,
16
+ RegisterWithOTPParameters,
17
+ RegisterWithOTPReturnType,
18
+ SignRawPayloadParameters,
19
+ SignRawPayloadReturnType,
20
+ SignTransactionParameters,
21
+ SignTransactionReturnType,
22
+ } from './actions/index.js'
23
+
24
+ // Actions
25
+ export {
26
+ // Auth actions
27
+ authenticateWithEmail,
28
+ authenticateWithOAuth,
29
+ // Wallet actions
30
+ getUserWallet,
31
+ getWhoami,
32
+ loginWithOTP,
33
+ registerWithOTP,
34
+ signRawPayload,
35
+ signTransaction,
36
+ } from './actions/index.js'
37
+ export type { ToViemAccountParams } from './adapters/viem.js'
38
+ // Adapters
39
+ export { toViemAccount } from './adapters/viem.js'
40
+ export type { ZeroDevWalletActions } from './client/decorators/client.js'
41
+ // Client decorators
42
+ export { zeroDevWalletActions } from './client/decorators/client.js'
43
+ export type { Client, ClientConfig, Transport } from './client/index.js'
44
+ // Client
45
+ export {
46
+ createBaseClient,
47
+ createClient,
48
+ type ZeroDevWalletClient,
49
+ zeroDevWalletTransport,
50
+ } from './client/index.js'
51
+ export type {
52
+ AuthParams,
53
+ ZeroDevWalletConfig,
54
+ ZeroDevWalletSDK,
55
+ } from './core/createZeroDevWallet.js'
56
+ // Core
57
+ export { createZeroDevWallet } from './core/createZeroDevWallet.js'
58
+ // Stampers
59
+ export {
60
+ createIframeStamper,
61
+ createIndexedDbStamper,
62
+ createWebauthnStamper,
63
+ } from './stampers/index.js'
64
+ export type {
65
+ IframeStamper,
66
+ IndexedDbStamper,
67
+ WebauthnStamper,
68
+ } from './stampers/types.js'
69
+ // Storage
70
+ export type { StorageAdapter, StorageManager } from './storage/manager.js'
71
+ // Session types
72
+ export type { StamperType, ZeroDevWalletSession } from './types/session.js'
73
+ export { exportWallet } from './utils/exportWallet.js'
74
+ // Utils
75
+ export { normalizeTimestamp } from './utils/utils.js'
@@ -0,0 +1,24 @@
1
+ const loadWindow = () => {
2
+ if (typeof window !== 'undefined') {
3
+ return window
4
+ }
5
+ return {
6
+ localStorage: {
7
+ getItem: (_key: string): string | null => {
8
+ return null
9
+ },
10
+ setItem: (_key: string, _value: string) => {},
11
+ removeItem: (_key: string) => {},
12
+ clear: () => {},
13
+ key: (_index: number): string | null => {
14
+ return null
15
+ },
16
+ length: 0,
17
+ },
18
+ location: {
19
+ hostname: '',
20
+ },
21
+ }
22
+ }
23
+
24
+ export default loadWindow()