@alchemy/wallet-apis 5.0.0-beta.9 → 5.0.1

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 (201) hide show
  1. package/README.md +2 -0
  2. package/dist/esm/actions/prepareCalls.d.ts +8 -3
  3. package/dist/esm/actions/prepareCalls.js +8 -0
  4. package/dist/esm/actions/prepareCalls.js.map +1 -1
  5. package/dist/esm/actions/requestAccount.d.ts +4 -3
  6. package/dist/esm/actions/requestAccount.js.map +1 -1
  7. package/dist/esm/actions/sendCalls.d.ts +5 -2
  8. package/dist/esm/actions/sendCalls.js +5 -2
  9. package/dist/esm/actions/sendCalls.js.map +1 -1
  10. package/dist/esm/actions/sendPreparedCalls.d.ts +3 -1
  11. package/dist/esm/actions/sendPreparedCalls.js.map +1 -1
  12. package/dist/esm/actions/signPreparedCalls.d.ts +2 -0
  13. package/dist/esm/actions/signPreparedCalls.js +14 -1
  14. package/dist/esm/actions/signPreparedCalls.js.map +1 -1
  15. package/dist/esm/actions/signSignatureRequest.d.ts +4 -4
  16. package/dist/esm/actions/signSignatureRequest.js +1 -1
  17. package/dist/esm/actions/signSignatureRequest.js.map +1 -1
  18. package/dist/esm/actions/signTypedData.d.ts +14 -4
  19. package/dist/esm/actions/signTypedData.js.map +1 -1
  20. package/dist/esm/actions/solana/getCallsStatus.d.ts +24 -0
  21. package/dist/esm/actions/solana/getCallsStatus.js +44 -0
  22. package/dist/esm/actions/solana/getCallsStatus.js.map +1 -0
  23. package/dist/esm/actions/solana/prepareCalls.d.ts +46 -0
  24. package/dist/esm/actions/solana/prepareCalls.js +70 -0
  25. package/dist/esm/actions/solana/prepareCalls.js.map +1 -0
  26. package/dist/esm/actions/solana/sendCalls.d.ts +34 -0
  27. package/dist/esm/actions/solana/sendCalls.js +44 -0
  28. package/dist/esm/actions/solana/sendCalls.js.map +1 -0
  29. package/dist/esm/actions/solana/sendPreparedCalls.d.ts +24 -0
  30. package/dist/esm/actions/solana/sendPreparedCalls.js +32 -0
  31. package/dist/esm/actions/solana/sendPreparedCalls.js.map +1 -0
  32. package/dist/esm/actions/solana/signPreparedCalls.d.ts +23 -0
  33. package/dist/esm/actions/solana/signPreparedCalls.js +24 -0
  34. package/dist/esm/actions/solana/signPreparedCalls.js.map +1 -0
  35. package/dist/esm/actions/solana/signSignatureRequest.d.ts +10 -0
  36. package/dist/esm/actions/solana/signSignatureRequest.js +33 -0
  37. package/dist/esm/actions/solana/signSignatureRequest.js.map +1 -0
  38. package/dist/esm/actions/solana/waitForCallsStatus.d.ts +24 -0
  39. package/dist/esm/actions/solana/waitForCallsStatus.js +46 -0
  40. package/dist/esm/actions/solana/waitForCallsStatus.js.map +1 -0
  41. package/dist/esm/actions/undelegateAccount.d.ts +37 -0
  42. package/dist/esm/actions/undelegateAccount.js +49 -0
  43. package/dist/esm/actions/undelegateAccount.js.map +1 -0
  44. package/dist/esm/adapters/SolanaSignerError.d.ts +4 -0
  45. package/dist/esm/adapters/SolanaSignerError.js +13 -0
  46. package/dist/esm/adapters/SolanaSignerError.js.map +1 -0
  47. package/dist/esm/adapters/fromKeypair.d.ts +21 -0
  48. package/dist/esm/adapters/fromKeypair.js +46 -0
  49. package/dist/esm/adapters/fromKeypair.js.map +1 -0
  50. package/dist/esm/adapters/fromKitSigner.d.ts +21 -0
  51. package/dist/esm/adapters/fromKitSigner.js +61 -0
  52. package/dist/esm/adapters/fromKitSigner.js.map +1 -0
  53. package/dist/esm/adapters/fromWalletAdapter.d.ts +26 -0
  54. package/dist/esm/adapters/fromWalletAdapter.js +45 -0
  55. package/dist/esm/adapters/fromWalletAdapter.js.map +1 -0
  56. package/dist/esm/adapters/fromWalletStandard.d.ts +31 -0
  57. package/dist/esm/adapters/fromWalletStandard.js +53 -0
  58. package/dist/esm/adapters/fromWalletStandard.js.map +1 -0
  59. package/dist/esm/adapters/resolveSignerSlot.d.ts +10 -0
  60. package/dist/esm/adapters/resolveSignerSlot.js +39 -0
  61. package/dist/esm/adapters/resolveSignerSlot.js.map +1 -0
  62. package/dist/esm/client.d.ts +29 -14
  63. package/dist/esm/client.js +63 -19
  64. package/dist/esm/client.js.map +1 -1
  65. package/dist/esm/decorators/smartWalletActions.d.ts +2 -0
  66. package/dist/esm/decorators/smartWalletActions.js +4 -2
  67. package/dist/esm/decorators/smartWalletActions.js.map +1 -1
  68. package/dist/esm/decorators/solanaSmartWalletActions.d.ts +16 -0
  69. package/dist/esm/decorators/solanaSmartWalletActions.js +16 -0
  70. package/dist/esm/decorators/solanaSmartWalletActions.js.map +1 -0
  71. package/dist/esm/experimental/actions/requestQuoteV0.d.ts +48 -11
  72. package/dist/esm/experimental/actions/requestQuoteV0.js +8 -4
  73. package/dist/esm/experimental/actions/requestQuoteV0.js.map +1 -1
  74. package/dist/esm/experimental/swapActionsDecorator.d.ts +3 -0
  75. package/dist/esm/experimental/swapActionsDecorator.js.map +1 -1
  76. package/dist/esm/exports/index.d.ts +5 -3
  77. package/dist/esm/exports/index.js +1 -0
  78. package/dist/esm/exports/index.js.map +1 -1
  79. package/dist/esm/exports/solana.d.ts +24 -0
  80. package/dist/esm/exports/solana.js +15 -0
  81. package/dist/esm/exports/solana.js.map +1 -0
  82. package/dist/esm/types.d.ts +28 -4
  83. package/dist/esm/types.js.map +1 -1
  84. package/dist/esm/utils/assertions.d.ts +4 -2
  85. package/dist/esm/utils/assertions.js +6 -0
  86. package/dist/esm/utils/assertions.js.map +1 -1
  87. package/dist/esm/utils/capabilities.d.ts +22 -6
  88. package/dist/esm/utils/capabilities.js +19 -2
  89. package/dist/esm/utils/capabilities.js.map +1 -1
  90. package/dist/esm/utils/format.d.ts +2 -2
  91. package/dist/esm/utils/format.js +4 -3
  92. package/dist/esm/utils/format.js.map +1 -1
  93. package/dist/esm/utils/schema.d.ts +14 -14
  94. package/dist/esm/utils/schema.js +35 -39
  95. package/dist/esm/utils/schema.js.map +1 -1
  96. package/dist/esm/version.d.ts +1 -1
  97. package/dist/esm/version.js +1 -1
  98. package/dist/esm/version.js.map +1 -1
  99. package/dist/types/actions/prepareCalls.d.ts +8 -3
  100. package/dist/types/actions/prepareCalls.d.ts.map +1 -1
  101. package/dist/types/actions/requestAccount.d.ts +4 -3
  102. package/dist/types/actions/requestAccount.d.ts.map +1 -1
  103. package/dist/types/actions/sendCalls.d.ts +5 -2
  104. package/dist/types/actions/sendCalls.d.ts.map +1 -1
  105. package/dist/types/actions/sendPreparedCalls.d.ts +3 -1
  106. package/dist/types/actions/sendPreparedCalls.d.ts.map +1 -1
  107. package/dist/types/actions/signPreparedCalls.d.ts +2 -0
  108. package/dist/types/actions/signPreparedCalls.d.ts.map +1 -1
  109. package/dist/types/actions/signSignatureRequest.d.ts +4 -4
  110. package/dist/types/actions/signSignatureRequest.d.ts.map +1 -1
  111. package/dist/types/actions/signTypedData.d.ts +14 -4
  112. package/dist/types/actions/signTypedData.d.ts.map +1 -1
  113. package/dist/types/actions/solana/getCallsStatus.d.ts +25 -0
  114. package/dist/types/actions/solana/getCallsStatus.d.ts.map +1 -0
  115. package/dist/types/actions/solana/prepareCalls.d.ts +47 -0
  116. package/dist/types/actions/solana/prepareCalls.d.ts.map +1 -0
  117. package/dist/types/actions/solana/sendCalls.d.ts +35 -0
  118. package/dist/types/actions/solana/sendCalls.d.ts.map +1 -0
  119. package/dist/types/actions/solana/sendPreparedCalls.d.ts +25 -0
  120. package/dist/types/actions/solana/sendPreparedCalls.d.ts.map +1 -0
  121. package/dist/types/actions/solana/signPreparedCalls.d.ts +24 -0
  122. package/dist/types/actions/solana/signPreparedCalls.d.ts.map +1 -0
  123. package/dist/types/actions/solana/signSignatureRequest.d.ts +11 -0
  124. package/dist/types/actions/solana/signSignatureRequest.d.ts.map +1 -0
  125. package/dist/types/actions/solana/waitForCallsStatus.d.ts +25 -0
  126. package/dist/types/actions/solana/waitForCallsStatus.d.ts.map +1 -0
  127. package/dist/types/actions/undelegateAccount.d.ts +38 -0
  128. package/dist/types/actions/undelegateAccount.d.ts.map +1 -0
  129. package/dist/types/adapters/SolanaSignerError.d.ts +5 -0
  130. package/dist/types/adapters/SolanaSignerError.d.ts.map +1 -0
  131. package/dist/types/adapters/fromKeypair.d.ts +22 -0
  132. package/dist/types/adapters/fromKeypair.d.ts.map +1 -0
  133. package/dist/types/adapters/fromKitSigner.d.ts +22 -0
  134. package/dist/types/adapters/fromKitSigner.d.ts.map +1 -0
  135. package/dist/types/adapters/fromWalletAdapter.d.ts +27 -0
  136. package/dist/types/adapters/fromWalletAdapter.d.ts.map +1 -0
  137. package/dist/types/adapters/fromWalletStandard.d.ts +32 -0
  138. package/dist/types/adapters/fromWalletStandard.d.ts.map +1 -0
  139. package/dist/types/adapters/resolveSignerSlot.d.ts +11 -0
  140. package/dist/types/adapters/resolveSignerSlot.d.ts.map +1 -0
  141. package/dist/types/client.d.ts +29 -14
  142. package/dist/types/client.d.ts.map +1 -1
  143. package/dist/types/decorators/smartWalletActions.d.ts +2 -0
  144. package/dist/types/decorators/smartWalletActions.d.ts.map +1 -1
  145. package/dist/types/decorators/solanaSmartWalletActions.d.ts +17 -0
  146. package/dist/types/decorators/solanaSmartWalletActions.d.ts.map +1 -0
  147. package/dist/types/experimental/actions/requestQuoteV0.d.ts +48 -11
  148. package/dist/types/experimental/actions/requestQuoteV0.d.ts.map +1 -1
  149. package/dist/types/experimental/swapActionsDecorator.d.ts +3 -0
  150. package/dist/types/experimental/swapActionsDecorator.d.ts.map +1 -1
  151. package/dist/types/exports/index.d.ts +5 -3
  152. package/dist/types/exports/index.d.ts.map +1 -1
  153. package/dist/types/exports/solana.d.ts +25 -0
  154. package/dist/types/exports/solana.d.ts.map +1 -0
  155. package/dist/types/types.d.ts +28 -4
  156. package/dist/types/types.d.ts.map +1 -1
  157. package/dist/types/utils/assertions.d.ts +4 -2
  158. package/dist/types/utils/assertions.d.ts.map +1 -1
  159. package/dist/types/utils/capabilities.d.ts +22 -6
  160. package/dist/types/utils/capabilities.d.ts.map +1 -1
  161. package/dist/types/utils/format.d.ts +2 -2
  162. package/dist/types/utils/format.d.ts.map +1 -1
  163. package/dist/types/utils/schema.d.ts +14 -14
  164. package/dist/types/utils/schema.d.ts.map +1 -1
  165. package/dist/types/version.d.ts +1 -1
  166. package/dist/types/version.d.ts.map +1 -1
  167. package/package.json +26 -9
  168. package/src/actions/prepareCalls.ts +21 -3
  169. package/src/actions/requestAccount.ts +7 -5
  170. package/src/actions/sendCalls.ts +5 -2
  171. package/src/actions/sendPreparedCalls.ts +4 -1
  172. package/src/actions/signPreparedCalls.ts +15 -2
  173. package/src/actions/signSignatureRequest.ts +8 -8
  174. package/src/actions/signTypedData.ts +15 -7
  175. package/src/actions/solana/getCallsStatus.ts +79 -0
  176. package/src/actions/solana/prepareCalls.ts +120 -0
  177. package/src/actions/solana/sendCalls.ts +66 -0
  178. package/src/actions/solana/sendPreparedCalls.ts +65 -0
  179. package/src/actions/solana/signPreparedCalls.ts +50 -0
  180. package/src/actions/solana/signSignatureRequest.ts +63 -0
  181. package/src/actions/solana/waitForCallsStatus.ts +84 -0
  182. package/src/actions/undelegateAccount.ts +68 -0
  183. package/src/adapters/SolanaSignerError.ts +5 -0
  184. package/src/adapters/fromKeypair.ts +58 -0
  185. package/src/adapters/fromKitSigner.ts +82 -0
  186. package/src/adapters/fromWalletAdapter.ts +58 -0
  187. package/src/adapters/fromWalletStandard.ts +100 -0
  188. package/src/adapters/resolveSignerSlot.ts +46 -0
  189. package/src/client.ts +131 -18
  190. package/src/decorators/smartWalletActions.ts +11 -2
  191. package/src/decorators/solanaSmartWalletActions.ts +62 -0
  192. package/src/experimental/actions/requestQuoteV0.ts +40 -15
  193. package/src/experimental/swapActionsDecorator.ts +3 -0
  194. package/src/exports/index.ts +10 -4
  195. package/src/exports/solana.ts +36 -0
  196. package/src/types.ts +38 -7
  197. package/src/utils/assertions.ts +17 -2
  198. package/src/utils/capabilities.ts +40 -8
  199. package/src/utils/format.ts +8 -3
  200. package/src/utils/schema.ts +58 -69
  201. package/src/version.ts +1 -1
