@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,515 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var viem = require('viem');
|
|
4
|
+
|
|
5
|
+
// src/errors.ts
|
|
6
|
+
var PEPU_ERRORS_DOCS_URL = "https://guide.pepeunchained.com/reference/errors";
|
|
7
|
+
var PEPU_ERROR_CATALOG = [
|
|
8
|
+
{
|
|
9
|
+
code: "PRIVY_KEY_QUORUM_MISMATCH",
|
|
10
|
+
title: "Privy authorization key does not match the wallet owner",
|
|
11
|
+
cause: "Privy returned 401 'No valid authorization keys or user signing keys available': the server's PRIVY_AUTHORIZATION_KEY is not a signer on the wallet, or the key quorum id differs from the one the user granted.",
|
|
12
|
+
fix: "Make sure PRIVY_AUTHORIZATION_KEY is the private half of the key whose quorum id is NEXT_PUBLIC_PRIVY_KEY_QUORUM_ID, and that the user granted that quorum as a signer.",
|
|
13
|
+
status: 500,
|
|
14
|
+
retryable: false,
|
|
15
|
+
matchers: [/No valid authorization keys or user signing keys available/i]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
code: "POLICY_NAME_TOO_LONG",
|
|
19
|
+
title: "Privy policy or rule name is too long",
|
|
20
|
+
cause: "Privy rejects policy and rule names of 50 or more characters (the real limit is 49).",
|
|
21
|
+
fix: "Shorten the policy or rule name to 49 characters or fewer.",
|
|
22
|
+
status: 400,
|
|
23
|
+
retryable: false,
|
|
24
|
+
matchers: [/must be fewer than 50 characters/i, /name[^.\n]{0,40}\b(50|49) characters/i]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
code: "WALLET_COINBASE_UNSUPPORTED_CHAIN",
|
|
28
|
+
title: "Coinbase Smart Wallet does not support PEPU",
|
|
29
|
+
cause: "Coinbase Smart Wallet is a smart-contract wallet on chains it knows; PEPU (97741) is not one of them, and it floods the console with unsupported-chain errors.",
|
|
30
|
+
fix: "Pin Coinbase to eoaOnly via createPepuPrivyConfig() from @pepu-chain/sdk/privy.",
|
|
31
|
+
status: 400,
|
|
32
|
+
retryable: false,
|
|
33
|
+
matchers: [
|
|
34
|
+
/coinbase[\s\S]{0,120}(unsupported|not supported)[\s\S]{0,60}chain/i,
|
|
35
|
+
/(unsupported|not supported) chain[\s\S]{0,120}coinbase/i
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
code: "PRIVY_CHAIN_REJECTED_97741",
|
|
40
|
+
title: "Privy rejects server-side eth_sendTransaction on PEPU",
|
|
41
|
+
cause: "Privy's server-side send path does not know chain 97741 and rejects it. Signing works; sending does not.",
|
|
42
|
+
fix: "Sign with eth_signTransaction on the server and broadcast the raw transaction yourself (signAndBroadcast from @pepu-chain/sdk/session).",
|
|
43
|
+
status: 502,
|
|
44
|
+
retryable: false,
|
|
45
|
+
matchers: [
|
|
46
|
+
/eip155:97741[\s\S]{0,160}(unsupported|not supported|invalid|unknown|not found)/i,
|
|
47
|
+
/(unsupported|not supported|unknown|invalid) (chain|network|caip2)[\s\S]{0,80}97741/i
|
|
48
|
+
]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
code: "PAYMASTER_ORIGIN_NOT_ALLOWED",
|
|
52
|
+
title: "Paymaster refused the request origin",
|
|
53
|
+
cause: "The request Origin is not on the project's allowlist.",
|
|
54
|
+
fix: "Add the exact origin (scheme, host and port) to the project's allowed origins.",
|
|
55
|
+
status: 403,
|
|
56
|
+
retryable: false,
|
|
57
|
+
matchers: [/origin_not_allowed/i]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
code: "PAYMASTER_DESTINATION_NOT_ALLOWED",
|
|
61
|
+
title: "Paymaster refused the call destination",
|
|
62
|
+
cause: "The UserOperation targets a contract that is not on the project's target allowlist.",
|
|
63
|
+
fix: "Add the contract to the project's targets, or sponsor only calls to allowed targets.",
|
|
64
|
+
status: 403,
|
|
65
|
+
retryable: false,
|
|
66
|
+
matchers: [/(destination|target)_not_allowed/i]
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
code: "PAYMASTER_PROJECT_NOT_CLAIMED",
|
|
70
|
+
title: "Sponsorship project is not claimed on-chain",
|
|
71
|
+
cause: "Deposits can sit in an unclaimed project, but nothing is sponsored until its owner has claimed it on-chain (the contract reports ProjectNotClaimed, the service project_not_claimed_onchain).",
|
|
72
|
+
fix: "Prove the Privy app (requestClaimAttestation from @pepu-chain/sdk/paymaster/server), call claimProject, then configureProject (setTargets, setDailyLimit, setSenderDailyLimit).",
|
|
73
|
+
status: 409,
|
|
74
|
+
retryable: false,
|
|
75
|
+
matchers: [/project_not_claimed_onchain/i, /ProjectNotClaimed/i]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
code: "PAYMASTER_PROJECT_OWNER_CHANGED",
|
|
79
|
+
title: "Project owner changed since the credentials were issued",
|
|
80
|
+
cause: "The on-chain owner of the project is no longer the address the off-chain credentials were issued to (an ownership transfer or re-claim completed).",
|
|
81
|
+
fix: "As the new owner, sign in with SIWE, register the project again and rotate the client token and server key.",
|
|
82
|
+
status: 403,
|
|
83
|
+
retryable: false,
|
|
84
|
+
matchers: [/project_owner_changed/i]
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
code: "PAYMASTER_PROJECT_PAUSED",
|
|
88
|
+
title: "Sponsorship project is paused",
|
|
89
|
+
cause: "The project owner paused sponsorship on-chain.",
|
|
90
|
+
fix: "The owner can resume it with setPaused(projectId, false).",
|
|
91
|
+
status: 403,
|
|
92
|
+
retryable: false,
|
|
93
|
+
matchers: [/project_paused/i, /SponsorPaused/i]
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
code: "PAYMASTER_IDENTITY_REQUIRED",
|
|
97
|
+
title: "A verified Privy account is required",
|
|
98
|
+
cause: "The free tier (and any project with requireIdentity on) only sponsors users with a verified Privy access token.",
|
|
99
|
+
fix: "Send the user's Privy access token as Authorization: Bearer (or context.privyAccessToken for ERC-7677).",
|
|
100
|
+
status: 401,
|
|
101
|
+
retryable: false,
|
|
102
|
+
matchers: [/(project|free_tier)_identity_required/i]
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
code: "PAYMASTER_FREE_TIER_UNAVAILABLE",
|
|
106
|
+
title: "Free tier cannot sponsor this operation",
|
|
107
|
+
cause: "The free tier is disabled, its pool is empty, or the operation is larger than the per-op cap.",
|
|
108
|
+
fix: "Deposit into your own project and use its credentials, or retry later.",
|
|
109
|
+
status: 429,
|
|
110
|
+
retryable: true,
|
|
111
|
+
matchers: [/free_tier_disabled/i, /free_pool_(empty|op_too_large)/i]
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
code: "PAYMASTER_RATE_LIMITED",
|
|
115
|
+
title: "Paymaster API rate limit",
|
|
116
|
+
cause: "Too many requests to the paymaster API from this IP or account.",
|
|
117
|
+
fix: "Back off for the Retry-After interval (error.details.retryAfterSeconds when present).",
|
|
118
|
+
status: 429,
|
|
119
|
+
retryable: true,
|
|
120
|
+
matchers: [/\brate_limited\b/i]
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
code: "PAYMASTER_SESSION_REQUIRED",
|
|
124
|
+
title: "Paymaster owner session missing or expired",
|
|
125
|
+
cause: "Owner endpoints need a SIWE session token (1 h lifetime) for the project's current on-chain owner.",
|
|
126
|
+
fix: "Call loginWithWallet() on the paymaster API client, then retry.",
|
|
127
|
+
status: 401,
|
|
128
|
+
retryable: false,
|
|
129
|
+
matchers: []
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
code: "PAYMASTER_API_ERROR",
|
|
133
|
+
title: "Paymaster API request failed",
|
|
134
|
+
cause: "The paymaster API returned an error that has no more specific PEPU code.",
|
|
135
|
+
fix: "Read error.details (HTTP status and the service's error code) and the OpenAPI spec for that route.",
|
|
136
|
+
status: 502,
|
|
137
|
+
retryable: false,
|
|
138
|
+
matchers: []
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
code: "PAYMASTER_DENIED",
|
|
142
|
+
title: "Paymaster denied the sponsorship",
|
|
143
|
+
cause: "The paymaster rejected the credential or the sender (for example unknown_or_invalid_app_credential or sender_not_owned_by_token_user).",
|
|
144
|
+
fix: "Check the app credential or token, and that the smart account belongs to the user whose access token you sent.",
|
|
145
|
+
status: 403,
|
|
146
|
+
retryable: false,
|
|
147
|
+
matchers: [
|
|
148
|
+
/unknown_or_invalid_app_credential/i,
|
|
149
|
+
/sender_not_owned_by_token_user/i,
|
|
150
|
+
/paymaster[\s\S]{0,40}(denied|rejected)/i
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
code: "PAYMASTER_NO_BALANCE",
|
|
155
|
+
title: "Sponsorship project has no balance",
|
|
156
|
+
cause: "The project's paymaster deposit cannot cover this operation.",
|
|
157
|
+
fix: "Deposit more PEPU to the project, then retry.",
|
|
158
|
+
status: 429,
|
|
159
|
+
retryable: true,
|
|
160
|
+
matchers: [/(project_)?(no|insufficient)_balance/i, /project_balance_exhausted/i, /InsufficientSponsorBalance/i, /insufficient (project )?(balance|deposit)[\s\S]{0,40}paymaster/i]
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
code: "PAYMASTER_CAP",
|
|
164
|
+
title: "Sponsorship cap reached",
|
|
165
|
+
cause: "A daily, per-sender or per-operation sponsorship cap was hit.",
|
|
166
|
+
fix: "Wait for the cap window to reset, or raise the project's daily and sender limits.",
|
|
167
|
+
status: 429,
|
|
168
|
+
retryable: true,
|
|
169
|
+
matchers: [/(daily|sender|per_sender)[_ -]?(cap|limit)[_ ]?(exceeded|reached)/i, /cap_exceeded|limit_exceeded/i, /free_tier_[a-z_]*_(exceeded|reached)/i, /fee_above_onchain_cap/i]
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
code: "BUNDLER_AA_FAILED",
|
|
173
|
+
title: "EntryPoint rejected the UserOperation",
|
|
174
|
+
cause: "The EntryPoint reported FailedOp with an AAxx code during validation or execution.",
|
|
175
|
+
fix: "Read the AAxx code: AA21 prefund missing, AA23 signature or validation reverted, AA25 invalid nonce, AA31/AA33/AA34 paymaster problems.",
|
|
176
|
+
status: 502,
|
|
177
|
+
retryable: false,
|
|
178
|
+
matchers: [/\bAA(1\d|2\d|3\d|4\d|5\d|9\d)\b/, /FailedOp(WithRevert)?/]
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
code: "BUNDLER_UNREACHABLE",
|
|
182
|
+
title: "Bundler or paymaster is unreachable",
|
|
183
|
+
cause: "The request to the bundler or paymaster URL failed before any response.",
|
|
184
|
+
fix: "Check PEPU_BUNDLER_URL and PEPU_PAYMASTER_URL. The hosted services may not be live yet; use checkSponsorship().",
|
|
185
|
+
status: 502,
|
|
186
|
+
retryable: true,
|
|
187
|
+
matchers: [/ECONNREFUSED|ENOTFOUND|ETIMEDOUT|fetch failed|bundler[\s\S]{0,30}unreachable/i]
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
code: "TX_NONCE_RACE",
|
|
191
|
+
title: "Nonce conflict",
|
|
192
|
+
cause: "Two transactions raced for one nonce, or a replacement was underpriced.",
|
|
193
|
+
fix: "Serialize sends per account (a lock), re-read the pending nonce, and retry.",
|
|
194
|
+
status: 409,
|
|
195
|
+
retryable: true,
|
|
196
|
+
matchers: [/nonce too (low|high)/i, /replacement transaction underpriced/i, /already known/i]
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
code: "TX_GAS_UNDERSHOOT",
|
|
200
|
+
title: "Gas limit too low",
|
|
201
|
+
cause: "Nitro gas estimation undershoots on PEPU: the L1 data component is not covered by the plain estimate.",
|
|
202
|
+
fix: "Add headroom to the estimate, 20% via withGasLimitBuffer() from @pepu-chain/sdk/session.",
|
|
203
|
+
status: 502,
|
|
204
|
+
retryable: true,
|
|
205
|
+
matchers: [/intrinsic gas too low/i, /gas required exceeds allowance/i, /gas limit too low/i]
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
code: "TX_REVERTED",
|
|
209
|
+
title: "Transaction reverted",
|
|
210
|
+
cause: "The contract call reverted.",
|
|
211
|
+
fix: "Decode the revert reason with explainError(<revert data>) and check arguments, allowances and balances.",
|
|
212
|
+
status: 502,
|
|
213
|
+
retryable: false,
|
|
214
|
+
matchers: [/execution reverted/i, /transaction (has )?reverted/i]
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
code: "MULTICALL3_CANONICAL_ADDRESS",
|
|
218
|
+
title: "Canonical Multicall3 address used on PEPU",
|
|
219
|
+
cause: "PEPU's Multicall3 is not at the canonical 0xcA11...CA11 address.",
|
|
220
|
+
fix: "Use getMulticall3() or pepuMulticall() from @pepu-chain/sdk, or the pepuMainnet chain object, which carries the right address.",
|
|
221
|
+
status: 500,
|
|
222
|
+
retryable: false,
|
|
223
|
+
matchers: [/0xcA11bde05977b3631167028862bE2a173976CA11/i]
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
code: "WALLET_INJECTED_ACTIVE",
|
|
227
|
+
title: "An injected browser wallet is the active account",
|
|
228
|
+
cause: "wagmi's active account is a browser extension rather than the Privy embedded wallet.",
|
|
229
|
+
fix: "Pin the embedded wallet with useActiveWalletPin() from @pepu-chain/sdk/privy/wagmi.",
|
|
230
|
+
status: 400,
|
|
231
|
+
retryable: false,
|
|
232
|
+
matchers: [/ConnectorNotConnectedError/i, /chrome-extension:\/\//i, /injected (wallet|provider|connector)/i]
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
code: "CONFIG_PRIVY_CREATE_ON_LOGIN",
|
|
236
|
+
title: "Embedded wallet never appears after login",
|
|
237
|
+
cause: "The dashboard's automatic embedded wallet creation is off, so createOnLogin never resolves.",
|
|
238
|
+
fix: "Create the wallet server-side with the ensure-wallet route (createEnsureWalletRoute), or enable creation in the Privy dashboard.",
|
|
239
|
+
status: 500,
|
|
240
|
+
retryable: false,
|
|
241
|
+
matchers: [/createOnLogin/i, /embedded wallet[\s\S]{0,60}(never|did not|didn't) (appear|created)/i]
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
code: "CONFIG_ORIGIN_MISMATCH",
|
|
245
|
+
title: "Origin is not allowed by Privy",
|
|
246
|
+
cause: "The page origin (scheme, host and port) is not in the Privy app's allowed origins. A different dev port is the usual cause.",
|
|
247
|
+
fix: "Add the exact origin, including the port, to Privy dashboard Allowed origins.",
|
|
248
|
+
status: 500,
|
|
249
|
+
retryable: false,
|
|
250
|
+
matchers: [/origin[^.\n]{0,60}(not allowed|not configured|not in (the )?allowed)/i, /allowed origins?/i]
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
code: "CONFIG_PRIVY_DASHBOARD",
|
|
254
|
+
title: "Privy dashboard misconfiguration",
|
|
255
|
+
cause: "A required Privy dashboard setting is missing.",
|
|
256
|
+
fix: "Run checkPrivyDashboardConfig() and follow its fix list.",
|
|
257
|
+
status: 500,
|
|
258
|
+
retryable: false,
|
|
259
|
+
matchers: []
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
code: "CONFIG_MISSING_ENV",
|
|
263
|
+
title: "Missing environment variable",
|
|
264
|
+
cause: "A required environment variable is not set.",
|
|
265
|
+
fix: "Set the listed variables (see .env.example) and restart the process.",
|
|
266
|
+
status: 500,
|
|
267
|
+
retryable: false,
|
|
268
|
+
matchers: [/missing required env/i]
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
code: "CONFIG_BAD_URL",
|
|
272
|
+
title: "Invalid endpoint URL",
|
|
273
|
+
cause: "A configured bundler, paymaster or RPC URL is not a valid http(s) URL.",
|
|
274
|
+
fix: "Use a full URL such as https://bundler.example.com.",
|
|
275
|
+
status: 500,
|
|
276
|
+
retryable: false,
|
|
277
|
+
matchers: []
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
code: "CONFIG_SERVER_ONLY",
|
|
281
|
+
title: "Server-only module imported in the browser",
|
|
282
|
+
cause: "A server entry point was bundled into client code.",
|
|
283
|
+
fix: "Import server entries only from route handlers, server actions and scripts.",
|
|
284
|
+
status: 500,
|
|
285
|
+
retryable: false,
|
|
286
|
+
matchers: []
|
|
287
|
+
},
|
|
288
|
+
{
|
|
289
|
+
code: "AUTH_INVALID_TOKEN",
|
|
290
|
+
title: "Invalid or missing Privy access token",
|
|
291
|
+
cause: "The request carried no bearer token, or Privy could not verify it.",
|
|
292
|
+
fix: "Send Authorization: Bearer <getAccessToken()> and verify the token server-side.",
|
|
293
|
+
status: 401,
|
|
294
|
+
retryable: false,
|
|
295
|
+
matchers: [/invalid (auth(orization)?|access|jwt|id) token/i, /\bjwt (expired|malformed|invalid)/i]
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
code: "WALLET_NOT_PROVISIONED",
|
|
299
|
+
title: "User has no embedded wallet yet",
|
|
300
|
+
cause: "The user is signed in but no embedded Ethereum wallet exists.",
|
|
301
|
+
fix: "Call the ensure-wallet route (useEnsureWallet or WalletGate) before acting.",
|
|
302
|
+
status: 409,
|
|
303
|
+
retryable: true,
|
|
304
|
+
matchers: []
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
code: "POLICY_UNSCOPED",
|
|
308
|
+
title: "Session policy is not scoped",
|
|
309
|
+
cause: "A session policy needs a target contract, at least one function and an expiry.",
|
|
310
|
+
fix: "Pass contractAddress, functions and expiresAtUnixSeconds to buildSessionPolicy().",
|
|
311
|
+
status: 400,
|
|
312
|
+
retryable: false,
|
|
313
|
+
matchers: []
|
|
314
|
+
},
|
|
315
|
+
{
|
|
316
|
+
code: "SESSION_EXPIRED",
|
|
317
|
+
title: "Session expired",
|
|
318
|
+
cause: "The session's expiry has passed.",
|
|
319
|
+
fix: "Grant a new session.",
|
|
320
|
+
status: 410,
|
|
321
|
+
retryable: false,
|
|
322
|
+
matchers: []
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
code: "SESSION_NONE",
|
|
326
|
+
title: "No active session",
|
|
327
|
+
cause: "The user has not granted a session, or it was revoked.",
|
|
328
|
+
fix: "Ask the user to grant a session first.",
|
|
329
|
+
status: 409,
|
|
330
|
+
retryable: false,
|
|
331
|
+
matchers: []
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
code: "SESSION_APPROVAL_MISMATCH",
|
|
335
|
+
title: "Session approval does not match",
|
|
336
|
+
cause: "The approval was made for another account, permission id or mode.",
|
|
337
|
+
fix: "Re-run prepare, have the owner sign again, then activate.",
|
|
338
|
+
status: 409,
|
|
339
|
+
retryable: false,
|
|
340
|
+
matchers: []
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
code: "UNKNOWN",
|
|
344
|
+
title: "Unknown error",
|
|
345
|
+
cause: "The error did not match any known PEPU failure.",
|
|
346
|
+
fix: "Read the original message. Run pepu_known_gotchas in the MCP server, or search the docs.",
|
|
347
|
+
status: 500,
|
|
348
|
+
retryable: false,
|
|
349
|
+
matchers: []
|
|
350
|
+
}
|
|
351
|
+
];
|
|
352
|
+
var catalogByCode = new Map(
|
|
353
|
+
PEPU_ERROR_CATALOG.map((e) => [e.code, e])
|
|
354
|
+
);
|
|
355
|
+
function getErrorEntry(code) {
|
|
356
|
+
const entry = catalogByCode.get(code) ?? catalogByCode.get("UNKNOWN");
|
|
357
|
+
if (!entry) throw new Error("PEPU_ERROR_CATALOG is missing the UNKNOWN entry");
|
|
358
|
+
return entry;
|
|
359
|
+
}
|
|
360
|
+
function errorDocsUrl(code) {
|
|
361
|
+
return `${PEPU_ERRORS_DOCS_URL}#${code}`;
|
|
362
|
+
}
|
|
363
|
+
var PepuError = class extends Error {
|
|
364
|
+
code;
|
|
365
|
+
hint;
|
|
366
|
+
docsUrl;
|
|
367
|
+
retryable;
|
|
368
|
+
status;
|
|
369
|
+
details;
|
|
370
|
+
constructor(code, message, options = {}) {
|
|
371
|
+
const entry = getErrorEntry(code);
|
|
372
|
+
super(message ?? entry.title, options.cause === void 0 ? void 0 : { cause: options.cause });
|
|
373
|
+
this.name = new.target.name;
|
|
374
|
+
this.code = code;
|
|
375
|
+
this.hint = options.hint ?? entry.fix;
|
|
376
|
+
this.docsUrl = options.docsUrl ?? errorDocsUrl(code);
|
|
377
|
+
this.retryable = options.retryable ?? entry.retryable;
|
|
378
|
+
this.status = options.status ?? entry.status;
|
|
379
|
+
if (options.details !== void 0) this.details = options.details;
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
var PepuConfigError = class extends PepuError {
|
|
383
|
+
};
|
|
384
|
+
var PepuAuthError = class extends PepuError {
|
|
385
|
+
};
|
|
386
|
+
var PepuPolicyError = class extends PepuError {
|
|
387
|
+
};
|
|
388
|
+
var PepuSessionError = class extends PepuError {
|
|
389
|
+
};
|
|
390
|
+
var PepuBundlerError = class extends PepuError {
|
|
391
|
+
};
|
|
392
|
+
var PepuPaymasterError = class extends PepuError {
|
|
393
|
+
};
|
|
394
|
+
var PepuChainError = class extends PepuError {
|
|
395
|
+
};
|
|
396
|
+
function classForCode(code) {
|
|
397
|
+
if (code.startsWith("CONFIG_") || code.startsWith("PRIVY_")) return PepuConfigError;
|
|
398
|
+
if (code === "AUTH_INVALID_TOKEN" || code === "WALLET_NOT_PROVISIONED") return PepuAuthError;
|
|
399
|
+
if (code.startsWith("POLICY_")) return PepuPolicyError;
|
|
400
|
+
if (code.startsWith("SESSION_")) return PepuSessionError;
|
|
401
|
+
if (code.startsWith("BUNDLER_")) return PepuBundlerError;
|
|
402
|
+
if (code.startsWith("PAYMASTER_")) return PepuPaymasterError;
|
|
403
|
+
if (code.startsWith("TX_") || code.startsWith("MULTICALL3_") || code.startsWith("WALLET_")) return PepuChainError;
|
|
404
|
+
return PepuError;
|
|
405
|
+
}
|
|
406
|
+
var REVERT_ABI = [
|
|
407
|
+
{ type: "error", name: "Error", inputs: [{ name: "message", type: "string" }] },
|
|
408
|
+
{ type: "error", name: "Panic", inputs: [{ name: "code", type: "uint256" }] },
|
|
409
|
+
{
|
|
410
|
+
type: "error",
|
|
411
|
+
name: "FailedOp",
|
|
412
|
+
inputs: [
|
|
413
|
+
{ name: "opIndex", type: "uint256" },
|
|
414
|
+
{ name: "reason", type: "string" }
|
|
415
|
+
]
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
type: "error",
|
|
419
|
+
name: "FailedOpWithRevert",
|
|
420
|
+
inputs: [
|
|
421
|
+
{ name: "opIndex", type: "uint256" },
|
|
422
|
+
{ name: "reason", type: "string" },
|
|
423
|
+
{ name: "inner", type: "bytes" }
|
|
424
|
+
]
|
|
425
|
+
}
|
|
426
|
+
];
|
|
427
|
+
function flatten(e) {
|
|
428
|
+
const seen = /* @__PURE__ */ new Set();
|
|
429
|
+
const parts = [];
|
|
430
|
+
let cur = e;
|
|
431
|
+
for (let depth = 0; depth < 6 && cur !== void 0 && cur !== null && !seen.has(cur); depth++) {
|
|
432
|
+
seen.add(cur);
|
|
433
|
+
if (typeof cur === "object") {
|
|
434
|
+
const o = cur;
|
|
435
|
+
for (const k of ["shortMessage", "message", "details", "reason"]) {
|
|
436
|
+
const v = o[k];
|
|
437
|
+
if (typeof v === "string") parts.push(v);
|
|
438
|
+
}
|
|
439
|
+
cur = o["cause"];
|
|
440
|
+
} else {
|
|
441
|
+
parts.push(String(cur));
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
return parts.join("\n");
|
|
446
|
+
}
|
|
447
|
+
function matchCatalog(text) {
|
|
448
|
+
return PEPU_ERROR_CATALOG.find((entry) => entry.matchers.some((m) => m.test(text)));
|
|
449
|
+
}
|
|
450
|
+
function explanation(entry, matched) {
|
|
451
|
+
return {
|
|
452
|
+
code: entry.code,
|
|
453
|
+
title: entry.title,
|
|
454
|
+
cause: entry.cause,
|
|
455
|
+
fix: entry.fix,
|
|
456
|
+
docsUrl: errorDocsUrl(entry.code),
|
|
457
|
+
matched
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
function explainError(e) {
|
|
461
|
+
if (e instanceof PepuError) return explanation(getErrorEntry(e.code), "catalog");
|
|
462
|
+
if (typeof e === "string" && viem.isHex(e) && e.length >= 10) {
|
|
463
|
+
try {
|
|
464
|
+
const decoded = viem.decodeErrorResult({ abi: REVERT_ABI, data: e });
|
|
465
|
+
const argText = (decoded.args ?? []).map((a) => typeof a === "string" ? a : "").join("\n");
|
|
466
|
+
const hit2 = matchCatalog(`${argText}
|
|
467
|
+
${decoded.errorName}`);
|
|
468
|
+
if (hit2) return explanation(hit2, "abi-decode");
|
|
469
|
+
return explanation(getErrorEntry("TX_REVERTED"), "abi-decode");
|
|
470
|
+
} catch {
|
|
471
|
+
return explanation(getErrorEntry("UNKNOWN"), "unknown");
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
const text = typeof e === "string" ? e : flatten(e);
|
|
475
|
+
const hit = matchCatalog(text);
|
|
476
|
+
return hit ? explanation(hit, "catalog") : explanation(getErrorEntry("UNKNOWN"), "unknown");
|
|
477
|
+
}
|
|
478
|
+
function toPepuError(e, ctx) {
|
|
479
|
+
if (e instanceof PepuError) return e;
|
|
480
|
+
const explained = explainError(e);
|
|
481
|
+
const original = (typeof e === "string" ? e : flatten(e)) || "Unknown error";
|
|
482
|
+
const message = ctx ? `${ctx.op}: ${original}` : original;
|
|
483
|
+
const Cls = classForCode(explained.code);
|
|
484
|
+
return new Cls(explained.code, message, { cause: e });
|
|
485
|
+
}
|
|
486
|
+
function toErrorBody(e) {
|
|
487
|
+
const err = toPepuError(e);
|
|
488
|
+
return { error: { code: err.code, message: err.message, hint: err.hint } };
|
|
489
|
+
}
|
|
490
|
+
function toErrorResponse(e) {
|
|
491
|
+
const err = toPepuError(e);
|
|
492
|
+
return new Response(JSON.stringify(toErrorBody(err)), {
|
|
493
|
+
status: err.status,
|
|
494
|
+
headers: { "content-type": "application/json" }
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
exports.PEPU_ERRORS_DOCS_URL = PEPU_ERRORS_DOCS_URL;
|
|
499
|
+
exports.PEPU_ERROR_CATALOG = PEPU_ERROR_CATALOG;
|
|
500
|
+
exports.PepuAuthError = PepuAuthError;
|
|
501
|
+
exports.PepuBundlerError = PepuBundlerError;
|
|
502
|
+
exports.PepuChainError = PepuChainError;
|
|
503
|
+
exports.PepuConfigError = PepuConfigError;
|
|
504
|
+
exports.PepuError = PepuError;
|
|
505
|
+
exports.PepuPaymasterError = PepuPaymasterError;
|
|
506
|
+
exports.PepuPolicyError = PepuPolicyError;
|
|
507
|
+
exports.PepuSessionError = PepuSessionError;
|
|
508
|
+
exports.errorDocsUrl = errorDocsUrl;
|
|
509
|
+
exports.explainError = explainError;
|
|
510
|
+
exports.getErrorEntry = getErrorEntry;
|
|
511
|
+
exports.toErrorBody = toErrorBody;
|
|
512
|
+
exports.toErrorResponse = toErrorResponse;
|
|
513
|
+
exports.toPepuError = toPepuError;
|
|
514
|
+
//# sourceMappingURL=chunk-YQL7NISX.cjs.map
|
|
515
|
+
//# sourceMappingURL=chunk-YQL7NISX.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts"],"names":["isHex","decodeErrorResult","hit"],"mappings":"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","file":"chunk-YQL7NISX.cjs","sourcesContent":["import { decodeErrorResult, isHex } from \"viem\";\nimport type { Abi, Hex } from \"viem\";\n\n/**\n * The SDK error model. Everything the SDK throws is a {@link PepuError}\n * subclass carrying a stable `code`, a one-sentence `hint` and a `docsUrl`.\n * Messages never contain secrets: they name environment variables, never\n * their values.\n */\n\nexport const PEPU_ERRORS_DOCS_URL = \"https://guide.pepeunchained.com/reference/errors\";\n\nexport type PepuErrorCode =\n | \"CONFIG_MISSING_ENV\"\n | \"CONFIG_BAD_URL\"\n | \"CONFIG_SERVER_ONLY\"\n | \"CONFIG_PRIVY_DASHBOARD\"\n | \"CONFIG_PRIVY_CREATE_ON_LOGIN\"\n | \"CONFIG_ORIGIN_MISMATCH\"\n | \"AUTH_INVALID_TOKEN\"\n | \"WALLET_NOT_PROVISIONED\"\n | \"WALLET_COINBASE_UNSUPPORTED_CHAIN\"\n | \"WALLET_INJECTED_ACTIVE\"\n | \"POLICY_UNSCOPED\"\n | \"POLICY_NAME_TOO_LONG\"\n | \"SESSION_EXPIRED\"\n | \"SESSION_NONE\"\n | \"SESSION_APPROVAL_MISMATCH\"\n | \"PRIVY_CHAIN_REJECTED_97741\"\n | \"PRIVY_KEY_QUORUM_MISMATCH\"\n | \"BUNDLER_UNREACHABLE\"\n | \"BUNDLER_AA_FAILED\"\n | \"PAYMASTER_DENIED\"\n | \"PAYMASTER_NO_BALANCE\"\n | \"PAYMASTER_CAP\"\n | \"PAYMASTER_ORIGIN_NOT_ALLOWED\"\n | \"PAYMASTER_DESTINATION_NOT_ALLOWED\"\n | \"PAYMASTER_PROJECT_NOT_CLAIMED\"\n | \"PAYMASTER_PROJECT_OWNER_CHANGED\"\n | \"PAYMASTER_PROJECT_PAUSED\"\n | \"PAYMASTER_IDENTITY_REQUIRED\"\n | \"PAYMASTER_FREE_TIER_UNAVAILABLE\"\n | \"PAYMASTER_RATE_LIMITED\"\n | \"PAYMASTER_SESSION_REQUIRED\"\n | \"PAYMASTER_API_ERROR\"\n | \"TX_REVERTED\"\n | \"TX_NONCE_RACE\"\n | \"TX_GAS_UNDERSHOOT\"\n | \"MULTICALL3_CANONICAL_ADDRESS\"\n | \"UNKNOWN\";\n\nexport interface ErrorCatalogEntry {\n readonly code: PepuErrorCode;\n readonly title: string;\n /** What went wrong, in one or two sentences. */\n readonly cause: string;\n /** How to fix it. */\n readonly fix: string;\n /** Suggested HTTP status for route factories. */\n readonly status: number;\n readonly retryable: boolean;\n /** Tested, in order, against the flattened error text. Empty for code-only entries. */\n readonly matchers: readonly RegExp[];\n}\n\n/**\n * Single source for the SDK `explainError`, the MCP `pepu_explain_error` tool\n * and the generated docs error page. ORDER MATTERS: the first entry whose\n * matcher hits wins, so specific entries come before general ones.\n */\nexport const PEPU_ERROR_CATALOG: readonly ErrorCatalogEntry[] = [\n {\n code: \"PRIVY_KEY_QUORUM_MISMATCH\",\n title: \"Privy authorization key does not match the wallet owner\",\n cause:\n \"Privy returned 401 'No valid authorization keys or user signing keys available': the server's PRIVY_AUTHORIZATION_KEY is not a signer on the wallet, or the key quorum id differs from the one the user granted.\",\n fix: \"Make sure PRIVY_AUTHORIZATION_KEY is the private half of the key whose quorum id is NEXT_PUBLIC_PRIVY_KEY_QUORUM_ID, and that the user granted that quorum as a signer.\",\n status: 500,\n retryable: false,\n matchers: [/No valid authorization keys or user signing keys available/i],\n },\n {\n code: \"POLICY_NAME_TOO_LONG\",\n title: \"Privy policy or rule name is too long\",\n cause: \"Privy rejects policy and rule names of 50 or more characters (the real limit is 49).\",\n fix: \"Shorten the policy or rule name to 49 characters or fewer.\",\n status: 400,\n retryable: false,\n matchers: [/must be fewer than 50 characters/i, /name[^.\\n]{0,40}\\b(50|49) characters/i],\n },\n {\n code: \"WALLET_COINBASE_UNSUPPORTED_CHAIN\",\n title: \"Coinbase Smart Wallet does not support PEPU\",\n cause:\n \"Coinbase Smart Wallet is a smart-contract wallet on chains it knows; PEPU (97741) is not one of them, and it floods the console with unsupported-chain errors.\",\n fix: \"Pin Coinbase to eoaOnly via createPepuPrivyConfig() from @pepu-chain/sdk/privy.\",\n status: 400,\n retryable: false,\n matchers: [\n /coinbase[\\s\\S]{0,120}(unsupported|not supported)[\\s\\S]{0,60}chain/i,\n /(unsupported|not supported) chain[\\s\\S]{0,120}coinbase/i,\n ],\n },\n {\n code: \"PRIVY_CHAIN_REJECTED_97741\",\n title: \"Privy rejects server-side eth_sendTransaction on PEPU\",\n cause: \"Privy's server-side send path does not know chain 97741 and rejects it. Signing works; sending does not.\",\n fix: \"Sign with eth_signTransaction on the server and broadcast the raw transaction yourself (signAndBroadcast from @pepu-chain/sdk/session).\",\n status: 502,\n retryable: false,\n matchers: [\n /eip155:97741[\\s\\S]{0,160}(unsupported|not supported|invalid|unknown|not found)/i,\n /(unsupported|not supported|unknown|invalid) (chain|network|caip2)[\\s\\S]{0,80}97741/i,\n ],\n },\n {\n code: \"PAYMASTER_ORIGIN_NOT_ALLOWED\",\n title: \"Paymaster refused the request origin\",\n cause: \"The request Origin is not on the project's allowlist.\",\n fix: \"Add the exact origin (scheme, host and port) to the project's allowed origins.\",\n status: 403,\n retryable: false,\n matchers: [/origin_not_allowed/i],\n },\n {\n code: \"PAYMASTER_DESTINATION_NOT_ALLOWED\",\n title: \"Paymaster refused the call destination\",\n cause: \"The UserOperation targets a contract that is not on the project's target allowlist.\",\n fix: \"Add the contract to the project's targets, or sponsor only calls to allowed targets.\",\n status: 403,\n retryable: false,\n matchers: [/(destination|target)_not_allowed/i],\n },\n {\n code: \"PAYMASTER_PROJECT_NOT_CLAIMED\",\n title: \"Sponsorship project is not claimed on-chain\",\n cause:\n \"Deposits can sit in an unclaimed project, but nothing is sponsored until its owner has claimed it on-chain (the contract reports ProjectNotClaimed, the service project_not_claimed_onchain).\",\n fix: \"Prove the Privy app (requestClaimAttestation from @pepu-chain/sdk/paymaster/server), call claimProject, then configureProject (setTargets, setDailyLimit, setSenderDailyLimit).\",\n status: 409,\n retryable: false,\n matchers: [/project_not_claimed_onchain/i, /ProjectNotClaimed/i],\n },\n {\n code: \"PAYMASTER_PROJECT_OWNER_CHANGED\",\n title: \"Project owner changed since the credentials were issued\",\n cause:\n \"The on-chain owner of the project is no longer the address the off-chain credentials were issued to (an ownership transfer or re-claim completed).\",\n fix: \"As the new owner, sign in with SIWE, register the project again and rotate the client token and server key.\",\n status: 403,\n retryable: false,\n matchers: [/project_owner_changed/i],\n },\n {\n code: \"PAYMASTER_PROJECT_PAUSED\",\n title: \"Sponsorship project is paused\",\n cause: \"The project owner paused sponsorship on-chain.\",\n fix: \"The owner can resume it with setPaused(projectId, false).\",\n status: 403,\n retryable: false,\n matchers: [/project_paused/i, /SponsorPaused/i],\n },\n {\n code: \"PAYMASTER_IDENTITY_REQUIRED\",\n title: \"A verified Privy account is required\",\n cause: \"The free tier (and any project with requireIdentity on) only sponsors users with a verified Privy access token.\",\n fix: \"Send the user's Privy access token as Authorization: Bearer (or context.privyAccessToken for ERC-7677).\",\n status: 401,\n retryable: false,\n matchers: [/(project|free_tier)_identity_required/i],\n },\n {\n code: \"PAYMASTER_FREE_TIER_UNAVAILABLE\",\n title: \"Free tier cannot sponsor this operation\",\n cause: \"The free tier is disabled, its pool is empty, or the operation is larger than the per-op cap.\",\n fix: \"Deposit into your own project and use its credentials, or retry later.\",\n status: 429,\n retryable: true,\n matchers: [/free_tier_disabled/i, /free_pool_(empty|op_too_large)/i],\n },\n {\n code: \"PAYMASTER_RATE_LIMITED\",\n title: \"Paymaster API rate limit\",\n cause: \"Too many requests to the paymaster API from this IP or account.\",\n fix: \"Back off for the Retry-After interval (error.details.retryAfterSeconds when present).\",\n status: 429,\n retryable: true,\n matchers: [/\\brate_limited\\b/i],\n },\n {\n code: \"PAYMASTER_SESSION_REQUIRED\",\n title: \"Paymaster owner session missing or expired\",\n cause: \"Owner endpoints need a SIWE session token (1 h lifetime) for the project's current on-chain owner.\",\n fix: \"Call loginWithWallet() on the paymaster API client, then retry.\",\n status: 401,\n retryable: false,\n matchers: [],\n },\n {\n code: \"PAYMASTER_API_ERROR\",\n title: \"Paymaster API request failed\",\n cause: \"The paymaster API returned an error that has no more specific PEPU code.\",\n fix: \"Read error.details (HTTP status and the service's error code) and the OpenAPI spec for that route.\",\n status: 502,\n retryable: false,\n matchers: [],\n },\n {\n code: \"PAYMASTER_DENIED\",\n title: \"Paymaster denied the sponsorship\",\n cause:\n \"The paymaster rejected the credential or the sender (for example unknown_or_invalid_app_credential or sender_not_owned_by_token_user).\",\n fix: \"Check the app credential or token, and that the smart account belongs to the user whose access token you sent.\",\n status: 403,\n retryable: false,\n matchers: [\n /unknown_or_invalid_app_credential/i,\n /sender_not_owned_by_token_user/i,\n /paymaster[\\s\\S]{0,40}(denied|rejected)/i,\n ],\n },\n {\n code: \"PAYMASTER_NO_BALANCE\",\n title: \"Sponsorship project has no balance\",\n cause: \"The project's paymaster deposit cannot cover this operation.\",\n fix: \"Deposit more PEPU to the project, then retry.\",\n status: 429,\n retryable: true,\n matchers: [/(project_)?(no|insufficient)_balance/i, /project_balance_exhausted/i, /InsufficientSponsorBalance/i, /insufficient (project )?(balance|deposit)[\\s\\S]{0,40}paymaster/i],\n },\n {\n code: \"PAYMASTER_CAP\",\n title: \"Sponsorship cap reached\",\n cause: \"A daily, per-sender or per-operation sponsorship cap was hit.\",\n fix: \"Wait for the cap window to reset, or raise the project's daily and sender limits.\",\n status: 429,\n retryable: true,\n matchers: [/(daily|sender|per_sender)[_ -]?(cap|limit)[_ ]?(exceeded|reached)/i, /cap_exceeded|limit_exceeded/i, /free_tier_[a-z_]*_(exceeded|reached)/i, /fee_above_onchain_cap/i],\n },\n {\n code: \"BUNDLER_AA_FAILED\",\n title: \"EntryPoint rejected the UserOperation\",\n cause: \"The EntryPoint reported FailedOp with an AAxx code during validation or execution.\",\n fix: \"Read the AAxx code: AA21 prefund missing, AA23 signature or validation reverted, AA25 invalid nonce, AA31/AA33/AA34 paymaster problems.\",\n status: 502,\n retryable: false,\n matchers: [/\\bAA(1\\d|2\\d|3\\d|4\\d|5\\d|9\\d)\\b/, /FailedOp(WithRevert)?/],\n },\n {\n code: \"BUNDLER_UNREACHABLE\",\n title: \"Bundler or paymaster is unreachable\",\n cause: \"The request to the bundler or paymaster URL failed before any response.\",\n fix: \"Check PEPU_BUNDLER_URL and PEPU_PAYMASTER_URL. The hosted services may not be live yet; use checkSponsorship().\",\n status: 502,\n retryable: true,\n matchers: [/ECONNREFUSED|ENOTFOUND|ETIMEDOUT|fetch failed|bundler[\\s\\S]{0,30}unreachable/i],\n },\n {\n code: \"TX_NONCE_RACE\",\n title: \"Nonce conflict\",\n cause: \"Two transactions raced for one nonce, or a replacement was underpriced.\",\n fix: \"Serialize sends per account (a lock), re-read the pending nonce, and retry.\",\n status: 409,\n retryable: true,\n matchers: [/nonce too (low|high)/i, /replacement transaction underpriced/i, /already known/i],\n },\n {\n code: \"TX_GAS_UNDERSHOOT\",\n title: \"Gas limit too low\",\n cause: \"Nitro gas estimation undershoots on PEPU: the L1 data component is not covered by the plain estimate.\",\n fix: \"Add headroom to the estimate, 20% via withGasLimitBuffer() from @pepu-chain/sdk/session.\",\n status: 502,\n retryable: true,\n matchers: [/intrinsic gas too low/i, /gas required exceeds allowance/i, /gas limit too low/i],\n },\n {\n code: \"TX_REVERTED\",\n title: \"Transaction reverted\",\n cause: \"The contract call reverted.\",\n fix: \"Decode the revert reason with explainError(<revert data>) and check arguments, allowances and balances.\",\n status: 502,\n retryable: false,\n matchers: [/execution reverted/i, /transaction (has )?reverted/i],\n },\n {\n code: \"MULTICALL3_CANONICAL_ADDRESS\",\n title: \"Canonical Multicall3 address used on PEPU\",\n cause: \"PEPU's Multicall3 is not at the canonical 0xcA11...CA11 address.\",\n fix: \"Use getMulticall3() or pepuMulticall() from @pepu-chain/sdk, or the pepuMainnet chain object, which carries the right address.\",\n status: 500,\n retryable: false,\n matchers: [/0xcA11bde05977b3631167028862bE2a173976CA11/i],\n },\n {\n code: \"WALLET_INJECTED_ACTIVE\",\n title: \"An injected browser wallet is the active account\",\n cause: \"wagmi's active account is a browser extension rather than the Privy embedded wallet.\",\n fix: \"Pin the embedded wallet with useActiveWalletPin() from @pepu-chain/sdk/privy/wagmi.\",\n status: 400,\n retryable: false,\n matchers: [/ConnectorNotConnectedError/i, /chrome-extension:\\/\\//i, /injected (wallet|provider|connector)/i],\n },\n {\n code: \"CONFIG_PRIVY_CREATE_ON_LOGIN\",\n title: \"Embedded wallet never appears after login\",\n cause: \"The dashboard's automatic embedded wallet creation is off, so createOnLogin never resolves.\",\n fix: \"Create the wallet server-side with the ensure-wallet route (createEnsureWalletRoute), or enable creation in the Privy dashboard.\",\n status: 500,\n retryable: false,\n matchers: [/createOnLogin/i, /embedded wallet[\\s\\S]{0,60}(never|did not|didn't) (appear|created)/i],\n },\n {\n code: \"CONFIG_ORIGIN_MISMATCH\",\n title: \"Origin is not allowed by Privy\",\n cause:\n \"The page origin (scheme, host and port) is not in the Privy app's allowed origins. A different dev port is the usual cause.\",\n fix: \"Add the exact origin, including the port, to Privy dashboard Allowed origins.\",\n status: 500,\n retryable: false,\n matchers: [/origin[^.\\n]{0,60}(not allowed|not configured|not in (the )?allowed)/i, /allowed origins?/i],\n },\n {\n code: \"CONFIG_PRIVY_DASHBOARD\",\n title: \"Privy dashboard misconfiguration\",\n cause: \"A required Privy dashboard setting is missing.\",\n fix: \"Run checkPrivyDashboardConfig() and follow its fix list.\",\n status: 500,\n retryable: false,\n matchers: [],\n },\n {\n code: \"CONFIG_MISSING_ENV\",\n title: \"Missing environment variable\",\n cause: \"A required environment variable is not set.\",\n fix: \"Set the listed variables (see .env.example) and restart the process.\",\n status: 500,\n retryable: false,\n matchers: [/missing required env/i],\n },\n {\n code: \"CONFIG_BAD_URL\",\n title: \"Invalid endpoint URL\",\n cause: \"A configured bundler, paymaster or RPC URL is not a valid http(s) URL.\",\n fix: \"Use a full URL such as https://bundler.example.com.\",\n status: 500,\n retryable: false,\n matchers: [],\n },\n {\n code: \"CONFIG_SERVER_ONLY\",\n title: \"Server-only module imported in the browser\",\n cause: \"A server entry point was bundled into client code.\",\n fix: \"Import server entries only from route handlers, server actions and scripts.\",\n status: 500,\n retryable: false,\n matchers: [],\n },\n {\n code: \"AUTH_INVALID_TOKEN\",\n title: \"Invalid or missing Privy access token\",\n cause: \"The request carried no bearer token, or Privy could not verify it.\",\n fix: \"Send Authorization: Bearer <getAccessToken()> and verify the token server-side.\",\n status: 401,\n retryable: false,\n matchers: [/invalid (auth(orization)?|access|jwt|id) token/i, /\\bjwt (expired|malformed|invalid)/i],\n },\n {\n code: \"WALLET_NOT_PROVISIONED\",\n title: \"User has no embedded wallet yet\",\n cause: \"The user is signed in but no embedded Ethereum wallet exists.\",\n fix: \"Call the ensure-wallet route (useEnsureWallet or WalletGate) before acting.\",\n status: 409,\n retryable: true,\n matchers: [],\n },\n {\n code: \"POLICY_UNSCOPED\",\n title: \"Session policy is not scoped\",\n cause: \"A session policy needs a target contract, at least one function and an expiry.\",\n fix: \"Pass contractAddress, functions and expiresAtUnixSeconds to buildSessionPolicy().\",\n status: 400,\n retryable: false,\n matchers: [],\n },\n {\n code: \"SESSION_EXPIRED\",\n title: \"Session expired\",\n cause: \"The session's expiry has passed.\",\n fix: \"Grant a new session.\",\n status: 410,\n retryable: false,\n matchers: [],\n },\n {\n code: \"SESSION_NONE\",\n title: \"No active session\",\n cause: \"The user has not granted a session, or it was revoked.\",\n fix: \"Ask the user to grant a session first.\",\n status: 409,\n retryable: false,\n matchers: [],\n },\n {\n code: \"SESSION_APPROVAL_MISMATCH\",\n title: \"Session approval does not match\",\n cause: \"The approval was made for another account, permission id or mode.\",\n fix: \"Re-run prepare, have the owner sign again, then activate.\",\n status: 409,\n retryable: false,\n matchers: [],\n },\n {\n code: \"UNKNOWN\",\n title: \"Unknown error\",\n cause: \"The error did not match any known PEPU failure.\",\n fix: \"Read the original message. Run pepu_known_gotchas in the MCP server, or search the docs.\",\n status: 500,\n retryable: false,\n matchers: [],\n },\n];\n\nconst catalogByCode: ReadonlyMap<PepuErrorCode, ErrorCatalogEntry> = new Map(\n PEPU_ERROR_CATALOG.map((e) => [e.code, e]),\n);\n\n/** Look up a catalog entry by code. */\nexport function getErrorEntry(code: PepuErrorCode): ErrorCatalogEntry {\n const entry = catalogByCode.get(code) ?? catalogByCode.get(\"UNKNOWN\");\n if (!entry) throw new Error(\"PEPU_ERROR_CATALOG is missing the UNKNOWN entry\");\n return entry;\n}\n\n/** `https://guide.pepeunchained.com/reference/errors#<CODE>` */\nexport function errorDocsUrl(code: PepuErrorCode): string {\n return `${PEPU_ERRORS_DOCS_URL}#${code}`;\n}\n\nexport interface PepuErrorOptions {\n hint?: string;\n docsUrl?: string;\n retryable?: boolean;\n status?: number;\n details?: unknown;\n cause?: unknown;\n}\n\nexport class PepuError extends Error {\n readonly code: PepuErrorCode;\n readonly hint: string;\n readonly docsUrl: string;\n readonly retryable: boolean;\n readonly status: number;\n readonly details?: unknown;\n\n constructor(code: PepuErrorCode, message?: string, options: PepuErrorOptions = {}) {\n const entry = getErrorEntry(code);\n super(message ?? entry.title, options.cause === undefined ? undefined : { cause: options.cause });\n this.name = new.target.name;\n this.code = code;\n this.hint = options.hint ?? entry.fix;\n this.docsUrl = options.docsUrl ?? errorDocsUrl(code);\n this.retryable = options.retryable ?? entry.retryable;\n this.status = options.status ?? entry.status;\n if (options.details !== undefined) this.details = options.details;\n }\n}\n\n/** Missing env, bad URL, dashboard misconfiguration. */\nexport class PepuConfigError extends PepuError {}\n/** Bad or missing Privy token, wrong owner. */\nexport class PepuAuthError extends PepuError {}\n/** Unscoped policy, name too long, expiry, denied by policy. */\nexport class PepuPolicyError extends PepuError {}\n/** No session, expired, mismatched approval. */\nexport class PepuSessionError extends PepuError {}\n/** AAxx, JSON-RPC errors, timeouts. */\nexport class PepuBundlerError extends PepuError {}\n/** Reason codes, caps, balance, origin. */\nexport class PepuPaymasterError extends PepuError {}\n/** Revert, nonce race, gas, rpc rate limit. */\nexport class PepuChainError extends PepuError {}\n\ntype PepuErrorClass = new (code: PepuErrorCode, message?: string, options?: PepuErrorOptions) => PepuError;\n\nfunction classForCode(code: PepuErrorCode): PepuErrorClass {\n if (code.startsWith(\"CONFIG_\") || code.startsWith(\"PRIVY_\")) return PepuConfigError;\n if (code === \"AUTH_INVALID_TOKEN\" || code === \"WALLET_NOT_PROVISIONED\") return PepuAuthError;\n if (code.startsWith(\"POLICY_\")) return PepuPolicyError;\n if (code.startsWith(\"SESSION_\")) return PepuSessionError;\n if (code.startsWith(\"BUNDLER_\")) return PepuBundlerError;\n if (code.startsWith(\"PAYMASTER_\")) return PepuPaymasterError;\n if (code.startsWith(\"TX_\") || code.startsWith(\"MULTICALL3_\") || code.startsWith(\"WALLET_\")) return PepuChainError;\n return PepuError;\n}\n\nconst REVERT_ABI = [\n { type: \"error\", name: \"Error\", inputs: [{ name: \"message\", type: \"string\" }] },\n { type: \"error\", name: \"Panic\", inputs: [{ name: \"code\", type: \"uint256\" }] },\n {\n type: \"error\",\n name: \"FailedOp\",\n inputs: [\n { name: \"opIndex\", type: \"uint256\" },\n { name: \"reason\", type: \"string\" },\n ],\n },\n {\n type: \"error\",\n name: \"FailedOpWithRevert\",\n inputs: [\n { name: \"opIndex\", type: \"uint256\" },\n { name: \"reason\", type: \"string\" },\n { name: \"inner\", type: \"bytes\" },\n ],\n },\n] as const satisfies Abi;\n\nfunction flatten(e: unknown): string {\n const seen = new Set<unknown>();\n const parts: string[] = [];\n let cur: unknown = e;\n for (let depth = 0; depth < 6 && cur !== undefined && cur !== null && !seen.has(cur); depth++) {\n seen.add(cur);\n if (typeof cur === \"object\") {\n const o = cur as Record<string, unknown>;\n for (const k of [\"shortMessage\", \"message\", \"details\", \"reason\"]) {\n const v = o[k];\n if (typeof v === \"string\") parts.push(v);\n }\n cur = o[\"cause\"];\n } else {\n parts.push(String(cur));\n break;\n }\n }\n return parts.join(\"\\n\");\n}\n\nexport interface ErrorExplanation {\n code: PepuErrorCode;\n title: string;\n cause: string;\n fix: string;\n docsUrl: string;\n matched: \"catalog\" | \"abi-decode\" | \"unknown\";\n}\n\nfunction matchCatalog(text: string): ErrorCatalogEntry | undefined {\n return PEPU_ERROR_CATALOG.find((entry) => entry.matchers.some((m) => m.test(text)));\n}\n\nfunction explanation(entry: ErrorCatalogEntry, matched: ErrorExplanation[\"matched\"]): ErrorExplanation {\n return {\n code: entry.code,\n title: entry.title,\n cause: entry.cause,\n fix: entry.fix,\n docsUrl: errorDocsUrl(entry.code),\n matched,\n };\n}\n\n/**\n * Explain an error, an error message, or raw revert data (`0x...`). Pure and\n * synchronous; never throws.\n */\nexport function explainError(e: unknown | string | Hex): ErrorExplanation {\n if (e instanceof PepuError) return explanation(getErrorEntry(e.code), \"catalog\");\n\n if (typeof e === \"string\" && isHex(e) && e.length >= 10) {\n try {\n const decoded = decodeErrorResult({ abi: REVERT_ABI, data: e });\n const argText = (decoded.args ?? []).map((a) => (typeof a === \"string\" ? a : \"\")).join(\"\\n\");\n const hit = matchCatalog(`${argText}\\n${decoded.errorName}`);\n if (hit) return explanation(hit, \"abi-decode\");\n return explanation(getErrorEntry(\"TX_REVERTED\"), \"abi-decode\");\n } catch {\n return explanation(getErrorEntry(\"UNKNOWN\"), \"unknown\");\n }\n }\n\n const text = typeof e === \"string\" ? e : flatten(e);\n const hit = matchCatalog(text);\n return hit ? explanation(hit, \"catalog\") : explanation(getErrorEntry(\"UNKNOWN\"), \"unknown\");\n}\n\n/** Wrap anything thrown into a typed {@link PepuError}. PepuErrors pass through. */\nexport function toPepuError(e: unknown, ctx?: { op: string }): PepuError {\n if (e instanceof PepuError) return e;\n const explained = explainError(e);\n const original = (typeof e === \"string\" ? e : flatten(e)) || \"Unknown error\";\n const message = ctx ? `${ctx.op}: ${original}` : original;\n const Cls = classForCode(explained.code);\n return new Cls(explained.code, message, { cause: e });\n}\n\n/** The `{ error: { code, message, hint } }` body route factories return. */\nexport function toErrorBody(e: unknown): { error: { code: PepuErrorCode; message: string; hint: string } } {\n const err = toPepuError(e);\n return { error: { code: err.code, message: err.message, hint: err.hint } };\n}\n\n/** A JSON `Response` with the error body and the status from the error model. */\nexport function toErrorResponse(e: unknown): Response {\n const err = toPepuError(e);\n return new Response(JSON.stringify(toErrorBody(err)), {\n status: err.status,\n headers: { \"content-type\": \"application/json\" },\n });\n}\n"]}
|