@pepu-chain/sdk 0.0.0-stage → 0.2.0

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 (232) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +565 -2
  3. package/dist/aa/kernel.cjs +40 -0
  4. package/dist/aa/kernel.cjs.map +1 -0
  5. package/dist/aa/kernel.d.cts +88 -0
  6. package/dist/aa/kernel.d.ts +88 -0
  7. package/dist/aa/kernel.js +11 -0
  8. package/dist/aa/kernel.js.map +1 -0
  9. package/dist/aa/react-direct.cjs +110 -0
  10. package/dist/aa/react-direct.cjs.map +1 -0
  11. package/dist/aa/react-direct.d.cts +42 -0
  12. package/dist/aa/react-direct.d.ts +42 -0
  13. package/dist/aa/react-direct.js +107 -0
  14. package/dist/aa/react-direct.js.map +1 -0
  15. package/dist/aa/react.cjs +151 -0
  16. package/dist/aa/react.cjs.map +1 -0
  17. package/dist/aa/react.d.cts +62 -0
  18. package/dist/aa/react.d.ts +62 -0
  19. package/dist/aa/react.js +147 -0
  20. package/dist/aa/react.js.map +1 -0
  21. package/dist/aa.cjs +84 -0
  22. package/dist/aa.cjs.map +1 -0
  23. package/dist/aa.d.cts +85 -0
  24. package/dist/aa.d.ts +85 -0
  25. package/dist/aa.js +11 -0
  26. package/dist/aa.js.map +1 -0
  27. package/dist/api-Dz4sCHH_.d.cts +654 -0
  28. package/dist/api-Dz4sCHH_.d.ts +654 -0
  29. package/dist/calls-BRPjKgjl.d.cts +70 -0
  30. package/dist/calls-z_EQOtFb.d.ts +70 -0
  31. package/dist/chains-DK13zGIp.d.cts +235 -0
  32. package/dist/chains-DK13zGIp.d.ts +235 -0
  33. package/dist/chunk-3XUGQODR.js +194 -0
  34. package/dist/chunk-3XUGQODR.js.map +1 -0
  35. package/dist/chunk-45KSZH26.cjs +145 -0
  36. package/dist/chunk-45KSZH26.cjs.map +1 -0
  37. package/dist/chunk-4GINFJO6.cjs +44 -0
  38. package/dist/chunk-4GINFJO6.cjs.map +1 -0
  39. package/dist/chunk-62M2LKQW.js +136 -0
  40. package/dist/chunk-62M2LKQW.js.map +1 -0
  41. package/dist/chunk-6DSZ4Z2N.js +498 -0
  42. package/dist/chunk-6DSZ4Z2N.js.map +1 -0
  43. package/dist/chunk-7MNJF2OB.cjs +72 -0
  44. package/dist/chunk-7MNJF2OB.cjs.map +1 -0
  45. package/dist/chunk-A5LP2UCS.cjs +2729 -0
  46. package/dist/chunk-A5LP2UCS.cjs.map +1 -0
  47. package/dist/chunk-AJS4UFQX.cjs +121 -0
  48. package/dist/chunk-AJS4UFQX.cjs.map +1 -0
  49. package/dist/chunk-C2XW44FI.cjs +200 -0
  50. package/dist/chunk-C2XW44FI.cjs.map +1 -0
  51. package/dist/chunk-C7IC36XS.cjs +13 -0
  52. package/dist/chunk-C7IC36XS.cjs.map +1 -0
  53. package/dist/chunk-D52PADVY.js +84 -0
  54. package/dist/chunk-D52PADVY.js.map +1 -0
  55. package/dist/chunk-DH6BFNVJ.cjs +272 -0
  56. package/dist/chunk-DH6BFNVJ.cjs.map +1 -0
  57. package/dist/chunk-DPCZJLB3.cjs +87 -0
  58. package/dist/chunk-DPCZJLB3.cjs.map +1 -0
  59. package/dist/chunk-EHBPIYY4.js +262 -0
  60. package/dist/chunk-EHBPIYY4.js.map +1 -0
  61. package/dist/chunk-ESMNAXUI.js +86 -0
  62. package/dist/chunk-ESMNAXUI.js.map +1 -0
  63. package/dist/chunk-ET3P6TX6.cjs +49 -0
  64. package/dist/chunk-ET3P6TX6.cjs.map +1 -0
  65. package/dist/chunk-FCXSP2YF.js +219 -0
  66. package/dist/chunk-FCXSP2YF.js.map +1 -0
  67. package/dist/chunk-IB2FSPMJ.js +66 -0
  68. package/dist/chunk-IB2FSPMJ.js.map +1 -0
  69. package/dist/chunk-IG7RSL2Y.cjs +178 -0
  70. package/dist/chunk-IG7RSL2Y.cjs.map +1 -0
  71. package/dist/chunk-IY3ALPUJ.js +2716 -0
  72. package/dist/chunk-IY3ALPUJ.js.map +1 -0
  73. package/dist/chunk-J3O2ZGG3.cjs +93 -0
  74. package/dist/chunk-J3O2ZGG3.cjs.map +1 -0
  75. package/dist/chunk-J6UXXHBE.js +37 -0
  76. package/dist/chunk-J6UXXHBE.js.map +1 -0
  77. package/dist/chunk-JLZ4LZ4Z.js +22 -0
  78. package/dist/chunk-JLZ4LZ4Z.js.map +1 -0
  79. package/dist/chunk-KIIFL4VM.js +274 -0
  80. package/dist/chunk-KIIFL4VM.js.map +1 -0
  81. package/dist/chunk-KVG3AYYR.js +99 -0
  82. package/dist/chunk-KVG3AYYR.js.map +1 -0
  83. package/dist/chunk-MBA4CLA5.js +45 -0
  84. package/dist/chunk-MBA4CLA5.js.map +1 -0
  85. package/dist/chunk-NE3QKDOB.cjs +24 -0
  86. package/dist/chunk-NE3QKDOB.cjs.map +1 -0
  87. package/dist/chunk-NVOPDXTA.cjs +95 -0
  88. package/dist/chunk-NVOPDXTA.cjs.map +1 -0
  89. package/dist/chunk-OH3QMAIB.js +11 -0
  90. package/dist/chunk-OH3QMAIB.js.map +1 -0
  91. package/dist/chunk-PHM3ZORG.cjs +110 -0
  92. package/dist/chunk-PHM3ZORG.cjs.map +1 -0
  93. package/dist/chunk-R5PXQNO3.cjs +209 -0
  94. package/dist/chunk-R5PXQNO3.cjs.map +1 -0
  95. package/dist/chunk-SLW7FRTL.cjs +285 -0
  96. package/dist/chunk-SLW7FRTL.cjs.map +1 -0
  97. package/dist/chunk-SVWRRALU.cjs +17 -0
  98. package/dist/chunk-SVWRRALU.cjs.map +1 -0
  99. package/dist/chunk-T43PQXJD.js +202 -0
  100. package/dist/chunk-T43PQXJD.js.map +1 -0
  101. package/dist/chunk-TIEAZYHF.cjs +225 -0
  102. package/dist/chunk-TIEAZYHF.cjs.map +1 -0
  103. package/dist/chunk-VBH3JLQ5.js +116 -0
  104. package/dist/chunk-VBH3JLQ5.js.map +1 -0
  105. package/dist/chunk-VF3D6KLQ.cjs +94 -0
  106. package/dist/chunk-VF3D6KLQ.cjs.map +1 -0
  107. package/dist/chunk-VTQIHMF3.js +82 -0
  108. package/dist/chunk-VTQIHMF3.js.map +1 -0
  109. package/dist/chunk-W3JN3YIW.js +15 -0
  110. package/dist/chunk-W3JN3YIW.js.map +1 -0
  111. package/dist/chunk-WANILJZQ.cjs +87 -0
  112. package/dist/chunk-WANILJZQ.cjs.map +1 -0
  113. package/dist/chunk-XC4IBCI2.js +86 -0
  114. package/dist/chunk-XC4IBCI2.js.map +1 -0
  115. package/dist/chunk-YKEWWQEJ.js +165 -0
  116. package/dist/chunk-YKEWWQEJ.js.map +1 -0
  117. package/dist/chunk-YQL7NISX.cjs +515 -0
  118. package/dist/chunk-YQL7NISX.cjs.map +1 -0
  119. package/dist/chunk-ZB6SVBK4.js +89 -0
  120. package/dist/chunk-ZB6SVBK4.js.map +1 -0
  121. package/dist/combo/react.cjs +235 -0
  122. package/dist/combo/react.cjs.map +1 -0
  123. package/dist/combo/react.d.cts +148 -0
  124. package/dist/combo/react.d.ts +148 -0
  125. package/dist/combo/react.js +230 -0
  126. package/dist/combo/react.js.map +1 -0
  127. package/dist/combo.cjs +262 -0
  128. package/dist/combo.cjs.map +1 -0
  129. package/dist/combo.d.cts +139 -0
  130. package/dist/combo.d.ts +139 -0
  131. package/dist/combo.js +249 -0
  132. package/dist/combo.js.map +1 -0
  133. package/dist/config-CHjz7ZjZ.d.cts +57 -0
  134. package/dist/config-COjhIZTh.d.ts +57 -0
  135. package/dist/doctor.cjs +354 -0
  136. package/dist/doctor.cjs.map +1 -0
  137. package/dist/doctor.d.cts +177 -0
  138. package/dist/doctor.d.ts +177 -0
  139. package/dist/doctor.js +345 -0
  140. package/dist/doctor.js.map +1 -0
  141. package/dist/erc7677-DOW58QBE.d.cts +111 -0
  142. package/dist/erc7677-DOW58QBE.d.ts +111 -0
  143. package/dist/errors-CgX1vNj7.d.cts +100 -0
  144. package/dist/errors-CgX1vNj7.d.ts +100 -0
  145. package/dist/index.cjs +802 -0
  146. package/dist/index.cjs.map +1 -0
  147. package/dist/index.d.cts +2398 -0
  148. package/dist/index.d.ts +2398 -0
  149. package/dist/index.js +559 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/paymaster/server.cjs +38 -0
  152. package/dist/paymaster/server.cjs.map +1 -0
  153. package/dist/paymaster/server.d.cts +57 -0
  154. package/dist/paymaster/server.d.ts +57 -0
  155. package/dist/paymaster/server.js +36 -0
  156. package/dist/paymaster/server.js.map +1 -0
  157. package/dist/paymaster.cjs +356 -0
  158. package/dist/paymaster.cjs.map +1 -0
  159. package/dist/paymaster.d.cts +1851 -0
  160. package/dist/paymaster.d.ts +1851 -0
  161. package/dist/paymaster.js +289 -0
  162. package/dist/paymaster.js.map +1 -0
  163. package/dist/privy/react.cjs +48 -0
  164. package/dist/privy/react.cjs.map +1 -0
  165. package/dist/privy/react.d.cts +194 -0
  166. package/dist/privy/react.d.ts +194 -0
  167. package/dist/privy/react.js +7 -0
  168. package/dist/privy/react.js.map +1 -0
  169. package/dist/privy/server.cjs +43 -0
  170. package/dist/privy/server.cjs.map +1 -0
  171. package/dist/privy/server.d.cts +192 -0
  172. package/dist/privy/server.d.ts +192 -0
  173. package/dist/privy/server.js +6 -0
  174. package/dist/privy/server.js.map +1 -0
  175. package/dist/privy/wagmi.d.ts +90 -0
  176. package/dist/privy/wagmi.js +55 -0
  177. package/dist/privy/wagmi.js.map +1 -0
  178. package/dist/privy.cjs +34 -0
  179. package/dist/privy.cjs.map +1 -0
  180. package/dist/privy.d.cts +4 -0
  181. package/dist/privy.d.ts +4 -0
  182. package/dist/privy.js +5 -0
  183. package/dist/privy.js.map +1 -0
  184. package/dist/react.cjs +72 -0
  185. package/dist/react.cjs.map +1 -0
  186. package/dist/react.d.cts +66 -0
  187. package/dist/react.d.ts +66 -0
  188. package/dist/react.js +68 -0
  189. package/dist/react.js.map +1 -0
  190. package/dist/requirements-C-QiJkL9.d.cts +134 -0
  191. package/dist/requirements-C-QiJkL9.d.ts +134 -0
  192. package/dist/scope-DBRkN7bR.d.cts +94 -0
  193. package/dist/scope-DBRkN7bR.d.ts +94 -0
  194. package/dist/server.cjs +59 -0
  195. package/dist/server.cjs.map +1 -0
  196. package/dist/server.d.cts +208 -0
  197. package/dist/server.d.ts +208 -0
  198. package/dist/server.js +8 -0
  199. package/dist/server.js.map +1 -0
  200. package/dist/session/kernel.cjs +82 -0
  201. package/dist/session/kernel.cjs.map +1 -0
  202. package/dist/session/kernel.d.cts +131 -0
  203. package/dist/session/kernel.d.ts +131 -0
  204. package/dist/session/kernel.js +13 -0
  205. package/dist/session/kernel.js.map +1 -0
  206. package/dist/session/react.cjs +37 -0
  207. package/dist/session/react.cjs.map +1 -0
  208. package/dist/session/react.d.cts +119 -0
  209. package/dist/session/react.d.ts +119 -0
  210. package/dist/session/react.js +8 -0
  211. package/dist/session/react.js.map +1 -0
  212. package/dist/session/server.cjs +267 -0
  213. package/dist/session/server.cjs.map +1 -0
  214. package/dist/session/server.d.cts +151 -0
  215. package/dist/session/server.d.ts +151 -0
  216. package/dist/session/server.js +252 -0
  217. package/dist/session/server.js.map +1 -0
  218. package/dist/session.cjs +74 -0
  219. package/dist/session.cjs.map +1 -0
  220. package/dist/session.d.cts +3 -0
  221. package/dist/session.d.ts +3 -0
  222. package/dist/session.js +5 -0
  223. package/dist/session.js.map +1 -0
  224. package/dist/status-CmOsyPmO.d.cts +295 -0
  225. package/dist/status-DwkkOrGQ.d.ts +295 -0
  226. package/dist/store-CjmLgp9g.d.cts +64 -0
  227. package/dist/store-CjmLgp9g.d.ts +64 -0
  228. package/dist/types-BEEM7WdG.d.cts +25 -0
  229. package/dist/types-BEEM7WdG.d.ts +25 -0
  230. package/dist/types-BilBTDqK.d.cts +27 -0
  231. package/dist/types-BilBTDqK.d.ts +27 -0
  232. package/package.json +209 -3