package/src/types.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { WalletServerViemRpcSchema } from "@alchemy/wallet-api-types/rpc";
2
+ import type { SolanaChainId } from "@alchemy/wallet-api-types";
2
3
  import type {
3
4
  Account,
4
5
  Address,
@@ -12,31 +13,61 @@ import type {
12
13
  } from "viem";
13
14
  import type { InternalState } from "./internal";
14
15
  import type { SmartWalletActions } from "./decorators/smartWalletActions";
16
+ import type { SolanaSmartWalletActions } from "./decorators/solanaSmartWalletActions";
15
17
 
16
18
  export type BaseWalletClient<
17
19
  TExtend extends { [key: string]: unknown } | undefined =
18
20
  | { [key: string]: unknown }
19
21
  | undefined,
22
+ TAccount extends Account | undefined = JsonRpcAccount<Address>,
20
23
  > = Client<
21
24
  Transport<"alchemyHttp">,
22
25
  Chain,
23
- JsonRpcAccount<Address>,
26
+ TAccount,
24
27
  WalletServerViemRpcSchema,
25
28
  TExtend
26
29
  >;
27
30
 
28
- export type InnerWalletApiClient = BaseWalletClient<{
29
- internal: InternalState | undefined; // undefined if you want to skip using an internal cache
30
- owner: SmartWalletSigner;
31
- policyIds?: string[];
32
- }>;
33
-
34
31
  export type SignerClient = WalletClient<Transport, Chain | undefined, Account>;
35
32
 
36
33
  export type SmartWalletSigner = LocalAccount | SignerClient;
37
34
 
38
35
  export type SmartWalletClient = BaseWalletClient<SmartWalletActions>;
39
36
 
37
+ export type SolanaSmartWalletClient = BaseWalletClient<
38
+ SolanaSmartWalletActions & { solanaAccount: string },
39
+ undefined
40
+ >;
41
+
42
+ /** Solana signer interface. Takes serialized tx bytes, returns signed serialized tx bytes. */
43
+ export interface SolanaSigner {
44
+ address: string;
45
+ signTransaction(input: {
46
+ transaction: Uint8Array;
47
+ [key: string]: unknown;
48
+ }): Promise<{ signedTransaction: Uint8Array }>;
49
+ }
50
+
51
+ export interface SolanaChainDef extends Chain {
52
+ solanaChainId: SolanaChainId;
53
+ }
54
+
55
+ export type InnerWalletApiClient = BaseWalletClient<{
56
+ internal: InternalState | undefined;
57
+ owner: SmartWalletSigner;
58
+ policyIds?: string[];
59
+ }>;
60
+
61
+ export type InnerSolanaWalletApiClient = BaseWalletClient<
62
+ {
63
+ internal: InternalState | undefined;
64
+ owner: SolanaSigner;
65
+ solanaAccount: string;
66
+ policyIds?: string[];
67
+ },
68
+ undefined
69
+ >;
70
+
40
71
  export type OptionalChainId<T> = T extends { chainId: number }
41
72
  ? Omit<T, "chainId"> & { chainId?: number | undefined }
42
73
  : T;
@@ -1,5 +1,10 @@
1
- import type { Client, LocalAccount } from "viem";
2
- import type { InnerWalletApiClient, SignerClient } from "../types.js";
1
+ import type { Chain, Client, LocalAccount } from "viem";
2
+ import type {
3
+ InnerWalletApiClient,
4
+ InnerSolanaWalletApiClient,
5
+ SignerClient,
6
+ SolanaChainDef,
7
+ } from "../types.js";
3
8
  import { BaseError } from "@alchemy/common";
4
9
 
5
10
  /**
@@ -14,6 +19,12 @@ export function isSmartWalletClient(
14
19
  return client.name === "alchemySmartWalletClient" && "owner" in client;
15
20
  }
16
21
 
22
+ export function isSolanaClient(
23
+ client: Client,
24
+ ): client is InnerSolanaWalletApiClient {
25
+ return client.name === "alchemySolanaSmartWalletClient" && "owner" in client;
26
+ }
27
+
17
28
  /**
18
29
  * Assertion function that throws an error if the client is not an Alchemy Smart Wallet Client.
19
30
  * After this function returns successfully, TypeScript will narrow the client type.
@@ -31,6 +42,10 @@ export function assertSmartWalletClient(
31
42
  }
32
43
  }
33
44
 
45
+ export function isSolanaChain(chain: Chain): chain is SolanaChainDef {
46
+ return "solanaChainId" in chain;
47
+ }
48
+
34
49
  export function isLocalAccount(
35
50
  signer: LocalAccount | SignerClient,
36
51
  ): signer is LocalAccount {
@@ -2,17 +2,18 @@ import {
2
2
  PrepareCallsCapabilities as PrepareCallsCapabilitiesSchema,
3
3
  SendPreparedCallsCapabilities as SendPreparedCallsCapabilitiesSchema,
4
4
  } from "@alchemy/wallet-api-types/capabilities";
5
- import type { StaticDecode } from "typebox";
6
- import type { InnerWalletApiClient } from "../types.js";
5
+ import type { z } from "zod";
6
+ import type {
7
+ InnerWalletApiClient,
8
+ InnerSolanaWalletApiClient,
9
+ } from "../types.js";
7
10
 
8
11
  /**
9
12
  * Decoded capabilities matching the schema shape (uses `paymasterService` key).
10
13
  * `ResolveCapabilities` renames this to `paymaster` for client-facing types.
11
14
  */
12
- type DecodedPrepareCallsCaps = StaticDecode<
13
- typeof PrepareCallsCapabilitiesSchema
14
- >;
15
- type DecodedSendPreparedCallsCaps = StaticDecode<
15
+ type DecodedPrepareCallsCaps = z.output<typeof PrepareCallsCapabilitiesSchema>;
16
+ type DecodedSendPreparedCallsCaps = z.output<
16
17
  typeof SendPreparedCallsCapabilitiesSchema
17
18
  >;
18
19
 
@@ -60,7 +61,7 @@ function hasNoPaymasterServiceField(
60
61
 
61
62
  /**
62
63
  * Converts capabilities (with `paymaster`) to RPC capabilities (with `paymasterService`)
63
- * for use with Value.Encode before sending to the RPC.
64
+ * for use with `encode` before sending to the RPC.
64
65
  *
65
66
  * @param {PrepareCallsCapabilities | SendPreparedCallsCapabilities | undefined} capabilities - Capabilities object containing a `paymaster` field
66
67
  * @returns {DecodedPrepareCallsCaps | DecodedSendPreparedCallsCaps | undefined} RPC capabilities with `paymasterService`, or undefined if input is undefined
@@ -82,7 +83,7 @@ export function toRpcCapabilities(
82
83
  }
83
84
 
84
85
  /**
85
- * Converts RPC capabilities (with `paymasterService`) from Value.Decode
86
+ * Converts RPC capabilities (with `paymasterService`) from `decode`
86
87
  * to capabilities (with `paymaster`).
87
88
  *
88
89
  * @param {DecodedPrepareCallsCaps | DecodedSendPreparedCallsCaps | undefined} capabilities - RPC capabilities object containing a `paymasterService` field
@@ -135,6 +136,37 @@ export const mergeClientCapabilities = <
135
136
  } as T;
136
137
  };
137
138
 
139
+ export type SolanaPaymasterCapability = {
140
+ policyId: string;
141
+ webhookData?: string;
142
+ };
143
+
144
+ export type SolanaPrepareCallsCapabilities = {
145
+ paymaster?: SolanaPaymasterCapability;
146
+ };
147
+
148
+ /**
149
+ * Merges Solana client-level capabilities (policyId from factory) with
150
+ * request-level capabilities. Request-level takes priority if provided.
151
+ *
152
+ * @param {InnerSolanaWalletApiClient} client - The Solana wallet API client
153
+ * @param {SolanaPrepareCallsCapabilities | undefined} capabilities - Request capabilities to merge with
154
+ * @returns {SolanaPrepareCallsCapabilities | undefined} The merged capabilities
155
+ */
156
+ export const mergeSolanaClientCapabilities = (
157
+ client: InnerSolanaWalletApiClient,
158
+ capabilities: SolanaPrepareCallsCapabilities | undefined,
159
+ ): SolanaPrepareCallsCapabilities | undefined => {
160
+ if (!client.policyIds?.length || capabilities?.paymaster) {
161
+ return capabilities;
162
+ }
163
+
164
+ return {
165
+ ...capabilities,
166
+ paymaster: { policyId: client.policyIds[0] },
167
+ };
168
+ };
169
+
138
170
  /**
139
171
  * Extracts capabilities from prepareCalls that are usable for sendPreparedCalls.
140
172
  * Only permissions and paymaster (policyId/policyIds & webhookData) are supported.
@@ -4,8 +4,10 @@ import {
4
4
  type Hex,
5
5
  type SignableMessage,
6
6
  bytesToHex,
7
+ type TypedData,
7
8
  type TypedDataDefinition,
8
9
  getTypesForEIP712Domain,
10
+ validateTypedData,
9
11
  } from "viem";
10
12
  import type { TypedDataDefinition as WalletServerTypedDataDefinition } from "@alchemy/wallet-api-types";
11
13
 
@@ -29,13 +31,16 @@ export const signableMessageToJsonSafe = (
29
31
  };
30
32
 
31
33
  // Purposefully not using `formatTypedData` from the wallet server types pkg
32
- // here, since that would require typebox at runtime (which breaks RN).
34
+ // here, since that would require zod at runtime (which breaks RN).
33
35
  export const typedDataToJsonSafe = ({
34
36
  domain,
35
37
  primaryType,
36
38
  message,
37
39
  types,
38
- }: TypedDataDefinition): WalletServerTypedDataDefinition => {
40
+ }: TypedDataDefinition<
41
+ TypedData | Record<string, unknown>
42
+ >): WalletServerTypedDataDefinition => {
43
+ validateTypedData({ domain, primaryType, message, types });
39
44
  return {
40
45
  domain: {
41
46
  ...domain,
@@ -48,7 +53,7 @@ export const typedDataToJsonSafe = ({
48
53
  ...Object.fromEntries(
49
54
  Object.entries(types).map(([key, value]) => [
50
55
  key,
51
- value ? [...value] : [],
56
+ Array.isArray(value) ? [...value] : [],
52
57
  ]),
53
58
  ),
54
59
  EIP712Domain: [...getTypesForEIP712Domain({ domain })],
@@ -1,109 +1,98 @@
1
- import type {
2
- TObject,
3
- TSchema,
4
- TTuple,
5
- StaticDecode,
6
- StaticEncode,
7
- } from "typebox";
8
- import { Value, EncodeError, DecodeError, Pointer } from "typebox/value";
1
+ import { z } from "zod";
9
2
  import { BaseError } from "@alchemy/common";
10
3
 
11
4
  /** Constraint for RPC method schemas from `@alchemy/wallet-api-types/rpc`. */
12
- type RpcMethodSchema = TObject<{
13
- Request: TObject<{
14
- method: TSchema;
15
- params: TTuple<[TSchema, ...TSchema[]]>;
5
+ type RpcMethodSchema = z.ZodObject<{
6
+ Request: z.ZodObject<{
7
+ method: z.ZodType;
8
+ params: z.ZodTuple<[z.ZodType, ...z.ZodType[]]>;
16
9
  }>;
17
- ReturnType: TSchema;
10
+ ReturnType: z.ZodType;
18
11
  }>;
19
12
 
20
- export function methodSchema<TReq extends TSchema, TRes extends TSchema>(
21
- schema: TObject<{
22
- Request: TObject<{ method: TSchema; params: TTuple<[TReq, ...TSchema[]]> }>;
13
+ export function methodSchema<TReq extends z.ZodType, TRes extends z.ZodType>(
14
+ schema: z.ZodObject<{
15
+ Request: z.ZodObject<{
16
+ method: z.ZodType;
17
+ params: z.ZodTuple<[TReq, ...z.ZodType[]]>;
18
+ }>;
23
19
  ReturnType: TRes;
24
20
  }>,
25
21
  ): { request: TReq; response: TRes } {
26
22
  return {
27
- request: schema.properties.Request.properties.params.items[0],
28
- response: schema.properties.ReturnType,
23
+ request: schema.shape.Request.shape.params.def.items[0],
24
+ response: schema.shape.ReturnType,
29
25
  };
30
26
  }
31
27
 
32
28
  /** Extracts the decoded params type from a method schema. */
33
- export type MethodParams<T extends RpcMethodSchema> = StaticDecode<
34
- T["properties"]["Request"]["properties"]["params"]["items"][0]
29
+ export type MethodParams<T extends RpcMethodSchema> = z.output<
30
+ T["shape"]["Request"]["shape"]["params"]["def"]["items"][0]
35
31
  >;
36
32
 
37
33
  /** Extracts the decoded response type from a method schema. */
38
- export type MethodResponse<T extends RpcMethodSchema> = StaticDecode<
39
- T["properties"]["ReturnType"]
34
+ export type MethodResponse<T extends RpcMethodSchema> = z.output<
35
+ T["shape"]["ReturnType"]
40
36
  >;
41
37
 
42
- /**
43
- * Formats an {@link EncodeError} or {@link DecodeError} into a human-readable
44
- * string describing what went wrong, including the JSON path and the schema's
45
- * custom error message (if any).
46
- *
47
- * @param {TSchema} schema - The TypeBox schema that validation was run against.
48
- * @param {EncodeError | DecodeError} error - The error thrown by {@link Value.Encode} or {@link Value.Decode}.
49
- * @returns {string} A formatted error string prefixed with `"Invalid params"`.
50
- */
51
- function formatCodecError(
52
- schema: TSchema,
53
- error: EncodeError | DecodeError,
54
- ): string {
55
- // Use only the first error — it's the most specific. Subsequent errors are
56
- // typically cascade noise from union/anyOf branches.
57
- const causeError = error.cause.errors[0];
58
- // errors is typed as an open array — guard against the (practically
59
- // impossible) empty case.
60
- if (!causeError) return "Invalid params";
38
+ function isUnionIssue(
39
+ issue: z.core.$ZodIssue,
40
+ ): issue is z.core.$ZodIssueInvalidUnion {
41
+ return issue.code === "invalid_union";
42
+ }
61
43
 
62
- const path = causeError.instancePath || "(root)";
44
+ function formatCodecError(error: z.ZodError): string {
45
+ let issue: z.core.$ZodIssue | undefined = error.issues[0];
46
+ if (!issue) return "Invalid params";
63
47
 
64
- // Prefer the schema's custom errorMessage annotation over the generic locale message.
65
- let message = causeError.message;
66
- const schemaPointer = causeError.schemaPath.replace(/^#/, "");
67
- if (schemaPointer) {
68
- const schemaNode = Pointer.Get(schema, schemaPointer);
69
- if (
70
- schemaNode &&
71
- typeof schemaNode === "object" &&
72
- "errorMessage" in schemaNode &&
73
- typeof (schemaNode as Record<string, unknown>).errorMessage === "string"
74
- ) {
75
- message = (schemaNode as Record<string, unknown>).errorMessage as string;
48
+ // For union errors, drill into the branch with the fewest issues (closest match).
49
+ // Accumulate paths as we drill — each union level carries a partial path.
50
+ const pathPrefix: PropertyKey[] = [];
51
+ while (isUnionIssue(issue)) {
52
+ pathPrefix.push(...issue.path);
53
+ let best: z.core.$ZodIssue[] | undefined;
54
+ for (const branch of issue.errors) {
55
+ if (!best || branch.length < best.length) best = branch;
76
56
  }
57
+ const next = best?.[0];
58
+ if (!next) break;
59
+ issue = next;
77
60
  }
78
61
 
79
- return `Invalid params: ${path}: ${message}`;
62
+ const fullPath = [...pathPrefix, ...issue.path];
63
+ const path =
64
+ fullPath.length > 0 ? "/" + fullPath.map(String).join("/") + ": " : "";
65
+
66
+ return `Invalid params: ${path}${issue.message}`;
80
67
  }
81
68
 
82
- // Type-safe wrapper around `Value.Encode` with human-readable errors.
83
- export function encode<const T extends TSchema>(
69
+ export function encode<const T extends z.ZodType>(
84
70
  schema: T,
85
- value: StaticDecode<T>,
86
- ): StaticEncode<T> {
71
+ value: z.output<T>,
72
+ ): z.input<T> {
87
73
  try {
88
- return Value.Encode(schema, value);
74
+ return schema.encode(value);
89
75
  } catch (error) {
90
- if (error instanceof EncodeError) {
91
- throw new BaseError(formatCodecError(schema, error), { cause: error });
76
+ if (error instanceof z.ZodError) {
77
+ throw new BaseError(formatCodecError(error), {
78
+ cause: error as Error,
79
+ });
92
80
  }
93
81
  throw error;
94
82
  }
95
83
  }
96
84
 
97
- // Type-safe wrapper around `Value.Decode` with human-readable errors.
98
- export function decode<const T extends TSchema>(
85
+ export function decode<const T extends z.ZodType>(
99
86
  schema: T,
100
- value: StaticEncode<T>,
101
- ): StaticDecode<T> {
87
+ value: z.input<T>,
88
+ ): z.output<T> {
102
89
  try {
103
- return Value.Decode(schema, value);
90
+ return schema.decode(value);
104
91
  } catch (error) {
105
- if (error instanceof DecodeError) {
106
- throw new BaseError(formatCodecError(schema, error), { cause: error });
92
+ if (error instanceof z.ZodError) {
93
+ throw new BaseError(formatCodecError(error), {
94
+ cause: error as Error,
95
+ });
107
96
  }
108
97
  throw error;
109
98
  }
package/src/version.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  // This file is autogenerated by inject-version.ts. Any changes will be
2
2
  // overwritten on commit!
3
- export const VERSION = "5.0.0-beta.9";
3
+ export const VERSION = "5.0.1";