@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,60 @@
1
+ import type { Hex } from 'viem'
2
+ import type { Client } from '../../client/types.js'
3
+
4
+ export type SignTransactionParameters = {
5
+ /** The organization ID */
6
+ organizationId: string
7
+ /** The project ID for the request */
8
+ projectId: string
9
+ /** The address to sign with */
10
+ address: Hex
11
+ /** The unsigned transaction to sign */
12
+ unsignedTransaction: string
13
+ }
14
+
15
+ export type SignTransactionReturnType = Hex
16
+
17
+ /**
18
+ * Signs a raw transaction with the user's wallet
19
+ *
20
+ * @param client - The ZeroDev Wallet client
21
+ * @param params - The parameters for signing
22
+ * @returns The signature
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * const result = await signTransaction(client, {
27
+ * organizationId: 'org_123',
28
+ * projectId: 'proj_456',
29
+ * address: '0x123...',
30
+ * unsignedTransaction: 'abc123...',
31
+ * });
32
+ * console.log(result.signature); // '0x...'
33
+ * ```
34
+ */
35
+ export async function signTransaction(
36
+ client: Client,
37
+ params: SignTransactionParameters,
38
+ ): Promise<SignTransactionReturnType> {
39
+ const { organizationId, projectId, address, unsignedTransaction } = params
40
+
41
+ const { signature } = await client.request({
42
+ path: `${projectId}/sign/transaction`,
43
+ body: {
44
+ body: {
45
+ type: 'ACTIVITY_TYPE_SIGN_TRANSACTION_V2',
46
+ timestampMs: Date.now().toString(),
47
+ organizationId,
48
+ parameters: {
49
+ signWith: address,
50
+ type: 'TRANSACTION_TYPE_ETHEREUM',
51
+ unsignedTransaction,
52
+ },
53
+ },
54
+ apiUrl: 'https://api.turnkey.com/public/v1/submit/sign_transaction',
55
+ },
56
+ stamp: true,
57
+ })
58
+
59
+ return `0x${signature}` as Hex
60
+ }
@@ -0,0 +1,158 @@
1
+ import {
2
+ type Hex,
3
+ hashMessage,
4
+ type LocalAccount,
5
+ parseSignature,
6
+ parseTransaction,
7
+ type SerializeTransactionFn,
8
+ type SignableMessage,
9
+ serializeTransaction,
10
+ serializeTypedData,
11
+ type TransactionSerializable,
12
+ zeroAddress,
13
+ } from 'viem'
14
+ import type {
15
+ SignAuthorizationParameters,
16
+ SignAuthorizationReturnType,
17
+ } from 'viem/accounts'
18
+ import { toAccount } from 'viem/accounts'
19
+ import { hashAuthorization } from 'viem/utils'
20
+ import type { signRawPayload } from '../actions/index.js'
21
+ import type { ZeroDevWalletClient } from '../client/index.js'
22
+
23
+ export interface ToViemAccountParams {
24
+ client: ZeroDevWalletClient
25
+ organizationId: string
26
+ projectId: string
27
+ }
28
+
29
+ export async function toViemAccount(
30
+ params: ToViemAccountParams,
31
+ ): Promise<LocalAccount> {
32
+ const { client, organizationId, projectId } = params
33
+
34
+ let address: Hex = zeroAddress
35
+
36
+ try {
37
+ const walletResponse = await client.getUserWallet({
38
+ organizationId,
39
+ projectId,
40
+ })
41
+ address = walletResponse.walletAddress
42
+ } catch {
43
+ address = zeroAddress
44
+ }
45
+ const signRawPayloadInternal = async (
46
+ payload: string,
47
+ encoding: Parameters<
48
+ typeof signRawPayload
49
+ >[1]['encoding'] = 'PAYLOAD_ENCODING_HEXADECIMAL',
50
+ ) => {
51
+ return await client.signRawPayload({
52
+ organizationId,
53
+ projectId,
54
+ address,
55
+ payload,
56
+ encoding,
57
+ })
58
+ }
59
+
60
+ // Modified from: https://github.com/tkhq/sdk/blob/4e439bf2973ea13b51d981d7c24a4841d4e5fd5f/packages/viem/src/index.ts#L419-L461
61
+ const signTransactionInternal = async <
62
+ TTransactionSerializable extends TransactionSerializable,
63
+ >(
64
+ transaction: TTransactionSerializable,
65
+ serializer: SerializeTransactionFn<TTransactionSerializable>,
66
+ ): Promise<Hex> => {
67
+ // Note: for Type 3 transactions, we are specifically handling parsing for payloads containing only the transaction payload body, without any wrappers around blobs, commitments, or proofs.
68
+ // See more: https://github.com/wevm/viem/blob/3ef19eac4963014fb20124d1e46d1715bed5509f/src/accounts/utils/signTransaction.ts#L54-L55
69
+ const signableTransaction =
70
+ transaction.type === 'eip4844'
71
+ ? { ...transaction, sidecars: false }
72
+ : transaction
73
+
74
+ const serializedTx = serializer(signableTransaction)
75
+ const nonHexPrefixedSerializedTx = serializedTx.replace(/^0x/, '')
76
+ const signature = await client.signTransaction({
77
+ organizationId,
78
+ projectId,
79
+ address,
80
+ unsignedTransaction: nonHexPrefixedSerializedTx,
81
+ })
82
+
83
+ if (transaction.type === 'eip4844') {
84
+ // Grab components of the signature
85
+ const { r, s, v } = parseTransaction(signature)
86
+
87
+ // Recombine with the original transaction
88
+ return serializeTransaction(transaction, {
89
+ r: r!,
90
+ s: s!,
91
+ v: v!,
92
+ })
93
+ }
94
+
95
+ return signature
96
+ }
97
+
98
+ return toAccount({
99
+ address,
100
+
101
+ async signMessage({ message }: { message: SignableMessage }): Promise<Hex> {
102
+ const hashedMessage = hashMessage(message)
103
+ return signRawPayloadInternal(hashedMessage)
104
+ },
105
+
106
+ signTransaction: async <
107
+ TTransactionSerializable extends TransactionSerializable,
108
+ >(
109
+ transaction: TTransactionSerializable,
110
+ options?: {
111
+ serializer?:
112
+ | SerializeTransactionFn<TTransactionSerializable>
113
+ | undefined
114
+ },
115
+ ) => {
116
+ const serializer: SerializeTransactionFn<TTransactionSerializable> =
117
+ options?.serializer ??
118
+ (serializeTransaction as SerializeTransactionFn<TTransactionSerializable>)
119
+ return signTransactionInternal(transaction, serializer)
120
+ },
121
+ signTypedData: async (typedData) => {
122
+ const serializedTypedData = serializeTypedData(typedData)
123
+ return signRawPayloadInternal(
124
+ serializedTypedData,
125
+ 'PAYLOAD_ENCODING_EIP712',
126
+ )
127
+ },
128
+
129
+ async signAuthorization(
130
+ parameters: Omit<SignAuthorizationParameters, 'privateKey'>,
131
+ ): Promise<SignAuthorizationReturnType> {
132
+ const { chainId, nonce } = parameters
133
+ const authAddress = parameters.contractAddress ?? parameters.address
134
+
135
+ if (!authAddress) {
136
+ throw new Error('Unable to sign authorization: address is undefined')
137
+ }
138
+
139
+ const hashedAuthorization = hashAuthorization({
140
+ address: authAddress,
141
+ chainId,
142
+ nonce,
143
+ })
144
+
145
+ const signature = await signRawPayloadInternal(hashedAuthorization)
146
+
147
+ const parsedSignature = parseSignature(signature)
148
+
149
+ return {
150
+ address: authAddress,
151
+ chainId,
152
+ nonce,
153
+ ...parsedSignature,
154
+ yParity: parsedSignature.v === BigInt(27) ? 0 : 1,
155
+ } as SignAuthorizationReturnType
156
+ },
157
+ })
158
+ }
@@ -0,0 +1,95 @@
1
+ import type { Stamper } from '../stampers/types.js'
2
+ import {
3
+ type ZeroDevWalletActions,
4
+ zeroDevWalletActions,
5
+ } from './decorators/client.js'
6
+ import type { Client, ClientConfig } from './types.js'
7
+
8
+ let clientId = 0
9
+
10
+ /**
11
+ * Creates a base ZeroDev Wallet client.
12
+ * This is the foundation client without any pre-loaded actions.
13
+ * Use createClient() for a client with ZeroDev Wallet actions pre-loaded.
14
+ */
15
+ export function createBaseClient<
16
+ extended extends Record<string, unknown> | undefined = undefined,
17
+ TStamper extends Stamper = Stamper,
18
+ >(config: ClientConfig): Client<extended, TStamper> {
19
+ const {
20
+ transport,
21
+ stamper,
22
+ organizationId,
23
+ key = 'zeroDevWallet',
24
+ name = 'ZeroDev Wallet Client',
25
+ } = config
26
+
27
+ // Initialize the transport with stamper
28
+ const {
29
+ config: transportConfig,
30
+ request,
31
+ value,
32
+ } = transport({
33
+ stamper,
34
+ })
35
+ const transportInstance = { ...transportConfig, ...value }
36
+
37
+ const uid = `${key}-${++clientId}`
38
+
39
+ const client = {
40
+ transport: transportInstance,
41
+ request,
42
+ stamper,
43
+ organizationId,
44
+ key,
45
+ name,
46
+ type: 'zeroDevWallet',
47
+ uid,
48
+ } as const
49
+
50
+ function extend(base: typeof client) {
51
+ type ExtendFn = (base: typeof client) => Record<string, unknown>
52
+ return (extendFn: ExtendFn) => {
53
+ const extended = extendFn(base) as Record<string, unknown>
54
+
55
+ // Remove base properties from extended to avoid conflicts
56
+ for (const key in client) {
57
+ delete extended[key]
58
+ }
59
+
60
+ // Combine base client with extensions
61
+ const combined = { ...base, ...extended }
62
+
63
+ // Return new client with updated extend function
64
+ return Object.assign(combined, { extend: extend(combined as any) })
65
+ }
66
+ }
67
+
68
+ return Object.assign(client, { extend: extend(client) as any }) as Client<
69
+ extended,
70
+ TStamper
71
+ >
72
+ }
73
+
74
+ export type ZeroDevWalletClient<TStamper extends Stamper = Stamper> = Client<
75
+ ZeroDevWalletActions,
76
+ TStamper
77
+ >
78
+
79
+ /**
80
+ * Creates a ZeroDev Wallet client with ZeroDev Wallet actions pre-loaded.
81
+ * This is equivalent to calling createBaseClient(config).extend(zeroDevWalletActions).
82
+ *
83
+ * For a client without pre-loaded actions, use createBaseClient().
84
+ */
85
+ export function createClient<TStamper extends Stamper = Stamper>(
86
+ config: ClientConfig<TStamper>,
87
+ ): ZeroDevWalletClient<TStamper> {
88
+ const { key = 'zeroDevWallet', name = 'ZeroDev Wallet Client' } = config
89
+ const client = createBaseClient({
90
+ ...config,
91
+ key,
92
+ name,
93
+ })
94
+ return client.extend(zeroDevWalletActions) as ZeroDevWalletClient<TStamper>
95
+ }
@@ -0,0 +1,152 @@
1
+ import {
2
+ type LoginWithStampParameters,
3
+ type LoginWithStampReturnType,
4
+ loginWithStamp,
5
+ } from '../../actions/auth/loginWithStamp.js'
6
+ import {
7
+ type AuthenticateWithEmailParameters,
8
+ type AuthenticateWithEmailReturnType,
9
+ type AuthenticateWithOAuthParameters,
10
+ type AuthenticateWithOAuthReturnType,
11
+ authenticateWithEmail,
12
+ authenticateWithOAuth,
13
+ type GetUserWalletParameters,
14
+ type GetUserWalletReturnType,
15
+ type GetWhoamiParameters,
16
+ type GetWhoamiReturnType,
17
+ getUserWallet,
18
+ getWhoami,
19
+ type LoginWithOTPParameters,
20
+ type LoginWithOTPReturnType,
21
+ loginWithOTP,
22
+ type RegisterWithOTPParameters,
23
+ type RegisterWithOTPReturnType,
24
+ type RegisterWithPasskeyParameters,
25
+ type RegisterWithPasskeyReturnType,
26
+ registerWithOTP,
27
+ registerWithPasskey,
28
+ type SignRawPayloadParameters,
29
+ type SignRawPayloadReturnType,
30
+ signRawPayload,
31
+ } from '../../actions/index.js'
32
+ import {
33
+ type SignTransactionParameters,
34
+ type SignTransactionReturnType,
35
+ signTransaction,
36
+ } from '../../actions/wallet/signTransaction.js'
37
+ import type { Client } from '../types.js'
38
+
39
+ /**
40
+ * ZeroDev Wallet client actions that can be performed with a client
41
+ */
42
+ export type ZeroDevWalletActions = {
43
+ // Auth actions
44
+ /**
45
+ * Authenticates a user with their email address
46
+ */
47
+ authenticateWithEmail: (
48
+ params: AuthenticateWithEmailParameters,
49
+ ) => Promise<AuthenticateWithEmailReturnType>
50
+
51
+ /**
52
+ * Authenticates a user with OAuth credentials
53
+ */
54
+ authenticateWithOAuth: (
55
+ params: AuthenticateWithOAuthParameters,
56
+ ) => Promise<AuthenticateWithOAuthReturnType>
57
+
58
+ /**
59
+ * Gets the current user information
60
+ */
61
+ getWhoami: (params: GetWhoamiParameters) => Promise<GetWhoamiReturnType>
62
+
63
+ // Wallet actions
64
+ /**
65
+ * Gets the user's wallet information
66
+ */
67
+ getUserWallet: (
68
+ params: GetUserWalletParameters,
69
+ ) => Promise<GetUserWalletReturnType>
70
+
71
+ /**
72
+ * Signs a raw payload with the user's wallet
73
+ */
74
+ signRawPayload: (
75
+ params: SignRawPayloadParameters,
76
+ ) => Promise<SignRawPayloadReturnType>
77
+
78
+ /**
79
+ * Signs a transaction with the user's wallet
80
+ */
81
+ signTransaction: (
82
+ params: SignTransactionParameters,
83
+ ) => Promise<SignTransactionReturnType>
84
+
85
+ /**
86
+ * Registers a passkey with the user's wallet
87
+ */
88
+ registerWithPasskey: (
89
+ params: RegisterWithPasskeyParameters,
90
+ ) => Promise<RegisterWithPasskeyReturnType>
91
+
92
+ /**
93
+ * Logs in a user with a stamp
94
+ */
95
+ loginWithStamp: (
96
+ params: LoginWithStampParameters,
97
+ ) => Promise<LoginWithStampReturnType>
98
+
99
+ /**
100
+ * Registers a user with OTP (One-Time Password) authentication
101
+ */
102
+ registerWithOTP: (
103
+ params: RegisterWithOTPParameters,
104
+ ) => Promise<RegisterWithOTPReturnType>
105
+
106
+ /**
107
+ * Logs in a user with OTP (One-Time Password) authentication
108
+ */
109
+ loginWithOTP: (
110
+ params: LoginWithOTPParameters,
111
+ ) => Promise<LoginWithOTPReturnType>
112
+ }
113
+
114
+ /**
115
+ * Decorator function that adds ZeroDev Wallet client actions to a client
116
+ *
117
+ * @param client - The base client to extend
118
+ * @returns An object containing all ZeroDev Wallet client actions bound to the client
119
+ *
120
+ * @example
121
+ * ```ts
122
+ * import { createClient, zeroDevWalletTransport, zeroDevWalletActions } from '@zerodev/wallet-core';
123
+ *
124
+ * const client = createClient({
125
+ * transport: zeroDevWalletTransport({ baseUrl: 'https://api.example.com' }),
126
+ * stamper: myStamper,
127
+ * }).extend(zeroDevWalletActions);
128
+ *
129
+ * // Now you can use actions directly on the client
130
+ * const userInfo = await client.getWhoami({
131
+ * organizationId: 'org_123',
132
+ * projectId: 'proj_456'
133
+ * });
134
+ * ```
135
+ */
136
+ export function zeroDevWalletActions(client: Client): ZeroDevWalletActions {
137
+ return {
138
+ // Auth actions
139
+ authenticateWithEmail: (params) => authenticateWithEmail(client, params),
140
+ authenticateWithOAuth: (params) => authenticateWithOAuth(client, params),
141
+ getWhoami: (params) => getWhoami(client, params),
142
+
143
+ // Wallet actions
144
+ getUserWallet: (params) => getUserWallet(client, params),
145
+ signRawPayload: (params) => signRawPayload(client, params),
146
+ signTransaction: (params) => signTransaction(client, params),
147
+ registerWithPasskey: (params) => registerWithPasskey(client, params),
148
+ loginWithStamp: (params) => loginWithStamp(client, params),
149
+ registerWithOTP: (params) => registerWithOTP(client, params),
150
+ loginWithOTP: (params) => loginWithOTP(client, params),
151
+ }
152
+ }
@@ -0,0 +1,12 @@
1
+ export {
2
+ createBaseClient,
3
+ createClient,
4
+ type ZeroDevWalletClient,
5
+ } from './createClient.js'
6
+ export { zeroDevWalletTransport } from './transports/createTransport.js'
7
+ export type {
8
+ Client,
9
+ ClientConfig,
10
+ Transport,
11
+ TransportConfig,
12
+ } from './types.js'
@@ -0,0 +1,52 @@
1
+ import type { Transport } from '../types.js'
2
+ import { rest } from './rest.js'
3
+
4
+ export type CreateTransportOptions = {
5
+ /** Base URL for the API */
6
+ baseUrl: string
7
+ /** Request timeout in milliseconds */
8
+ timeoutMs?: number
9
+ /** Transport key identifier */
10
+ key?: string
11
+ /** Transport name */
12
+ name?: string
13
+ }
14
+
15
+ /**
16
+ * Creates a transport for the ZeroDev Wallet client.
17
+ * Requires a stamper for authenticated requests.
18
+ */
19
+ export function zeroDevWalletTransport(
20
+ options: CreateTransportOptions,
21
+ ): Transport {
22
+ const {
23
+ baseUrl,
24
+ timeoutMs = 10_000,
25
+ key = 'zeroDevWallet',
26
+ name = 'ZeroDev Wallet Transport',
27
+ } = options
28
+
29
+ return ({ stamper }) => {
30
+ // Create REST transport with stamper
31
+ const transport = rest(baseUrl, {
32
+ timeoutMs,
33
+ key,
34
+ name,
35
+ stamper,
36
+ })
37
+
38
+ return {
39
+ config: {
40
+ name,
41
+ key,
42
+ url: baseUrl,
43
+ timeoutMs,
44
+ type: 'zeroDevWallet',
45
+ },
46
+ request: transport.request,
47
+ value: {
48
+ stamper,
49
+ },
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,121 @@
1
+ import { RestRequestError, RestTimeoutError } from '../../errors/request.js'
2
+ import type { Stamper } from '../../stampers/types.js'
3
+
4
+ export type RestRequestArgs = {
5
+ path: string
6
+ method?: 'GET' | 'POST' | 'PUT' | 'DELETE'
7
+ body?: any
8
+ headers?: Record<string, string>
9
+ stamp?: boolean // When true, will stamp the request body
10
+ }
11
+
12
+ export type RestRequestFn = <T = any>(args: RestRequestArgs) => Promise<T>
13
+
14
+ export type RestTransport = {
15
+ config: { key: string; name: string; url: string; timeoutMs: number }
16
+ request: RestRequestFn
17
+ value: Record<string, unknown>
18
+ }
19
+
20
+ export type RestTransportConfig = {
21
+ fetchOptions?: Omit<RequestInit, 'body' | 'method' | 'signal'>
22
+ onRequest?: (
23
+ url: string,
24
+ init: RequestInit,
25
+ ) => Promise<RequestInit | undefined> | RequestInit | undefined
26
+ onResponse?: (res: Response) => Promise<void> | void
27
+ timeoutMs?: number
28
+ key?: string
29
+ name?: string
30
+ stamper?: Stamper
31
+ }
32
+
33
+ export function rest(
34
+ url: string,
35
+ cfg: RestTransportConfig = {},
36
+ ): RestTransport {
37
+ const timeoutMs = cfg.timeoutMs ?? 10_000
38
+ const key = cfg.key ?? 'rest'
39
+ const name = cfg.name ?? 'HTTP REST'
40
+
41
+ const request: RestRequestFn = async (args) => {
42
+ const fullUrl = `${url}/${args.path}`
43
+ const controller = new AbortController()
44
+ const timer = setTimeout(() => controller.abort(), timeoutMs)
45
+
46
+ try {
47
+ let requestBody = args.body
48
+ const requestHeaders = {
49
+ 'content-type': 'application/json',
50
+ ...(args.headers ?? {}),
51
+ ...(cfg.fetchOptions?.headers ?? {}),
52
+ }
53
+
54
+ // Handle stamping if requested
55
+ if (args.stamp && cfg.stamper) {
56
+ const { body, apiUrl } = args.body
57
+ const bodyString = `${JSON.stringify(body ?? args.body)}\n`
58
+ const stamp = await cfg.stamper.stamp(bodyString)
59
+
60
+ // Restructure request body to match backend expectation
61
+ if (body) {
62
+ requestBody = {
63
+ body: bodyString,
64
+ stamp: {
65
+ stampHeaderName: stamp.stampHeaderName,
66
+ stampHeaderValue: stamp.stampHeaderValue,
67
+ },
68
+ apiUrl: apiUrl,
69
+ }
70
+ } else {
71
+ requestBody = {
72
+ ...args.body,
73
+ stamp: {
74
+ stampHeaderName: stamp.stampHeaderName,
75
+ stampHeaderValue: stamp.stampHeaderValue,
76
+ },
77
+ }
78
+ }
79
+ }
80
+
81
+ const init: RequestInit = {
82
+ ...cfg.fetchOptions,
83
+ method: args.method ?? 'POST',
84
+ headers: requestHeaders,
85
+ body: requestBody != null ? JSON.stringify(requestBody) : null,
86
+ signal: controller.signal,
87
+ }
88
+
89
+ const finalInit = (await cfg.onRequest?.(fullUrl, init)) ?? init
90
+ const res = await fetch(fullUrl, finalInit)
91
+
92
+ await cfg.onResponse?.(res)
93
+
94
+ let data: any
95
+ const ct = res.headers.get('content-type') ?? ''
96
+ if (ct.startsWith('application/json')) data = await res.json()
97
+ else {
98
+ const text = await res.text()
99
+ try {
100
+ data = text ? JSON.parse(text) : {}
101
+ } catch {
102
+ data = text
103
+ }
104
+ }
105
+
106
+ if (!res.ok) throw new RestRequestError(fullUrl, res.status, data)
107
+ return data as any
108
+ } catch (err: any) {
109
+ if (err.name === 'AbortError') throw new RestTimeoutError(fullUrl)
110
+ throw err
111
+ } finally {
112
+ clearTimeout(timer)
113
+ }
114
+ }
115
+
116
+ return {
117
+ config: { key, name, url, timeoutMs },
118
+ request,
119
+ value: {},
120
+ }
121
+ }