@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.
- package/LICENSE +21 -0
- package/README.md +565 -2
- package/dist/aa/kernel.cjs +40 -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.js +11 -0
- package/dist/aa/kernel.js.map +1 -0
- package/dist/aa/react-direct.cjs +110 -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.js +107 -0
- package/dist/aa/react-direct.js.map +1 -0
- package/dist/aa/react.cjs +151 -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.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-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-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-ET3P6TX6.cjs +49 -0
- package/dist/chunk-ET3P6TX6.cjs.map +1 -0
- package/dist/chunk-FCXSP2YF.js +219 -0
- package/dist/chunk-FCXSP2YF.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-KIIFL4VM.js +274 -0
- package/dist/chunk-KIIFL4VM.js.map +1 -0
- package/dist/chunk-KVG3AYYR.js +99 -0
- package/dist/chunk-KVG3AYYR.js.map +1 -0
- package/dist/chunk-MBA4CLA5.js +45 -0
- package/dist/chunk-MBA4CLA5.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-SLW7FRTL.cjs +285 -0
- package/dist/chunk-SLW7FRTL.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-TIEAZYHF.cjs +225 -0
- package/dist/chunk-TIEAZYHF.cjs.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 +235 -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.js +230 -0
- package/dist/combo/react.js.map +1 -0
- package/dist/combo.cjs +262 -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.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 +802 -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 +48 -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.js +7 -0
- package/dist/privy/react.js.map +1 -0
- package/dist/privy/server.cjs +43 -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.js +6 -0
- package/dist/privy/server.js.map +1 -0
- package/dist/privy/wagmi.d.ts +90 -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 +72 -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.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 +82 -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.js +13 -0
- package/dist/session/kernel.js.map +1 -0
- package/dist/session/react.cjs +37 -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.js +8 -0
- package/dist/session/react.js.map +1 -0
- package/dist/session/server.cjs +267 -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.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-CmOsyPmO.d.cts +295 -0
- package/dist/status-DwkkOrGQ.d.ts +295 -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 +209 -3
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { pepuTestnet, pepuMainnet } from './chunk-VTQIHMF3.js';
|
|
2
|
+
|
|
3
|
+
// src/contracts.ts
|
|
4
|
+
var MULTICALL3_PENDING_REASON = "Canonical Multicall3 (0xcA11bde05977b3631167028862bE2a173976CA11) was deployed elsewhere via a pre-signed CREATE transaction with a 1,000,000 gas limit. This Arbitrum Nitro chain needs ~14.3M gas to deploy the same bytecode, so that transaction cannot execute here and the canonical address is unreachable. A PEPU-specific deployment is pending; do not substitute the canonical address.";
|
|
5
|
+
var MULTICALL3_MAINNET_NOTES = "PEPU-specific deployment. NOT at the canonical Multicall3 address, which is unreachable on this Nitro chain (the canonical pre-signed CREATE tx carries a 1,000,000 gas limit; this bytecode needs ~14.3M). Deployed from canonical mds1/multicall3 source (solc 0.8.12, optimizer 10,000,000 runs) via the CREATE2 deterministic deployer with a zero salt, so the same source reproduces this address on any chain that has that deployer. Verified on pepuscan. viem/wagmi multicall confirmed working against it.";
|
|
6
|
+
var ZERODEV_NOTES = "Deployed by ZeroDev's one-click Conduit Marketplace integration (mainnet only \u2014 not present on testnet).";
|
|
7
|
+
var PERMIT2_PENDING_REASON = "Not yet deployed on this chain. The CREATE2 deterministic deployer needed to reproduce Permit2's canonical address is live, so this is unblocked, but no deployment has happened (and been verified) yet.";
|
|
8
|
+
var PERMIT2_MAINNET_NOTES = "Deployed at the canonical Permit2 address via the CREATE2 deterministic deployer, same as on every other chain that has it. Verified live 2026-09-24 via eth_getCode (9,152 bytes, matching Permit2's known bytecode size) plus a successful DOMAIN_SEPARATOR() eth_call. This is the canonical Permit2 \u2014 do not confuse it with PepuSwap's own separate Permit2 deployment at pepuSwapContracts.permit2NonCanonical in ./dex.js, which predates this one and is not interchangeable with it.";
|
|
9
|
+
var PAYMASTER_MAINNET_NOTES = "Alias of `paymasterV2`: the tiered PepuSponsoredPaymasterV7 canary (0xdb28...C30D), deployed around block 10537341 and funded in small tranches. Internally reviewed 3x, external audit pending. Owner 0x5966dFaB11c8AEe767e0739083417D02f4a634A1, manager 0x063Ab6C16c38D19A4bC76E7c39A4A0A73afCaBb0. The free pool was seeded with 300 PEPU; free-tier destinations are TapScore only for now. It sponsors only through the hosted policy service (paymaster.pepeunchained.com) with the hosted bundler (bundler.pepeunchained.com). The v1 paymaster is retired (see `paymasterV1`).";
|
|
10
|
+
var VERIFIED_AT = "2026-10-02";
|
|
11
|
+
var PAYMASTER_V2_VERIFIED_AT = "2026-10-14";
|
|
12
|
+
var KERNEL_IMPL_NOTES = ZERODEV_NOTES + " Kernel v3.1 implementation that kernelFactory.implementation() resolves to; same address ZeroDev uses on every chain with this version.";
|
|
13
|
+
var TAPSCORE_NOTES = "TapScore demo contract used by the game-app template. Verified via eth_getCode.";
|
|
14
|
+
var PAYMASTER_V1_NOTES = "RETIRED. The project's first verifying paymaster (PepuVerifyingPaymasterV7). Its EntryPoint deposit was withdrawn (deposit is 0), so it cannot sponsor anything. The contract still has bytecode; do not deposit to it or route new work to it. Superseded by `paymasterV2`. A real sponsored operation ran through the hosted URLs on v1 before retirement (tx 0x57cf2f5a332248476d775c096b4b8339d81867c14211ed3bc4fcb1895dff0f9f).";
|
|
15
|
+
var PAYMASTER_V2_NOTES = "PepuSponsoredPaymasterV7 (v2), deployed on PEPU mainnet as a canary around block 10537341: internally reviewed 3x, external audit pending, funded in small tranches. Owner 0x5966dFaB11c8AEe767e0739083417D02f4a634A1, manager 0x063Ab6C16c38D19A4bC76E7c39A4A0A73afCaBb0. Free pool seeded with 300 PEPU; free-tier destinations are TapScore only for now. Free tier per user is 100 PEPU/day and 50 PEPU/hour, enforced by the policy service; beyond that a dApp deposits into its own project. Record: services/paymaster/contracts/deployed-address-v2.txt.";
|
|
16
|
+
var PAYMASTER_TESTNET_PENDING_REASON = "No paymaster (or any other ERC-4337 infrastructure) has been deployed to testnet \u2014 see TESTNET_AA_PENDING_REASON. The mainnet paymaster is a project-specific deployment, not something that would appear on testnet by default even once the rest of the AA stack does.";
|
|
17
|
+
var TESTNET_AA_PENDING_REASON = "Account-abstraction contracts were deployed on mainnet (97741) only, via ZeroDev's Conduit Marketplace integration. Nothing has been deployed to testnet, and testnet is currently out of scope (no faucet exists, so it cannot be funded without bridging).";
|
|
18
|
+
var pepuContracts = {
|
|
19
|
+
[pepuMainnet.id]: {
|
|
20
|
+
create2Factory: {
|
|
21
|
+
status: "deployed",
|
|
22
|
+
name: "CREATE2 Deterministic Deployer",
|
|
23
|
+
address: "0x4e59b44847b379578588920cA78FbF26c0B4956C",
|
|
24
|
+
verifiedAt: VERIFIED_AT,
|
|
25
|
+
notes: "Standard Nick's-method deterministic deployer."
|
|
26
|
+
},
|
|
27
|
+
multicall3: {
|
|
28
|
+
status: "deployed",
|
|
29
|
+
name: "Multicall3",
|
|
30
|
+
address: "0x9CE19273Ae9c24437DFF512E8DFCAed4E4B001bd",
|
|
31
|
+
verifiedAt: VERIFIED_AT,
|
|
32
|
+
notes: MULTICALL3_MAINNET_NOTES
|
|
33
|
+
},
|
|
34
|
+
permit2: {
|
|
35
|
+
status: "deployed",
|
|
36
|
+
name: "Permit2",
|
|
37
|
+
address: "0x000000000022D473030F116dDEE9F6B43aC78BA3",
|
|
38
|
+
verifiedAt: VERIFIED_AT,
|
|
39
|
+
notes: PERMIT2_MAINNET_NOTES
|
|
40
|
+
},
|
|
41
|
+
entryPoint06: {
|
|
42
|
+
status: "deployed",
|
|
43
|
+
name: "ERC-4337 EntryPoint v0.6",
|
|
44
|
+
address: "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789",
|
|
45
|
+
verifiedAt: VERIFIED_AT,
|
|
46
|
+
notes: ZERODEV_NOTES + " At the canonical v0.6 address."
|
|
47
|
+
},
|
|
48
|
+
entryPoint07: {
|
|
49
|
+
status: "deployed",
|
|
50
|
+
name: "ERC-4337 EntryPoint v0.7",
|
|
51
|
+
address: "0x0000000071727De22E5E9d8BAf0edAc6f37da032",
|
|
52
|
+
verifiedAt: VERIFIED_AT,
|
|
53
|
+
notes: ZERODEV_NOTES + " At the canonical v0.7 address; getNonce/balanceOf confirmed live."
|
|
54
|
+
},
|
|
55
|
+
kernelFactory: {
|
|
56
|
+
status: "deployed",
|
|
57
|
+
name: "Kernel v3 Account Factory",
|
|
58
|
+
address: "0xaac5D4240AF87249B3f71BC8E4A2cae074A3E419",
|
|
59
|
+
verifiedAt: VERIFIED_AT,
|
|
60
|
+
notes: ZERODEV_NOTES
|
|
61
|
+
},
|
|
62
|
+
kernelMetaFactory: {
|
|
63
|
+
status: "deployed",
|
|
64
|
+
name: "Kernel MetaFactory",
|
|
65
|
+
address: "0xd703aaE79538628d27099B8c4f621bE4CCd142d5",
|
|
66
|
+
verifiedAt: VERIFIED_AT,
|
|
67
|
+
notes: ZERODEV_NOTES
|
|
68
|
+
},
|
|
69
|
+
ecdsaValidator: {
|
|
70
|
+
status: "deployed",
|
|
71
|
+
name: "Kernel ECDSA Validator",
|
|
72
|
+
address: "0x845ADb2C711129d4f3966735eD98a9F09fC4cE57",
|
|
73
|
+
verifiedAt: VERIFIED_AT,
|
|
74
|
+
notes: ZERODEV_NOTES
|
|
75
|
+
},
|
|
76
|
+
paymaster: {
|
|
77
|
+
status: "deployed",
|
|
78
|
+
name: "Sponsored Paymaster v2 (PepuSponsoredPaymasterV7, alias of paymasterV2)",
|
|
79
|
+
address: "0xdb28528C9399C33c9A0297E8A62F39145acbC30D",
|
|
80
|
+
verifiedAt: PAYMASTER_V2_VERIFIED_AT,
|
|
81
|
+
notes: PAYMASTER_MAINNET_NOTES
|
|
82
|
+
},
|
|
83
|
+
kernelImplementation: {
|
|
84
|
+
status: "deployed",
|
|
85
|
+
name: "Kernel v3.1 Implementation",
|
|
86
|
+
address: "0xbAC849bB641841b44E965fb01A4Bf5F074F84B4d",
|
|
87
|
+
verifiedAt: VERIFIED_AT,
|
|
88
|
+
notes: KERNEL_IMPL_NOTES
|
|
89
|
+
},
|
|
90
|
+
kernelEcdsaSignerModule: {
|
|
91
|
+
status: "deployed",
|
|
92
|
+
name: "Kernel ECDSA Signer (permission signer module)",
|
|
93
|
+
address: "0x6A6F069E2a08c2468e7724Ab3250CdBFBA14D4FF",
|
|
94
|
+
verifiedAt: VERIFIED_AT,
|
|
95
|
+
notes: ZERODEV_NOTES + " Used as the signer in permission-validator session keys."
|
|
96
|
+
},
|
|
97
|
+
kernelCallPolicyV004: {
|
|
98
|
+
status: "deployed",
|
|
99
|
+
name: "ZeroDev Call Policy v0.0.4",
|
|
100
|
+
address: "0x9a52283276A0ec8740DF50bF01B28A80D880eaf2",
|
|
101
|
+
verifiedAt: VERIFIED_AT,
|
|
102
|
+
notes: ZERODEV_NOTES + " Scopes a session key to specific targets and selectors."
|
|
103
|
+
},
|
|
104
|
+
kernelTimestampPolicy: {
|
|
105
|
+
status: "deployed",
|
|
106
|
+
name: "ZeroDev Timestamp Policy",
|
|
107
|
+
address: "0xB9f8f524bE6EcD8C945b1b87f9ae5C192FdCE20F",
|
|
108
|
+
verifiedAt: VERIFIED_AT,
|
|
109
|
+
notes: ZERODEV_NOTES + " Bounds a session key to a validity window."
|
|
110
|
+
},
|
|
111
|
+
tapScore: {
|
|
112
|
+
status: "deployed",
|
|
113
|
+
name: "TapScore",
|
|
114
|
+
address: "0x261eA5971B93237a56990206A46Bc80318e4d078",
|
|
115
|
+
verifiedAt: VERIFIED_AT,
|
|
116
|
+
notes: TAPSCORE_NOTES
|
|
117
|
+
},
|
|
118
|
+
paymasterV1: {
|
|
119
|
+
status: "deployed",
|
|
120
|
+
name: "Verifying Paymaster v1 (PepuVerifyingPaymasterV7) - RETIRED",
|
|
121
|
+
address: "0x2B6FED323bFA24f0475f4e1Dd3C7F6Cc1f3ae8B0",
|
|
122
|
+
verifiedAt: VERIFIED_AT,
|
|
123
|
+
retired: true,
|
|
124
|
+
notes: PAYMASTER_V1_NOTES
|
|
125
|
+
},
|
|
126
|
+
paymasterV2: {
|
|
127
|
+
status: "deployed",
|
|
128
|
+
name: "Sponsored Paymaster v2 (PepuSponsoredPaymasterV7), canary",
|
|
129
|
+
address: "0xdb28528C9399C33c9A0297E8A62F39145acbC30D",
|
|
130
|
+
verifiedAt: PAYMASTER_V2_VERIFIED_AT,
|
|
131
|
+
notes: PAYMASTER_V2_NOTES
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
[pepuTestnet.id]: {
|
|
135
|
+
create2Factory: {
|
|
136
|
+
status: "deployed",
|
|
137
|
+
name: "CREATE2 Deterministic Deployer",
|
|
138
|
+
address: "0x4e59b44847b379578588920cA78FbF26c0B4956C",
|
|
139
|
+
notes: "Standard Nick's-method deterministic deployer."
|
|
140
|
+
},
|
|
141
|
+
multicall3: {
|
|
142
|
+
status: "pending",
|
|
143
|
+
name: "Multicall3",
|
|
144
|
+
reason: MULTICALL3_PENDING_REASON
|
|
145
|
+
},
|
|
146
|
+
permit2: {
|
|
147
|
+
status: "pending",
|
|
148
|
+
name: "Permit2",
|
|
149
|
+
reason: PERMIT2_PENDING_REASON
|
|
150
|
+
},
|
|
151
|
+
entryPoint06: {
|
|
152
|
+
status: "pending",
|
|
153
|
+
name: "ERC-4337 EntryPoint v0.6",
|
|
154
|
+
reason: TESTNET_AA_PENDING_REASON
|
|
155
|
+
},
|
|
156
|
+
entryPoint07: {
|
|
157
|
+
status: "pending",
|
|
158
|
+
name: "ERC-4337 EntryPoint v0.7",
|
|
159
|
+
reason: TESTNET_AA_PENDING_REASON
|
|
160
|
+
},
|
|
161
|
+
kernelFactory: {
|
|
162
|
+
status: "pending",
|
|
163
|
+
name: "Kernel v3 Account Factory",
|
|
164
|
+
reason: TESTNET_AA_PENDING_REASON
|
|
165
|
+
},
|
|
166
|
+
kernelMetaFactory: {
|
|
167
|
+
status: "pending",
|
|
168
|
+
name: "Kernel MetaFactory",
|
|
169
|
+
reason: TESTNET_AA_PENDING_REASON
|
|
170
|
+
},
|
|
171
|
+
ecdsaValidator: {
|
|
172
|
+
status: "pending",
|
|
173
|
+
name: "Kernel ECDSA Validator",
|
|
174
|
+
reason: TESTNET_AA_PENDING_REASON
|
|
175
|
+
},
|
|
176
|
+
paymaster: {
|
|
177
|
+
status: "pending",
|
|
178
|
+
name: "Verifying Paymaster (PepuVerifyingPaymasterV7)",
|
|
179
|
+
reason: PAYMASTER_TESTNET_PENDING_REASON
|
|
180
|
+
},
|
|
181
|
+
kernelImplementation: { status: "pending", name: "Kernel v3.1 Implementation", reason: TESTNET_AA_PENDING_REASON },
|
|
182
|
+
kernelEcdsaSignerModule: { status: "pending", name: "Kernel ECDSA Signer (permission signer module)", reason: TESTNET_AA_PENDING_REASON },
|
|
183
|
+
kernelCallPolicyV004: { status: "pending", name: "ZeroDev Call Policy v0.0.4", reason: TESTNET_AA_PENDING_REASON },
|
|
184
|
+
kernelTimestampPolicy: { status: "pending", name: "ZeroDev Timestamp Policy", reason: TESTNET_AA_PENDING_REASON },
|
|
185
|
+
tapScore: { status: "pending", name: "TapScore", reason: "Deployed on mainnet only." },
|
|
186
|
+
paymasterV1: { status: "pending", name: "Verifying Paymaster v1 (PepuVerifyingPaymasterV7)", reason: PAYMASTER_TESTNET_PENDING_REASON },
|
|
187
|
+
paymasterV2: { status: "pending", name: "Verifying Paymaster v2", reason: PAYMASTER_TESTNET_PENDING_REASON }
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
function getContract(chainId, name) {
|
|
191
|
+
return pepuContracts[chainId]?.[name];
|
|
192
|
+
}
|
|
193
|
+
function listContracts(chainId) {
|
|
194
|
+
const registry = pepuContracts[chainId];
|
|
195
|
+
return registry ? Object.values(registry) : [];
|
|
196
|
+
}
|
|
197
|
+
function isDeployed(entry) {
|
|
198
|
+
return entry?.status === "deployed";
|
|
199
|
+
}
|
|
200
|
+
function getPepuAddresses(chainId = pepuMainnet.id) {
|
|
201
|
+
const registry = pepuContracts[chainId];
|
|
202
|
+
if (!registry) return [];
|
|
203
|
+
return Object.keys(registry).map((key) => {
|
|
204
|
+
const e = registry[key];
|
|
205
|
+
return e.status === "deployed" ? {
|
|
206
|
+
key,
|
|
207
|
+
name: e.name,
|
|
208
|
+
status: "deployed",
|
|
209
|
+
address: e.address,
|
|
210
|
+
...e.verifiedAt ? { verifiedAt: e.verifiedAt } : {},
|
|
211
|
+
...e.retired ? { retired: true } : {},
|
|
212
|
+
note: e.notes ?? ""
|
|
213
|
+
} : { key, name: e.name, status: "pending", note: e.reason };
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export { getContract, getPepuAddresses, isDeployed, listContracts, pepuContracts };
|
|
218
|
+
//# sourceMappingURL=chunk-FCXSP2YF.js.map
|
|
219
|
+
//# sourceMappingURL=chunk-FCXSP2YF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/contracts.ts"],"names":[],"mappings":"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","file":"chunk-FCXSP2YF.js","sourcesContent":["import type { Address } from \"viem\";\n\nimport { pepuMainnet, pepuTestnet } from \"./chains.js\";\n\n/**\n * Canonical keys for contracts tracked by this registry. Adding a new key\n * here (and a corresponding entry per chain below) is not a breaking\n * change for consumers that read the registry through {@link getContract}\n * or {@link listContracts}.\n */\nexport type PepuContractName =\n | \"create2Factory\"\n | \"multicall3\"\n | \"permit2\"\n | \"entryPoint06\"\n | \"entryPoint07\"\n | \"kernelFactory\"\n | \"kernelMetaFactory\"\n | \"ecdsaValidator\"\n | \"paymaster\"\n | \"kernelImplementation\"\n | \"kernelEcdsaSignerModule\"\n | \"kernelCallPolicyV004\"\n | \"kernelTimestampPolicy\"\n | \"tapScore\"\n | \"paymasterV1\"\n | \"paymasterV2\";\n\n/** A contract that is confirmed live on-chain at `address`. */\nexport interface DeployedContract {\n readonly status: \"deployed\";\n /** Human-readable name, for logging/UI. */\n readonly name: string;\n /** Verified contract address. */\n readonly address: Address;\n /** Optional short note, e.g. how the address was verified. */\n readonly notes?: string;\n /**\n * ISO date (YYYY-MM-DD) on which the address was last confirmed to have\n * bytecode via `eth_getCode` against the PEPU mainnet RPC. Re-run\n * `node packages/sdk/scripts/live-check.mjs` to refresh.\n */\n readonly verifiedAt?: string;\n /**\n * True when the contract still has bytecode but must not be used (for example\n * the v1 paymaster, whose EntryPoint deposit was withdrawn). Never route new\n * work to a retired contract.\n */\n readonly retired?: true;\n}\n\n/**\n * A contract that is not yet deployed on this chain. Deliberately has no\n * `address` field — callers must not be able to accidentally read a\n * placeholder value and treat it as real. Use {@link getContract} /\n * {@link isDeployed} to narrow before reading an address.\n */\nexport interface PendingContract {\n readonly status: \"pending\";\n /** Human-readable name, for logging/UI. */\n readonly name: string;\n /** Why this contract has no verified address yet. */\n readonly reason: string;\n}\n\nexport type ContractEntry = DeployedContract | PendingContract;\n\n/** Per-chain contract catalog, keyed by {@link PepuContractName}. */\nexport type PepuContractRegistry = Readonly<\n Record<PepuContractName, ContractEntry>\n>;\n\nconst MULTICALL3_PENDING_REASON =\n \"Canonical Multicall3 (0xcA11bde05977b3631167028862bE2a173976CA11) was \" +\n \"deployed elsewhere via a pre-signed CREATE transaction with a \" +\n \"1,000,000 gas limit. This Arbitrum Nitro chain needs ~14.3M gas to \" +\n \"deploy the same bytecode, so that transaction cannot execute here and \" +\n \"the canonical address is unreachable. A PEPU-specific deployment is \" +\n \"pending; do not substitute the canonical address.\";\n\nconst MULTICALL3_MAINNET_NOTES =\n \"PEPU-specific deployment. NOT at the canonical Multicall3 address, \" +\n \"which is unreachable on this Nitro chain (the canonical pre-signed \" +\n \"CREATE tx carries a 1,000,000 gas limit; this bytecode needs ~14.3M). \" +\n \"Deployed from canonical mds1/multicall3 source (solc 0.8.12, optimizer \" +\n \"10,000,000 runs) via the CREATE2 deterministic deployer with a zero \" +\n \"salt, so the same source reproduces this address on any chain that has \" +\n \"that deployer. Verified on pepuscan. viem/wagmi multicall confirmed \" +\n \"working against it.\";\n\nconst ZERODEV_NOTES =\n \"Deployed by ZeroDev's one-click Conduit Marketplace integration \" +\n \"(mainnet only — not present on testnet).\";\n\nconst PERMIT2_PENDING_REASON =\n \"Not yet deployed on this chain. The CREATE2 deterministic deployer \" +\n \"needed to reproduce Permit2's canonical address is live, so this is \" +\n \"unblocked, but no deployment has happened (and been verified) yet.\";\n\nconst PERMIT2_MAINNET_NOTES =\n \"Deployed at the canonical Permit2 address via the CREATE2 deterministic \" +\n \"deployer, same as on every other chain that has it. Verified live \" +\n \"2026-09-24 via eth_getCode (9,152 bytes, matching Permit2's known \" +\n \"bytecode size) plus a successful DOMAIN_SEPARATOR() eth_call. This is \" +\n \"the canonical Permit2 — do not confuse it with PepuSwap's own separate \" +\n \"Permit2 deployment at pepuSwapContracts.permit2NonCanonical in ./dex.js, \" +\n \"which predates this one and is not interchangeable with it.\";\n\nconst PAYMASTER_MAINNET_NOTES =\n \"Alias of `paymasterV2`: the tiered PepuSponsoredPaymasterV7 canary (0xdb28...C30D), deployed \" +\n \"around block 10537341 and funded in small tranches. Internally reviewed 3x, external audit \" +\n \"pending. Owner 0x5966dFaB11c8AEe767e0739083417D02f4a634A1, manager \" +\n \"0x063Ab6C16c38D19A4bC76E7c39A4A0A73afCaBb0. The free pool was seeded with 300 PEPU; free-tier \" +\n \"destinations are TapScore only for now. It sponsors only through the hosted policy service \" +\n \"(paymaster.pepeunchained.com) with the hosted bundler (bundler.pepeunchained.com). The v1 \" +\n \"paymaster is retired (see `paymasterV1`).\";\n\n/** Date the mainnet addresses below were last checked with eth_getCode. */\nconst VERIFIED_AT = \"2026-10-02\";\n\n/** Date the v2 paymaster canary was verified live (deployment record: deploy-receipt-v2.json). */\nconst PAYMASTER_V2_VERIFIED_AT = \"2026-10-14\";\n\nconst KERNEL_IMPL_NOTES =\n ZERODEV_NOTES +\n \" Kernel v3.1 implementation that kernelFactory.implementation() resolves to; \" +\n \"same address ZeroDev uses on every chain with this version.\";\n\nconst TAPSCORE_NOTES =\n \"TapScore demo contract used by the game-app template. Verified via eth_getCode.\";\n\nconst PAYMASTER_V1_NOTES =\n \"RETIRED. The project's first verifying paymaster (PepuVerifyingPaymasterV7). Its EntryPoint \" +\n \"deposit was withdrawn (deposit is 0), so it cannot sponsor anything. The contract still has \" +\n \"bytecode; do not deposit to it or route new work to it. Superseded by `paymasterV2`. A real \" +\n \"sponsored operation ran through the hosted URLs on v1 before retirement (tx \" +\n \"0x57cf2f5a332248476d775c096b4b8339d81867c14211ed3bc4fcb1895dff0f9f).\";\n\nconst PAYMASTER_V2_NOTES =\n \"PepuSponsoredPaymasterV7 (v2), deployed on PEPU mainnet as a canary around block 10537341: \" +\n \"internally reviewed 3x, external audit pending, funded in small tranches. Owner \" +\n \"0x5966dFaB11c8AEe767e0739083417D02f4a634A1, manager 0x063Ab6C16c38D19A4bC76E7c39A4A0A73afCaBb0. \" +\n \"Free pool seeded with 300 PEPU; free-tier destinations are TapScore only for now. Free tier per \" +\n \"user is 100 PEPU/day and 50 PEPU/hour, enforced by the policy service; beyond that a dApp \" +\n \"deposits into its own project. Record: services/paymaster/contracts/deployed-address-v2.txt.\";\n\nconst PAYMASTER_TESTNET_PENDING_REASON =\n \"No paymaster (or any other ERC-4337 infrastructure) has been deployed to testnet — see \" +\n \"TESTNET_AA_PENDING_REASON. The mainnet paymaster is a project-specific deployment, not \" +\n \"something that would appear on testnet by default even once the rest of the AA stack does.\";\n\nconst TESTNET_AA_PENDING_REASON =\n \"Account-abstraction contracts were deployed on mainnet (97741) only, \" +\n \"via ZeroDev's Conduit Marketplace integration. Nothing has been \" +\n \"deployed to testnet, and testnet is currently out of scope (no faucet \" +\n \"exists, so it cannot be funded without bridging).\";\n\n/**\n * Contract registry, keyed by chain id. Tracked as independent per-chain\n * entries because deployments happen per-chain and have already diverged:\n * mainnet has the CREATE2 deployer, a PEPU-specific Multicall3, the\n * canonical Permit2, the full ZeroDev Kernel v3 AA stack (EntryPoint\n * v0.6/v0.7, Kernel factory/meta-factory, ECDSA validator), and a\n * project-deployed, funded verifying paymaster. Testnet has only the\n * CREATE2 deployer — everything else is `status: \"pending\"` because\n * testnet is out of scope for this package (no faucet exists to fund\n * verification there).\n *\n * Note on the paymaster specifically: `status: \"deployed\"` here means the\n * contract has live bytecode and a real EntryPoint deposit — it does NOT\n * mean gas sponsorship is usable by an application. See\n * `getSponsorshipStatus` in `./aa/status.js`, which is the single source of\n * truth for that separate question.\n */\nexport const pepuContracts: Readonly<\n Record<number, PepuContractRegistry>\n> = {\n [pepuMainnet.id]: {\n create2Factory: {\n status: \"deployed\",\n name: \"CREATE2 Deterministic Deployer\",\n address: \"0x4e59b44847b379578588920cA78FbF26c0B4956C\",\n verifiedAt: VERIFIED_AT,\n notes: \"Standard Nick's-method deterministic deployer.\",\n },\n multicall3: {\n status: \"deployed\",\n name: \"Multicall3\",\n address: \"0x9CE19273Ae9c24437DFF512E8DFCAed4E4B001bd\",\n verifiedAt: VERIFIED_AT,\n notes: MULTICALL3_MAINNET_NOTES,\n },\n permit2: {\n status: \"deployed\",\n name: \"Permit2\",\n address: \"0x000000000022D473030F116dDEE9F6B43aC78BA3\",\n verifiedAt: VERIFIED_AT,\n notes: PERMIT2_MAINNET_NOTES,\n },\n entryPoint06: {\n status: \"deployed\",\n name: \"ERC-4337 EntryPoint v0.6\",\n address: \"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789\",\n verifiedAt: VERIFIED_AT,\n notes: ZERODEV_NOTES + \" At the canonical v0.6 address.\",\n },\n entryPoint07: {\n status: \"deployed\",\n name: \"ERC-4337 EntryPoint v0.7\",\n address: \"0x0000000071727De22E5E9d8BAf0edAc6f37da032\",\n verifiedAt: VERIFIED_AT,\n notes:\n ZERODEV_NOTES +\n \" At the canonical v0.7 address; getNonce/balanceOf confirmed live.\",\n },\n kernelFactory: {\n status: \"deployed\",\n name: \"Kernel v3 Account Factory\",\n address: \"0xaac5D4240AF87249B3f71BC8E4A2cae074A3E419\",\n verifiedAt: VERIFIED_AT,\n notes: ZERODEV_NOTES,\n },\n kernelMetaFactory: {\n status: \"deployed\",\n name: \"Kernel MetaFactory\",\n address: \"0xd703aaE79538628d27099B8c4f621bE4CCd142d5\",\n verifiedAt: VERIFIED_AT,\n notes: ZERODEV_NOTES,\n },\n ecdsaValidator: {\n status: \"deployed\",\n name: \"Kernel ECDSA Validator\",\n address: \"0x845ADb2C711129d4f3966735eD98a9F09fC4cE57\",\n verifiedAt: VERIFIED_AT,\n notes: ZERODEV_NOTES,\n },\n paymaster: {\n status: \"deployed\",\n name: \"Sponsored Paymaster v2 (PepuSponsoredPaymasterV7, alias of paymasterV2)\",\n address: \"0xdb28528C9399C33c9A0297E8A62F39145acbC30D\",\n verifiedAt: PAYMASTER_V2_VERIFIED_AT,\n notes: PAYMASTER_MAINNET_NOTES,\n },\n kernelImplementation: {\n status: \"deployed\",\n name: \"Kernel v3.1 Implementation\",\n address: \"0xbAC849bB641841b44E965fb01A4Bf5F074F84B4d\",\n verifiedAt: VERIFIED_AT,\n notes: KERNEL_IMPL_NOTES,\n },\n kernelEcdsaSignerModule: {\n status: \"deployed\",\n name: \"Kernel ECDSA Signer (permission signer module)\",\n address: \"0x6A6F069E2a08c2468e7724Ab3250CdBFBA14D4FF\",\n verifiedAt: VERIFIED_AT,\n notes: ZERODEV_NOTES + \" Used as the signer in permission-validator session keys.\",\n },\n kernelCallPolicyV004: {\n status: \"deployed\",\n name: \"ZeroDev Call Policy v0.0.4\",\n address: \"0x9a52283276A0ec8740DF50bF01B28A80D880eaf2\",\n verifiedAt: VERIFIED_AT,\n notes: ZERODEV_NOTES + \" Scopes a session key to specific targets and selectors.\",\n },\n kernelTimestampPolicy: {\n status: \"deployed\",\n name: \"ZeroDev Timestamp Policy\",\n address: \"0xB9f8f524bE6EcD8C945b1b87f9ae5C192FdCE20F\",\n verifiedAt: VERIFIED_AT,\n notes: ZERODEV_NOTES + \" Bounds a session key to a validity window.\",\n },\n tapScore: {\n status: \"deployed\",\n name: \"TapScore\",\n address: \"0x261eA5971B93237a56990206A46Bc80318e4d078\",\n verifiedAt: VERIFIED_AT,\n notes: TAPSCORE_NOTES,\n },\n paymasterV1: {\n status: \"deployed\",\n name: \"Verifying Paymaster v1 (PepuVerifyingPaymasterV7) - RETIRED\",\n address: \"0x2B6FED323bFA24f0475f4e1Dd3C7F6Cc1f3ae8B0\",\n verifiedAt: VERIFIED_AT,\n retired: true,\n notes: PAYMASTER_V1_NOTES,\n },\n paymasterV2: {\n status: \"deployed\",\n name: \"Sponsored Paymaster v2 (PepuSponsoredPaymasterV7), canary\",\n address: \"0xdb28528C9399C33c9A0297E8A62F39145acbC30D\",\n verifiedAt: PAYMASTER_V2_VERIFIED_AT,\n notes: PAYMASTER_V2_NOTES,\n },\n },\n [pepuTestnet.id]: {\n create2Factory: {\n status: \"deployed\",\n name: \"CREATE2 Deterministic Deployer\",\n address: \"0x4e59b44847b379578588920cA78FbF26c0B4956C\",\n notes: \"Standard Nick's-method deterministic deployer.\",\n },\n multicall3: {\n status: \"pending\",\n name: \"Multicall3\",\n reason: MULTICALL3_PENDING_REASON,\n },\n permit2: {\n status: \"pending\",\n name: \"Permit2\",\n reason: PERMIT2_PENDING_REASON,\n },\n entryPoint06: {\n status: \"pending\",\n name: \"ERC-4337 EntryPoint v0.6\",\n reason: TESTNET_AA_PENDING_REASON,\n },\n entryPoint07: {\n status: \"pending\",\n name: \"ERC-4337 EntryPoint v0.7\",\n reason: TESTNET_AA_PENDING_REASON,\n },\n kernelFactory: {\n status: \"pending\",\n name: \"Kernel v3 Account Factory\",\n reason: TESTNET_AA_PENDING_REASON,\n },\n kernelMetaFactory: {\n status: \"pending\",\n name: \"Kernel MetaFactory\",\n reason: TESTNET_AA_PENDING_REASON,\n },\n ecdsaValidator: {\n status: \"pending\",\n name: \"Kernel ECDSA Validator\",\n reason: TESTNET_AA_PENDING_REASON,\n },\n paymaster: {\n status: \"pending\",\n name: \"Verifying Paymaster (PepuVerifyingPaymasterV7)\",\n reason: PAYMASTER_TESTNET_PENDING_REASON,\n },\n kernelImplementation: { status: \"pending\", name: \"Kernel v3.1 Implementation\", reason: TESTNET_AA_PENDING_REASON },\n kernelEcdsaSignerModule: { status: \"pending\", name: \"Kernel ECDSA Signer (permission signer module)\", reason: TESTNET_AA_PENDING_REASON },\n kernelCallPolicyV004: { status: \"pending\", name: \"ZeroDev Call Policy v0.0.4\", reason: TESTNET_AA_PENDING_REASON },\n kernelTimestampPolicy: { status: \"pending\", name: \"ZeroDev Timestamp Policy\", reason: TESTNET_AA_PENDING_REASON },\n tapScore: { status: \"pending\", name: \"TapScore\", reason: \"Deployed on mainnet only.\" },\n paymasterV1: { status: \"pending\", name: \"Verifying Paymaster v1 (PepuVerifyingPaymasterV7)\", reason: PAYMASTER_TESTNET_PENDING_REASON },\n paymasterV2: { status: \"pending\", name: \"Verifying Paymaster v2\", reason: PAYMASTER_TESTNET_PENDING_REASON },\n },\n};\n\n/** Look up one contract entry for a chain id. Returns `undefined` if the chain isn't in the registry. */\nexport function getContract(\n chainId: number,\n name: PepuContractName,\n): ContractEntry | undefined {\n return pepuContracts[chainId]?.[name];\n}\n\n/** List all tracked contract entries for a chain id, in registry order. */\nexport function listContracts(\n chainId: number,\n): readonly ContractEntry[] {\n const registry = pepuContracts[chainId];\n return registry ? Object.values(registry) : [];\n}\n\n/** Narrow a {@link ContractEntry} to {@link DeployedContract}. */\nexport function isDeployed(\n entry: ContractEntry | undefined,\n): entry is DeployedContract {\n return entry?.status === \"deployed\";\n}\n\n/** One row of the address table returned by {@link getPepuAddresses}. */\nexport interface PepuAddressRow {\n readonly key: PepuContractName;\n readonly name: string;\n readonly status: \"deployed\" | \"pending\";\n /** Present only when `status` is `\"deployed\"`. */\n readonly address?: Address;\n /** ISO date of the last `eth_getCode` check, when known. */\n readonly verifiedAt?: string;\n /** True for a deployed contract that is retired and must not be used (the v1 paymaster). */\n readonly retired?: true;\n /** Notes (deployed) or reason (pending). */\n readonly note: string;\n}\n\n/**\n * The full supporting-contract table for a chain, flattened for docs and\n * MCP rendering. Pending entries carry no `address`.\n *\n * @example\n * ```ts\n * const rows = getPepuAddresses(); // mainnet by default\n * const live = rows.filter((r) => r.status === \"deployed\");\n * ```\n */\nexport function getPepuAddresses(chainId: number = pepuMainnet.id): readonly PepuAddressRow[] {\n const registry = pepuContracts[chainId];\n if (!registry) return [];\n return (Object.keys(registry) as PepuContractName[]).map((key): PepuAddressRow => {\n const e = registry[key];\n return e.status === \"deployed\"\n ? {\n key,\n name: e.name,\n status: \"deployed\",\n address: e.address,\n ...(e.verifiedAt ? { verifiedAt: e.verifiedAt } : {}),\n ...(e.retired ? { retired: true as const } : {}),\n note: e.notes ?? \"\",\n }\n : { key, name: e.name, status: \"pending\", note: e.reason };\n });\n}\n"]}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { buildErc7677Url } from './chunk-IY3ALPUJ.js';
|
|
2
|
+
import { resolvePepuEndpoints, PEPU_ENV } from './chunk-XC4IBCI2.js';
|
|
3
|
+
import { pepuMainnet } from './chunk-VTQIHMF3.js';
|
|
4
|
+
import { PepuConfigError } from './chunk-6DSZ4Z2N.js';
|
|
5
|
+
import { http, createPublicClient } from 'viem';
|
|
6
|
+
import { createPaymasterClient, createBundlerClient } from 'viem/account-abstraction';
|
|
7
|
+
|
|
8
|
+
var ENTRY_POINT_V07 = {
|
|
9
|
+
address: "0x0000000071727De22E5E9d8BAf0edAc6f37da032",
|
|
10
|
+
version: "0.7"
|
|
11
|
+
};
|
|
12
|
+
var FEE_HEADROOM_NUM = 12n;
|
|
13
|
+
var FEE_HEADROOM_DEN = 10n;
|
|
14
|
+
async function estimatePepuUserOpFees(publicClient) {
|
|
15
|
+
const fees = await publicClient.estimateFeesPerGas();
|
|
16
|
+
return {
|
|
17
|
+
maxFeePerGas: fees.maxFeePerGas * FEE_HEADROOM_NUM / FEE_HEADROOM_DEN,
|
|
18
|
+
maxPriorityFeePerGas: fees.maxPriorityFeePerGas
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function requireBundlerUrl(explicit) {
|
|
22
|
+
const { bundlerUrl } = resolvePepuEndpoints(explicit === void 0 ? {} : { bundlerUrl: explicit });
|
|
23
|
+
if (bundlerUrl === null) {
|
|
24
|
+
throw new PepuConfigError("CONFIG_MISSING_ENV", `No bundler URL. Set ${PEPU_ENV.bundlerUrl} or pass bundlerUrl.`, {
|
|
25
|
+
hint: "The hosted PEPU bundler is the default; if it was cleared, set PEPU_BUNDLER_URL to https://bundler.pepeunchained.com or your own bundler."
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
return bundlerUrl;
|
|
29
|
+
}
|
|
30
|
+
function requirePaymasterUrl(explicit, token) {
|
|
31
|
+
const { paymasterUrl, paymasterBaseUrl } = resolvePepuEndpoints(explicit === void 0 ? {} : { paymasterUrl: explicit });
|
|
32
|
+
if (paymasterUrl !== null) return paymasterUrl;
|
|
33
|
+
if (token !== void 0 && token.trim() !== "" && paymasterBaseUrl !== null) {
|
|
34
|
+
return buildErc7677Url({ baseUrl: paymasterBaseUrl, token });
|
|
35
|
+
}
|
|
36
|
+
throw new PepuConfigError("CONFIG_MISSING_ENV", `No ERC-7677 paymaster URL. Set ${PEPU_ENV.paymasterUrl} or pass paymasterUrl / paymasterToken.`, {
|
|
37
|
+
hint: "The hosted paymaster (https://paymaster.pepeunchained.com) needs your project's client token: set PEPU_PAYMASTER_URL to https://paymaster.pepeunchained.com/v2/paymaster/<client token>."
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function createPepuPaymasterClient(o = {}) {
|
|
41
|
+
const client = createPaymasterClient({ transport: http(requirePaymasterUrl(o.paymasterUrl, o.paymasterToken)) });
|
|
42
|
+
const ctx = o.context;
|
|
43
|
+
if (!ctx) return client;
|
|
44
|
+
return {
|
|
45
|
+
...client,
|
|
46
|
+
getPaymasterData: (p) => client.getPaymasterData({ ...p, context: p.context ?? ctx }),
|
|
47
|
+
getPaymasterStubData: (p) => client.getPaymasterStubData({ ...p, context: p.context ?? ctx })
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function createPepuBundlerClient(o) {
|
|
51
|
+
const rpcUrl = resolvePepuEndpoints().rpcUrl;
|
|
52
|
+
const publicClient = o.publicClient ?? createPublicClient({ chain: pepuMainnet, transport: http(rpcUrl) });
|
|
53
|
+
return createBundlerClient({
|
|
54
|
+
account: o.account,
|
|
55
|
+
chain: pepuMainnet,
|
|
56
|
+
client: publicClient,
|
|
57
|
+
transport: http(requireBundlerUrl(o.bundlerUrl)),
|
|
58
|
+
...o.paymaster ? { paymaster: o.paymaster } : {},
|
|
59
|
+
...o.paymasterContext ? { paymasterContext: o.paymasterContext } : {},
|
|
60
|
+
userOperation: { estimateFeesPerGas: async () => estimatePepuUserOpFees(publicClient) }
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { ENTRY_POINT_V07, createPepuBundlerClient, createPepuPaymasterClient, estimatePepuUserOpFees, requireBundlerUrl };
|
|
65
|
+
//# sourceMappingURL=chunk-IB2FSPMJ.js.map
|
|
66
|
+
//# sourceMappingURL=chunk-IB2FSPMJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/aa/clients.ts"],"names":[],"mappings":"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","file":"chunk-IB2FSPMJ.js","sourcesContent":["import { createPublicClient, http } from \"viem\";\nimport type { PublicClient } from \"viem\";\nimport { createBundlerClient, createPaymasterClient } from \"viem/account-abstraction\";\nimport type { BundlerClient, PaymasterClient, SmartAccount } from \"viem/account-abstraction\";\n\nimport { pepuMainnet } from \"../chains.js\";\nimport { PEPU_ENV, resolvePepuEndpoints } from \"../endpoints.js\";\nimport { PepuConfigError } from \"../errors.js\";\nimport type { PaymasterContext } from \"../erc7677.js\";\nimport { buildErc7677Url } from \"../paymaster/api.js\";\n\n/** EntryPoint v0.7, the only version PEPU's bundler and paymaster speak. */\nexport const ENTRY_POINT_V07 = {\n address: \"0x0000000071727De22E5E9d8BAf0edAc6f37da032\",\n version: \"0.7\",\n} as const;\n\n/** Fee headroom numerator/denominator: 12/10 = +20%. */\nconst FEE_HEADROOM_NUM = 12n;\nconst FEE_HEADROOM_DEN = 10n;\n\n/**\n * The Alto-compatible fee estimator: the chain's own `estimateFeesPerGas`,\n * with `maxFeePerGas` x 1.2. Alto does not implement ZeroDev's\n * `zd_getUserOperationGasPrice`, so the default estimator would fail.\n * Ported from `templates/sponsored-session-app/lib/kernel.ts`.\n *\n * @example\n * const fees = await estimatePepuUserOpFees(publicClient);\n */\nexport async function estimatePepuUserOpFees(\n publicClient: Pick<PublicClient, \"estimateFeesPerGas\">,\n): Promise<{ maxFeePerGas: bigint; maxPriorityFeePerGas: bigint }> {\n const fees = await publicClient.estimateFeesPerGas();\n return {\n maxFeePerGas: (fees.maxFeePerGas * FEE_HEADROOM_NUM) / FEE_HEADROOM_DEN,\n maxPriorityFeePerGas: fees.maxPriorityFeePerGas,\n };\n}\n\n/** Resolve the bundler URL or throw `CONFIG_MISSING_ENV` naming the variable. */\nexport function requireBundlerUrl(explicit?: string): string {\n const { bundlerUrl } = resolvePepuEndpoints(explicit === undefined ? {} : { bundlerUrl: explicit });\n if (bundlerUrl === null) {\n throw new PepuConfigError(\"CONFIG_MISSING_ENV\", `No bundler URL. Set ${PEPU_ENV.bundlerUrl} or pass bundlerUrl.`, {\n hint: \"The hosted PEPU bundler is the default; if it was cleared, set PEPU_BUNDLER_URL to https://bundler.pepeunchained.com or your own bundler.\",\n });\n }\n return bundlerUrl;\n}\n\n/**\n * Resolve the complete ERC-7677 paymaster URL or throw `CONFIG_MISSING_ENV`.\n * Order: `explicit` URL, then `PEPU_PAYMASTER_URL`, then `token` (a project client token, built against the\n * paymaster base: the hosted service unless a custom URL is configured). The hosted paymaster has no tokenless\n * ERC-7677 URL, because the token names the project (or free-tier app) that is billed.\n */\nexport function requirePaymasterUrl(explicit?: string, token?: string): string {\n const { paymasterUrl, paymasterBaseUrl } = resolvePepuEndpoints(explicit === undefined ? {} : { paymasterUrl: explicit });\n if (paymasterUrl !== null) return paymasterUrl;\n if (token !== undefined && token.trim() !== \"\" && paymasterBaseUrl !== null) {\n return buildErc7677Url({ baseUrl: paymasterBaseUrl, token });\n }\n throw new PepuConfigError(\"CONFIG_MISSING_ENV\", `No ERC-7677 paymaster URL. Set ${PEPU_ENV.paymasterUrl} or pass paymasterUrl / paymasterToken.`, {\n hint: \"The hosted paymaster (https://paymaster.pepeunchained.com) needs your project's client token: set PEPU_PAYMASTER_URL to https://paymaster.pepeunchained.com/v2/paymaster/<client token>.\",\n });\n}\n\n/**\n * An ERC-7677 paymaster client for PEPU (viem `createPaymasterClient`), using\n * the endpoints registry for the URL. A `context` (for example\n * `buildPaymasterContext({ privyAccessToken })`) is injected into every\n * `pm_getPaymasterStubData` and `pm_getPaymasterData` call unless the caller\n * passes one.\n *\n * @example\n * const paymaster = createPepuPaymasterClient({\n * context: buildPaymasterContext({ privyAccessToken }),\n * });\n */\nexport function createPepuPaymasterClient(\n o: { paymasterUrl?: string; paymasterToken?: string; context?: PaymasterContext } = {},\n): PaymasterClient {\n const client = createPaymasterClient({ transport: http(requirePaymasterUrl(o.paymasterUrl, o.paymasterToken)) });\n const ctx = o.context;\n if (!ctx) return client;\n return {\n ...client,\n getPaymasterData: (p) => client.getPaymasterData({ ...p, context: p.context ?? ctx }),\n getPaymasterStubData: (p) => client.getPaymasterStubData({ ...p, context: p.context ?? ctx }),\n };\n}\n\n/**\n * A viem bundler client for PEPU's bundler, with the fee estimator\n * pre-wired ({@link estimatePepuUserOpFees}).\n *\n * @example\n * const bundler = createPepuBundlerClient({ account, paymaster: createPepuPaymasterClient() });\n * const hash = await bundler.sendUserOperation({ calls: [{ to, data }] });\n */\nexport function createPepuBundlerClient(o: {\n bundlerUrl?: string;\n account: SmartAccount;\n paymaster?: PaymasterClient;\n paymasterContext?: PaymasterContext;\n publicClient?: PublicClient;\n}): BundlerClient {\n const rpcUrl = resolvePepuEndpoints().rpcUrl;\n const publicClient = o.publicClient ?? createPublicClient({ chain: pepuMainnet, transport: http(rpcUrl) });\n return createBundlerClient({\n account: o.account,\n chain: pepuMainnet,\n client: publicClient,\n transport: http(requireBundlerUrl(o.bundlerUrl)),\n ...(o.paymaster ? { paymaster: o.paymaster } : {}),\n ...(o.paymasterContext ? { paymasterContext: o.paymasterContext } : {}),\n userOperation: { estimateFeesPerGas: async () => estimatePepuUserOpFees(publicClient) },\n }) as BundlerClient;\n}\n"]}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkYQL7NISX_cjs = require('./chunk-YQL7NISX.cjs');
|
|
4
|
+
var viem = require('viem');
|
|
5
|
+
|
|
6
|
+
var PRIVY_POLICY_NAME_MAX_LENGTH = 49;
|
|
7
|
+
function assertWithinPolicyNameLimit(value, field) {
|
|
8
|
+
if (value.length > PRIVY_POLICY_NAME_MAX_LENGTH) {
|
|
9
|
+
throw new chunkYQL7NISX_cjs.PepuPolicyError(
|
|
10
|
+
"POLICY_NAME_TOO_LONG",
|
|
11
|
+
`${field} is ${value.length} characters ("${value}"), but Privy rejects policy/rule names of ${PRIVY_POLICY_NAME_MAX_LENGTH + 1} or more (max ${PRIVY_POLICY_NAME_MAX_LENGTH}). Shorten it.`
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
function truncateAddress(address) {
|
|
17
|
+
return `${address.slice(0, 6)}...${address.slice(-4)}`;
|
|
18
|
+
}
|
|
19
|
+
function buildSessionPolicy({
|
|
20
|
+
contractAddress,
|
|
21
|
+
functions,
|
|
22
|
+
expiresAtUnixSeconds,
|
|
23
|
+
name
|
|
24
|
+
}) {
|
|
25
|
+
if (!viem.isAddress(contractAddress, { strict: false })) {
|
|
26
|
+
throw new chunkYQL7NISX_cjs.PepuPolicyError(
|
|
27
|
+
"POLICY_UNSCOPED",
|
|
28
|
+
"buildSessionPolicy: contractAddress must be a valid 0x address; refusing to build an unscoped policy."
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
if (functions.length === 0) {
|
|
32
|
+
throw new chunkYQL7NISX_cjs.PepuPolicyError(
|
|
33
|
+
"POLICY_UNSCOPED",
|
|
34
|
+
"buildSessionPolicy: at least one function is required; refusing to build an unscoped policy."
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
for (const fn of functions) {
|
|
38
|
+
if (fn.type !== "function" || !fn.name) {
|
|
39
|
+
throw new chunkYQL7NISX_cjs.PepuPolicyError(
|
|
40
|
+
"POLICY_UNSCOPED",
|
|
41
|
+
"buildSessionPolicy: every entry in `functions` must be an ABI function fragment with a name."
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (!Number.isInteger(expiresAtUnixSeconds) || expiresAtUnixSeconds <= 0) {
|
|
46
|
+
throw new chunkYQL7NISX_cjs.PepuPolicyError(
|
|
47
|
+
"POLICY_UNSCOPED",
|
|
48
|
+
"buildSessionPolicy: expiresAtUnixSeconds must be a positive integer (unix seconds); refusing to build a policy with no expiry."
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
const short = truncateAddress(contractAddress);
|
|
52
|
+
const policyName = assertWithinPolicyNameLimit(
|
|
53
|
+
name ?? `session: ${functions.map((f) => f.name).join("/")} on ${short}`,
|
|
54
|
+
"Policy name"
|
|
55
|
+
);
|
|
56
|
+
const rules = functions.map((fn, index) => ({
|
|
57
|
+
name: assertWithinPolicyNameLimit(
|
|
58
|
+
`Allow ${fn.name}() on ${short}, 0 value, expires`,
|
|
59
|
+
`Rule name ("rules[${index}].name")`
|
|
60
|
+
),
|
|
61
|
+
method: "eth_signTransaction",
|
|
62
|
+
action: "ALLOW",
|
|
63
|
+
conditions: [
|
|
64
|
+
{ field_source: "ethereum_transaction", field: "to", operator: "eq", value: contractAddress },
|
|
65
|
+
{
|
|
66
|
+
field_source: "ethereum_calldata",
|
|
67
|
+
field: "function_name",
|
|
68
|
+
abi: [fn],
|
|
69
|
+
operator: "eq",
|
|
70
|
+
value: fn.name
|
|
71
|
+
},
|
|
72
|
+
{ field_source: "ethereum_transaction", field: "value", operator: "eq", value: "0x0" },
|
|
73
|
+
{
|
|
74
|
+
field_source: "system",
|
|
75
|
+
field: "current_unix_timestamp",
|
|
76
|
+
operator: "lte",
|
|
77
|
+
value: String(expiresAtUnixSeconds)
|
|
78
|
+
}
|
|
79
|
+
]
|
|
80
|
+
}));
|
|
81
|
+
return { version: "1.0", name: policyName, chain_type: "ethereum", rules };
|
|
82
|
+
}
|
|
83
|
+
function withGasLimitBuffer(estimatedGas) {
|
|
84
|
+
return estimatedGas + estimatedGas * 20n / 100n;
|
|
85
|
+
}
|
|
86
|
+
async function broadcastSignedTransaction(client, signed) {
|
|
87
|
+
const raw = typeof signed === "string" ? signed : signed.signed_transaction;
|
|
88
|
+
if (!viem.isHex(raw) || raw.length <= 2) {
|
|
89
|
+
throw new Error("broadcastSignedTransaction: expected a 0x-prefixed hex signed transaction.");
|
|
90
|
+
}
|
|
91
|
+
return client.sendRawTransaction({ serializedTransaction: raw });
|
|
92
|
+
}
|
|
93
|
+
async function signAndBroadcast(params) {
|
|
94
|
+
const { client, from, to, chainId, sign } = params;
|
|
95
|
+
const value = params.value ?? 0n;
|
|
96
|
+
const data = params.data ?? (params.abi && params.functionName ? viem.encodeFunctionData({
|
|
97
|
+
abi: params.abi,
|
|
98
|
+
functionName: params.functionName,
|
|
99
|
+
...params.args ? { args: params.args } : {}
|
|
100
|
+
}) : void 0);
|
|
101
|
+
if (!data) {
|
|
102
|
+
throw new Error("signAndBroadcast: provide `data`, or `abi` + `functionName`.");
|
|
103
|
+
}
|
|
104
|
+
const [nonce, estimatedGas, gasPrice] = await Promise.all([
|
|
105
|
+
client.getTransactionCount({ address: from, blockTag: "pending" }),
|
|
106
|
+
client.estimateGas({ account: from, to, data, value }),
|
|
107
|
+
client.getGasPrice()
|
|
108
|
+
]);
|
|
109
|
+
const transaction = {
|
|
110
|
+
to,
|
|
111
|
+
data,
|
|
112
|
+
value: viem.toHex(value),
|
|
113
|
+
chain_id: chainId,
|
|
114
|
+
type: 0,
|
|
115
|
+
nonce,
|
|
116
|
+
gas_limit: viem.toHex(withGasLimitBuffer(estimatedGas)),
|
|
117
|
+
gas_price: viem.toHex(gasPrice)
|
|
118
|
+
};
|
|
119
|
+
return broadcastSignedTransaction(client, await sign(transaction));
|
|
120
|
+
}
|
|
121
|
+
var DEFAULT_SESSION_MINUTES = 15;
|
|
122
|
+
var MAX_SESSION_MINUTES = 1440;
|
|
123
|
+
function resolveSessionMinutes(raw) {
|
|
124
|
+
if (raw === null || raw === void 0 || typeof raw === "string" && raw.trim() === "") {
|
|
125
|
+
return DEFAULT_SESSION_MINUTES;
|
|
126
|
+
}
|
|
127
|
+
const n = Number(raw);
|
|
128
|
+
if (!Number.isFinite(n) || n <= 0) return DEFAULT_SESSION_MINUTES;
|
|
129
|
+
return Math.min(n, MAX_SESSION_MINUTES);
|
|
130
|
+
}
|
|
131
|
+
function sessionExpiry(nowSeconds, minutes) {
|
|
132
|
+
return Math.floor(nowSeconds + minutes * 60);
|
|
133
|
+
}
|
|
134
|
+
function describeSessionScope(p) {
|
|
135
|
+
if (!viem.isAddress(p.contractAddress, { strict: false })) {
|
|
136
|
+
throw new chunkYQL7NISX_cjs.PepuPolicyError("POLICY_UNSCOPED", "describeSessionScope: contractAddress must be a valid 0x address.");
|
|
137
|
+
}
|
|
138
|
+
if (p.functions.length === 0) {
|
|
139
|
+
throw new chunkYQL7NISX_cjs.PepuPolicyError("POLICY_UNSCOPED", "describeSessionScope: at least one function is required.");
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
contractAddress: p.contractAddress,
|
|
143
|
+
expiresAtUnixSeconds: p.expiresAtUnixSeconds,
|
|
144
|
+
functions: p.functions.map((fn) => {
|
|
145
|
+
if (fn.type !== "function" || !fn.name) {
|
|
146
|
+
throw new chunkYQL7NISX_cjs.PepuPolicyError(
|
|
147
|
+
"POLICY_UNSCOPED",
|
|
148
|
+
"describeSessionScope: every entry in `functions` must be an ABI function fragment with a name."
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
name: fn.name,
|
|
153
|
+
signature: viem.toFunctionSignature(fn).replace(/^function /, ""),
|
|
154
|
+
selector: viem.toFunctionSelector(fn),
|
|
155
|
+
valueWei: "0"
|
|
156
|
+
};
|
|
157
|
+
})
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
var SESSION_TRUST_NOTICE = {
|
|
161
|
+
"privy-offchain": "This scope is enforced by Privy's backend policy engine when it receives each transaction request, not by an on-chain contract. You are trusting Privy's policy engine and this app's policy configuration to enforce the limits correctly. Gas is paid by your wallet and is not capped by the policy.",
|
|
162
|
+
"kernel-onchain": "This scope is enforced on-chain by your smart account's permission validator (call and timestamp policies). The limits hold even if this app's backend is compromised, but the session key can still act within them until it expires or you revoke it."
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
exports.DEFAULT_SESSION_MINUTES = DEFAULT_SESSION_MINUTES;
|
|
166
|
+
exports.MAX_SESSION_MINUTES = MAX_SESSION_MINUTES;
|
|
167
|
+
exports.PRIVY_POLICY_NAME_MAX_LENGTH = PRIVY_POLICY_NAME_MAX_LENGTH;
|
|
168
|
+
exports.SESSION_TRUST_NOTICE = SESSION_TRUST_NOTICE;
|
|
169
|
+
exports.assertWithinPolicyNameLimit = assertWithinPolicyNameLimit;
|
|
170
|
+
exports.broadcastSignedTransaction = broadcastSignedTransaction;
|
|
171
|
+
exports.buildSessionPolicy = buildSessionPolicy;
|
|
172
|
+
exports.describeSessionScope = describeSessionScope;
|
|
173
|
+
exports.resolveSessionMinutes = resolveSessionMinutes;
|
|
174
|
+
exports.sessionExpiry = sessionExpiry;
|
|
175
|
+
exports.signAndBroadcast = signAndBroadcast;
|
|
176
|
+
exports.withGasLimitBuffer = withGasLimitBuffer;
|
|
177
|
+
//# sourceMappingURL=chunk-IG7RSL2Y.cjs.map
|
|
178
|
+
//# sourceMappingURL=chunk-IG7RSL2Y.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/session/policy.ts"],"names":["PepuPolicyError","isAddress","isHex","encodeFunctionData","toHex","toFunctionSignature","toFunctionSelector"],"mappings":"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","file":"chunk-IG7RSL2Y.cjs","sourcesContent":["import { encodeFunctionData, isAddress, isHex, toFunctionSelector, toFunctionSignature, toHex } from \"viem\";\nimport type { Abi, AbiFunction, Address, Hash, Hex } from \"viem\";\nimport { PepuPolicyError } from \"../errors.js\";\n\n/**\n * SERVER-ONLY helpers (`@pepu-chain/sdk/server`). Nothing here holds a secret,\n * but these run on a backend that does hold Privy's app secret and\n * authorization key; keep this entry point out of client bundles. No module\n * in `src/` imports the `./server` barrel (enforced by a test). This file is the pure policy builder; it is re-exported from `@pepu-chain/sdk/session` and `@pepu-chain/sdk/server`.\n */\n\n/**\n * Privy rejects policy and rule names of 50 characters or more. Its published\n * OpenAPI spec says `maxLength: 50`, but the live validator says \"must be\n * fewer than 50 characters\", so the real limit is 49 (measured on a real\n * `POST /policies` 400). Using 49 is safe under both readings.\n */\nexport const PRIVY_POLICY_NAME_MAX_LENGTH = 49;\n\n/** Throws if `value` is over {@link PRIVY_POLICY_NAME_MAX_LENGTH}; returns it otherwise. */\nexport function assertWithinPolicyNameLimit(value: string, field: string): string {\n if (value.length > PRIVY_POLICY_NAME_MAX_LENGTH) {\n throw new PepuPolicyError(\"POLICY_NAME_TOO_LONG\", \n `${field} is ${value.length} characters (\"${value}\"), but Privy rejects policy/rule names ` +\n `of ${PRIVY_POLICY_NAME_MAX_LENGTH + 1} or more (max ${PRIVY_POLICY_NAME_MAX_LENGTH}). Shorten it.`,\n );\n }\n return value;\n}\n\nexport type SessionPolicyCondition =\n | { field_source: \"ethereum_transaction\"; field: \"to\" | \"value\"; operator: \"eq\"; value: string }\n | {\n field_source: \"ethereum_calldata\";\n field: \"function_name\";\n abi: AbiFunction[];\n operator: \"eq\";\n value: string;\n }\n | { field_source: \"system\"; field: \"current_unix_timestamp\"; operator: \"lte\"; value: string };\n\nexport interface SessionPolicyRule {\n name: string;\n method: \"eth_signTransaction\";\n action: \"ALLOW\";\n conditions: SessionPolicyCondition[];\n}\n\n/** Body for `privy.policies().create(...)`. */\nexport interface SessionPolicy {\n version: \"1.0\";\n name: string;\n chain_type: \"ethereum\";\n rules: SessionPolicyRule[];\n}\n\nexport interface BuildSessionPolicyParams {\n /** The one contract the session may call. */\n contractAddress: Address;\n /** The function(s) the session may call, as ABI function fragments. At least one. */\n functions: readonly AbiFunction[];\n /** Unix seconds after which Privy's engine denies every request. */\n expiresAtUnixSeconds: number;\n /** Optional dashboard label; must be at most 49 characters. */\n name?: string;\n}\n\nfunction truncateAddress(address: string): string {\n return `${address.slice(0, 6)}...${address.slice(-4)}`;\n}\n\n/**\n * Build the scoped Privy session-signer policy: ONE `ALLOW` rule per function,\n * each requiring `to` equals the contract, calldata decodes to that function,\n * `value` is exactly zero, and the clock is before expiry. Privy ANDs the\n * conditions in a rule, ORs the rules, and denies by default.\n *\n * Refuses to build an unscoped policy: it throws on an invalid contract\n * address, no functions, a non-function ABI item, or a bad expiry. Names are\n * checked against {@link PRIVY_POLICY_NAME_MAX_LENGTH}. The method is\n * `eth_signTransaction` (a rule for `eth_sendTransaction` never matches the\n * sign-and-broadcast flow).\n *\n * The scope is enforced by Privy's backend policy engine, not on-chain.\n */\nexport function buildSessionPolicy({\n contractAddress,\n functions,\n expiresAtUnixSeconds,\n name,\n}: BuildSessionPolicyParams): SessionPolicy {\n if (!isAddress(contractAddress, { strict: false })) {\n throw new PepuPolicyError(\"POLICY_UNSCOPED\", \n \"buildSessionPolicy: contractAddress must be a valid 0x address; refusing to build an unscoped policy.\",\n );\n }\n if (functions.length === 0) {\n throw new PepuPolicyError(\"POLICY_UNSCOPED\", \n \"buildSessionPolicy: at least one function is required; refusing to build an unscoped policy.\",\n );\n }\n for (const fn of functions) {\n if (fn.type !== \"function\" || !fn.name) {\n throw new PepuPolicyError(\"POLICY_UNSCOPED\", \n \"buildSessionPolicy: every entry in `functions` must be an ABI function fragment with a name.\",\n );\n }\n }\n if (!Number.isInteger(expiresAtUnixSeconds) || expiresAtUnixSeconds <= 0) {\n throw new PepuPolicyError(\"POLICY_UNSCOPED\", \n \"buildSessionPolicy: expiresAtUnixSeconds must be a positive integer (unix seconds); refusing to build a policy with no expiry.\",\n );\n }\n\n const short = truncateAddress(contractAddress);\n const policyName = assertWithinPolicyNameLimit(\n name ?? `session: ${functions.map((f) => f.name).join(\"/\")} on ${short}`,\n \"Policy name\",\n );\n\n const rules: SessionPolicyRule[] = functions.map((fn, index) => ({\n name: assertWithinPolicyNameLimit(\n `Allow ${fn.name}() on ${short}, 0 value, expires`,\n `Rule name (\"rules[${index}].name\")`,\n ),\n method: \"eth_signTransaction\",\n action: \"ALLOW\",\n conditions: [\n { field_source: \"ethereum_transaction\", field: \"to\", operator: \"eq\", value: contractAddress },\n {\n field_source: \"ethereum_calldata\",\n field: \"function_name\",\n abi: [fn],\n operator: \"eq\",\n value: fn.name,\n },\n { field_source: \"ethereum_transaction\", field: \"value\", operator: \"eq\", value: \"0x0\" },\n {\n field_source: \"system\",\n field: \"current_unix_timestamp\",\n operator: \"lte\",\n value: String(expiresAtUnixSeconds),\n },\n ],\n }));\n\n return { version: \"1.0\", name: policyName, chain_type: \"ethereum\", rules };\n}\n\n/** The unsigned legacy transaction body Privy's `eth_signTransaction` takes (snake_case, hex quantities). */\nexport interface PrivyUnsignedTransaction {\n readonly to: Address;\n readonly data: Hex;\n readonly value: Hex;\n readonly chain_id: number;\n readonly type: 0;\n readonly nonce: number;\n readonly gas_limit: Hex;\n readonly gas_price: Hex;\n}\n\n/** What Privy's `signTransaction` returns, or just the raw hex. */\nexport type SignedTransactionLike = Hex | { signed_transaction: string };\n\n/** Minimal viem client surface needed to broadcast. */\nexport interface BroadcastClient {\n sendRawTransaction(args: { serializedTransaction: Hex }): Promise<Hash>;\n}\n\n/** Minimal viem client surface needed to resolve nonce/gas and broadcast. */\nexport interface SignAndBroadcastClient extends BroadcastClient {\n getTransactionCount(args: { address: Address; blockTag: \"pending\" }): Promise<number>;\n estimateGas(args: { account: Address; to: Address; data: Hex; value: bigint }): Promise<bigint>;\n getGasPrice(): Promise<bigint>;\n}\n\n/** Estimate plus 20%: Nitro gas estimates can undershoot slightly. */\nexport function withGasLimitBuffer(estimatedGas: bigint): bigint {\n return estimatedGas + (estimatedGas * 20n) / 100n;\n}\n\n/**\n * Broadcast a raw signed transaction (from Privy `eth_signTransaction`) to\n * PEPU through a viem client and return the transaction hash. Accepts the raw\n * hex or Privy's `{ signed_transaction }` object. A failure here is a failed\n * TRANSACTION (revert, nonce race), not proof the session signer is gone.\n */\nexport async function broadcastSignedTransaction(\n client: BroadcastClient,\n signed: SignedTransactionLike,\n): Promise<Hash> {\n const raw = typeof signed === \"string\" ? signed : signed.signed_transaction;\n if (!isHex(raw) || raw.length <= 2) {\n throw new Error(\"broadcastSignedTransaction: expected a 0x-prefixed hex signed transaction.\");\n }\n return client.sendRawTransaction({ serializedTransaction: raw });\n}\n\nexport interface SignAndBroadcastParams {\n client: SignAndBroadcastClient;\n /** The wallet that signs (the session-signer wallet's address). */\n from: Address;\n to: Address;\n /** Pre-encoded calldata, or use `abi` + `functionName` + `args`. */\n data?: Hex;\n abi?: Abi;\n functionName?: string;\n args?: readonly unknown[];\n /** Native value in wei. Default 0n. */\n value?: bigint;\n chainId: number;\n /**\n * Performs the signing, e.g. a call to\n * `privy.wallets().ethereum().signTransaction(walletId, { params: { transaction }, authorization_context })`\n * and returns its result. Injected so this package has no Privy dependency.\n */\n sign: (transaction: PrivyUnsignedTransaction) => Promise<SignedTransactionLike>;\n}\n\n/**\n * The full sign-with-Privy, broadcast-yourself flow: resolve nonce (pending),\n * gas (+20%) and gas price against PEPU's RPC, build the unsigned legacy\n * transaction, hand it to `sign`, then broadcast the result and return the hash.\n * Privy's server-side `eth_sendTransaction` rejects chain 97741, which is why\n * this exists.\n */\nexport async function signAndBroadcast(params: SignAndBroadcastParams): Promise<Hash> {\n const { client, from, to, chainId, sign } = params;\n const value = params.value ?? 0n;\n const data =\n params.data ??\n (params.abi && params.functionName\n ? encodeFunctionData({\n abi: params.abi,\n functionName: params.functionName,\n ...(params.args ? { args: params.args } : {}),\n } as Parameters<typeof encodeFunctionData>[0])\n : undefined);\n if (!data) {\n throw new Error(\"signAndBroadcast: provide `data`, or `abi` + `functionName`.\");\n }\n\n const [nonce, estimatedGas, gasPrice] = await Promise.all([\n client.getTransactionCount({ address: from, blockTag: \"pending\" }),\n client.estimateGas({ account: from, to, data, value }),\n client.getGasPrice(),\n ]);\n\n const transaction: PrivyUnsignedTransaction = {\n to,\n data,\n value: toHex(value),\n chain_id: chainId,\n type: 0,\n nonce,\n gas_limit: toHex(withGasLimitBuffer(estimatedGas)),\n gas_price: toHex(gasPrice),\n };\n\n return broadcastSignedTransaction(client, await sign(transaction));\n}\n\n/** Default session length when `SESSION_DURATION_MINUTES` is unset or invalid. */\nexport const DEFAULT_SESSION_MINUTES = 15;\n/** Upper bound for a session: 24 hours. Larger requests are clamped. */\nexport const MAX_SESSION_MINUTES = 1440;\n\n/**\n * Parse a session duration (an env value or number) into minutes: anything\n * missing, non-numeric, zero or negative falls back to\n * {@link DEFAULT_SESSION_MINUTES}; anything above {@link MAX_SESSION_MINUTES} is clamped.\n * Lifted from templates/game-app/lib/env.server.ts.\n *\n * @example\n * resolveSessionMinutes(process.env.SESSION_DURATION_MINUTES); // 15 when unset\n * resolveSessionMinutes(\"99999\"); // 1440\n */\nexport function resolveSessionMinutes(raw: string | number | null | undefined): number {\n if (raw === null || raw === undefined || (typeof raw === \"string\" && raw.trim() === \"\")) {\n return DEFAULT_SESSION_MINUTES;\n }\n const n = Number(raw);\n if (!Number.isFinite(n) || n <= 0) return DEFAULT_SESSION_MINUTES;\n return Math.min(n, MAX_SESSION_MINUTES);\n}\n\n/**\n * The unix-seconds expiry for a session that starts at `nowSeconds` and lasts\n * `minutes`. Whole seconds, rounded down.\n *\n * @example\n * sessionExpiry(1_700_000_000, 15); // 1_700_000_900\n */\nexport function sessionExpiry(nowSeconds: number, minutes: number): number {\n return Math.floor(nowSeconds + minutes * 60);\n}\n\n/** One callable function in a session's scope, ready for a consent screen. */\nexport interface SessionScopeFunction {\n name: string;\n /** e.g. `tap()` or `transfer(address,uint256)`. */\n signature: string;\n /** 4-byte selector. */\n selector: Hex;\n /** Always `\"0\"`: a session call never carries native value. */\n valueWei: \"0\";\n}\n\n/** What a session may do, as plain data for a consent screen. */\nexport interface SessionScope {\n contractAddress: Address;\n functions: SessionScopeFunction[];\n expiresAtUnixSeconds: number;\n}\n\n/**\n * Consent-screen data for a session: the one contract, each allowed function\n * (name, signature, selector), zero value, and the expiry. Throws on an\n * invalid address or an empty or non-function list, same as {@link buildSessionPolicy}.\n *\n * @example\n * const scope = describeSessionScope({ contractAddress, functions: [tapAbi], expiresAtUnixSeconds });\n * scope.functions[0]?.signature; // \"tap()\"\n */\nexport function describeSessionScope(p: {\n contractAddress: Address;\n functions: readonly AbiFunction[];\n expiresAtUnixSeconds: number;\n}): SessionScope {\n if (!isAddress(p.contractAddress, { strict: false })) {\n throw new PepuPolicyError(\"POLICY_UNSCOPED\", \"describeSessionScope: contractAddress must be a valid 0x address.\");\n }\n if (p.functions.length === 0) {\n throw new PepuPolicyError(\"POLICY_UNSCOPED\", \"describeSessionScope: at least one function is required.\");\n }\n return {\n contractAddress: p.contractAddress,\n expiresAtUnixSeconds: p.expiresAtUnixSeconds,\n functions: p.functions.map((fn) => {\n if (fn.type !== \"function\" || !fn.name) {\n throw new PepuPolicyError(\"POLICY_UNSCOPED\", \n \"describeSessionScope: every entry in `functions` must be an ABI function fragment with a name.\",\n );\n }\n return {\n name: fn.name,\n signature: toFunctionSignature(fn).replace(/^function /, \"\"),\n selector: toFunctionSelector(fn),\n valueWei: \"0\" as const,\n };\n }),\n };\n}\n\n/**\n * The mandatory honest statements about who enforces a session's limits. Show\n * the one for the mode in use on the consent screen. Adapted from\n * templates/game-app/components/session-consent-screen.tsx.\n *\n * @example\n * <p>{SESSION_TRUST_NOTICE[\"privy-offchain\"]}</p>\n */\nexport const SESSION_TRUST_NOTICE: Record<\"privy-offchain\" | \"kernel-onchain\", string> = {\n \"privy-offchain\":\n \"This scope is enforced by Privy's backend policy engine when it receives each transaction request, not by an on-chain contract. You are trusting Privy's policy engine and this app's policy configuration to enforce the limits correctly. Gas is paid by your wallet and is not capped by the policy.\",\n \"kernel-onchain\":\n \"This scope is enforced on-chain by your smart account's permission validator (call and timestamp policies). The limits hold even if this app's backend is compromised, but the session key can still act within them until it expires or you revoke it.\",\n};\n"]}
|