@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,95 @@
1
+ 'use strict';
2
+
3
+ var chunk7MNJF2OB_cjs = require('./chunk-7MNJF2OB.cjs');
4
+ var chunkAJS4UFQX_cjs = require('./chunk-AJS4UFQX.cjs');
5
+ var chunkWANILJZQ_cjs = require('./chunk-WANILJZQ.cjs');
6
+ var chunk4GINFJO6_cjs = require('./chunk-4GINFJO6.cjs');
7
+ var chunkVF3D6KLQ_cjs = require('./chunk-VF3D6KLQ.cjs');
8
+ var chunkDPCZJLB3_cjs = require('./chunk-DPCZJLB3.cjs');
9
+ var ecdsaValidator = require('@zerodev/ecdsa-validator');
10
+ var sdk = require('@zerodev/sdk');
11
+ var viem = require('viem');
12
+
13
+ var KERNEL_VERSION = sdk.constants.KERNEL_V3_1;
14
+ function zd(client) {
15
+ return client;
16
+ }
17
+ function defaultPublicClient() {
18
+ return viem.createPublicClient({ chain: chunkDPCZJLB3_cjs.pepuMainnet, transport: viem.http(chunkVF3D6KLQ_cjs.resolvePepuEndpoints().rpcUrl) });
19
+ }
20
+ async function toPepuKernelAccount(p) {
21
+ const sudo = await ecdsaValidator.signerToEcdsaValidator(zd(p.publicClient), {
22
+ signer: p.owner,
23
+ entryPoint: chunk7MNJF2OB_cjs.ENTRY_POINT_V07,
24
+ kernelVersion: KERNEL_VERSION
25
+ });
26
+ return sdk.createKernelAccount(zd(p.publicClient), {
27
+ entryPoint: chunk7MNJF2OB_cjs.ENTRY_POINT_V07,
28
+ kernelVersion: KERNEL_VERSION,
29
+ plugins: { sudo, ...p.plugins?.regular ? { regular: p.plugins.regular } : {} },
30
+ ...p.index !== void 0 ? { index: p.index } : {}
31
+ });
32
+ }
33
+ function toEmptyAccount(address) {
34
+ const refuse = async () => {
35
+ throw new Error("read-only account cannot sign");
36
+ };
37
+ return {
38
+ address,
39
+ type: "local",
40
+ source: "custom",
41
+ publicKey: "0x",
42
+ signMessage: refuse,
43
+ signTransaction: refuse,
44
+ signTypedData: refuse
45
+ };
46
+ }
47
+ async function getKernelAddress(publicClient, owner) {
48
+ const account = await toPepuKernelAccount({ publicClient, owner: toEmptyAccount(owner) });
49
+ return account.address;
50
+ }
51
+ function createPepuSponsoredClient(p) {
52
+ const publicClient = p.publicClient ?? defaultPublicClient();
53
+ const paymaster = chunk7MNJF2OB_cjs.createPepuPaymasterClient({
54
+ ...p.paymasterUrl !== void 0 ? { paymasterUrl: p.paymasterUrl } : {},
55
+ ...p.paymasterToken !== void 0 ? { paymasterToken: p.paymasterToken } : {},
56
+ ...p.paymasterContext ? { context: p.paymasterContext } : {}
57
+ });
58
+ return sdk.createKernelAccountClient({
59
+ account: p.account,
60
+ chain: chunkDPCZJLB3_cjs.pepuMainnet,
61
+ client: zd(publicClient),
62
+ bundlerTransport: viem.http(chunk7MNJF2OB_cjs.requireBundlerUrl(p.bundlerUrl)),
63
+ paymaster,
64
+ userOperation: { estimateFeesPerGas: async () => chunk7MNJF2OB_cjs.estimatePepuUserOpFees(publicClient) }
65
+ });
66
+ }
67
+ async function sendSponsored(p) {
68
+ const calls = chunkAJS4UFQX_cjs.normalizeCalls(p.calls);
69
+ try {
70
+ const account = p.client.account;
71
+ if (!account) throw new Error("The Kernel client has no account.");
72
+ const callData = await account.encodeCalls(calls);
73
+ const userOpHash = await p.client.sendUserOperation({ callData });
74
+ const receipt = await p.client.waitForUserOperationReceipt({ hash: userOpHash, timeout: p.timeoutMs ?? 9e4 });
75
+ const transactionHash = receipt.receipt.transactionHash;
76
+ return {
77
+ userOpHash,
78
+ transactionHash,
79
+ success: receipt.success,
80
+ paymaster: receipt.paymaster ?? null,
81
+ actualGasCostWei: receipt.actualGasCost,
82
+ explorerUrl: chunk4GINFJO6_cjs.txUrl(chunkDPCZJLB3_cjs.pepuMainnet, transactionHash)
83
+ };
84
+ } catch (e) {
85
+ throw chunkWANILJZQ_cjs.describeUserOpFailure(e);
86
+ }
87
+ }
88
+
89
+ exports.KERNEL_VERSION = KERNEL_VERSION;
90
+ exports.createPepuSponsoredClient = createPepuSponsoredClient;
91
+ exports.getKernelAddress = getKernelAddress;
92
+ exports.sendSponsored = sendSponsored;
93
+ exports.toPepuKernelAccount = toPepuKernelAccount;
94
+ //# sourceMappingURL=chunk-NVOPDXTA.cjs.map
95
+ //# sourceMappingURL=chunk-NVOPDXTA.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/aa/kernel.ts"],"names":["constants","createPublicClient","pepuMainnet","http","resolvePepuEndpoints","signerToEcdsaValidator","ENTRY_POINT_V07","createKernelAccount","createPepuPaymasterClient","createKernelAccountClient","requireBundlerUrl","estimatePepuUserOpFees","normalizeCalls","txUrl","describeUserOpFailure"],"mappings":"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","file":"chunk-NVOPDXTA.cjs","sourcesContent":["/**\n * @pepu-chain/sdk/aa/kernel: Kernel v3.1 smart account plus sponsored-send\n * helpers for the \"direct\" transport (your own bundler and paymaster URLs).\n * Needs the optional peers `@zerodev/sdk` and `@zerodev/ecdsa-validator`.\n *\n * This is the only module in the SDK (with `session/kernel` and `combo`) that\n * imports ZeroDev. Ported from `templates/sponsored-session-app/lib/kernel.ts`\n * (Kernel v3.1 build, 20% fee headroom because Alto lacks\n * `zd_getUserOperationGasPrice`).\n *\n * Session keys: `toPepuKernelAccount` takes an optional `plugins.regular`\n * validator, which is the plug point WP-B6 (`/session/kernel`, `/combo`) uses\n * to add a permission validator on top of the ECDSA root.\n */\nimport { signerToEcdsaValidator } from \"@zerodev/ecdsa-validator\";\nimport { constants, createKernelAccount, createKernelAccountClient } from \"@zerodev/sdk\";\nimport type { Signer } from \"@zerodev/sdk/types\";\nimport { createPublicClient, http } from \"viem\";\nimport type { Address, Hex, LocalAccount, PublicClient, WalletClient } from \"viem\";\n\nimport { pepuMainnet } from \"../chains.js\";\nimport { resolvePepuEndpoints } from \"../endpoints.js\";\nimport { txUrl } from \"../explorer.js\";\nimport type { PaymasterContext } from \"../erc7677.js\";\nimport { normalizeCalls } from \"./calls.js\";\nimport { ENTRY_POINT_V07, createPepuPaymasterClient, estimatePepuUserOpFees, requireBundlerUrl } from \"./clients.js\";\nimport { describeUserOpFailure } from \"./describe.js\";\nimport type { Call } from \"./types.js\";\n\nexport type { Call } from \"./types.js\";\nexport { encodeKernelExecute } from \"./calls.js\";\n\n/** Kernel v3.1, the version deployed on PEPU mainnet (factory in the contract registry). */\nexport const KERNEL_VERSION = constants.KERNEL_V3_1;\n\ntype ZeroDevClient = Parameters<typeof createKernelAccount>[0];\ntype KernelAccountParams = Parameters<typeof createKernelAccount>[1];\n\n/**\n * The ZeroDev packages resolve their own copy of viem as a peer. In a monorepo\n * with several viem installs two identical `PublicClient` types are nominally\n * different; this is a type-level bridge only (same object at runtime).\n */\nfunction zd(client: PublicClient): ZeroDevClient {\n return client as unknown as ZeroDevClient;\n}\n\n/** The Kernel account type this module builds. */\nexport type KernelSmartAccount = Awaited<ReturnType<typeof createKernelAccount>>;\n/** The sponsored client type {@link createPepuSponsoredClient} returns. */\nexport type KernelAccountClient = ReturnType<typeof createKernelAccountClient>;\n\n/** Anything that can sign for the Kernel owner. */\nexport type KernelOwner = LocalAccount | Signer | WalletClient;\n\nfunction defaultPublicClient(): PublicClient {\n return createPublicClient({ chain: pepuMainnet, transport: http(resolvePepuEndpoints().rpcUrl) }) as PublicClient;\n}\n\n/**\n * Build a Kernel v3.1 smart account owned by `owner` (ECDSA root validator).\n * The address depends only on the owner and `index`, never on a session.\n * Pass `plugins.regular` to add a permission (session-key) validator on top\n * of the root; that is how `@pepu-chain/sdk/session/kernel` builds on this.\n *\n * @example\n * const account = await toPepuKernelAccount({ publicClient, owner: privateKeyToAccount(key) });\n */\nexport async function toPepuKernelAccount(p: {\n publicClient: PublicClient;\n owner: KernelOwner;\n index?: bigint;\n /**\n * `regular` is a ZeroDev validator plugin, for example the permission\n * validator from `@zerodev/permissions` (see `@pepu-chain/sdk/session/kernel`).\n * Typed as `object` so this entry does not need `@zerodev/permissions` types.\n */\n plugins?: { regular?: object };\n}): Promise<KernelSmartAccount> {\n const sudo = await signerToEcdsaValidator(zd(p.publicClient), {\n signer: p.owner as Signer,\n entryPoint: ENTRY_POINT_V07,\n kernelVersion: KERNEL_VERSION,\n });\n return createKernelAccount(zd(p.publicClient), {\n entryPoint: ENTRY_POINT_V07,\n kernelVersion: KERNEL_VERSION,\n plugins: { sudo, ...(p.plugins?.regular ? { regular: p.plugins.regular } : {}) },\n ...(p.index !== undefined ? { index: p.index } : {}),\n } as KernelAccountParams);\n}\n\nfunction toEmptyAccount(address: Address): LocalAccount {\n const refuse = async (): Promise<never> => {\n throw new Error(\"read-only account cannot sign\");\n };\n return {\n address,\n type: \"local\",\n source: \"custom\",\n publicKey: \"0x\" as Hex,\n signMessage: refuse,\n signTransaction: refuse,\n signTypedData: refuse,\n } as unknown as LocalAccount;\n}\n\n/**\n * The counterfactual Kernel address for an owner, with no signature needed.\n * Lifted from `templates/sponsored-session-app/lib/kernel.ts`.\n *\n * @example\n * const smartAccount = await getKernelAddress(publicClient, ownerAddress);\n */\nexport async function getKernelAddress(publicClient: PublicClient, owner: Address): Promise<Address> {\n const account = await toPepuKernelAccount({ publicClient, owner: toEmptyAccount(owner) });\n return account.address;\n}\n\n/**\n * A Kernel client that sends through YOUR bundler and has gas paid by YOUR\n * paymaster (ERC-7677). Fees come from the chain with 20% headroom.\n *\n * @example\n * const client = createPepuSponsoredClient({ account, paymasterContext: { privyAccessToken } });\n */\nexport function createPepuSponsoredClient(p: {\n account: KernelSmartAccount;\n bundlerUrl?: string;\n paymasterUrl?: string;\n /** Project client token; builds the ERC-7677 URL against the paymaster base when no URL is configured. */\n paymasterToken?: string;\n paymasterContext?: PaymasterContext;\n publicClient?: PublicClient;\n}): KernelAccountClient {\n const publicClient = p.publicClient ?? defaultPublicClient();\n const paymaster = createPepuPaymasterClient({\n ...(p.paymasterUrl !== undefined ? { paymasterUrl: p.paymasterUrl } : {}),\n ...(p.paymasterToken !== undefined ? { paymasterToken: p.paymasterToken } : {}),\n ...(p.paymasterContext ? { context: p.paymasterContext } : {}),\n });\n return createKernelAccountClient({\n account: p.account,\n chain: pepuMainnet,\n client: zd(publicClient),\n bundlerTransport: http(requireBundlerUrl(p.bundlerUrl)),\n paymaster,\n userOperation: { estimateFeesPerGas: async () => estimatePepuUserOpFees(publicClient) },\n } as unknown as Parameters<typeof createKernelAccountClient>[0]);\n}\n\n/** Result of {@link sendSponsored}. */\nexport interface SendSponsoredResult {\n userOpHash: Hex;\n transactionHash: Hex;\n success: boolean;\n paymaster: Address | null;\n actualGasCostWei: bigint;\n explorerUrl: string;\n}\n\n/**\n * Encode `calls`, send one UserOperation, wait for its receipt, and report\n * who paid. Failures are mapped through `describeUserOpFailure` (AAxx and\n * paymaster reasons become typed PepuErrors). Flow ported from\n * `sendSessionTap` in the sponsored-session-app template.\n *\n * @example\n * const r = await sendSponsored({ client, calls: [{ to, abi, functionName: \"tap\" }] });\n * console.log(r.paymaster, r.explorerUrl);\n */\nexport async function sendSponsored(p: {\n client: KernelAccountClient;\n calls: Call[];\n timeoutMs?: number;\n}): Promise<SendSponsoredResult> {\n const calls = normalizeCalls(p.calls);\n try {\n const account = p.client.account;\n if (!account) throw new Error(\"The Kernel client has no account.\");\n const callData = await account.encodeCalls(calls);\n const userOpHash = await p.client.sendUserOperation({ callData });\n const receipt = await p.client.waitForUserOperationReceipt({ hash: userOpHash, timeout: p.timeoutMs ?? 90_000 });\n const transactionHash = receipt.receipt.transactionHash;\n return {\n userOpHash,\n transactionHash,\n success: receipt.success,\n paymaster: receipt.paymaster ?? null,\n actualGasCostWei: receipt.actualGasCost,\n explorerUrl: txUrl(pepuMainnet, transactionHash),\n };\n } catch (e) {\n throw describeUserOpFailure(e);\n }\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import { http, createPublicClient } from 'viem';
2
+
3
+ // src/client.ts
4
+ function getPublicClient(chain, options) {
5
+ const transport = options?.transport ?? http();
6
+ return createPublicClient({ chain, transport });
7
+ }
8
+
9
+ export { getPublicClient };
10
+ //# sourceMappingURL=chunk-OH3QMAIB.js.map
11
+ //# sourceMappingURL=chunk-OH3QMAIB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";;;AAWO,SAAS,eAAA,CACd,OACA,OAAA,EACoC;AAIpC,EAAA,MAAM,SAAA,GAAY,OAAA,EAAS,SAAA,IAAa,IAAA,EAAK;AAC7C,EAAA,OAAO,kBAAA,CAAmB,EAAE,KAAA,EAAO,SAAA,EAAW,CAAA;AAChD","file":"chunk-OH3QMAIB.js","sourcesContent":["import { type PublicClient, type Transport, createPublicClient, http } from \"viem\";\n\nimport type { PepuChain } from \"./chains.js\";\n\n/**\n * Create a viem `PublicClient` for a Pepe Unchained V2 chain, defaulting\n * its transport to the chain's first `rpcUrls.default.http` entry.\n *\n * Pass `transport` to use a different RPC endpoint (e.g. an authenticated\n * provider URL) while keeping the rest of the chain definition.\n */\nexport function getPublicClient(\n chain: PepuChain,\n options?: { transport?: Transport },\n): PublicClient<Transport, PepuChain> {\n // `http()` with no URL falls back to `chain.rpcUrls.default.http[0]`\n // internally (see viem's `http` transport), so the chain definition\n // stays the single source of truth for the default RPC endpoint.\n const transport = options?.transport ?? http();\n return createPublicClient({ chain, transport });\n}\n"]}
@@ -0,0 +1,110 @@
1
+ 'use strict';
2
+
3
+ var chunkNVOPDXTA_cjs = require('./chunk-NVOPDXTA.cjs');
4
+ var chunk7MNJF2OB_cjs = require('./chunk-7MNJF2OB.cjs');
5
+ var chunkJ3O2ZGG3_cjs = require('./chunk-J3O2ZGG3.cjs');
6
+ var permissions = require('@zerodev/permissions');
7
+ var policies = require('@zerodev/permissions/policies');
8
+ var signers = require('@zerodev/permissions/signers');
9
+ var accounts = require('viem/accounts');
10
+
11
+ // src/session/store.ts
12
+ function createMemoryStore() {
13
+ const records = /* @__PURE__ */ new Map();
14
+ const locks = /* @__PURE__ */ new Set();
15
+ return {
16
+ get: (userId) => records.get(userId),
17
+ set: (record) => {
18
+ records.set(record.userId, record);
19
+ },
20
+ delete: (userId) => {
21
+ records.delete(userId);
22
+ },
23
+ tryLock: (userId) => {
24
+ if (locks.has(userId)) return false;
25
+ locks.add(userId);
26
+ return true;
27
+ },
28
+ unlock: (userId) => {
29
+ locks.delete(userId);
30
+ }
31
+ };
32
+ }
33
+ function isLive(record, nowSeconds) {
34
+ return record.approval !== null && nowSeconds < record.validUntil;
35
+ }
36
+
37
+ // src/session/kernel.ts
38
+ var CALL_POLICY_V0_0_4_ADDRESS = "0x9a52283276A0ec8740DF50bF01B28A80D880eaf2";
39
+ var TIMESTAMP_POLICY_ADDRESS = "0xB9f8f524bE6EcD8C945b1b87f9ae5C192FdCE20F";
40
+ var SESSION_GAS_RESERVATION_PEPU = { firstOperation: 20.5, laterOperation: 6.9 };
41
+ function zd(client) {
42
+ return client;
43
+ }
44
+ function buildKernelSessionPolicies(p) {
45
+ chunkJ3O2ZGG3_cjs.assertCalls(p.calls);
46
+ return [
47
+ policies.toCallPolicy({
48
+ policyVersion: policies.CallPolicyVersion.V0_0_4,
49
+ permissions: p.calls.map((c) => ({
50
+ target: c.target,
51
+ valueLimit: c.valueLimit ?? 0n,
52
+ abi: [chunkJ3O2ZGG3_cjs.findFunction(c)],
53
+ functionName: c.functionName
54
+ }))
55
+ }),
56
+ policies.toTimestampPolicy({ validAfter: p.validAfter ?? 0, validUntil: p.validUntil })
57
+ ];
58
+ }
59
+ function generateSessionKey() {
60
+ const privateKey = accounts.generatePrivateKey();
61
+ return { privateKey, address: accounts.privateKeyToAccount(privateKey).address };
62
+ }
63
+ function permissionFor(publicClient, sessionKeyAddress, policies) {
64
+ return permissions.toPermissionValidator(zd(publicClient), {
65
+ entryPoint: chunk7MNJF2OB_cjs.ENTRY_POINT_V07,
66
+ kernelVersion: chunkNVOPDXTA_cjs.KERNEL_VERSION,
67
+ signer: signers.toEmptyECDSASigner(sessionKeyAddress),
68
+ policies
69
+ });
70
+ }
71
+ async function expectedPermissionId(p) {
72
+ const permission = await permissionFor(p.publicClient, p.sessionKeyAddress, p.policies);
73
+ const { permissionId } = permission.getPluginSerializationParams();
74
+ if (!permissionId) throw new Error("Could not derive the permission id.");
75
+ return permissionId;
76
+ }
77
+ async function approveKernelSession(p) {
78
+ const regular = await permissionFor(p.publicClient, p.sessionKeyAddress, p.policies);
79
+ const account = await chunkNVOPDXTA_cjs.toPepuKernelAccount({
80
+ publicClient: p.publicClient,
81
+ owner: p.owner,
82
+ plugins: { regular }
83
+ });
84
+ const approval = await permissions.serializePermissionAccount(account);
85
+ return { approval, kernelAddress: account.address };
86
+ }
87
+ async function loadKernelSessionAccount(p) {
88
+ const sessionSigner = await signers.toECDSASigner({ signer: accounts.privateKeyToAccount(p.sessionPrivateKey) });
89
+ const account = await permissions.deserializePermissionAccount(
90
+ zd(p.publicClient),
91
+ chunk7MNJF2OB_cjs.ENTRY_POINT_V07,
92
+ chunkNVOPDXTA_cjs.KERNEL_VERSION,
93
+ p.approval,
94
+ sessionSigner
95
+ );
96
+ return account;
97
+ }
98
+
99
+ exports.CALL_POLICY_V0_0_4_ADDRESS = CALL_POLICY_V0_0_4_ADDRESS;
100
+ exports.SESSION_GAS_RESERVATION_PEPU = SESSION_GAS_RESERVATION_PEPU;
101
+ exports.TIMESTAMP_POLICY_ADDRESS = TIMESTAMP_POLICY_ADDRESS;
102
+ exports.approveKernelSession = approveKernelSession;
103
+ exports.buildKernelSessionPolicies = buildKernelSessionPolicies;
104
+ exports.createMemoryStore = createMemoryStore;
105
+ exports.expectedPermissionId = expectedPermissionId;
106
+ exports.generateSessionKey = generateSessionKey;
107
+ exports.isLive = isLive;
108
+ exports.loadKernelSessionAccount = loadKernelSessionAccount;
109
+ //# sourceMappingURL=chunk-PHM3ZORG.cjs.map
110
+ //# sourceMappingURL=chunk-PHM3ZORG.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/session/store.ts","../src/session/kernel.ts"],"names":["assertCalls","toCallPolicy","CallPolicyVersion","findFunction","toTimestampPolicy","generatePrivateKey","privateKeyToAccount","toPermissionValidator","ENTRY_POINT_V07","KERNEL_VERSION","toEmptyECDSASigner","toPepuKernelAccount","serializePermissionAccount","toECDSASigner","deserializePermissionAccount"],"mappings":"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","file":"chunk-PHM3ZORG.cjs","sourcesContent":["import type { Address, Hex } from \"viem\";\n\n/**\n * Server-side session records for the Kernel (on-chain) session flow, keyed by\n * Privy user id. Ported from templates/sponsored-session-app/lib/session-store.ts.\n *\n * WHAT IS STORED: the session private key (a hot key whose power is limited\n * ON-CHAIN by the call and timestamp policies until `validUntil`) and the\n * public approval. The owner's key never reaches the server.\n *\n * PRODUCTION: {@link createMemoryStore} is DEV-GRADE. It is lost on every\n * restart (the user simply starts a new session) and is not shared between\n * serverless instances. A production deployment must implement\n * {@link SessionStore} on a persistent database or KV AND keep\n * `sessionPrivateKey` encrypted at rest (KMS or an envelope key). Nothing else\n * in the SDK changes.\n */\nexport interface SessionRecord {\n userId: string;\n ownerAddress: Address;\n kernelAddress: Address;\n /** The session key's private half. Encrypt it at rest in any persistent store. */\n sessionPrivateKey: Hex;\n sessionKeyAddress: Address;\n permissionId: string;\n /** Unix seconds. The on-chain permission is invalid at and after this time. */\n validUntil: number;\n /** Present once the owner has signed the grant. */\n approval: string | null;\n /** Number of successful sponsored actions in this session. */\n actions: number;\n}\n\ntype MaybePromise<T> = T | Promise<T>;\n\n/**\n * Pluggable storage for {@link SessionRecord}s. Every method may be sync or\n * async. `tryLock` must be atomic per user: it returns `false` when an action\n * is already running for that user (a multi-instance deployment needs a\n * distributed lock, for example a Redis `SET NX PX`).\n */\nexport interface SessionStore {\n get(userId: string): MaybePromise<SessionRecord | undefined>;\n set(record: SessionRecord): MaybePromise<void>;\n delete(userId: string): MaybePromise<void>;\n tryLock(userId: string): MaybePromise<boolean>;\n unlock(userId: string): MaybePromise<void>;\n}\n\n/**\n * An in-memory {@link SessionStore} for development and tests. DEV-GRADE: not\n * persistent, not shared across instances, and the session key is held in\n * plaintext in process memory. Production needs an encrypted persistent store.\n *\n * @example\n * const store = createMemoryStore();\n */\nexport function createMemoryStore(): SessionStore {\n const records = new Map<string, SessionRecord>();\n const locks = new Set<string>();\n return {\n get: (userId) => records.get(userId),\n set: (record) => {\n records.set(record.userId, record);\n },\n delete: (userId) => {\n records.delete(userId);\n },\n tryLock: (userId) => {\n if (locks.has(userId)) return false;\n locks.add(userId);\n return true;\n },\n unlock: (userId) => {\n locks.delete(userId);\n },\n };\n}\n\n/**\n * True while the on-chain permission is still valid: approved and before expiry.\n *\n * @example\n * isLive(record, Math.floor(Date.now() / 1000));\n */\nexport function isLive(record: SessionRecord, nowSeconds: number): boolean {\n return record.approval !== null && nowSeconds < record.validUntil;\n}\n","import { deserializePermissionAccount, serializePermissionAccount, toPermissionValidator } from \"@zerodev/permissions\";\nimport type { Policy } from \"@zerodev/permissions\";\nimport { CallPolicyVersion, toCallPolicy, toTimestampPolicy } from \"@zerodev/permissions/policies\";\nimport { toECDSASigner, toEmptyECDSASigner } from \"@zerodev/permissions/signers\";\nimport type { createKernelAccount } from \"@zerodev/sdk\";\nimport type { Abi, Address, Hex, PublicClient } from \"viem\";\nimport { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\";\n\nimport { ENTRY_POINT_V07 } from \"../aa/clients.js\";\nimport { KERNEL_VERSION, toPepuKernelAccount } from \"../aa/kernel.js\";\nimport type { KernelOwner, KernelSmartAccount } from \"../aa/kernel.js\";\nimport { assertCalls, findFunction } from \"./scope.js\";\nimport type { KernelSessionCall } from \"./scope.js\";\n\nexport { KERNEL_VERSION, getKernelAddress } from \"../aa/kernel.js\";\nexport type { KernelOwner, KernelSmartAccount } from \"../aa/kernel.js\";\nexport { createMemoryStore, isLive } from \"./store.js\";\nexport type { SessionRecord, SessionStore } from \"./store.js\";\nexport { checkApproval, describeKernelSessionScope, isCallInScope, parseApproval } from \"./scope.js\";\nexport type { ApprovalCheck, KernelSessionCall, KernelSessionScope, ParsedApproval } from \"./scope.js\";\n\n/**\n * `@pepu-chain/sdk/session/kernel`: on-chain session keys with ZeroDev Kernel\n * permissions. Extracted from templates/sponsored-session-app/lib/{kernel,\n * session-policy,approval}.ts and built on `toPepuKernelAccount`\n * (`plugins.regular`).\n *\n * The scope is enforced ON-CHAIN by ZeroDev's policy contracts, which the\n * user's Kernel account calls during UserOperation validation:\n *\n * - Call policy v0.0.4: only the listed targets and function selectors, with a\n * native value no larger than `valueLimit` (default 0).\n * - Timestamp policy: the permission is invalid outside `validAfter`..`validUntil`.\n *\n * A UserOperation outside this scope is rejected by the EntryPoint itself, no\n * matter who relays it or what the app backend does.\n *\n * Deployed on PEPU mainnet (eth_getCode verified 2026-10-02): Kernel v3.1\n * factory 0xaac5D4240AF87249B3f71BC8E4A2cae074A3E419, ECDSA validator\n * 0x845ADb2C711129d4f3966735eD98a9F09fC4cE57, ECDSA signer module\n * 0x6A6F069E2a08c2468e7724Ab3250CdBFBA14D4FF, call policy v0.0.4 and the\n * timestamp policy below. Call policy v0.0.5 is NOT deployed on PEPU, so the\n * version is pinned.\n *\n * Optional peers: `@zerodev/sdk`, `@zerodev/permissions`, `@zerodev/ecdsa-validator`.\n */\n\n/** Call policy v0.0.4. Pinned: v0.0.5 is not deployed on PEPU mainnet. */\nexport const CALL_POLICY_V0_0_4_ADDRESS: Address = \"0x9a52283276A0ec8740DF50bF01B28A80D880eaf2\";\n/** ZeroDev timestamp policy on PEPU mainnet. */\nexport const TIMESTAMP_POLICY_ADDRESS: Address = \"0xB9f8f524bE6EcD8C945b1b87f9ae5C192FdCE20F\";\n\n/**\n * Worst-case gas the paymaster policy service RESERVES per sponsored operation,\n * measured on PEPU mainnet with the sponsored-session-app template: the first\n * operation of a session (account deploy plus enabling the permission) about\n * 20.5 PEPU, later operations about 6.9 PEPU. The real first-session cost was\n * about 12.8 PEPU for two operations. Size per-user hourly and daily spend\n * caps above these, or users hit `trailing-hour spend ... would exceed cap`\n * after their first action.\n */\nexport const SESSION_GAS_RESERVATION_PEPU = { firstOperation: 20.5, laterOperation: 6.9 } as const;\n\ntype ZeroDevClient = Parameters<typeof createKernelAccount>[0];\n\n/** Type-level bridge for ZeroDev's own viem copy (same object at runtime). */\nfunction zd(client: PublicClient): ZeroDevClient {\n return client as unknown as ZeroDevClient;\n}\n\n/**\n * The on-chain policies for one session: call policy v0.0.4 plus the timestamp\n * policy. Pure and deterministic given its input. Only the named function\n * fragments go into the policy, which keeps the grant small.\n *\n * @example\n * const policies = buildKernelSessionPolicies({\n * calls: [{ target: tapScore, abi: tapScoreAbi, functionName: \"tap\" }],\n * validUntil: Math.floor(Date.now() / 1000) + 900,\n * });\n */\nexport function buildKernelSessionPolicies(p: {\n calls: readonly KernelSessionCall[];\n validUntil: number;\n validAfter?: number;\n}): Policy[] {\n assertCalls(p.calls);\n return [\n toCallPolicy({\n policyVersion: CallPolicyVersion.V0_0_4,\n permissions: p.calls.map((c) => ({\n target: c.target,\n valueLimit: c.valueLimit ?? 0n,\n abi: [findFunction(c)] as Abi,\n functionName: c.functionName,\n })),\n } as Parameters<typeof toCallPolicy>[0]),\n toTimestampPolicy({ validAfter: p.validAfter ?? 0, validUntil: p.validUntil }),\n ];\n}\n\n/**\n * A fresh random session key. SERVER ONLY: the private key must never reach\n * the browser. Only the address is sent to the owner for approval.\n *\n * @example\n * const { privateKey, address } = generateSessionKey();\n */\nexport function generateSessionKey(): { privateKey: Hex; address: Address } {\n const privateKey = generatePrivateKey();\n return { privateKey, address: privateKeyToAccount(privateKey).address };\n}\n\nfunction permissionFor(publicClient: PublicClient, sessionKeyAddress: Address, policies: Policy[]) {\n return toPermissionValidator(zd(publicClient), {\n entryPoint: ENTRY_POINT_V07,\n kernelVersion: KERNEL_VERSION,\n signer: toEmptyECDSASigner(sessionKeyAddress),\n policies,\n });\n}\n\n/**\n * The permission id the chain derives for this session key plus these\n * policies. The server compares it with a browser-supplied approval.\n *\n * @example\n * const permissionId = await expectedPermissionId({ publicClient, sessionKeyAddress, policies });\n */\nexport async function expectedPermissionId(p: {\n publicClient: PublicClient;\n sessionKeyAddress: Address;\n policies: Policy[];\n}): Promise<string> {\n const permission = await permissionFor(p.publicClient, p.sessionKeyAddress, p.policies);\n const { permissionId } = permission.getPluginSerializationParams();\n if (!permissionId) throw new Error(\"Could not derive the permission id.\");\n return permissionId;\n}\n\n/**\n * In the user's browser: the owner (the Privy embedded wallet, the only thing\n * that can authorize a session) signs ONE EIP-712 message that enables a\n * permission validator on their Kernel account. That signature is the whole\n * grant. It names the session key's public address (never its private key)\n * and the policies. The returned `approval` holds no secret: it is the enable\n * signature plus the policy parameters, useless without the session key.\n *\n * @example\n * const { approval, kernelAddress } = await approveKernelSession({\n * publicClient, owner: walletClient, sessionKeyAddress, policies,\n * });\n */\nexport async function approveKernelSession(p: {\n publicClient: PublicClient;\n owner: KernelOwner;\n sessionKeyAddress: Address;\n policies: Policy[];\n}): Promise<{ approval: string; kernelAddress: Address }> {\n const regular = await permissionFor(p.publicClient, p.sessionKeyAddress, p.policies);\n const account = await toPepuKernelAccount({\n publicClient: p.publicClient,\n owner: p.owner,\n plugins: { regular },\n });\n const approval = await serializePermissionAccount(account as never);\n return { approval, kernelAddress: account.address };\n}\n\n/**\n * On the server: rebuild the session's Kernel account from the approval and\n * the server-held session key (an ECDSA signer for that key). No owner\n * signature is involved. Pass the result to `createPepuSponsoredClient`.\n *\n * @example\n * const account = await loadKernelSessionAccount({ publicClient, approval, sessionPrivateKey });\n */\nexport async function loadKernelSessionAccount(p: {\n publicClient: PublicClient;\n approval: string;\n sessionPrivateKey: Hex;\n}): Promise<KernelSmartAccount> {\n const sessionSigner = await toECDSASigner({ signer: privateKeyToAccount(p.sessionPrivateKey) });\n const account = await deserializePermissionAccount(\n zd(p.publicClient),\n ENTRY_POINT_V07,\n KERNEL_VERSION,\n p.approval,\n sessionSigner,\n );\n return account as unknown as KernelSmartAccount;\n}\n"]}
@@ -0,0 +1,209 @@
1
+ 'use strict';
2
+
3
+ var chunkDH6BFNVJ_cjs = require('./chunk-DH6BFNVJ.cjs');
4
+ var chunkYQL7NISX_cjs = require('./chunk-YQL7NISX.cjs');
5
+ var reactAuth = require('@privy-io/react-auth');
6
+ var react = require('react');
7
+
8
+ var KNOWN_CODES = new Set(chunkYQL7NISX_cjs.PEPU_ERROR_CATALOG.map((e) => e.code));
9
+ async function errorFromResponse(res) {
10
+ const body = await res.json().catch(() => null);
11
+ const e = body?.error;
12
+ const message = typeof e === "string" ? e : e?.message;
13
+ const rawCode = typeof e === "object" ? e?.code : void 0;
14
+ const code = res.status === 409 && !rawCode ? "SESSION_NONE" : rawCode && KNOWN_CODES.has(rawCode) ? rawCode : res.status === 401 ? "AUTH_INVALID_TOKEN" : "UNKNOWN";
15
+ const Cls = code === "SESSION_NONE" ? chunkYQL7NISX_cjs.PepuSessionError : code === "AUTH_INVALID_TOKEN" ? chunkYQL7NISX_cjs.PepuAuthError : chunkYQL7NISX_cjs.PepuError;
16
+ return new Cls(code, message ?? `Request failed (${res.status}).`, {
17
+ status: res.status,
18
+ ...typeof e === "object" && e?.hint ? { hint: e.hint } : {}
19
+ });
20
+ }
21
+ function deriveSessionState(p) {
22
+ if (!p.delegated) return { state: "none" };
23
+ if (p.expiresAt === void 0) return { state: "active" };
24
+ const secondsLeft = p.expiresAt - p.nowSeconds;
25
+ return secondsLeft <= 0 ? { state: "expired", secondsLeft: 0 } : { state: "active", secondsLeft };
26
+ }
27
+ var CHANGE_EVENT = "pepu-session-change";
28
+ var storageKey = (address) => `pepu:session:${address.toLowerCase()}`;
29
+ function readStored(address) {
30
+ if (!address) return void 0;
31
+ try {
32
+ const raw = globalThis.localStorage?.getItem(storageKey(address));
33
+ return raw ? JSON.parse(raw) : void 0;
34
+ } catch {
35
+ return void 0;
36
+ }
37
+ }
38
+ function writeStored(address, value) {
39
+ try {
40
+ if (value) globalThis.localStorage?.setItem(storageKey(address), JSON.stringify(value));
41
+ else globalThis.localStorage?.removeItem(storageKey(address));
42
+ } catch {
43
+ }
44
+ globalThis.dispatchEvent?.(new Event(CHANGE_EVENT));
45
+ }
46
+ function useAuthFetch(o) {
47
+ const { user } = reactAuth.usePrivy();
48
+ const pepuAuthFetch = chunkDH6BFNVJ_cjs.usePepuAuthFetch();
49
+ const custom = o.authFetch;
50
+ const authFetch = react.useCallback(
51
+ (url, init) => custom ? custom(url, init) : pepuAuthFetch(url, init),
52
+ [custom, pepuAuthFetch]
53
+ );
54
+ return { authFetch, address: o.address ?? user?.wallet?.address };
55
+ }
56
+ function useSessionGrant(o = {}) {
57
+ const { authFetch, address } = useAuthFetch(o);
58
+ const { addSigners } = reactAuth.useSigners();
59
+ const [status, setStatus] = react.useState("idle");
60
+ const [error, setError] = react.useState();
61
+ const endpoint = o.grantEndpoint ?? "/api/session/grant";
62
+ const grant = react.useCallback(async () => {
63
+ setError(void 0);
64
+ try {
65
+ if (!address) throw new chunkYQL7NISX_cjs.PepuAuthError("WALLET_NOT_PROVISIONED", "No embedded wallet address yet.");
66
+ setStatus("creating-policy");
67
+ const res = await authFetch(endpoint, { method: "POST" });
68
+ if (!res.ok) throw await errorFromResponse(res);
69
+ const body = await res.json();
70
+ if (!body.alreadyGranted) {
71
+ setStatus("awaiting-consent");
72
+ try {
73
+ await addSigners({ address, signers: [{ signerId: body.signerId, policyIds: [body.policyId] }] });
74
+ } catch (caught) {
75
+ const msg = caught instanceof Error ? caught.message : "";
76
+ if (!/duplicate signer/i.test(msg)) throw caught;
77
+ }
78
+ writeStored(address, { expiresAt: body.expiresAt, policyId: body.policyId });
79
+ } else {
80
+ globalThis.dispatchEvent?.(new Event(CHANGE_EVENT));
81
+ }
82
+ setStatus("granted");
83
+ } catch (e) {
84
+ setError(chunkYQL7NISX_cjs.toPepuError(e, { op: "session grant" }));
85
+ setStatus("error");
86
+ }
87
+ }, [address, authFetch, endpoint, addSigners]);
88
+ return { grant, status, ...error ? { error } : {} };
89
+ }
90
+ function useSessionStatus(o = {}) {
91
+ const { authFetch, address } = useAuthFetch(o);
92
+ const endpoint = o.statusEndpoint ?? "/api/session/status";
93
+ const [delegated, setDelegated] = react.useState(false);
94
+ const [loading, setLoading] = react.useState(true);
95
+ const [serverExpiresAt, setServerExpiresAt] = react.useState();
96
+ const [now, setNow] = react.useState(() => Math.floor(Date.now() / 1e3));
97
+ const [tick, setTick] = react.useState(0);
98
+ const refetch = react.useCallback(() => setTick((t) => t + 1), []);
99
+ react.useEffect(() => {
100
+ let cancelled = false;
101
+ void (async () => {
102
+ try {
103
+ const res = await authFetch(endpoint);
104
+ if (!res.ok) return;
105
+ const body = await res.json();
106
+ if (cancelled) return;
107
+ setDelegated(Boolean(body.delegated));
108
+ setServerExpiresAt(body.expiresAt);
109
+ } catch {
110
+ } finally {
111
+ if (!cancelled) setLoading(false);
112
+ }
113
+ })();
114
+ return () => {
115
+ cancelled = true;
116
+ };
117
+ }, [authFetch, endpoint, tick]);
118
+ react.useEffect(() => {
119
+ const onChange = () => setTick((t) => t + 1);
120
+ globalThis.addEventListener?.(CHANGE_EVENT, onChange);
121
+ return () => globalThis.removeEventListener?.(CHANGE_EVENT, onChange);
122
+ }, []);
123
+ react.useEffect(() => {
124
+ const id = setInterval(() => setNow(Math.floor(Date.now() / 1e3)), 1e3);
125
+ return () => clearInterval(id);
126
+ }, []);
127
+ react.useEffect(() => {
128
+ if (!o.pollMs) return;
129
+ const id = setInterval(() => setTick((t) => t + 1), o.pollMs);
130
+ return () => clearInterval(id);
131
+ }, [o.pollMs]);
132
+ const expiresAt = serverExpiresAt ?? readStored(address)?.expiresAt;
133
+ const derived = deriveSessionState({ delegated, expiresAt, nowSeconds: now });
134
+ return {
135
+ state: derived.state,
136
+ loading,
137
+ ...expiresAt !== void 0 ? { expiresAt } : {},
138
+ ...derived.secondsLeft !== void 0 ? { secondsLeft: derived.secondsLeft } : {},
139
+ refetch
140
+ };
141
+ }
142
+ function useSessionRevoke(o = {}) {
143
+ const { authFetch, address } = useAuthFetch(o);
144
+ const { removeSigners } = reactAuth.useSigners();
145
+ const [status, setStatus] = react.useState("idle");
146
+ const [error, setError] = react.useState();
147
+ const endpoint = o.revokeEndpoint ?? "/api/session/revoke";
148
+ const revoke = react.useCallback(async () => {
149
+ setError(void 0);
150
+ try {
151
+ if (!address) throw new chunkYQL7NISX_cjs.PepuAuthError("WALLET_NOT_PROVISIONED", "No embedded wallet address yet.");
152
+ setStatus("revoking");
153
+ const stored = readStored(address);
154
+ await removeSigners({ address });
155
+ try {
156
+ await authFetch(endpoint, {
157
+ method: "POST",
158
+ headers: { "content-type": "application/json" },
159
+ body: JSON.stringify({ policyId: stored?.policyId })
160
+ });
161
+ } catch {
162
+ }
163
+ writeStored(address, null);
164
+ setStatus("revoked");
165
+ } catch (e) {
166
+ setError(chunkYQL7NISX_cjs.toPepuError(e, { op: "session revoke" }));
167
+ setStatus("error");
168
+ }
169
+ }, [address, authFetch, endpoint, removeSigners]);
170
+ return { revoke, status, ...error ? { error } : {} };
171
+ }
172
+ function useSessionAct(o) {
173
+ const { authFetch } = useAuthFetch(o);
174
+ const [status, setStatus] = react.useState("idle");
175
+ const [error, setError] = react.useState();
176
+ const act = react.useCallback(
177
+ async (input) => {
178
+ setStatus("pending");
179
+ setError(void 0);
180
+ try {
181
+ const res = await authFetch(o.endpoint, {
182
+ method: "POST",
183
+ headers: { "content-type": "application/json" },
184
+ body: JSON.stringify(input ?? {})
185
+ });
186
+ if (!res.ok) throw await errorFromResponse(res);
187
+ const out = await res.json();
188
+ setStatus("success");
189
+ return out;
190
+ } catch (e) {
191
+ const err = chunkYQL7NISX_cjs.toPepuError(e, { op: "session action" });
192
+ setError(err);
193
+ setStatus("error");
194
+ throw err;
195
+ }
196
+ },
197
+ [authFetch, o.endpoint]
198
+ );
199
+ return { act, status, ...error ? { error } : {} };
200
+ }
201
+
202
+ exports.deriveSessionState = deriveSessionState;
203
+ exports.errorFromResponse = errorFromResponse;
204
+ exports.useSessionAct = useSessionAct;
205
+ exports.useSessionGrant = useSessionGrant;
206
+ exports.useSessionRevoke = useSessionRevoke;
207
+ exports.useSessionStatus = useSessionStatus;
208
+ //# sourceMappingURL=chunk-R5PXQNO3.cjs.map
209
+ //# sourceMappingURL=chunk-R5PXQNO3.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/session/react.ts"],"names":["PEPU_ERROR_CATALOG","PepuSessionError","PepuAuthError","PepuError","usePrivy","usePepuAuthFetch","useCallback","useSigners","useState","toPepuError","useEffect"],"mappings":"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","file":"chunk-R5PXQNO3.cjs","sourcesContent":["import { usePrivy, useSigners } from \"@privy-io/react-auth\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { PEPU_ERROR_CATALOG, PepuAuthError, PepuError, PepuSessionError, toPepuError } from \"../errors.js\";\nimport type { PepuErrorCode } from \"../errors.js\";\nimport { usePepuAuthFetch } from \"../privy/react.js\";\n\n/**\n * Client hooks for the Privy-mode session. Ported from\n * templates/game-app/components/session-consent-screen.tsx and\n * session-status-card.tsx. Auth defaults to `usePepuAuthFetch` from\n * `@pepu-chain/sdk/privy/react` (Privy bearer token); pass `authFetch` to use\n * your own.\n */\n\n/** A fetch that adds the user's Privy bearer token. */\nexport type AuthFetch = (url: string, init?: RequestInit) => Promise<Response>;\n\ninterface BaseOptions {\n /** Custom authenticated fetch. Default: `usePepuAuthFetch()` (Privy bearer token). */\n authFetch?: AuthFetch;\n /** The embedded wallet address. Default: the Privy user's wallet. */\n address?: string;\n}\n\nconst KNOWN_CODES = new Set<string>(PEPU_ERROR_CATALOG.map((e) => e.code));\n\n/**\n * Turn a non-OK route response into a typed error. Reads the\n * `{ error: { code, message, hint } }` body the SDK route factories return.\n * Only a 409 means \"no session\" (`SESSION_NONE`).\n *\n * @example\n * if (!res.ok) throw await errorFromResponse(res);\n */\nexport async function errorFromResponse(res: Response): Promise<PepuError> {\n const body = (await res.json().catch(() => null)) as {\n error?: { code?: string; message?: string; hint?: string } | string;\n } | null;\n const e = body?.error;\n const message = typeof e === \"string\" ? e : e?.message;\n const rawCode = typeof e === \"object\" ? e?.code : undefined;\n const code: PepuErrorCode =\n res.status === 409 && !rawCode\n ? \"SESSION_NONE\"\n : rawCode && KNOWN_CODES.has(rawCode)\n ? (rawCode as PepuErrorCode)\n : res.status === 401\n ? \"AUTH_INVALID_TOKEN\"\n : \"UNKNOWN\";\n const Cls = code === \"SESSION_NONE\" ? PepuSessionError : code === \"AUTH_INVALID_TOKEN\" ? PepuAuthError : PepuError;\n return new Cls(code, message ?? `Request failed (${res.status}).`, {\n status: res.status,\n ...(typeof e === \"object\" && e?.hint ? { hint: e.hint } : {}),\n });\n}\n\n/** Session state from the server's `delegated` flag and the locally tracked expiry. */\nexport type SessionState = \"none\" | \"active\" | \"expired\";\n\n/**\n * Derive the session state. A delegated signer with a known expiry in the\n * past is `expired` (Privy denies it, but the signer still exists until\n * revoked). Pure.\n *\n * @example\n * deriveSessionState({ delegated: true, expiresAt: 100, nowSeconds: 200 }); // { state: \"expired\", secondsLeft: 0 }\n */\nexport function deriveSessionState(p: {\n delegated: boolean;\n expiresAt?: number | undefined;\n nowSeconds: number;\n}): { state: SessionState; secondsLeft?: number } {\n if (!p.delegated) return { state: \"none\" };\n if (p.expiresAt === undefined) return { state: \"active\" };\n const secondsLeft = p.expiresAt - p.nowSeconds;\n return secondsLeft <= 0 ? { state: \"expired\", secondsLeft: 0 } : { state: \"active\", secondsLeft };\n}\n\ntype G = { localStorage?: Storage; dispatchEvent?: (e: Event) => boolean; addEventListener?: (t: string, l: () => void) => void; removeEventListener?: (t: string, l: () => void) => void };\nconst CHANGE_EVENT = \"pepu-session-change\";\nconst storageKey = (address: string): string => `pepu:session:${address.toLowerCase()}`;\n\ninterface StoredSession {\n expiresAt: number;\n policyId?: string;\n}\n\nfunction readStored(address: string | undefined): StoredSession | undefined {\n if (!address) return undefined;\n try {\n const raw = (globalThis as G).localStorage?.getItem(storageKey(address));\n return raw ? (JSON.parse(raw) as StoredSession) : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction writeStored(address: string, value: StoredSession | null): void {\n try {\n if (value) (globalThis as G).localStorage?.setItem(storageKey(address), JSON.stringify(value));\n else (globalThis as G).localStorage?.removeItem(storageKey(address));\n } catch {\n // Storage can be blocked; the session still works without a countdown.\n }\n (globalThis as G).dispatchEvent?.(new Event(CHANGE_EVENT));\n}\n\nfunction useAuthFetch(o: BaseOptions): { authFetch: AuthFetch; address: string | undefined } {\n const { user } = usePrivy();\n const pepuAuthFetch = usePepuAuthFetch();\n const custom = o.authFetch;\n const authFetch = useCallback<AuthFetch>(\n (url, init) => (custom ? custom(url, init) : pepuAuthFetch(url, init)),\n [custom, pepuAuthFetch],\n );\n return { authFetch, address: o.address ?? user?.wallet?.address };\n}\n\nexport type SessionGrantStatus = \"idle\" | \"creating-policy\" | \"awaiting-consent\" | \"granted\" | \"error\";\n\n/**\n * Grant a session: POST the grant route, then ask the user to approve with\n * Privy's `addSigners`. Skips `addSigners` when the server says\n * `alreadyGranted`, and swallows Privy's \"duplicate signer\" error.\n *\n * @example\n * const { grant, status, error } = useSessionGrant();\n * <button onClick={grant} disabled={status === \"creating-policy\"}>Grant</button>\n */\nexport function useSessionGrant(o: BaseOptions & { grantEndpoint?: string } = {}): {\n grant(): Promise<void>;\n status: SessionGrantStatus;\n error?: PepuError;\n} {\n const { authFetch, address } = useAuthFetch(o);\n const { addSigners } = useSigners();\n const [status, setStatus] = useState<SessionGrantStatus>(\"idle\");\n const [error, setError] = useState<PepuError | undefined>();\n const endpoint = o.grantEndpoint ?? \"/api/session/grant\";\n\n const grant = useCallback(async () => {\n setError(undefined);\n try {\n if (!address) throw new PepuAuthError(\"WALLET_NOT_PROVISIONED\", \"No embedded wallet address yet.\");\n setStatus(\"creating-policy\");\n const res = await authFetch(endpoint, { method: \"POST\" });\n if (!res.ok) throw await errorFromResponse(res);\n const body = (await res.json()) as\n | { alreadyGranted: true }\n | { alreadyGranted: false; policyId: string; expiresAt: number; signerId: string };\n if (!body.alreadyGranted) {\n setStatus(\"awaiting-consent\");\n try {\n await addSigners({ address, signers: [{ signerId: body.signerId, policyIds: [body.policyId] }] });\n } catch (caught) {\n const msg = caught instanceof Error ? caught.message : \"\";\n if (!/duplicate signer/i.test(msg)) throw caught;\n }\n writeStored(address, { expiresAt: body.expiresAt, policyId: body.policyId });\n } else {\n (globalThis as G).dispatchEvent?.(new Event(CHANGE_EVENT));\n }\n setStatus(\"granted\");\n } catch (e) {\n setError(toPepuError(e, { op: \"session grant\" }));\n setStatus(\"error\");\n }\n }, [address, authFetch, endpoint, addSigners]);\n\n return { grant, status, ...(error ? { error } : {}) };\n}\n\n/**\n * Current session state. Asks the status route whether a signer is attached\n * and combines it with the expiry tracked from the grant. Ticks every second\n * for `secondsLeft`; re-polls every `pollMs` if given.\n *\n * @example\n * const { state, secondsLeft } = useSessionStatus({ pollMs: 30_000 });\n */\nexport function useSessionStatus(o: BaseOptions & { statusEndpoint?: string; pollMs?: number } = {}): {\n state: SessionState;\n /**\n * True until the first status response (or failure) has been applied. Show a\n * spinner while it is true so the \"start a session\" UI does not flash on reload.\n */\n loading: boolean;\n expiresAt?: number;\n secondsLeft?: number;\n refetch(): void;\n} {\n const { authFetch, address } = useAuthFetch(o);\n const endpoint = o.statusEndpoint ?? \"/api/session/status\";\n const [delegated, setDelegated] = useState(false);\n const [loading, setLoading] = useState(true);\n const [serverExpiresAt, setServerExpiresAt] = useState<number | undefined>();\n const [now, setNow] = useState(() => Math.floor(Date.now() / 1000));\n const [tick, setTick] = useState(0);\n const refetch = useCallback(() => setTick((t) => t + 1), []);\n\n useEffect(() => {\n let cancelled = false;\n void (async () => {\n try {\n const res = await authFetch(endpoint);\n if (!res.ok) return;\n const body = (await res.json()) as { delegated?: boolean; expiresAt?: number };\n if (cancelled) return;\n setDelegated(Boolean(body.delegated));\n setServerExpiresAt(body.expiresAt);\n } catch {\n // Keep the last known state on a transient failure.\n } finally {\n if (!cancelled) setLoading(false);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [authFetch, endpoint, tick]);\n\n useEffect(() => {\n const onChange = (): void => setTick((t) => t + 1);\n (globalThis as G).addEventListener?.(CHANGE_EVENT, onChange);\n return () => (globalThis as G).removeEventListener?.(CHANGE_EVENT, onChange);\n }, []);\n\n useEffect(() => {\n const id = setInterval(() => setNow(Math.floor(Date.now() / 1000)), 1000);\n return () => clearInterval(id);\n }, []);\n\n useEffect(() => {\n if (!o.pollMs) return;\n const id = setInterval(() => setTick((t) => t + 1), o.pollMs);\n return () => clearInterval(id);\n }, [o.pollMs]);\n\n const expiresAt = serverExpiresAt ?? readStored(address)?.expiresAt;\n const derived = deriveSessionState({ delegated, expiresAt, nowSeconds: now });\n return {\n state: derived.state,\n loading,\n ...(expiresAt !== undefined ? { expiresAt } : {}),\n ...(derived.secondsLeft !== undefined ? { secondsLeft: derived.secondsLeft } : {}),\n refetch,\n };\n}\n\nexport type SessionRevokeStatus = \"idle\" | \"revoking\" | \"revoked\" | \"error\";\n\n/**\n * Revoke the session. The Privy `removeSigners` call is the real revoke; the\n * server revoke route afterwards is best-effort cleanup of the policy.\n *\n * @example\n * const { revoke, status } = useSessionRevoke();\n */\nexport function useSessionRevoke(o: BaseOptions & { revokeEndpoint?: string } = {}): {\n revoke(): Promise<void>;\n status: SessionRevokeStatus;\n error?: PepuError;\n} {\n const { authFetch, address } = useAuthFetch(o);\n const { removeSigners } = useSigners();\n const [status, setStatus] = useState<SessionRevokeStatus>(\"idle\");\n const [error, setError] = useState<PepuError | undefined>();\n const endpoint = o.revokeEndpoint ?? \"/api/session/revoke\";\n\n const revoke = useCallback(async () => {\n setError(undefined);\n try {\n if (!address) throw new PepuAuthError(\"WALLET_NOT_PROVISIONED\", \"No embedded wallet address yet.\");\n setStatus(\"revoking\");\n const stored = readStored(address);\n await removeSigners({ address });\n try {\n await authFetch(endpoint, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ policyId: stored?.policyId }),\n });\n } catch {\n // Cleanup only; the signer is already gone.\n }\n writeStored(address, null);\n setStatus(\"revoked\");\n } catch (e) {\n setError(toPepuError(e, { op: \"session revoke\" }));\n setStatus(\"error\");\n }\n }, [address, authFetch, endpoint, removeSigners]);\n\n return { revoke, status, ...(error ? { error } : {}) };\n}\n\nexport type SessionActStatus = \"idle\" | \"pending\" | \"success\" | \"error\";\n\n/**\n * Call a session action route (built with `createSessionActionRoute`). A 409\n * is the only \"no session\" signal and surfaces as `error.code ===\n * \"SESSION_NONE\"`; any other failure is a failed transaction, so do not send\n * the user back to the consent screen for it.\n *\n * @example\n * const { act } = useSessionAct<{}, { hash: string }>({ endpoint: \"/api/game/tap\" });\n * const { hash } = await act({});\n */\nexport function useSessionAct<I, O>(o: BaseOptions & { endpoint: string }): {\n act(input: I): Promise<O>;\n status: SessionActStatus;\n error?: PepuError;\n} {\n const { authFetch } = useAuthFetch(o);\n const [status, setStatus] = useState<SessionActStatus>(\"idle\");\n const [error, setError] = useState<PepuError | undefined>();\n\n const act = useCallback(\n async (input: I): Promise<O> => {\n setStatus(\"pending\");\n setError(undefined);\n try {\n const res = await authFetch(o.endpoint, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(input ?? {}),\n });\n if (!res.ok) throw await errorFromResponse(res);\n const out = (await res.json()) as O;\n setStatus(\"success\");\n return out;\n } catch (e) {\n const err = toPepuError(e, { op: \"session action\" });\n setError(err);\n setStatus(\"error\");\n throw err;\n }\n },\n [authFetch, o.endpoint],\n );\n\n return { act, status, ...(error ? { error } : {}) };\n}\n"]}