@pepu-chain/sdk 0.0.0-stage → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +590 -2
- package/dist/aa/kernel.cjs +41 -0
- package/dist/aa/kernel.cjs.map +1 -0
- package/dist/aa/kernel.d.cts +88 -0
- package/dist/aa/kernel.d.ts +88 -0
- package/dist/aa/kernel.guard.js +15 -0
- package/dist/aa/kernel.js +11 -0
- package/dist/aa/kernel.js.map +1 -0
- package/dist/aa/react-direct.cjs +111 -0
- package/dist/aa/react-direct.cjs.map +1 -0
- package/dist/aa/react-direct.d.cts +42 -0
- package/dist/aa/react-direct.d.ts +42 -0
- package/dist/aa/react-direct.guard.js +15 -0
- package/dist/aa/react-direct.js +107 -0
- package/dist/aa/react-direct.js.map +1 -0
- package/dist/aa/react.cjs +152 -0
- package/dist/aa/react.cjs.map +1 -0
- package/dist/aa/react.d.cts +62 -0
- package/dist/aa/react.d.ts +62 -0
- package/dist/aa/react.guard.js +15 -0
- package/dist/aa/react.js +147 -0
- package/dist/aa/react.js.map +1 -0
- package/dist/aa.cjs +84 -0
- package/dist/aa.cjs.map +1 -0
- package/dist/aa.d.cts +85 -0
- package/dist/aa.d.ts +85 -0
- package/dist/aa.js +11 -0
- package/dist/aa.js.map +1 -0
- package/dist/api-Dz4sCHH_.d.cts +654 -0
- package/dist/api-Dz4sCHH_.d.ts +654 -0
- package/dist/calls-BRPjKgjl.d.cts +70 -0
- package/dist/calls-z_EQOtFb.d.ts +70 -0
- package/dist/chains-DK13zGIp.d.cts +235 -0
- package/dist/chains-DK13zGIp.d.ts +235 -0
- package/dist/chunk-3XUGQODR.js +194 -0
- package/dist/chunk-3XUGQODR.js.map +1 -0
- package/dist/chunk-45KSZH26.cjs +145 -0
- package/dist/chunk-45KSZH26.cjs.map +1 -0
- package/dist/chunk-4GINFJO6.cjs +44 -0
- package/dist/chunk-4GINFJO6.cjs.map +1 -0
- package/dist/chunk-62M2LKQW.js +136 -0
- package/dist/chunk-62M2LKQW.js.map +1 -0
- package/dist/chunk-6DSZ4Z2N.js +498 -0
- package/dist/chunk-6DSZ4Z2N.js.map +1 -0
- package/dist/chunk-7MNJF2OB.cjs +72 -0
- package/dist/chunk-7MNJF2OB.cjs.map +1 -0
- package/dist/chunk-7PVR7QSE.js +45 -0
- package/dist/chunk-7PVR7QSE.js.map +1 -0
- package/dist/chunk-A5LP2UCS.cjs +2729 -0
- package/dist/chunk-A5LP2UCS.cjs.map +1 -0
- package/dist/chunk-AJS4UFQX.cjs +121 -0
- package/dist/chunk-AJS4UFQX.cjs.map +1 -0
- package/dist/chunk-BGALSKAF.cjs +315 -0
- package/dist/chunk-BGALSKAF.cjs.map +1 -0
- package/dist/chunk-C2XW44FI.cjs +200 -0
- package/dist/chunk-C2XW44FI.cjs.map +1 -0
- package/dist/chunk-C7IC36XS.cjs +13 -0
- package/dist/chunk-C7IC36XS.cjs.map +1 -0
- package/dist/chunk-D52PADVY.js +84 -0
- package/dist/chunk-D52PADVY.js.map +1 -0
- package/dist/chunk-DH6BFNVJ.cjs +272 -0
- package/dist/chunk-DH6BFNVJ.cjs.map +1 -0
- package/dist/chunk-DPCZJLB3.cjs +87 -0
- package/dist/chunk-DPCZJLB3.cjs.map +1 -0
- package/dist/chunk-EHBPIYY4.js +262 -0
- package/dist/chunk-EHBPIYY4.js.map +1 -0
- package/dist/chunk-ESMNAXUI.js +86 -0
- package/dist/chunk-ESMNAXUI.js.map +1 -0
- package/dist/chunk-F2R473FR.js +304 -0
- package/dist/chunk-F2R473FR.js.map +1 -0
- package/dist/chunk-IB2FSPMJ.js +66 -0
- package/dist/chunk-IB2FSPMJ.js.map +1 -0
- package/dist/chunk-IG7RSL2Y.cjs +178 -0
- package/dist/chunk-IG7RSL2Y.cjs.map +1 -0
- package/dist/chunk-IY3ALPUJ.js +2716 -0
- package/dist/chunk-IY3ALPUJ.js.map +1 -0
- package/dist/chunk-J3O2ZGG3.cjs +93 -0
- package/dist/chunk-J3O2ZGG3.cjs.map +1 -0
- package/dist/chunk-J6UXXHBE.js +37 -0
- package/dist/chunk-J6UXXHBE.js.map +1 -0
- package/dist/chunk-JLZ4LZ4Z.js +22 -0
- package/dist/chunk-JLZ4LZ4Z.js.map +1 -0
- package/dist/chunk-K7JSQPZO.cjs +231 -0
- package/dist/chunk-K7JSQPZO.cjs.map +1 -0
- package/dist/chunk-KJYNF5KH.js +224 -0
- package/dist/chunk-KJYNF5KH.js.map +1 -0
- package/dist/chunk-KVG3AYYR.js +99 -0
- package/dist/chunk-KVG3AYYR.js.map +1 -0
- package/dist/chunk-NE3QKDOB.cjs +24 -0
- package/dist/chunk-NE3QKDOB.cjs.map +1 -0
- package/dist/chunk-NVOPDXTA.cjs +95 -0
- package/dist/chunk-NVOPDXTA.cjs.map +1 -0
- package/dist/chunk-OH3QMAIB.js +11 -0
- package/dist/chunk-OH3QMAIB.js.map +1 -0
- package/dist/chunk-PHM3ZORG.cjs +110 -0
- package/dist/chunk-PHM3ZORG.cjs.map +1 -0
- package/dist/chunk-R5PXQNO3.cjs +209 -0
- package/dist/chunk-R5PXQNO3.cjs.map +1 -0
- package/dist/chunk-RCMKPJZO.cjs +49 -0
- package/dist/chunk-RCMKPJZO.cjs.map +1 -0
- package/dist/chunk-SVWRRALU.cjs +17 -0
- package/dist/chunk-SVWRRALU.cjs.map +1 -0
- package/dist/chunk-T43PQXJD.js +202 -0
- package/dist/chunk-T43PQXJD.js.map +1 -0
- package/dist/chunk-VBH3JLQ5.js +116 -0
- package/dist/chunk-VBH3JLQ5.js.map +1 -0
- package/dist/chunk-VF3D6KLQ.cjs +94 -0
- package/dist/chunk-VF3D6KLQ.cjs.map +1 -0
- package/dist/chunk-VTQIHMF3.js +82 -0
- package/dist/chunk-VTQIHMF3.js.map +1 -0
- package/dist/chunk-W3JN3YIW.js +15 -0
- package/dist/chunk-W3JN3YIW.js.map +1 -0
- package/dist/chunk-WANILJZQ.cjs +87 -0
- package/dist/chunk-WANILJZQ.cjs.map +1 -0
- package/dist/chunk-XC4IBCI2.js +86 -0
- package/dist/chunk-XC4IBCI2.js.map +1 -0
- package/dist/chunk-YKEWWQEJ.js +165 -0
- package/dist/chunk-YKEWWQEJ.js.map +1 -0
- package/dist/chunk-YQL7NISX.cjs +515 -0
- package/dist/chunk-YQL7NISX.cjs.map +1 -0
- package/dist/chunk-ZB6SVBK4.js +89 -0
- package/dist/chunk-ZB6SVBK4.js.map +1 -0
- package/dist/combo/react.cjs +236 -0
- package/dist/combo/react.cjs.map +1 -0
- package/dist/combo/react.d.cts +148 -0
- package/dist/combo/react.d.ts +148 -0
- package/dist/combo/react.guard.js +15 -0
- package/dist/combo/react.js +230 -0
- package/dist/combo/react.js.map +1 -0
- package/dist/combo.cjs +263 -0
- package/dist/combo.cjs.map +1 -0
- package/dist/combo.d.cts +139 -0
- package/dist/combo.d.ts +139 -0
- package/dist/combo.guard.js +15 -0
- package/dist/combo.js +249 -0
- package/dist/combo.js.map +1 -0
- package/dist/config-CHjz7ZjZ.d.cts +57 -0
- package/dist/config-COjhIZTh.d.ts +57 -0
- package/dist/doctor.cjs +354 -0
- package/dist/doctor.cjs.map +1 -0
- package/dist/doctor.d.cts +177 -0
- package/dist/doctor.d.ts +177 -0
- package/dist/doctor.js +345 -0
- package/dist/doctor.js.map +1 -0
- package/dist/erc7677-DOW58QBE.d.cts +111 -0
- package/dist/erc7677-DOW58QBE.d.ts +111 -0
- package/dist/errors-CgX1vNj7.d.cts +100 -0
- package/dist/errors-CgX1vNj7.d.ts +100 -0
- package/dist/index.cjs +806 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2398 -0
- package/dist/index.d.ts +2398 -0
- package/dist/index.js +559 -0
- package/dist/index.js.map +1 -0
- package/dist/paymaster/server.cjs +38 -0
- package/dist/paymaster/server.cjs.map +1 -0
- package/dist/paymaster/server.d.cts +57 -0
- package/dist/paymaster/server.d.ts +57 -0
- package/dist/paymaster/server.js +36 -0
- package/dist/paymaster/server.js.map +1 -0
- package/dist/paymaster.cjs +356 -0
- package/dist/paymaster.cjs.map +1 -0
- package/dist/paymaster.d.cts +1851 -0
- package/dist/paymaster.d.ts +1851 -0
- package/dist/paymaster.js +289 -0
- package/dist/paymaster.js.map +1 -0
- package/dist/privy/react.cjs +49 -0
- package/dist/privy/react.cjs.map +1 -0
- package/dist/privy/react.d.cts +194 -0
- package/dist/privy/react.d.ts +194 -0
- package/dist/privy/react.guard.js +15 -0
- package/dist/privy/react.js +7 -0
- package/dist/privy/react.js.map +1 -0
- package/dist/privy/server.cjs +44 -0
- package/dist/privy/server.cjs.map +1 -0
- package/dist/privy/server.d.cts +192 -0
- package/dist/privy/server.d.ts +192 -0
- package/dist/privy/server.guard.js +15 -0
- package/dist/privy/server.js +6 -0
- package/dist/privy/server.js.map +1 -0
- package/dist/privy/wagmi.d.ts +90 -0
- package/dist/privy/wagmi.guard.js +15 -0
- package/dist/privy/wagmi.js +55 -0
- package/dist/privy/wagmi.js.map +1 -0
- package/dist/privy.cjs +34 -0
- package/dist/privy.cjs.map +1 -0
- package/dist/privy.d.cts +4 -0
- package/dist/privy.d.ts +4 -0
- package/dist/privy.js +5 -0
- package/dist/privy.js.map +1 -0
- package/dist/react.cjs +73 -0
- package/dist/react.cjs.map +1 -0
- package/dist/react.d.cts +66 -0
- package/dist/react.d.ts +66 -0
- package/dist/react.guard.js +15 -0
- package/dist/react.js +68 -0
- package/dist/react.js.map +1 -0
- package/dist/requirements-C-QiJkL9.d.cts +134 -0
- package/dist/requirements-C-QiJkL9.d.ts +134 -0
- package/dist/scope-DBRkN7bR.d.cts +94 -0
- package/dist/scope-DBRkN7bR.d.ts +94 -0
- package/dist/server.cjs +59 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +208 -0
- package/dist/server.d.ts +208 -0
- package/dist/server.js +8 -0
- package/dist/server.js.map +1 -0
- package/dist/session/kernel.cjs +83 -0
- package/dist/session/kernel.cjs.map +1 -0
- package/dist/session/kernel.d.cts +131 -0
- package/dist/session/kernel.d.ts +131 -0
- package/dist/session/kernel.guard.js +15 -0
- package/dist/session/kernel.js +13 -0
- package/dist/session/kernel.js.map +1 -0
- package/dist/session/react.cjs +38 -0
- package/dist/session/react.cjs.map +1 -0
- package/dist/session/react.d.cts +119 -0
- package/dist/session/react.d.ts +119 -0
- package/dist/session/react.guard.js +15 -0
- package/dist/session/react.js +8 -0
- package/dist/session/react.js.map +1 -0
- package/dist/session/server.cjs +268 -0
- package/dist/session/server.cjs.map +1 -0
- package/dist/session/server.d.cts +151 -0
- package/dist/session/server.d.ts +151 -0
- package/dist/session/server.guard.js +15 -0
- package/dist/session/server.js +252 -0
- package/dist/session/server.js.map +1 -0
- package/dist/session.cjs +74 -0
- package/dist/session.cjs.map +1 -0
- package/dist/session.d.cts +3 -0
- package/dist/session.d.ts +3 -0
- package/dist/session.js +5 -0
- package/dist/session.js.map +1 -0
- package/dist/status-Dx9zAFo9.d.ts +327 -0
- package/dist/status-wgTM26V7.d.cts +327 -0
- package/dist/store-CjmLgp9g.d.cts +64 -0
- package/dist/store-CjmLgp9g.d.ts +64 -0
- package/dist/types-BEEM7WdG.d.cts +25 -0
- package/dist/types-BEEM7WdG.d.ts +25 -0
- package/dist/types-BilBTDqK.d.cts +27 -0
- package/dist/types-BilBTDqK.d.ts +27 -0
- package/package.json +245 -3
|
@@ -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"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkK7JSQPZO_cjs = require('./chunk-K7JSQPZO.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 = chunkK7JSQPZO_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-RCMKPJZO.cjs.map
|
|
49
|
+
//# sourceMappingURL=chunk-RCMKPJZO.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-RCMKPJZO.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"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkYQL7NISX_cjs = require('./chunk-YQL7NISX.cjs');
|
|
4
|
+
|
|
5
|
+
// src/internal/assert-server.ts
|
|
6
|
+
function assertServerOnly(entry) {
|
|
7
|
+
if (globalThis.window !== void 0) {
|
|
8
|
+
throw new chunkYQL7NISX_cjs.PepuConfigError(
|
|
9
|
+
"CONFIG_SERVER_ONLY",
|
|
10
|
+
`${entry} is server-only and was imported in a browser bundle. Import it from a route handler, server action or script, never from client code.`
|
|
11
|
+
);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
exports.assertServerOnly = assertServerOnly;
|
|
16
|
+
//# sourceMappingURL=chunk-SVWRRALU.cjs.map
|
|
17
|
+
//# sourceMappingURL=chunk-SVWRRALU.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/internal/assert-server.ts"],"names":["PepuConfigError"],"mappings":";;;;;AAUO,SAAS,iBAAiB,KAAA,EAAqB;AACpD,EAAA,IAAK,UAAA,CAAoC,WAAW,MAAA,EAAW;AAC7D,IAAA,MAAM,IAAIA,iCAAA;AAAA,MACR,oBAAA;AAAA,MACA,GAAG,KAAK,CAAA,sIAAA;AAAA,KACV;AAAA,EACF;AACF","file":"chunk-SVWRRALU.cjs","sourcesContent":["import { PepuConfigError } from \"../errors.js\";\n\n/**\n * Called at import time by every server-only entry point\n * (`@pepu-chain/sdk/server`, `/privy/server`, `/session/server`,\n * `/paymaster/server`, `/combo`). Those entries sit next to secrets (Privy app\n * secret, authorization key, paymaster server keys) and must never be bundled\n * for the browser. A browser bundle that reaches one fails loudly here instead\n * of silently shipping the module.\n */\nexport function assertServerOnly(entry: string): void {\n if ((globalThis as { window?: unknown }).window !== undefined) {\n throw new PepuConfigError(\n \"CONFIG_SERVER_ONLY\",\n `${entry} is server-only and was imported in a browser bundle. Import it from a route handler, server action or script, never from client code.`,\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { usePepuAuthFetch } from './chunk-EHBPIYY4.js';
|
|
2
|
+
import { PEPU_ERROR_CATALOG, PepuSessionError, PepuAuthError, PepuError, toPepuError } from './chunk-6DSZ4Z2N.js';
|
|
3
|
+
import { useSigners, usePrivy } from '@privy-io/react-auth';
|
|
4
|
+
import { useState, useCallback, useEffect } from 'react';
|
|
5
|
+
|
|
6
|
+
var KNOWN_CODES = new Set(PEPU_ERROR_CATALOG.map((e) => e.code));
|
|
7
|
+
async function errorFromResponse(res) {
|
|
8
|
+
const body = await res.json().catch(() => null);
|
|
9
|
+
const e = body?.error;
|
|
10
|
+
const message = typeof e === "string" ? e : e?.message;
|
|
11
|
+
const rawCode = typeof e === "object" ? e?.code : void 0;
|
|
12
|
+
const code = res.status === 409 && !rawCode ? "SESSION_NONE" : rawCode && KNOWN_CODES.has(rawCode) ? rawCode : res.status === 401 ? "AUTH_INVALID_TOKEN" : "UNKNOWN";
|
|
13
|
+
const Cls = code === "SESSION_NONE" ? PepuSessionError : code === "AUTH_INVALID_TOKEN" ? PepuAuthError : PepuError;
|
|
14
|
+
return new Cls(code, message ?? `Request failed (${res.status}).`, {
|
|
15
|
+
status: res.status,
|
|
16
|
+
...typeof e === "object" && e?.hint ? { hint: e.hint } : {}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function deriveSessionState(p) {
|
|
20
|
+
if (!p.delegated) return { state: "none" };
|
|
21
|
+
if (p.expiresAt === void 0) return { state: "active" };
|
|
22
|
+
const secondsLeft = p.expiresAt - p.nowSeconds;
|
|
23
|
+
return secondsLeft <= 0 ? { state: "expired", secondsLeft: 0 } : { state: "active", secondsLeft };
|
|
24
|
+
}
|
|
25
|
+
var CHANGE_EVENT = "pepu-session-change";
|
|
26
|
+
var storageKey = (address) => `pepu:session:${address.toLowerCase()}`;
|
|
27
|
+
function readStored(address) {
|
|
28
|
+
if (!address) return void 0;
|
|
29
|
+
try {
|
|
30
|
+
const raw = globalThis.localStorage?.getItem(storageKey(address));
|
|
31
|
+
return raw ? JSON.parse(raw) : void 0;
|
|
32
|
+
} catch {
|
|
33
|
+
return void 0;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function writeStored(address, value) {
|
|
37
|
+
try {
|
|
38
|
+
if (value) globalThis.localStorage?.setItem(storageKey(address), JSON.stringify(value));
|
|
39
|
+
else globalThis.localStorage?.removeItem(storageKey(address));
|
|
40
|
+
} catch {
|
|
41
|
+
}
|
|
42
|
+
globalThis.dispatchEvent?.(new Event(CHANGE_EVENT));
|
|
43
|
+
}
|
|
44
|
+
function useAuthFetch(o) {
|
|
45
|
+
const { user } = usePrivy();
|
|
46
|
+
const pepuAuthFetch = usePepuAuthFetch();
|
|
47
|
+
const custom = o.authFetch;
|
|
48
|
+
const authFetch = useCallback(
|
|
49
|
+
(url, init) => custom ? custom(url, init) : pepuAuthFetch(url, init),
|
|
50
|
+
[custom, pepuAuthFetch]
|
|
51
|
+
);
|
|
52
|
+
return { authFetch, address: o.address ?? user?.wallet?.address };
|
|
53
|
+
}
|
|
54
|
+
function useSessionGrant(o = {}) {
|
|
55
|
+
const { authFetch, address } = useAuthFetch(o);
|
|
56
|
+
const { addSigners } = useSigners();
|
|
57
|
+
const [status, setStatus] = useState("idle");
|
|
58
|
+
const [error, setError] = useState();
|
|
59
|
+
const endpoint = o.grantEndpoint ?? "/api/session/grant";
|
|
60
|
+
const grant = useCallback(async () => {
|
|
61
|
+
setError(void 0);
|
|
62
|
+
try {
|
|
63
|
+
if (!address) throw new PepuAuthError("WALLET_NOT_PROVISIONED", "No embedded wallet address yet.");
|
|
64
|
+
setStatus("creating-policy");
|
|
65
|
+
const res = await authFetch(endpoint, { method: "POST" });
|
|
66
|
+
if (!res.ok) throw await errorFromResponse(res);
|
|
67
|
+
const body = await res.json();
|
|
68
|
+
if (!body.alreadyGranted) {
|
|
69
|
+
setStatus("awaiting-consent");
|
|
70
|
+
try {
|
|
71
|
+
await addSigners({ address, signers: [{ signerId: body.signerId, policyIds: [body.policyId] }] });
|
|
72
|
+
} catch (caught) {
|
|
73
|
+
const msg = caught instanceof Error ? caught.message : "";
|
|
74
|
+
if (!/duplicate signer/i.test(msg)) throw caught;
|
|
75
|
+
}
|
|
76
|
+
writeStored(address, { expiresAt: body.expiresAt, policyId: body.policyId });
|
|
77
|
+
} else {
|
|
78
|
+
globalThis.dispatchEvent?.(new Event(CHANGE_EVENT));
|
|
79
|
+
}
|
|
80
|
+
setStatus("granted");
|
|
81
|
+
} catch (e) {
|
|
82
|
+
setError(toPepuError(e, { op: "session grant" }));
|
|
83
|
+
setStatus("error");
|
|
84
|
+
}
|
|
85
|
+
}, [address, authFetch, endpoint, addSigners]);
|
|
86
|
+
return { grant, status, ...error ? { error } : {} };
|
|
87
|
+
}
|
|
88
|
+
function useSessionStatus(o = {}) {
|
|
89
|
+
const { authFetch, address } = useAuthFetch(o);
|
|
90
|
+
const endpoint = o.statusEndpoint ?? "/api/session/status";
|
|
91
|
+
const [delegated, setDelegated] = useState(false);
|
|
92
|
+
const [loading, setLoading] = useState(true);
|
|
93
|
+
const [serverExpiresAt, setServerExpiresAt] = useState();
|
|
94
|
+
const [now, setNow] = useState(() => Math.floor(Date.now() / 1e3));
|
|
95
|
+
const [tick, setTick] = useState(0);
|
|
96
|
+
const refetch = useCallback(() => setTick((t) => t + 1), []);
|
|
97
|
+
useEffect(() => {
|
|
98
|
+
let cancelled = false;
|
|
99
|
+
void (async () => {
|
|
100
|
+
try {
|
|
101
|
+
const res = await authFetch(endpoint);
|
|
102
|
+
if (!res.ok) return;
|
|
103
|
+
const body = await res.json();
|
|
104
|
+
if (cancelled) return;
|
|
105
|
+
setDelegated(Boolean(body.delegated));
|
|
106
|
+
setServerExpiresAt(body.expiresAt);
|
|
107
|
+
} catch {
|
|
108
|
+
} finally {
|
|
109
|
+
if (!cancelled) setLoading(false);
|
|
110
|
+
}
|
|
111
|
+
})();
|
|
112
|
+
return () => {
|
|
113
|
+
cancelled = true;
|
|
114
|
+
};
|
|
115
|
+
}, [authFetch, endpoint, tick]);
|
|
116
|
+
useEffect(() => {
|
|
117
|
+
const onChange = () => setTick((t) => t + 1);
|
|
118
|
+
globalThis.addEventListener?.(CHANGE_EVENT, onChange);
|
|
119
|
+
return () => globalThis.removeEventListener?.(CHANGE_EVENT, onChange);
|
|
120
|
+
}, []);
|
|
121
|
+
useEffect(() => {
|
|
122
|
+
const id = setInterval(() => setNow(Math.floor(Date.now() / 1e3)), 1e3);
|
|
123
|
+
return () => clearInterval(id);
|
|
124
|
+
}, []);
|
|
125
|
+
useEffect(() => {
|
|
126
|
+
if (!o.pollMs) return;
|
|
127
|
+
const id = setInterval(() => setTick((t) => t + 1), o.pollMs);
|
|
128
|
+
return () => clearInterval(id);
|
|
129
|
+
}, [o.pollMs]);
|
|
130
|
+
const expiresAt = serverExpiresAt ?? readStored(address)?.expiresAt;
|
|
131
|
+
const derived = deriveSessionState({ delegated, expiresAt, nowSeconds: now });
|
|
132
|
+
return {
|
|
133
|
+
state: derived.state,
|
|
134
|
+
loading,
|
|
135
|
+
...expiresAt !== void 0 ? { expiresAt } : {},
|
|
136
|
+
...derived.secondsLeft !== void 0 ? { secondsLeft: derived.secondsLeft } : {},
|
|
137
|
+
refetch
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function useSessionRevoke(o = {}) {
|
|
141
|
+
const { authFetch, address } = useAuthFetch(o);
|
|
142
|
+
const { removeSigners } = useSigners();
|
|
143
|
+
const [status, setStatus] = useState("idle");
|
|
144
|
+
const [error, setError] = useState();
|
|
145
|
+
const endpoint = o.revokeEndpoint ?? "/api/session/revoke";
|
|
146
|
+
const revoke = useCallback(async () => {
|
|
147
|
+
setError(void 0);
|
|
148
|
+
try {
|
|
149
|
+
if (!address) throw new PepuAuthError("WALLET_NOT_PROVISIONED", "No embedded wallet address yet.");
|
|
150
|
+
setStatus("revoking");
|
|
151
|
+
const stored = readStored(address);
|
|
152
|
+
await removeSigners({ address });
|
|
153
|
+
try {
|
|
154
|
+
await authFetch(endpoint, {
|
|
155
|
+
method: "POST",
|
|
156
|
+
headers: { "content-type": "application/json" },
|
|
157
|
+
body: JSON.stringify({ policyId: stored?.policyId })
|
|
158
|
+
});
|
|
159
|
+
} catch {
|
|
160
|
+
}
|
|
161
|
+
writeStored(address, null);
|
|
162
|
+
setStatus("revoked");
|
|
163
|
+
} catch (e) {
|
|
164
|
+
setError(toPepuError(e, { op: "session revoke" }));
|
|
165
|
+
setStatus("error");
|
|
166
|
+
}
|
|
167
|
+
}, [address, authFetch, endpoint, removeSigners]);
|
|
168
|
+
return { revoke, status, ...error ? { error } : {} };
|
|
169
|
+
}
|
|
170
|
+
function useSessionAct(o) {
|
|
171
|
+
const { authFetch } = useAuthFetch(o);
|
|
172
|
+
const [status, setStatus] = useState("idle");
|
|
173
|
+
const [error, setError] = useState();
|
|
174
|
+
const act = useCallback(
|
|
175
|
+
async (input) => {
|
|
176
|
+
setStatus("pending");
|
|
177
|
+
setError(void 0);
|
|
178
|
+
try {
|
|
179
|
+
const res = await authFetch(o.endpoint, {
|
|
180
|
+
method: "POST",
|
|
181
|
+
headers: { "content-type": "application/json" },
|
|
182
|
+
body: JSON.stringify(input ?? {})
|
|
183
|
+
});
|
|
184
|
+
if (!res.ok) throw await errorFromResponse(res);
|
|
185
|
+
const out = await res.json();
|
|
186
|
+
setStatus("success");
|
|
187
|
+
return out;
|
|
188
|
+
} catch (e) {
|
|
189
|
+
const err = toPepuError(e, { op: "session action" });
|
|
190
|
+
setError(err);
|
|
191
|
+
setStatus("error");
|
|
192
|
+
throw err;
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
[authFetch, o.endpoint]
|
|
196
|
+
);
|
|
197
|
+
return { act, status, ...error ? { error } : {} };
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
export { deriveSessionState, errorFromResponse, useSessionAct, useSessionGrant, useSessionRevoke, useSessionStatus };
|
|
201
|
+
//# sourceMappingURL=chunk-T43PQXJD.js.map
|
|
202
|
+
//# sourceMappingURL=chunk-T43PQXJD.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/session/react.ts"],"names":[],"mappings":"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","file":"chunk-T43PQXJD.js","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"]}
|