@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.
- package/README.md +272 -0
- package/dist/_cjs/actions/auth/authenticateWithEmail.js +17 -0
- package/dist/_cjs/actions/auth/authenticateWithEmail.js.map +1 -0
- package/dist/_cjs/actions/auth/authenticateWithOAuth.js +17 -0
- package/dist/_cjs/actions/auth/authenticateWithOAuth.js.map +1 -0
- package/dist/_cjs/actions/auth/getWhoami.js +15 -0
- package/dist/_cjs/actions/auth/getWhoami.js.map +1 -0
- package/dist/_cjs/actions/auth/index.js +18 -0
- package/dist/_cjs/actions/auth/index.js.map +1 -0
- package/dist/_cjs/actions/auth/loginWithOTP.js +17 -0
- package/dist/_cjs/actions/auth/loginWithOTP.js.map +1 -0
- package/dist/_cjs/actions/auth/loginWithStamp.js +29 -0
- package/dist/_cjs/actions/auth/loginWithStamp.js.map +1 -0
- package/dist/_cjs/actions/auth/registerWithOTP.js +17 -0
- package/dist/_cjs/actions/auth/registerWithOTP.js.map +1 -0
- package/dist/_cjs/actions/auth/registerWithPasskey.js +17 -0
- package/dist/_cjs/actions/auth/registerWithPasskey.js.map +1 -0
- package/dist/_cjs/actions/index.js +15 -0
- package/dist/_cjs/actions/index.js.map +1 -0
- package/dist/_cjs/actions/wallet/getUserWallet.js +13 -0
- package/dist/_cjs/actions/wallet/getUserWallet.js.map +1 -0
- package/dist/_cjs/actions/wallet/index.js +10 -0
- package/dist/_cjs/actions/wallet/index.js.map +1 -0
- package/dist/_cjs/actions/wallet/signRawPayload.js +26 -0
- package/dist/_cjs/actions/wallet/signRawPayload.js.map +1 -0
- package/dist/_cjs/actions/wallet/signTransaction.js +25 -0
- package/dist/_cjs/actions/wallet/signTransaction.js.map +1 -0
- package/dist/_cjs/adapters/viem.js +89 -0
- package/dist/_cjs/adapters/viem.js.map +1 -0
- package/dist/_cjs/client/createClient.js +45 -0
- package/dist/_cjs/client/createClient.js.map +1 -0
- package/dist/_cjs/client/decorators/client.js +21 -0
- package/dist/_cjs/client/decorators/client.js.map +1 -0
- package/dist/_cjs/client/index.js +9 -0
- package/dist/_cjs/client/index.js.map +1 -0
- package/dist/_cjs/client/transports/createTransport.js +29 -0
- package/dist/_cjs/client/transports/createTransport.js.map +1 -0
- package/dist/_cjs/client/transports/rest.js +86 -0
- package/dist/_cjs/client/transports/rest.js.map +1 -0
- package/dist/_cjs/client/types.js +3 -0
- package/dist/_cjs/client/types.js.map +1 -0
- package/dist/_cjs/constants.js +9 -0
- package/dist/_cjs/constants.js.map +1 -0
- package/dist/_cjs/core/createZeroDevWallet.js +330 -0
- package/dist/_cjs/core/createZeroDevWallet.js.map +1 -0
- package/dist/_cjs/errors/request.js +61 -0
- package/dist/_cjs/errors/request.js.map +1 -0
- package/dist/_cjs/index.js +31 -0
- package/dist/_cjs/index.js.map +1 -0
- package/dist/_cjs/package.json +1 -0
- package/dist/_cjs/polyfills/window.js +26 -0
- package/dist/_cjs/polyfills/window.js.map +1 -0
- package/dist/_cjs/stampers/iframeStamper.js +32 -0
- package/dist/_cjs/stampers/iframeStamper.js.map +1 -0
- package/dist/_cjs/stampers/index.js +10 -0
- package/dist/_cjs/stampers/index.js.map +1 -0
- package/dist/_cjs/stampers/indexedDbStamper.js +23 -0
- package/dist/_cjs/stampers/indexedDbStamper.js.map +1 -0
- package/dist/_cjs/stampers/types.js +3 -0
- package/dist/_cjs/stampers/types.js.map +1 -0
- package/dist/_cjs/stampers/webauthnStamper.js +17 -0
- package/dist/_cjs/stampers/webauthnStamper.js.map +1 -0
- package/dist/_cjs/storage/adapters.js +18 -0
- package/dist/_cjs/storage/adapters.js.map +1 -0
- package/dist/_cjs/storage/manager.js +108 -0
- package/dist/_cjs/storage/manager.js.map +1 -0
- package/dist/_cjs/types/session.js +9 -0
- package/dist/_cjs/types/session.js.map +1 -0
- package/dist/_cjs/utils/exportWallet.js +70 -0
- package/dist/_cjs/utils/exportWallet.js.map +1 -0
- package/dist/_cjs/utils/utils.js +75 -0
- package/dist/_cjs/utils/utils.js.map +1 -0
- package/dist/_esm/actions/auth/authenticateWithEmail.js +18 -0
- package/dist/_esm/actions/auth/authenticateWithEmail.js.map +1 -0
- package/dist/_esm/actions/auth/authenticateWithOAuth.js +31 -0
- package/dist/_esm/actions/auth/authenticateWithOAuth.js.map +1 -0
- package/dist/_esm/actions/auth/getWhoami.js +28 -0
- package/dist/_esm/actions/auth/getWhoami.js.map +1 -0
- package/dist/_esm/actions/auth/index.js +8 -0
- package/dist/_esm/actions/auth/index.js.map +1 -0
- package/dist/_esm/actions/auth/loginWithOTP.js +36 -0
- package/dist/_esm/actions/auth/loginWithOTP.js.map +1 -0
- package/dist/_esm/actions/auth/loginWithStamp.js +42 -0
- package/dist/_esm/actions/auth/loginWithStamp.js.map +1 -0
- package/dist/_esm/actions/auth/registerWithOTP.js +36 -0
- package/dist/_esm/actions/auth/registerWithOTP.js.map +1 -0
- package/dist/_esm/actions/auth/registerWithPasskey.js +36 -0
- package/dist/_esm/actions/auth/registerWithPasskey.js.map +1 -0
- package/dist/_esm/actions/index.js +5 -0
- package/dist/_esm/actions/index.js.map +1 -0
- package/dist/_esm/actions/wallet/getUserWallet.js +26 -0
- package/dist/_esm/actions/wallet/getUserWallet.js.map +1 -0
- package/dist/_esm/actions/wallet/index.js +4 -0
- package/dist/_esm/actions/wallet/index.js.map +1 -0
- package/dist/_esm/actions/wallet/signRawPayload.js +41 -0
- package/dist/_esm/actions/wallet/signRawPayload.js.map +1 -0
- package/dist/_esm/actions/wallet/signTransaction.js +40 -0
- package/dist/_esm/actions/wallet/signTransaction.js.map +1 -0
- package/dist/_esm/adapters/viem.js +91 -0
- package/dist/_esm/adapters/viem.js.map +1 -0
- package/dist/_esm/client/createClient.js +56 -0
- package/dist/_esm/client/createClient.js.map +1 -0
- package/dist/_esm/client/decorators/client.js +42 -0
- package/dist/_esm/client/decorators/client.js.map +1 -0
- package/dist/_esm/client/index.js +3 -0
- package/dist/_esm/client/index.js.map +1 -0
- package/dist/_esm/client/transports/createTransport.js +31 -0
- package/dist/_esm/client/transports/createTransport.js.map +1 -0
- package/dist/_esm/client/transports/rest.js +85 -0
- package/dist/_esm/client/transports/rest.js.map +1 -0
- package/dist/_esm/client/types.js +2 -0
- package/dist/_esm/client/types.js.map +1 -0
- package/dist/_esm/constants.js +6 -0
- package/dist/_esm/constants.js.map +1 -0
- package/dist/_esm/core/createZeroDevWallet.js +332 -0
- package/dist/_esm/core/createZeroDevWallet.js.map +1 -0
- package/dist/_esm/errors/request.js +60 -0
- package/dist/_esm/errors/request.js.map +1 -0
- package/dist/_esm/index.js +20 -0
- package/dist/_esm/index.js.map +1 -0
- package/dist/_esm/package.json +1 -0
- package/dist/_esm/polyfills/window.js +24 -0
- package/dist/_esm/polyfills/window.js.map +1 -0
- package/dist/_esm/stampers/iframeStamper.js +29 -0
- package/dist/_esm/stampers/iframeStamper.js.map +1 -0
- package/dist/_esm/stampers/index.js +4 -0
- package/dist/_esm/stampers/index.js.map +1 -0
- package/dist/_esm/stampers/indexedDbStamper.js +20 -0
- package/dist/_esm/stampers/indexedDbStamper.js.map +1 -0
- package/dist/_esm/stampers/types.js +2 -0
- package/dist/_esm/stampers/types.js.map +1 -0
- package/dist/_esm/stampers/webauthnStamper.js +15 -0
- package/dist/_esm/stampers/webauthnStamper.js.map +1 -0
- package/dist/_esm/storage/adapters.js +15 -0
- package/dist/_esm/storage/adapters.js.map +1 -0
- package/dist/_esm/storage/manager.js +118 -0
- package/dist/_esm/storage/manager.js.map +1 -0
- package/dist/_esm/types/session.js +6 -0
- package/dist/_esm/types/session.js.map +1 -0
- package/dist/_esm/utils/exportWallet.js +98 -0
- package/dist/_esm/utils/exportWallet.js.map +1 -0
- package/dist/_esm/utils/utils.js +105 -0
- package/dist/_esm/utils/utils.js.map +1 -0
- package/dist/_types/actions/auth/authenticateWithEmail.d.ts +33 -0
- package/dist/_types/actions/auth/authenticateWithEmail.d.ts.map +1 -0
- package/dist/_types/actions/auth/authenticateWithOAuth.d.ts +40 -0
- package/dist/_types/actions/auth/authenticateWithOAuth.d.ts.map +1 -0
- package/dist/_types/actions/auth/getWhoami.d.ts +35 -0
- package/dist/_types/actions/auth/getWhoami.d.ts.map +1 -0
- package/dist/_types/actions/auth/index.d.ts +8 -0
- package/dist/_types/actions/auth/index.d.ts.map +1 -0
- package/dist/_types/actions/auth/loginWithOTP.d.ts +41 -0
- package/dist/_types/actions/auth/loginWithOTP.d.ts.map +1 -0
- package/dist/_types/actions/auth/loginWithStamp.d.ts +35 -0
- package/dist/_types/actions/auth/loginWithStamp.d.ts.map +1 -0
- package/dist/_types/actions/auth/registerWithOTP.d.ts +52 -0
- package/dist/_types/actions/auth/registerWithOTP.d.ts.map +1 -0
- package/dist/_types/actions/auth/registerWithPasskey.d.ts +53 -0
- package/dist/_types/actions/auth/registerWithPasskey.d.ts.map +1 -0
- package/dist/_types/actions/index.d.ts +3 -0
- package/dist/_types/actions/index.d.ts.map +1 -0
- package/dist/_types/actions/wallet/getUserWallet.d.ts +32 -0
- package/dist/_types/actions/wallet/getUserWallet.d.ts.map +1 -0
- package/dist/_types/actions/wallet/index.d.ts +4 -0
- package/dist/_types/actions/wallet/index.d.ts.map +1 -0
- package/dist/_types/actions/wallet/signRawPayload.d.ts +37 -0
- package/dist/_types/actions/wallet/signRawPayload.d.ts.map +1 -0
- package/dist/_types/actions/wallet/signTransaction.d.ts +33 -0
- package/dist/_types/actions/wallet/signTransaction.d.ts.map +1 -0
- package/dist/_types/adapters/viem.d.ts +9 -0
- package/dist/_types/adapters/viem.d.ts.map +1 -0
- package/dist/_types/client/createClient.d.ts +18 -0
- package/dist/_types/client/createClient.d.ts.map +1 -0
- package/dist/_types/client/decorators/client.d.ts +73 -0
- package/dist/_types/client/decorators/client.d.ts.map +1 -0
- package/dist/_types/client/index.d.ts +4 -0
- package/dist/_types/client/index.d.ts.map +1 -0
- package/dist/_types/client/transports/createTransport.d.ts +17 -0
- package/dist/_types/client/transports/createTransport.d.ts.map +1 -0
- package/dist/_types/client/transports/rest.d.ts +30 -0
- package/dist/_types/client/transports/rest.d.ts.map +1 -0
- package/dist/_types/client/types.d.ts +60 -0
- package/dist/_types/client/types.d.ts.map +1 -0
- package/dist/_types/constants.d.ts +6 -0
- package/dist/_types/constants.d.ts.map +1 -0
- package/dist/_types/core/createZeroDevWallet.d.ts +55 -0
- package/dist/_types/core/createZeroDevWallet.d.ts.map +1 -0
- package/dist/_types/errors/request.d.ts +12 -0
- package/dist/_types/errors/request.d.ts.map +1 -0
- package/dist/_types/index.d.ts +17 -0
- package/dist/_types/index.d.ts.map +1 -0
- package/dist/_types/polyfills/window.d.ts +15 -0
- package/dist/_types/polyfills/window.d.ts.map +1 -0
- package/dist/_types/stampers/iframeStamper.d.ts +7 -0
- package/dist/_types/stampers/iframeStamper.d.ts.map +1 -0
- package/dist/_types/stampers/index.d.ts +5 -0
- package/dist/_types/stampers/index.d.ts.map +1 -0
- package/dist/_types/stampers/indexedDbStamper.d.ts +3 -0
- package/dist/_types/stampers/indexedDbStamper.d.ts.map +1 -0
- package/dist/_types/stampers/types.d.ts +23 -0
- package/dist/_types/stampers/types.d.ts.map +1 -0
- package/dist/_types/stampers/webauthnStamper.d.ts +5 -0
- package/dist/_types/stampers/webauthnStamper.d.ts.map +1 -0
- package/dist/_types/storage/adapters.d.ts +3 -0
- package/dist/_types/storage/adapters.d.ts.map +1 -0
- package/dist/_types/storage/manager.d.ts +19 -0
- package/dist/_types/storage/manager.d.ts.map +1 -0
- package/dist/_types/types/session.d.ts +17 -0
- package/dist/_types/types/session.d.ts.map +1 -0
- package/dist/_types/utils/exportWallet.d.ts +44 -0
- package/dist/_types/utils/exportWallet.d.ts.map +1 -0
- package/dist/_types/utils/utils.d.ts +52 -0
- package/dist/_types/utils/utils.d.ts.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/package.json +73 -0
- package/src/actions/auth/authenticateWithEmail.ts +52 -0
- package/src/actions/auth/authenticateWithOAuth.ts +58 -0
- package/src/actions/auth/getWhoami.ts +51 -0
- package/src/actions/auth/index.ts +40 -0
- package/src/actions/auth/loginWithOTP.ts +60 -0
- package/src/actions/auth/loginWithStamp.ts +68 -0
- package/src/actions/auth/registerWithOTP.ts +71 -0
- package/src/actions/auth/registerWithPasskey.ts +72 -0
- package/src/actions/index.ts +36 -0
- package/src/actions/wallet/getUserWallet.ts +46 -0
- package/src/actions/wallet/index.ts +17 -0
- package/src/actions/wallet/signRawPayload.ts +71 -0
- package/src/actions/wallet/signTransaction.ts +60 -0
- package/src/adapters/viem.ts +158 -0
- package/src/client/createClient.ts +95 -0
- package/src/client/decorators/client.ts +152 -0
- package/src/client/index.ts +12 -0
- package/src/client/transports/createTransport.ts +52 -0
- package/src/client/transports/rest.ts +121 -0
- package/src/client/types.ts +66 -0
- package/src/constants.ts +5 -0
- package/src/core/createZeroDevWallet.ts +477 -0
- package/src/errors/request.ts +36 -0
- package/src/index.ts +75 -0
- package/src/polyfills/window.ts +24 -0
- package/src/stampers/iframeStamper.ts +35 -0
- package/src/stampers/index.ts +8 -0
- package/src/stampers/indexedDbStamper.ts +22 -0
- package/src/stampers/types.ts +28 -0
- package/src/stampers/webauthnStamper.ts +21 -0
- package/src/storage/adapters.ts +20 -0
- package/src/storage/manager.ts +170 -0
- package/src/types/session.ts +18 -0
- package/src/utils/exportWallet.ts +124 -0
- 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
|
+
}
|