@@ -0,0 +1,262 @@
1
+ import { createPepuPrivyConfig } from './chunk-JLZ4LZ4Z.js';
2
+ import { PRIVY_ENV } from './chunk-3XUGQODR.js';
3
+ import { PEPU_ERROR_CATALOG, PepuAuthError, PepuError, toPepuError } from './chunk-6DSZ4Z2N.js';
4
+ import { createElement, Fragment, useEffect, useState, useRef, useCallback } from 'react';
5
+ import { PrivyProvider, useWallets, getEmbeddedConnectedWallet, usePrivy, useUser } from '@privy-io/react-auth';
6
+
7
+ // src/privy/ensure-client.ts
8
+ var DEFAULT_ENSURE_ENDPOINT = "/api/wallet/ensure";
9
+ var DEFAULT_ENSURE_REQUEST_TIMEOUT_MS = 2e4;
10
+ var DEFAULT_ENSURE_APPEAR_TIMEOUT_MS = 8e3;
11
+ var KNOWN_CODES = new Set(PEPU_ERROR_CATALOG.map((e) => e.code));
12
+ var isRecord = (v) => typeof v === "object" && v !== null;
13
+ function errorFromEnsureResponse(status, body) {
14
+ const err = isRecord(body) ? body["error"] : void 0;
15
+ if (isRecord(err)) {
16
+ const code = typeof err["code"] === "string" && KNOWN_CODES.has(err["code"]) ? err["code"] : "UNKNOWN";
17
+ const message2 = typeof err["message"] === "string" ? err["message"] : `Wallet setup failed (HTTP ${status}).`;
18
+ const hint = typeof err["hint"] === "string" ? err["hint"] : void 0;
19
+ const opts = { status, ...hint !== void 0 ? { hint } : {} };
20
+ return status === 401 ? new PepuAuthError(code, message2, opts) : new PepuError(code, message2, opts);
21
+ }
22
+ const message = typeof err === "string" ? err : `Wallet setup failed (HTTP ${status}).`;
23
+ if (status === 401) return new PepuAuthError("AUTH_INVALID_TOKEN", message, { status });
24
+ return new PepuError("WALLET_NOT_PROVISIONED", message, { status });
25
+ }
26
+ async function requestEnsureWallet(o) {
27
+ const token = await o.getAccessToken();
28
+ if (!token) {
29
+ throw new PepuAuthError(
30
+ "AUTH_INVALID_TOKEN",
31
+ "Could not get a Privy access token for this session. Try signing in again."
32
+ );
33
+ }
34
+ const controller = new AbortController();
35
+ const timeoutMs = o.timeoutMs ?? DEFAULT_ENSURE_REQUEST_TIMEOUT_MS;
36
+ let timedOut = false;
37
+ const timer = setTimeout(() => {
38
+ timedOut = true;
39
+ controller.abort();
40
+ }, timeoutMs);
41
+ const onAbort = () => controller.abort();
42
+ o.signal?.addEventListener("abort", onAbort);
43
+ try {
44
+ const doFetch = o.fetch ?? globalThis.fetch;
45
+ let response;
46
+ try {
47
+ response = await doFetch(o.endpoint ?? DEFAULT_ENSURE_ENDPOINT, {
48
+ method: "POST",
49
+ headers: { Authorization: `Bearer ${token}` },
50
+ signal: controller.signal
51
+ });
52
+ } catch (e) {
53
+ if (timedOut) {
54
+ throw new PepuError("WALLET_NOT_PROVISIONED", "Wallet setup timed out. Please try again.", {
55
+ retryable: true,
56
+ cause: e
57
+ });
58
+ }
59
+ throw toPepuError(e, { op: "ensure wallet" });
60
+ }
61
+ const body = await response.json().catch(() => null);
62
+ if (!response.ok) throw errorFromEnsureResponse(response.status, body);
63
+ const address = isRecord(body) ? body["address"] : void 0;
64
+ if (typeof address !== "string" || !/^0x[0-9a-fA-F]{40}$/.test(address)) {
65
+ throw new PepuError("WALLET_NOT_PROVISIONED", "The ensure-wallet route did not return a wallet address.", {
66
+ status: 502
67
+ });
68
+ }
69
+ return { address, created: isRecord(body) && body["created"] === true };
70
+ } finally {
71
+ clearTimeout(timer);
72
+ o.signal?.removeEventListener("abort", onAbort);
73
+ }
74
+ }
75
+
76
+ // src/privy/react.ts
77
+ function composeProviders(layers, leaves = []) {
78
+ return function ComposedProviders({ children }) {
79
+ let node = createElement(
80
+ Fragment,
81
+ null,
82
+ ...leaves.map((Leaf, i) => createElement(Leaf, { key: `leaf-${i}` })),
83
+ children
84
+ );
85
+ for (let i = layers.length - 1; i >= 0; i--) {
86
+ const layer = layers[i];
87
+ if (!layer) continue;
88
+ node = createElement(layer[0], layer[1], node);
89
+ }
90
+ return node;
91
+ };
92
+ }
93
+ function PepuPrivyProvider(props) {
94
+ const { appId, config, fallback, wrapper, children } = props;
95
+ if (!appId) {
96
+ return createElement(
97
+ Fragment,
98
+ null,
99
+ fallback ?? createElement(
100
+ "div",
101
+ { role: "alert" },
102
+ `Missing ${PRIVY_ENV.appId}. Set it to your Privy app id and restart the dev server.`
103
+ )
104
+ );
105
+ }
106
+ const inner = wrapper ? createElement(wrapper, null, children) : children;
107
+ return createElement(PrivyProvider, {
108
+ appId,
109
+ config: createPepuPrivyConfig(config),
110
+ children: inner
111
+ });
112
+ }
113
+ function useEmbeddedWallet() {
114
+ const { wallets, ready } = useWallets();
115
+ const wallet = getEmbeddedConnectedWallet(wallets);
116
+ const external = wallets.filter((w) => w !== wallet);
117
+ return wallet ? { ready, wallet, address: wallet.address, external } : { ready, wallet: null, external };
118
+ }
119
+ function shouldPinEmbeddedWallet(o) {
120
+ if (!o.enabled || !o.ready || !o.embeddedAddress) return false;
121
+ return o.activeAddress?.toLowerCase() !== o.embeddedAddress.toLowerCase();
122
+ }
123
+ function usePinEmbeddedWallet(o) {
124
+ const { enabled, activeAddress, setActiveWallet } = o;
125
+ const { wallets, ready } = useWallets();
126
+ const embedded = getEmbeddedConnectedWallet(wallets);
127
+ const embeddedAddress = embedded?.address;
128
+ useEffect(() => {
129
+ if (!embedded) return;
130
+ if (!shouldPinEmbeddedWallet({ enabled, ready, embeddedAddress, activeAddress })) return;
131
+ void setActiveWallet(embedded);
132
+ }, [enabled, ready, embedded, embeddedAddress, activeAddress, setActiveWallet]);
133
+ }
134
+ function useEnsureWallet(o = {}) {
135
+ const endpoint = o.endpoint ?? DEFAULT_ENSURE_ENDPOINT;
136
+ const requestTimeoutMs = o.requestTimeoutMs ?? DEFAULT_ENSURE_REQUEST_TIMEOUT_MS;
137
+ const appearTimeoutMs = o.appearTimeoutMs ?? DEFAULT_ENSURE_APPEAR_TIMEOUT_MS;
138
+ const { ready: privyReady, authenticated, getAccessToken } = usePrivy();
139
+ const { wallets, ready: walletsReady } = useWallets();
140
+ const { refreshUser } = useUser();
141
+ const [error, setError] = useState(null);
142
+ const [requesting, setRequesting] = useState(false);
143
+ const [confirmed, setConfirmed] = useState(null);
144
+ const [stalled, setStalled] = useState(false);
145
+ const [attempt, setAttempt] = useState(0);
146
+ const settledFor = useRef(-1);
147
+ const getAccessTokenRef = useRef(getAccessToken);
148
+ const refreshUserRef = useRef(refreshUser);
149
+ getAccessTokenRef.current = getAccessToken;
150
+ refreshUserRef.current = refreshUser;
151
+ const embedded = getEmbeddedConnectedWallet(wallets);
152
+ const hasWallet = embedded !== null;
153
+ useEffect(() => {
154
+ if (!privyReady || !authenticated || !walletsReady || hasWallet) return;
155
+ if (settledFor.current === attempt) return;
156
+ let cancelled = false;
157
+ const controller = new AbortController();
158
+ setRequesting(true);
159
+ void (async () => {
160
+ try {
161
+ const { address } = await requestEnsureWallet({
162
+ getAccessToken: () => getAccessTokenRef.current(),
163
+ endpoint,
164
+ timeoutMs: requestTimeoutMs,
165
+ signal: controller.signal
166
+ });
167
+ await refreshUserRef.current();
168
+ if (cancelled) return;
169
+ settledFor.current = attempt;
170
+ setConfirmed(address);
171
+ } catch (e) {
172
+ if (cancelled) return;
173
+ settledFor.current = attempt;
174
+ setError(toPepuError(e, { op: "ensure wallet" }));
175
+ } finally {
176
+ if (!cancelled) setRequesting(false);
177
+ }
178
+ })();
179
+ return () => {
180
+ cancelled = true;
181
+ controller.abort();
182
+ };
183
+ }, [privyReady, authenticated, walletsReady, hasWallet, attempt, endpoint, requestTimeoutMs]);
184
+ useEffect(() => {
185
+ if (!confirmed || hasWallet) return;
186
+ const id = setTimeout(() => setStalled(true), appearTimeoutMs);
187
+ return () => {
188
+ clearTimeout(id);
189
+ setStalled(false);
190
+ };
191
+ }, [confirmed, hasWallet, appearTimeoutMs]);
192
+ const retry = useCallback(() => {
193
+ setError(null);
194
+ setConfirmed(null);
195
+ setStalled(false);
196
+ setRequesting(false);
197
+ setAttempt((n) => n + 1);
198
+ }, []);
199
+ if (hasWallet) return { status: "ready", address: embedded.address, retry };
200
+ if (!privyReady || !authenticated || !walletsReady) return { status: "idle", retry };
201
+ if (error) return { status: "error", error, retry };
202
+ if (stalled && confirmed) return { status: "stalled", address: confirmed, retry };
203
+ if (confirmed) return { status: "checking", address: confirmed, retry };
204
+ return { status: requesting ? "creating" : "checking", retry };
205
+ }
206
+ function WalletGate(p) {
207
+ const ensure = useEnsureWallet(p.endpoint !== void 0 ? { endpoint: p.endpoint } : {});
208
+ if (ensure.status === "ready") return createElement(Fragment, null, p.children);
209
+ if (ensure.status === "error" && ensure.error) {
210
+ const { error, retry } = ensure;
211
+ return createElement(
212
+ Fragment,
213
+ null,
214
+ p.error ? p.error(error, retry) : createElement(
215
+ "div",
216
+ { role: "alert" },
217
+ createElement("p", null, "Could not create your wallet."),
218
+ createElement("p", null, error.message),
219
+ createElement("button", { type: "button", onClick: retry }, "Try again")
220
+ )
221
+ );
222
+ }
223
+ if (ensure.status === "stalled" && ensure.address) {
224
+ const a = ensure.address;
225
+ const reload = () => globalThis.location.reload();
226
+ if (p.stalled) return createElement(Fragment, null, p.stalled(a, reload));
227
+ return createElement(
228
+ "div",
229
+ { role: "status" },
230
+ createElement("p", null, `Your wallet was created (${a.slice(0, 6)}\u2026${a.slice(-4)}), but it has not appeared in this session yet.`),
231
+ createElement("p", null, "This is a client sync delay, not a lost wallet. Reloading usually fixes it."),
232
+ createElement("button", { type: "button", onClick: reload }, "Reload")
233
+ );
234
+ }
235
+ return createElement(
236
+ Fragment,
237
+ null,
238
+ p.loading ?? createElement("div", { role: "status", "aria-label": "Loading" }, "Setting up your wallet\u2026")
239
+ );
240
+ }
241
+ function usePepuAuthFetch() {
242
+ const { getAccessToken } = usePrivy();
243
+ return useCallback(
244
+ async (input, init) => {
245
+ const token = await getAccessToken();
246
+ if (!token) {
247
+ throw new PepuAuthError(
248
+ "AUTH_INVALID_TOKEN",
249
+ "No Privy access token for this session. Sign in again."
250
+ );
251
+ }
252
+ const headers = new Headers(init?.headers);
253
+ headers.set("Authorization", `Bearer ${token}`);
254
+ return fetch(input, { ...init, headers });
255
+ },
256
+ [getAccessToken]
257
+ );
258
+ }
259
+
260
+ export { PepuPrivyProvider, WalletGate, composeProviders, requestEnsureWallet, shouldPinEmbeddedWallet, useEmbeddedWallet, useEnsureWallet, usePepuAuthFetch, usePinEmbeddedWallet };
261
+ //# sourceMappingURL=chunk-EHBPIYY4.js.map
262
+ //# sourceMappingURL=chunk-EHBPIYY4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/privy/ensure-client.ts","../src/privy/react.ts"],"names":["message"],"mappings":"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","file":"chunk-EHBPIYY4.js","sourcesContent":["import type { Address } from \"viem\";\nimport { PEPU_ERROR_CATALOG, PepuAuthError, PepuError, toPepuError } from \"../errors.js\";\nimport type { PepuErrorCode } from \"../errors.js\";\n\n/**\n * Framework-free client for the ensure-wallet route. No React, no Privy: the\n * hooks in `./react.ts` wrap it, and tests drive it directly.\n *\n * Ported from templates/consumer-app/components/wallet-gate.tsx (request,\n * timeout and response handling).\n */\n\n/** Default route path, matching `createEnsureWalletRoute()`. */\nexport const DEFAULT_ENSURE_ENDPOINT = \"/api/wallet/ensure\";\n/** Bound on the request itself (consumer-app: ENSURE_REQUEST_TIMEOUT_MS). */\nexport const DEFAULT_ENSURE_REQUEST_TIMEOUT_MS = 20_000;\n/** Bound on waiting for the wallet to show up client-side (consumer-app: APPEAR_IN_CLIENT_TIMEOUT_MS). */\nexport const DEFAULT_ENSURE_APPEAR_TIMEOUT_MS = 8_000;\n\nconst KNOWN_CODES: ReadonlySet<string> = new Set(PEPU_ERROR_CATALOG.map((e) => e.code));\n\nconst isRecord = (v: unknown): v is Record<string, unknown> => typeof v === \"object\" && v !== null;\n\n/**\n * Turn a non-2xx response body into a typed error. Understands the SDK shape\n * `{ error: { code, message, hint } }` and the legacy `{ error: \"text\" }`.\n */\nexport function errorFromEnsureResponse(status: number, body: unknown): PepuError {\n const err = isRecord(body) ? body[\"error\"] : undefined;\n if (isRecord(err)) {\n const code = typeof err[\"code\"] === \"string\" && KNOWN_CODES.has(err[\"code\"]) ? (err[\"code\"] as PepuErrorCode) : \"UNKNOWN\";\n const message = typeof err[\"message\"] === \"string\" ? err[\"message\"] : `Wallet setup failed (HTTP ${status}).`;\n const hint = typeof err[\"hint\"] === \"string\" ? err[\"hint\"] : undefined;\n const opts = { status, ...(hint !== undefined ? { hint } : {}) };\n return status === 401 ? new PepuAuthError(code, message, opts) : new PepuError(code, message, opts);\n }\n const message = typeof err === \"string\" ? err : `Wallet setup failed (HTTP ${status}).`;\n if (status === 401) return new PepuAuthError(\"AUTH_INVALID_TOKEN\", message, { status });\n return new PepuError(\"WALLET_NOT_PROVISIONED\", message, { status });\n}\n\n/**\n * POST to the ensure-wallet route with the user's Privy access token and return\n * the wallet address. Bounded by a timeout. Never leaks the token in errors.\n *\n * @example\n * ```ts\n * const { address } = await requestEnsureWallet({ getAccessToken, endpoint: \"/api/wallet/ensure\" });\n * ```\n */\nexport async function requestEnsureWallet(o: {\n getAccessToken: () => Promise<string | null>;\n endpoint?: string;\n timeoutMs?: number;\n fetch?: typeof fetch;\n signal?: AbortSignal;\n}): Promise<{ address: Address; created: boolean }> {\n const token = await o.getAccessToken();\n if (!token) {\n throw new PepuAuthError(\n \"AUTH_INVALID_TOKEN\",\n \"Could not get a Privy access token for this session. Try signing in again.\",\n );\n }\n const controller = new AbortController();\n const timeoutMs = o.timeoutMs ?? DEFAULT_ENSURE_REQUEST_TIMEOUT_MS;\n let timedOut = false;\n const timer = setTimeout(() => {\n timedOut = true;\n controller.abort();\n }, timeoutMs);\n const onAbort = (): void => controller.abort();\n o.signal?.addEventListener(\"abort\", onAbort);\n try {\n const doFetch = o.fetch ?? globalThis.fetch;\n let response: Response;\n try {\n response = await doFetch(o.endpoint ?? DEFAULT_ENSURE_ENDPOINT, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${token}` },\n signal: controller.signal,\n });\n } catch (e) {\n if (timedOut) {\n throw new PepuError(\"WALLET_NOT_PROVISIONED\", \"Wallet setup timed out. Please try again.\", {\n retryable: true,\n cause: e,\n });\n }\n throw toPepuError(e, { op: \"ensure wallet\" });\n }\n const body: unknown = await response.json().catch(() => null);\n if (!response.ok) throw errorFromEnsureResponse(response.status, body);\n const address = isRecord(body) ? body[\"address\"] : undefined;\n if (typeof address !== \"string\" || !/^0x[0-9a-fA-F]{40}$/.test(address)) {\n throw new PepuError(\"WALLET_NOT_PROVISIONED\", \"The ensure-wallet route did not return a wallet address.\", {\n status: 502,\n });\n }\n return { address: address as Address, created: isRecord(body) && body[\"created\"] === true };\n } finally {\n clearTimeout(timer);\n o.signal?.removeEventListener(\"abort\", onAbort);\n }\n}\n","import { createElement, Fragment, useCallback, useEffect, useRef, useState } from \"react\";\nimport type { ComponentType, ReactElement, ReactNode } from \"react\";\nimport { getEmbeddedConnectedWallet, PrivyProvider, usePrivy, useUser, useWallets } from \"@privy-io/react-auth\";\nimport type { ConnectedWallet, PrivyClientConfig } from \"@privy-io/react-auth\";\nimport type { Address } from \"viem\";\nimport { PepuAuthError, PepuError, toPepuError } from \"../errors.js\";\nimport { createPepuPrivyConfig, PRIVY_ENV } from \"./config.js\";\nimport type { CreatePepuPrivyConfigOptions } from \"./config.js\";\nimport {\n DEFAULT_ENSURE_APPEAR_TIMEOUT_MS,\n DEFAULT_ENSURE_ENDPOINT,\n DEFAULT_ENSURE_REQUEST_TIMEOUT_MS,\n requestEnsureWallet,\n} from \"./ensure-client.js\";\n\n/**\n * `@pepu-chain/sdk/privy/react` (browser). Provider, embedded-wallet\n * detection, wallet provisioning and the gate. Add `\"use client\"` in the file\n * where you import these from a Next.js server component.\n *\n * `react` and `@privy-io/react-auth` are optional peers of this entry only.\n */\n\nexport { requestEnsureWallet } from \"./ensure-client.js\";\n\n// ---------------------------------------------------------------------------\n// Provider\n// ---------------------------------------------------------------------------\n\nexport interface PepuPrivyProviderProps {\n /** Privy app id. When missing, `fallback` renders instead of throwing deep inside Privy. */\n appId: string | undefined;\n /** Overrides for {@link createPepuPrivyConfig}. */\n config?: Partial<CreatePepuPrivyConfigOptions> | undefined;\n /** Shown when `appId` is empty. Defaults to a short notice naming the env variable. */\n fallback?: ReactNode;\n /**\n * Extra providers rendered inside PrivyProvider (used by `/privy/wagmi`).\n * Build one with {@link composeProviders}.\n */\n wrapper?: ComponentType<{ children?: ReactNode }> | undefined;\n children?: ReactNode;\n}\n\n/**\n * Compose providers (outermost first) into one wrapper component, with optional\n * leaf components rendered next to `children` in the innermost position. A\n * building block for `/privy/wagmi`; it keeps `react` imports in this entry.\n *\n * @example\n * ```ts\n * const Wrapper = composeProviders([[QueryClientProvider, { client }]], [MyEffectOnlyComponent]);\n * ```\n */\nexport function composeProviders(\n layers: readonly (readonly [ComponentType<any>, Record<string, unknown>])[], // eslint-disable-line @typescript-eslint/no-explicit-any\n leaves: readonly ComponentType<Record<string, never>>[] = [],\n): ComponentType<{ children?: ReactNode }> {\n return function ComposedProviders({ children }: { children?: ReactNode }): ReactElement {\n let node: ReactElement = createElement(\n Fragment,\n null,\n ...leaves.map((Leaf, i) => createElement(Leaf as ComponentType<{ key?: string }>, { key: `leaf-${i}` })),\n children,\n );\n for (let i = layers.length - 1; i >= 0; i--) {\n const layer = layers[i];\n if (!layer) continue;\n node = createElement(layer[0], layer[1], node);\n }\n return node;\n };\n}\n\n/**\n * `<PrivyProvider>` preconfigured for PEPU: mainnet only, Coinbase pinned to\n * `eoaOnly`, wallet creation off (the server provisions it, see\n * {@link WalletGate}). Renders `fallback` instead of crashing when `appId` is\n * missing.\n *\n * Ported from templates/consumer-app/app/providers.tsx.\n *\n * @example\n * ```tsx\n * <PepuPrivyProvider appId={process.env.NEXT_PUBLIC_PRIVY_APP_ID} config={{ loginMethods: [\"email\", \"google\"] }}>\n * <App />\n * </PepuPrivyProvider>\n * ```\n */\nexport function PepuPrivyProvider(props: PepuPrivyProviderProps): ReactElement {\n const { appId, config, fallback, wrapper, children } = props;\n if (!appId) {\n return createElement(\n Fragment,\n null,\n fallback ??\n createElement(\n \"div\",\n { role: \"alert\" },\n `Missing ${PRIVY_ENV.appId}. Set it to your Privy app id and restart the dev server.`,\n ),\n );\n }\n const inner: ReactNode = wrapper ? createElement(wrapper, null, children) : children;\n return createElement(PrivyProvider, {\n appId,\n config: createPepuPrivyConfig(config) as unknown as PrivyClientConfig,\n children: inner,\n });\n}\n\n// ---------------------------------------------------------------------------\n// Embedded wallet\n// ---------------------------------------------------------------------------\n\n/**\n * This user's Privy embedded wallet, separated from any external wallet Privy\n * is tracking (an installed MetaMask or Phantom). Never re-implements the\n * embedded filter: it calls Privy's `getEmbeddedConnectedWallet`.\n *\n * Ported from templates/consumer-app/lib/wallet.ts (`useWalletSnapshot`).\n *\n * @example\n * ```tsx\n * const { ready, address, external } = useEmbeddedWallet();\n * ```\n */\nexport function useEmbeddedWallet(): {\n ready: boolean;\n wallet: ConnectedWallet | null;\n address?: Address;\n external: ConnectedWallet[];\n} {\n const { wallets, ready } = useWallets();\n const wallet = getEmbeddedConnectedWallet(wallets);\n const external = wallets.filter((w) => w !== wallet);\n return wallet\n ? { ready, wallet, address: wallet.address as Address, external }\n : { ready, wallet: null, external };\n}\n\n/**\n * Pure decision behind the pin hooks: pin only when enabled, hydrated, an\n * embedded wallet exists and the active account is not already it. The address\n * comparison is what prevents a render loop.\n *\n * @example\n * ```ts\n * shouldPinEmbeddedWallet({ enabled: true, ready: true, embeddedAddress: \"0xA\", activeAddress: \"0xB\" }); // true\n * ```\n */\nexport function shouldPinEmbeddedWallet(o: {\n enabled: boolean;\n ready: boolean;\n embeddedAddress: string | undefined;\n activeAddress: string | undefined;\n}): boolean {\n if (!o.enabled || !o.ready || !o.embeddedAddress) return false;\n return o.activeAddress?.toLowerCase() !== o.embeddedAddress.toLowerCase();\n}\n\n/**\n * Generic half of the active-wallet pin: re-asserts the embedded wallet whenever\n * the active account drifts away from it. `useActiveWalletPin` in\n * `/privy/wagmi` supplies wagmi's active address and `setActiveWallet`.\n *\n * Ported from templates/consumer-app/lib/wallet.ts (`useActiveWalletSync`).\n * A user with no embedded wallet is left alone on purpose.\n *\n * @example\n * ```ts\n * usePinEmbeddedWallet({ enabled: true, activeAddress, setActiveWallet });\n * ```\n */\nexport function usePinEmbeddedWallet(o: {\n enabled: boolean;\n activeAddress: string | undefined;\n setActiveWallet: (wallet: ConnectedWallet) => Promise<unknown> | void;\n}): void {\n const { enabled, activeAddress, setActiveWallet } = o;\n const { wallets, ready } = useWallets();\n const embedded = getEmbeddedConnectedWallet(wallets);\n const embeddedAddress = embedded?.address;\n useEffect(() => {\n if (!embedded) return;\n if (!shouldPinEmbeddedWallet({ enabled, ready, embeddedAddress, activeAddress })) return;\n void setActiveWallet(embedded);\n }, [enabled, ready, embedded, embeddedAddress, activeAddress, setActiveWallet]);\n}\n\n// ---------------------------------------------------------------------------\n// Ensure wallet\n// ---------------------------------------------------------------------------\n\ntype FetchInput = Parameters<typeof fetch>[0];\n\nexport type EnsureWalletStatus = \"idle\" | \"checking\" | \"creating\" | \"ready\" | \"stalled\" | \"error\";\n\n/**\n * Provision this user's embedded wallet through the ensure-wallet route (see\n * `createEnsureWalletRoute` in `/privy/server`), not Privy's client-side\n * creation, which hangs for apps with the dashboard's creation setting off.\n * Gates on the EMBEDDED wallet, never on \"any connected wallet\".\n *\n * Ported from templates/consumer-app/components/wallet-gate.tsx.\n *\n * @example\n * ```tsx\n * const { status, address, error, retry } = useEnsureWallet();\n * ```\n */\nexport function useEnsureWallet(o: { endpoint?: string; requestTimeoutMs?: number; appearTimeoutMs?: number } = {}): {\n status: EnsureWalletStatus;\n address?: Address;\n error?: PepuError;\n retry(): void;\n} {\n const endpoint = o.endpoint ?? DEFAULT_ENSURE_ENDPOINT;\n const requestTimeoutMs = o.requestTimeoutMs ?? DEFAULT_ENSURE_REQUEST_TIMEOUT_MS;\n const appearTimeoutMs = o.appearTimeoutMs ?? DEFAULT_ENSURE_APPEAR_TIMEOUT_MS;\n\n const { ready: privyReady, authenticated, getAccessToken } = usePrivy();\n const { wallets, ready: walletsReady } = useWallets();\n const { refreshUser } = useUser();\n\n const [error, setError] = useState<PepuError | null>(null);\n const [requesting, setRequesting] = useState(false);\n const [confirmed, setConfirmed] = useState<Address | null>(null);\n const [stalled, setStalled] = useState(false);\n const [attempt, setAttempt] = useState(0);\n // The attempt number whose request already settled. An unsettled attempt is\n // restarted if the effect re-runs (React StrictMode mounts effects twice), a\n // settled one never is, so a re-render cannot trigger a second POST.\n const settledFor = useRef(-1);\n // Latest Privy callbacks, kept out of the effect deps so a new function\n // identity never cancels an in-flight request.\n const getAccessTokenRef = useRef(getAccessToken);\n const refreshUserRef = useRef(refreshUser);\n getAccessTokenRef.current = getAccessToken;\n refreshUserRef.current = refreshUser;\n\n const embedded = getEmbeddedConnectedWallet(wallets);\n const hasWallet = embedded !== null;\n\n useEffect(() => {\n if (!privyReady || !authenticated || !walletsReady || hasWallet) return;\n if (settledFor.current === attempt) return;\n\n let cancelled = false;\n const controller = new AbortController();\n setRequesting(true);\n void (async () => {\n try {\n const { address } = await requestEnsureWallet({\n getAccessToken: () => getAccessTokenRef.current(),\n endpoint,\n timeoutMs: requestTimeoutMs,\n signal: controller.signal,\n });\n // Pull the server-side change into Privy's client state without a reload.\n await refreshUserRef.current();\n if (cancelled) return;\n settledFor.current = attempt;\n setConfirmed(address);\n } catch (e) {\n if (cancelled) return;\n settledFor.current = attempt;\n setError(toPepuError(e, { op: \"ensure wallet\" }));\n } finally {\n if (!cancelled) setRequesting(false);\n }\n })();\n return () => {\n cancelled = true;\n controller.abort();\n };\n }, [privyReady, authenticated, walletsReady, hasWallet, attempt, endpoint, requestTimeoutMs]);\n\n // Bounded safety net: the server confirmed the wallet, the client never saw it.\n useEffect(() => {\n if (!confirmed || hasWallet) return;\n const id = setTimeout(() => setStalled(true), appearTimeoutMs);\n return () => {\n clearTimeout(id);\n setStalled(false);\n };\n }, [confirmed, hasWallet, appearTimeoutMs]);\n\n const retry = useCallback((): void => {\n setError(null);\n setConfirmed(null);\n setStalled(false);\n setRequesting(false);\n setAttempt((n) => n + 1);\n }, []);\n\n if (hasWallet) return { status: \"ready\", address: embedded.address as Address, retry };\n if (!privyReady || !authenticated || !walletsReady) return { status: \"idle\", retry };\n if (error) return { status: \"error\", error, retry };\n if (stalled && confirmed) return { status: \"stalled\", address: confirmed, retry };\n if (confirmed) return { status: \"checking\", address: confirmed, retry };\n return { status: requesting ? \"creating\" : \"checking\", retry };\n}\n\n/**\n * Renders `children` once the user's embedded wallet exists, provisioning it\n * first through the ensure-wallet route. Shows `loading`, an error (with\n * retry) or a reload prompt when the wallet exists but has not synced yet.\n * Each of the three states takes a render prop (`loading`, `error`, `stalled`)\n * so an app can use the gate directly with its own markup and classes.\n *\n * Ported from templates/consumer-app/components/wallet-gate.tsx.\n *\n * @example\n * ```tsx\n * <WalletGate\n * loading={<Spinner />}\n * error={(e, retry) => <button onClick={retry}>{e.message}</button>}\n * stalled={(address, reload) => <button onClick={reload}>Reload ({address})</button>}\n * >\n * <Dashboard />\n * </WalletGate>\n * ```\n */\nexport function WalletGate(p: {\n endpoint?: string;\n loading?: ReactNode;\n error?: (e: PepuError, retry: () => void) => ReactNode;\n /**\n * The server confirmed the wallet but this session has not seen it after a\n * bounded wait (a client sync delay). `reload` reloads the page.\n */\n stalled?: (address: Address, reload: () => void) => ReactNode;\n children: ReactNode;\n}): ReactElement {\n const ensure = useEnsureWallet(p.endpoint !== undefined ? { endpoint: p.endpoint } : {});\n if (ensure.status === \"ready\") return createElement(Fragment, null, p.children);\n\n if (ensure.status === \"error\" && ensure.error) {\n const { error, retry } = ensure;\n return createElement(\n Fragment,\n null,\n p.error\n ? p.error(error, retry)\n : createElement(\n \"div\",\n { role: \"alert\" },\n createElement(\"p\", null, \"Could not create your wallet.\"),\n createElement(\"p\", null, error.message),\n createElement(\"button\", { type: \"button\", onClick: retry }, \"Try again\"),\n ),\n );\n }\n\n if (ensure.status === \"stalled\" && ensure.address) {\n const a = ensure.address;\n const reload = (): void => (globalThis as unknown as { location: { reload(): void } }).location.reload();\n if (p.stalled) return createElement(Fragment, null, p.stalled(a, reload));\n return createElement(\n \"div\",\n { role: \"status\" },\n createElement(\"p\", null, `Your wallet was created (${a.slice(0, 6)}…${a.slice(-4)}), but it has not appeared in this session yet.`),\n createElement(\"p\", null, \"This is a client sync delay, not a lost wallet. Reloading usually fixes it.\"),\n createElement(\"button\", { type: \"button\", onClick: reload }, \"Reload\"),\n );\n }\n\n return createElement(\n Fragment,\n null,\n p.loading ?? createElement(\"div\", { role: \"status\", \"aria-label\": \"Loading\" }, \"Setting up your wallet…\"),\n );\n}\n\n// ---------------------------------------------------------------------------\n// Authenticated fetch\n// ---------------------------------------------------------------------------\n\n/**\n * A `fetch` that attaches `Authorization: Bearer <Privy access token>`. Throws\n * {@link PepuAuthError} when there is no token (signed out or expired).\n *\n * @example\n * ```tsx\n * const authFetch = usePepuAuthFetch();\n * const res = await authFetch(\"/api/session/status\");\n * ```\n */\nexport function usePepuAuthFetch(): (input: FetchInput, init?: RequestInit) => Promise<Response> {\n const { getAccessToken } = usePrivy();\n return useCallback(\n async (input: FetchInput, init?: RequestInit): Promise<Response> => {\n const token = await getAccessToken();\n if (!token) {\n throw new PepuAuthError(\n \"AUTH_INVALID_TOKEN\",\n \"No Privy access token for this session. Sign in again.\",\n );\n }\n const headers = new Headers(init?.headers);\n headers.set(\"Authorization\", `Bearer ${token}`);\n return fetch(input, { ...init, headers });\n },\n [getAccessToken],\n );\n}\n"]}
@@ -0,0 +1,86 @@
1
+ import { PepuPolicyError } from './chunk-6DSZ4Z2N.js';
2
+ import { toFunctionSelector, toFunctionSignature } from 'viem';
3
+
4
+ function findFunction(call) {
5
+ const fn = call.abi.find((item) => item.type === "function" && item.name === call.functionName);
6
+ if (!fn) {
7
+ throw new PepuPolicyError("POLICY_UNSCOPED", `The ABI has no function named "${call.functionName}".`);
8
+ }
9
+ return fn;
10
+ }
11
+ function assertCalls(calls) {
12
+ if (calls.length === 0) {
13
+ throw new PepuPolicyError("POLICY_UNSCOPED", "A session needs at least one allowed call.");
14
+ }
15
+ for (const c of calls) {
16
+ if (!/^0x[0-9a-fA-F]{40}$/.test(c.target)) {
17
+ throw new PepuPolicyError("POLICY_UNSCOPED", "Every session call needs a valid 0x target address.");
18
+ }
19
+ findFunction(c);
20
+ }
21
+ }
22
+ function describeKernelSessionScope(p) {
23
+ assertCalls(p.calls);
24
+ return {
25
+ calls: p.calls.map((c) => {
26
+ const fn = findFunction(c);
27
+ return {
28
+ target: c.target,
29
+ functionName: c.functionName,
30
+ signature: toFunctionSignature(fn).replace(/^function /, ""),
31
+ selector: toFunctionSelector(fn),
32
+ maxValueWei: (c.valueLimit ?? 0n).toString()
33
+ };
34
+ }),
35
+ validAfter: p.validAfter ?? 0,
36
+ validUntil: p.validUntil
37
+ };
38
+ }
39
+ function isCallInScope(scope, call) {
40
+ const selector = call.data.slice(0, 10).toLowerCase();
41
+ return scope.calls.some(
42
+ (c) => c.target.toLowerCase() === call.to.toLowerCase() && c.selector.toLowerCase() === selector && (call.value ?? 0n) <= BigInt(c.maxValueWei)
43
+ );
44
+ }
45
+ function decodeBase64Json(text) {
46
+ const binary = atob(text);
47
+ const bytes = Uint8Array.from(binary, (ch) => ch.charCodeAt(0));
48
+ return JSON.parse(new TextDecoder().decode(bytes));
49
+ }
50
+ function parseApproval(approval) {
51
+ try {
52
+ const json = decodeBase64Json(approval);
53
+ if (typeof json !== "object" || json === null) return null;
54
+ const record = json;
55
+ const permissionParams = record.permissionParams;
56
+ const accountParams = record.accountParams;
57
+ return {
58
+ permissionId: typeof permissionParams?.permissionId === "string" ? permissionParams.permissionId : null,
59
+ accountAddress: typeof accountParams?.accountAddress === "string" ? accountParams.accountAddress : null,
60
+ isPreInstalled: typeof record.isPreInstalled === "boolean" ? record.isPreInstalled : null,
61
+ hasPrivateKey: typeof record.privateKey === "string" && record.privateKey.length > 0
62
+ };
63
+ } catch {
64
+ return null;
65
+ }
66
+ }
67
+ function checkApproval(approval, expected) {
68
+ if (approval.length === 0 || approval.length > 2e4) {
69
+ return { ok: false, reason: "Approval has an unexpected size." };
70
+ }
71
+ const parsed = parseApproval(approval);
72
+ if (!parsed) return { ok: false, reason: "Approval is not a valid session approval." };
73
+ if (parsed.hasPrivateKey) return { ok: false, reason: "Approval must not contain a private key." };
74
+ if (parsed.isPreInstalled !== false) return { ok: false, reason: "Approval must be an enable-mode grant." };
75
+ if (parsed.accountAddress?.toLowerCase() !== expected.kernelAddress.toLowerCase()) {
76
+ return { ok: false, reason: "Approval is for a different smart account than yours." };
77
+ }
78
+ if (parsed.permissionId?.toLowerCase() !== expected.permissionId.toLowerCase()) {
79
+ return { ok: false, reason: "Approval does not match the scope, session key or expiry this server issued." };
80
+ }
81
+ return { ok: true };
82
+ }
83
+
84
+ export { assertCalls, checkApproval, describeKernelSessionScope, findFunction, isCallInScope, parseApproval };
85
+ //# sourceMappingURL=chunk-ESMNAXUI.js.map
86
+ //# sourceMappingURL=chunk-ESMNAXUI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/session/scope.ts"],"names":[],"mappings":"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","file":"chunk-ESMNAXUI.js","sourcesContent":["import { toFunctionSelector, toFunctionSignature } from \"viem\";\nimport type { Abi, AbiFunction, Address, Hex } from \"viem\";\n\nimport { PepuPolicyError } from \"../errors.js\";\n\n/**\n * Pure Kernel session helpers (scope types, consent-screen data, call-in-scope\n * check, approval parsing). They need only `viem`, so they load without any\n * `@zerodev/*` peer. Also re-exported from `@pepu-chain/sdk/session/kernel`.\n */\n\n/** One function a session may call on one contract. */\nexport interface KernelSessionCall {\n target: Address;\n abi: Abi;\n functionName: string;\n /** Max native value per call, in wei. Default `0n`. */\n valueLimit?: bigint;\n}\n\n/** What a Kernel session allows, as plain data for a consent screen. */\nexport interface KernelSessionScope {\n calls: {\n target: Address;\n functionName: string;\n /** e.g. `tap()`. */\n signature: string;\n selector: Hex;\n /** Max value per call in wei, as a decimal string. */\n maxValueWei: string;\n }[];\n validAfter: number;\n validUntil: number;\n}\n\nexport function findFunction(call: KernelSessionCall): AbiFunction {\n const fn = call.abi.find((item): item is AbiFunction => item.type === \"function\" && item.name === call.functionName);\n if (!fn) {\n throw new PepuPolicyError(\"POLICY_UNSCOPED\", `The ABI has no function named \"${call.functionName}\".`);\n }\n return fn;\n}\n\nexport function assertCalls(calls: readonly KernelSessionCall[]): void {\n if (calls.length === 0) {\n throw new PepuPolicyError(\"POLICY_UNSCOPED\", \"A session needs at least one allowed call.\");\n }\n for (const c of calls) {\n if (!/^0x[0-9a-fA-F]{40}$/.test(c.target)) {\n throw new PepuPolicyError(\"POLICY_UNSCOPED\", \"Every session call needs a valid 0x target address.\");\n }\n findFunction(c);\n }\n}\n\n/**\n * Consent-screen data: each allowed call with its selector, the value limit\n * and the expiry. Pure.\n *\n * @example\n * const scope = describeKernelSessionScope({ calls, validUntil });\n * scope.calls[0]?.signature; // \"tap()\"\n */\nexport function describeKernelSessionScope(p: {\n calls: readonly KernelSessionCall[];\n validUntil: number;\n validAfter?: number;\n}): KernelSessionScope {\n assertCalls(p.calls);\n return {\n calls: p.calls.map((c) => {\n const fn = findFunction(c);\n return {\n target: c.target,\n functionName: c.functionName,\n signature: toFunctionSignature(fn).replace(/^function /, \"\"),\n selector: toFunctionSelector(fn),\n maxValueWei: (c.valueLimit ?? 0n).toString(),\n };\n }),\n validAfter: p.validAfter ?? 0,\n validUntil: p.validUntil,\n };\n}\n\n/**\n * True when `call` (target plus 4-byte selector, value) is inside `scope`.\n * Used server-side to fail fast before sponsoring; the chain still enforces\n * the real limit. Pure.\n *\n * @example\n * isCallInScope(scope, { to, data, value: 0n });\n */\nexport function isCallInScope(\n scope: Pick<KernelSessionScope, \"calls\">,\n call: { to: Address; data: Hex; value?: bigint },\n): boolean {\n const selector = call.data.slice(0, 10).toLowerCase();\n return scope.calls.some(\n (c) =>\n c.target.toLowerCase() === call.to.toLowerCase() &&\n c.selector.toLowerCase() === selector &&\n (call.value ?? 0n) <= BigInt(c.maxValueWei),\n );\n}\n\n/** Parsed fields of an `approval` string. */\nexport interface ParsedApproval {\n permissionId: string | null;\n accountAddress: string | null;\n isPreInstalled: boolean | null;\n hasPrivateKey: boolean;\n}\n\nfunction decodeBase64Json(text: string): unknown {\n const binary = atob(text);\n const bytes = Uint8Array.from(binary, (ch) => ch.charCodeAt(0));\n return JSON.parse(new TextDecoder().decode(bytes));\n}\n\n/**\n * Parse a serialized approval (base64 JSON from `serializePermissionAccount`)\n * without trusting it. Returns `null` when it is not an approval at all.\n *\n * @example\n * parseApproval(approval)?.permissionId;\n */\nexport function parseApproval(approval: string): ParsedApproval | null {\n try {\n const json = decodeBase64Json(approval);\n if (typeof json !== \"object\" || json === null) return null;\n const record = json as Record<string, unknown>;\n const permissionParams = record.permissionParams as { permissionId?: unknown } | undefined;\n const accountParams = record.accountParams as { accountAddress?: unknown } | undefined;\n return {\n permissionId: typeof permissionParams?.permissionId === \"string\" ? permissionParams.permissionId : null,\n accountAddress: typeof accountParams?.accountAddress === \"string\" ? accountParams.accountAddress : null,\n isPreInstalled: typeof record.isPreInstalled === \"boolean\" ? record.isPreInstalled : null,\n hasPrivateKey: typeof record.privateKey === \"string\" && record.privateKey.length > 0,\n };\n } catch {\n return null;\n }\n}\n\n/** Result of {@link checkApproval}. */\nexport type ApprovalCheck = { ok: true } | { ok: false; reason: string };\n\n/**\n * Check a browser-supplied approval before the server stores it. It rejects a\n * payload that carries a private key, is not an enable-mode grant, is for\n * another account, or whose permission id differs from the one this server\n * issued (so scope, session key or expiry changed). The approval is untrusted\n * input; the chain enforces the real limits regardless.\n *\n * @example\n * const check = checkApproval(approval, { kernelAddress, permissionId });\n * if (!check.ok) console.log(check.reason);\n */\nexport function checkApproval(\n approval: string,\n expected: { kernelAddress: Address; permissionId: string },\n): ApprovalCheck {\n if (approval.length === 0 || approval.length > 20_000) {\n return { ok: false, reason: \"Approval has an unexpected size.\" };\n }\n const parsed = parseApproval(approval);\n if (!parsed) return { ok: false, reason: \"Approval is not a valid session approval.\" };\n if (parsed.hasPrivateKey) return { ok: false, reason: \"Approval must not contain a private key.\" };\n if (parsed.isPreInstalled !== false) return { ok: false, reason: \"Approval must be an enable-mode grant.\" };\n if (parsed.accountAddress?.toLowerCase() !== expected.kernelAddress.toLowerCase()) {\n return { ok: false, reason: \"Approval is for a different smart account than yours.\" };\n }\n if (parsed.permissionId?.toLowerCase() !== expected.permissionId.toLowerCase()) {\n return { ok: false, reason: \"Approval does not match the scope, session key or expiry this server issued.\" };\n }\n return { ok: true };\n}\n\n"]}
@@ -0,0 +1,49 @@
1
+ 'use strict';
2
+
3
+ var chunkTIEAZYHF_cjs = require('./chunk-TIEAZYHF.cjs');
4
+ var chunkDPCZJLB3_cjs = require('./chunk-DPCZJLB3.cjs');
5
+ var viem = require('viem');
6
+
7
+ function buildPaymasterContext(entries = {}) {
8
+ const context = {};
9
+ for (const [key, value] of Object.entries(entries)) {
10
+ if (value === void 0) continue;
11
+ const kind = typeof value;
12
+ if (kind === "bigint" || kind === "function" || kind === "symbol") {
13
+ throw new Error(
14
+ `buildPaymasterContext: "${key}" is a ${kind}, which is not JSON-serializable. Convert it to a string or number first.`
15
+ );
16
+ }
17
+ context[key] = value;
18
+ }
19
+ return context;
20
+ }
21
+ function buildParams(options) {
22
+ const entryPointEntry = chunkTIEAZYHF_cjs.getContract(chunkDPCZJLB3_cjs.pepuMainnet.id, "entryPoint07");
23
+ const entryPoint = options.entryPoint ?? (entryPointEntry?.status === "deployed" ? entryPointEntry.address : void 0);
24
+ if (!entryPoint) throw new Error("buildPaymasterRequest: no EntryPoint v0.7 address available.");
25
+ const chainId = viem.toHex(options.chainId ?? chunkDPCZJLB3_cjs.pepuMainnet.id);
26
+ return options.context ? [options.userOperation, entryPoint, chainId, options.context] : [options.userOperation, entryPoint, chainId];
27
+ }
28
+ function buildPaymasterStubDataRequest(options) {
29
+ return {
30
+ jsonrpc: "2.0",
31
+ id: options.id ?? 1,
32
+ method: "pm_getPaymasterStubData",
33
+ params: buildParams(options)
34
+ };
35
+ }
36
+ function buildPaymasterDataRequest(options) {
37
+ return {
38
+ jsonrpc: "2.0",
39
+ id: options.id ?? 1,
40
+ method: "pm_getPaymasterData",
41
+ params: buildParams(options)
42
+ };
43
+ }
44
+
45
+ exports.buildPaymasterContext = buildPaymasterContext;
46
+ exports.buildPaymasterDataRequest = buildPaymasterDataRequest;
47
+ exports.buildPaymasterStubDataRequest = buildPaymasterStubDataRequest;
48
+ //# sourceMappingURL=chunk-ET3P6TX6.cjs.map
49
+ //# sourceMappingURL=chunk-ET3P6TX6.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/erc7677.ts"],"names":["getContract","pepuMainnet","toHex"],"mappings":";;;;;;AAkGO,SAAS,qBAAA,CACd,OAAA,GAA6C,EAAC,EAC5B;AAClB,EAAA,MAAM,UAA4B,EAAC;AACnC,EAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,OAAO,CAAA,EAAG;AAClD,IAAA,IAAI,UAAU,MAAA,EAAW;AACzB,IAAA,MAAM,OAAO,OAAO,KAAA;AACpB,IAAA,IAAI,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,UAAA,IAAc,SAAS,QAAA,EAAU;AACjE,MAAA,MAAM,IAAI,KAAA;AAAA,QACR,CAAA,wBAAA,EAA2B,GAAG,CAAA,OAAA,EAAU,IAAI,CAAA,yEAAA;AAAA,OAC9C;AAAA,IACF;AACA,IAAA,OAAA,CAAQ,GAAG,CAAA,GAAI,KAAA;AAAA,EACjB;AACA,EAAA,OAAO,OAAA;AACT;AAYA,SAAS,YAAY,OAAA,EAA2D;AAC9E,EAAA,MAAM,eAAA,GAAkBA,6BAAA,CAAYC,6BAAA,CAAY,EAAA,EAAI,cAAc,CAAA;AAClE,EAAA,MAAM,aACJ,OAAA,CAAQ,UAAA,KACP,iBAAiB,MAAA,KAAW,UAAA,GAAa,gBAAgB,OAAA,GAAU,MAAA,CAAA;AACtE,EAAA,IAAI,CAAC,UAAA,EAAY,MAAM,IAAI,MAAM,8DAA8D,CAAA;AAC/F,EAAA,MAAM,OAAA,GAAUC,UAAA,CAAM,OAAA,CAAQ,OAAA,IAAWD,8BAAY,EAAE,CAAA;AACvD,EAAA,OAAO,OAAA,CAAQ,OAAA,GACX,CAAC,OAAA,CAAQ,eAAe,UAAA,EAAY,OAAA,EAAS,OAAA,CAAQ,OAAO,CAAA,GAC5D,CAAC,OAAA,CAAQ,aAAA,EAAe,YAAY,OAAO,CAAA;AACjD;AAGO,SAAS,8BACd,OAAA,EAC0B;AAC1B,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,KAAA;AAAA,IACT,EAAA,EAAI,QAAQ,EAAA,IAAM,CAAA;AAAA,IAClB,MAAA,EAAQ,yBAAA;AAAA,IACR,MAAA,EAAQ,YAAY,OAAO;AAAA,GAC7B;AACF;AAGO,SAAS,0BACd,OAAA,EACsB;AACtB,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,KAAA;AAAA,IACT,EAAA,EAAI,QAAQ,EAAA,IAAM,CAAA;AAAA,IAClB,MAAA,EAAQ,qBAAA;AAAA,IACR,MAAA,EAAQ,YAAY,OAAO;AAAA,GAC7B;AACF","file":"chunk-ET3P6TX6.cjs","sourcesContent":["import { toHex } from \"viem\";\nimport type { Address, Hex } from \"viem\";\n\nimport { pepuMainnet } from \"./chains.js\";\nimport { getContract } from \"./contracts.js\";\n\n/**\n * ERC-7677 paymaster web-service types, for the two JSON-RPC methods PEPU's\n * paymaster policy service implements: `pm_getPaymasterStubData` and\n * `pm_getPaymasterData`. See https://eips.ethereum.org/EIPS/eip-7677.\n *\n * Pure types plus a few tiny builders: no network, no secrets, safe in a\n * browser bundle. Quantities are `0x`-prefixed hex strings, as on the wire.\n *\n * Note this package never implies sponsorship is available to an app: see\n * `getSponsorshipStatus()`. These types describe the protocol only.\n */\n\n/** An ERC-4337 v0.7 UserOperation in its unpacked JSON-RPC shape. */\nexport interface Erc7677UserOperation {\n sender: Address;\n nonce: Hex;\n factory?: Address;\n factoryData?: Hex;\n callData: Hex;\n callGasLimit: Hex;\n verificationGasLimit: Hex;\n preVerificationGas: Hex;\n maxFeePerGas: Hex;\n maxPriorityFeePerGas: Hex;\n paymaster?: Address;\n paymasterVerificationGasLimit?: Hex;\n paymasterPostOpGasLimit?: Hex;\n paymasterData?: Hex;\n signature: Hex;\n}\n\n/** Paymaster-defined, JSON-serializable context (params[3]). */\nexport type PaymasterContext = Record<string, unknown>;\n\nexport type PaymasterRpcParams = readonly [\n userOperation: Partial<Erc7677UserOperation> & Pick<Erc7677UserOperation, \"sender\" | \"callData\">,\n entryPoint: Address,\n chainId: Hex,\n context?: PaymasterContext,\n];\n\nexport interface PaymasterStubDataRequest {\n jsonrpc: \"2.0\";\n id: number | string;\n method: \"pm_getPaymasterStubData\";\n params: PaymasterRpcParams;\n}\n\nexport interface PaymasterDataRequest {\n jsonrpc: \"2.0\";\n id: number | string;\n method: \"pm_getPaymasterData\";\n params: PaymasterRpcParams;\n}\n\n/** Result of `pm_getPaymasterStubData`. Stub values are for gas estimation only. */\nexport interface PaymasterStubDataResult {\n paymaster: Address;\n paymasterData: Hex;\n paymasterVerificationGasLimit?: Hex;\n paymasterPostOpGasLimit?: Hex;\n /** `true` when the stub values are also the final values. */\n isFinal?: boolean;\n sponsor?: { name: string; icon?: string };\n}\n\n/** Result of `pm_getPaymasterData`: the signed values to submit. */\nexport interface PaymasterDataResult {\n paymaster: Address;\n paymasterData: Hex;\n paymasterVerificationGasLimit?: Hex;\n paymasterPostOpGasLimit?: Hex;\n}\n\nexport interface PaymasterRpcError {\n code: number;\n message: string;\n /** PEPU's policy service puts the machine-readable denial reason in `data.reason`. */\n data?: { reason?: string } & Record<string, unknown>;\n}\n\nexport type PaymasterRpcResponse<TResult> =\n | { jsonrpc: \"2.0\"; id: number | string | null; result: TResult }\n | { jsonrpc: \"2.0\"; id: number | string | null; error: PaymasterRpcError };\n\n/**\n * Build a paymaster `context` object: drops `undefined` entries and throws on\n * anything that would not survive `JSON.stringify` (bigint, function, symbol),\n * so a bad value fails here instead of as an opaque RPC error. Returns `{}`\n * for no input. The context is paymaster-defined; PEPU's policy service\n * currently accepts and ignores it.\n */\nexport function buildPaymasterContext(\n entries: Readonly<Record<string, unknown>> = {},\n): PaymasterContext {\n const context: PaymasterContext = {};\n for (const [key, value] of Object.entries(entries)) {\n if (value === undefined) continue;\n const kind = typeof value;\n if (kind === \"bigint\" || kind === \"function\" || kind === \"symbol\") {\n throw new Error(\n `buildPaymasterContext: \"${key}\" is a ${kind}, which is not JSON-serializable. Convert it to a string or number first.`,\n );\n }\n context[key] = value;\n }\n return context;\n}\n\nexport interface BuildPaymasterRequestOptions {\n userOperation: PaymasterRpcParams[0];\n /** Defaults to PEPU mainnet's EntryPoint v0.7. */\n entryPoint?: Address;\n /** Defaults to 97741 (PEPU mainnet). */\n chainId?: number;\n context?: PaymasterContext;\n id?: number | string;\n}\n\nfunction buildParams(options: BuildPaymasterRequestOptions): PaymasterRpcParams {\n const entryPointEntry = getContract(pepuMainnet.id, \"entryPoint07\");\n const entryPoint =\n options.entryPoint ??\n (entryPointEntry?.status === \"deployed\" ? entryPointEntry.address : undefined);\n if (!entryPoint) throw new Error(\"buildPaymasterRequest: no EntryPoint v0.7 address available.\");\n const chainId = toHex(options.chainId ?? pepuMainnet.id);\n return options.context\n ? [options.userOperation, entryPoint, chainId, options.context]\n : [options.userOperation, entryPoint, chainId];\n}\n\n/** Build a `pm_getPaymasterStubData` JSON-RPC request body. */\nexport function buildPaymasterStubDataRequest(\n options: BuildPaymasterRequestOptions,\n): PaymasterStubDataRequest {\n return {\n jsonrpc: \"2.0\",\n id: options.id ?? 1,\n method: \"pm_getPaymasterStubData\",\n params: buildParams(options),\n };\n}\n\n/** Build a `pm_getPaymasterData` JSON-RPC request body. */\nexport function buildPaymasterDataRequest(\n options: BuildPaymasterRequestOptions,\n): PaymasterDataRequest {\n return {\n jsonrpc: \"2.0\",\n id: options.id ?? 1,\n method: \"pm_getPaymasterData\",\n params: buildParams(options),\n };\n}\n"]}