@pepu-chain/sdk 0.2.1 → 0.2.2
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/README.md +1 -2
- package/dist/aa/kernel.cjs +10 -9
- package/dist/aa/kernel.js +5 -4
- package/dist/aa/react-direct.cjs +10 -9
- package/dist/aa/react-direct.cjs.map +1 -1
- package/dist/aa/react-direct.js +5 -4
- package/dist/aa/react-direct.js.map +1 -1
- package/dist/aa/react.cjs +5 -4
- package/dist/aa/react.cjs.map +1 -1
- package/dist/aa/react.js +3 -2
- package/dist/aa/react.js.map +1 -1
- package/dist/aa.cjs +18 -17
- package/dist/aa.js +5 -4
- package/dist/chunk-4GEC7GUU.cjs +283 -0
- package/dist/chunk-4GEC7GUU.cjs.map +1 -0
- package/dist/{chunk-PHM3ZORG.cjs → chunk-4L4CHIXE.cjs} +9 -9
- package/dist/{chunk-PHM3ZORG.cjs.map → chunk-4L4CHIXE.cjs.map} +1 -1
- package/dist/{chunk-A5LP2UCS.cjs → chunk-65Y5UCQ7.cjs} +2 -276
- package/dist/chunk-65Y5UCQ7.cjs.map +1 -0
- package/dist/{chunk-7MNJF2OB.cjs → chunk-DNWWZWUW.cjs} +4 -4
- package/dist/{chunk-7MNJF2OB.cjs.map → chunk-DNWWZWUW.cjs.map} +1 -1
- package/dist/{chunk-D52PADVY.js → chunk-GFKIM7HT.js} +25 -2
- package/dist/chunk-GFKIM7HT.js.map +1 -0
- package/dist/{chunk-IY3ALPUJ.js → chunk-GIZNH65Q.js} +5 -273
- package/dist/chunk-GIZNH65Q.js.map +1 -0
- package/dist/{chunk-WANILJZQ.cjs → chunk-HTCX46RJ.cjs} +25 -2
- package/dist/chunk-HTCX46RJ.cjs.map +1 -0
- package/dist/{chunk-KVG3AYYR.js → chunk-NHPWXIA2.js} +4 -4
- package/dist/{chunk-KVG3AYYR.js.map → chunk-NHPWXIA2.js.map} +1 -1
- package/dist/{chunk-ZB6SVBK4.js → chunk-QIDMFFAQ.js} +4 -4
- package/dist/{chunk-ZB6SVBK4.js.map → chunk-QIDMFFAQ.js.map} +1 -1
- package/dist/{chunk-IB2FSPMJ.js → chunk-QZKUPCUD.js} +3 -3
- package/dist/{chunk-IB2FSPMJ.js.map → chunk-QZKUPCUD.js.map} +1 -1
- package/dist/chunk-RSPAN44L.js +276 -0
- package/dist/chunk-RSPAN44L.js.map +1 -0
- package/dist/{chunk-NVOPDXTA.cjs → chunk-UQH4ZAXD.cjs} +10 -10
- package/dist/{chunk-NVOPDXTA.cjs.map → chunk-UQH4ZAXD.cjs.map} +1 -1
- package/dist/{chunk-BGALSKAF.cjs → chunk-VYMAZVIK.cjs} +4 -4
- package/dist/{chunk-BGALSKAF.cjs.map → chunk-VYMAZVIK.cjs.map} +1 -1
- package/dist/{chunk-F2R473FR.js → chunk-XR5ONV2Y.js} +3 -3
- package/dist/{chunk-F2R473FR.js.map → chunk-XR5ONV2Y.js.map} +1 -1
- package/dist/combo/react.cjs +61 -13
- package/dist/combo/react.cjs.map +1 -1
- package/dist/combo/react.d.cts +14 -2
- package/dist/combo/react.d.ts +14 -2
- package/dist/combo/react.guard.js +1 -1
- package/dist/combo/react.js +58 -11
- package/dist/combo/react.js.map +1 -1
- package/dist/combo.cjs +41 -26
- package/dist/combo.cjs.map +1 -1
- package/dist/combo.d.cts +11 -0
- package/dist/combo.d.ts +11 -0
- package/dist/combo.js +31 -16
- package/dist/combo.js.map +1 -1
- package/dist/index.cjs +10 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/paymaster.cjs +37 -36
- package/dist/paymaster.cjs.map +1 -1
- package/dist/paymaster.js +3 -2
- package/dist/paymaster.js.map +1 -1
- package/dist/react.cjs +4 -3
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +3 -2
- package/dist/react.js.map +1 -1
- package/dist/session/kernel.cjs +18 -17
- package/dist/session/kernel.js +6 -5
- package/package.json +1 -1
- package/dist/chunk-A5LP2UCS.cjs.map +0 -1
- package/dist/chunk-D52PADVY.js.map +0 -1
- package/dist/chunk-IY3ALPUJ.js.map +0 -1
- package/dist/chunk-WANILJZQ.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkRCMKPJZO_cjs = require('./chunk-RCMKPJZO.cjs');
|
|
4
|
-
var
|
|
5
|
-
require('./chunk-
|
|
4
|
+
var chunkVYMAZVIK_cjs = require('./chunk-VYMAZVIK.cjs');
|
|
5
|
+
require('./chunk-HTCX46RJ.cjs');
|
|
6
6
|
var chunkK7JSQPZO_cjs = require('./chunk-K7JSQPZO.cjs');
|
|
7
|
+
require('./chunk-65Y5UCQ7.cjs');
|
|
7
8
|
var chunkC7IC36XS_cjs = require('./chunk-C7IC36XS.cjs');
|
|
8
9
|
var chunk4GINFJO6_cjs = require('./chunk-4GINFJO6.cjs');
|
|
9
10
|
var chunkVF3D6KLQ_cjs = require('./chunk-VF3D6KLQ.cjs');
|
|
@@ -566,31 +567,31 @@ Object.defineProperty(exports, "buildPaymasterStubDataRequest", {
|
|
|
566
567
|
});
|
|
567
568
|
Object.defineProperty(exports, "KERNEL_V3_1_IMPLEMENTATION_ADDRESS", {
|
|
568
569
|
enumerable: true,
|
|
569
|
-
get: function () { return
|
|
570
|
+
get: function () { return chunkVYMAZVIK_cjs.KERNEL_V3_1_IMPLEMENTATION_ADDRESS; }
|
|
570
571
|
});
|
|
571
572
|
Object.defineProperty(exports, "checkSponsorship", {
|
|
572
573
|
enumerable: true,
|
|
573
|
-
get: function () { return
|
|
574
|
+
get: function () { return chunkVYMAZVIK_cjs.checkSponsorship; }
|
|
574
575
|
});
|
|
575
576
|
Object.defineProperty(exports, "entryPointV07Abi", {
|
|
576
577
|
enumerable: true,
|
|
577
|
-
get: function () { return
|
|
578
|
+
get: function () { return chunkVYMAZVIK_cjs.entryPointV07Abi; }
|
|
578
579
|
});
|
|
579
580
|
Object.defineProperty(exports, "getKernelAccountAddress", {
|
|
580
581
|
enumerable: true,
|
|
581
|
-
get: function () { return
|
|
582
|
+
get: function () { return chunkVYMAZVIK_cjs.getKernelAccountAddress; }
|
|
582
583
|
});
|
|
583
584
|
Object.defineProperty(exports, "getPepuKernelStack", {
|
|
584
585
|
enumerable: true,
|
|
585
|
-
get: function () { return
|
|
586
|
+
get: function () { return chunkVYMAZVIK_cjs.getPepuKernelStack; }
|
|
586
587
|
});
|
|
587
588
|
Object.defineProperty(exports, "getSponsorshipStatus", {
|
|
588
589
|
enumerable: true,
|
|
589
|
-
get: function () { return
|
|
590
|
+
get: function () { return chunkVYMAZVIK_cjs.getSponsorshipStatus; }
|
|
590
591
|
});
|
|
591
592
|
Object.defineProperty(exports, "kernelFactoryAbi", {
|
|
592
593
|
enumerable: true,
|
|
593
|
-
get: function () { return
|
|
594
|
+
get: function () { return chunkVYMAZVIK_cjs.kernelFactoryAbi; }
|
|
594
595
|
});
|
|
595
596
|
Object.defineProperty(exports, "getContract", {
|
|
596
597
|
enumerable: true,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/dex.ts","../src/tokens.ts","../src/pepuscan.ts","../src/wallet.ts","../src/abi/arbGasInfo.ts","../src/gas.ts","../src/abi/kernelEcdsaValidator.ts","../src/abi/pepuSwapMulticall.ts","../src/abi/pepuSwapPermit2.ts","../src/abi/pepuSwapPositionManager.ts","../src/abi/pepuSwapQuoter.ts","../src/abi/pepuSwapRouter.ts","../src/abi/pepuSwapTickLens.ts","../src/abi/pepuSwapUniversalRouter.ts","../src/abi/pepuSwapV3Factory.ts","../src/abi/pepuSwapV3Pool.ts","../src/abi/wpepu.ts","../src/abi/multicall3.ts","../src/abi/permit2.ts","../src/multicall.ts","../src/permit2.ts"],"names":["pepuMainnet","explorerUrl","numberToHex","parseAbi","formatUnits","erc721Abi","erc20Abi","isAddressEqual","PepuChainError","getContract","isDeployed","encodeFunctionData","decodeFunctionResult"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ContractEntry } from \"./contracts.js\";\nimport { pepuMainnet } from \"./chains.js\";\n\n/**\n * PepuSwap is PEPU's flagship DEX and a Uniswap V3 fork. This registry is\n * deliberately separate from {@link pepuContracts} in `contracts.ts`:\n * `pepuContracts` tracks *chain infrastructure* (things any app might rely\n * on — Multicall3, the AA stack), while this tracks *one specific\n * application's* deployment. Mixing the two would make `pepuContracts`\n * ambiguous about what counts as \"the chain\" versus \"a dapp on the chain.\"\n *\n * Mainnet only — PepuSwap has no testnet deployment, and testnet (97740) is\n * out of scope for this package regardless (no faucet exists to fund\n * verification there).\n *\n * Every address below was independently verified on 2026-09-24 with both\n * an `eth_getCode` check (non-empty bytecode) and a successful `eth_call`\n * against a real function — see the doc comment on that contract's ABI file\n * in `./abi/` for the exact call and response. Two addresses\n * (`multicallNonCanonical`, `permit2NonCanonical`) are PepuSwap-specific\n * overrides of otherwise-canonical contracts; do not confuse them with\n * {@link pepuContracts}'s `multicall3`/`permit2` entries, which track the\n * *canonical* versions of those same standards.\n */\nexport type PepuSwapContractName =\n | \"v3Factory\"\n | \"swapRouter02\"\n | \"universalRouter\"\n | \"positionManager\"\n | \"quoterV2\"\n | \"tickLens\"\n | \"v3Migrator\"\n | \"v3Staker\"\n | \"multicallNonCanonical\"\n | \"permit2NonCanonical\";\n\nconst V3_FACTORY_NOTES =\n \"Uniswap V3 core factory. owner() returns a live address; getPool() \" +\n \"resolves real WPEPU/USDT pools at multiple fee tiers, and those pools' \" +\n \"own token0()/token1() match. Four other PepuSwap contracts \" +\n \"(swapRouter02, positionManager, quoterV2, v3Migrator) each read their \" +\n \"own factory() immutable and all agree on this exact address.\";\n\nexport const pepuSwapContracts: Readonly<\n Record<number, Readonly<Record<PepuSwapContractName, ContractEntry>>>\n> = {\n [pepuMainnet.id]: {\n v3Factory: {\n status: \"deployed\",\n name: \"PepuSwap V3 Factory\",\n address: \"0x5984B8BF2d4dB9C0aCB1d7924762e4474D80C807\",\n notes: V3_FACTORY_NOTES,\n },\n swapRouter02: {\n status: \"deployed\",\n name: \"PepuSwap SwapRouter02\",\n address: \"0x150c3F0f16C3D9EB34351d7af9c961FeDc97A0fb\",\n notes:\n \"factory() and WETH9() both resolve to the independently-verified \" +\n \"v3Factory/WPEPU addresses.\",\n },\n universalRouter: {\n status: \"deployed\",\n name: \"PepuSwap UniversalRouter\",\n address: \"0x0dE72b751b77d3c74fB96C5fAd0320Cd8d133d36\",\n notes:\n \"No public getters for its configured Permit2/factory addresses \" +\n \"(dispatcher contracts don't expose those). Verified instead by \" +\n \"simulating execute(\\\"0x\\\", [], farFutureDeadline) via eth_call, \" +\n \"which returned successfully under the exact UniversalRouter \" +\n \"selector.\",\n },\n positionManager: {\n status: \"deployed\",\n name: \"PepuSwap NonfungiblePositionManager\",\n address: \"0xe2060CbdE18b5e765c86e5Cd6EE68AF209a9faa7\",\n notes:\n \"factory() and WETH9() both resolve to the independently-verified \" +\n \"v3Factory/WPEPU addresses. LP positions are ERC-721 tokens minted \" +\n \"by this contract (pepuscan lists them as \\\"Launchpad V3 Positions \" +\n \"NFT\\\" / UNI-V3-POS).\",\n },\n quoterV2: {\n status: \"deployed\",\n name: \"PepuSwap QuoterV2\",\n address: \"0xd647b2D80b48e93613Aa6982b85f8909578b4829\",\n notes:\n \"factory() and WETH9() both resolve to the independently-verified \" +\n \"v3Factory/WPEPU addresses. Off-chain-quote contract — call via \" +\n \"eth_call/simulateContract only, never send it a real transaction.\",\n },\n tickLens: {\n status: \"deployed\",\n name: \"PepuSwap TickLens\",\n address: \"0x4EB8aA84c066f9bf210eAfE33B30AE49BfafD9a6\",\n notes:\n \"Stateless (no zero-arg getter to probe). Verified instead by \" +\n \"calling getPopulatedTicksInWord() against a real WPEPU/USDT pool \" +\n \"at that pool's own current tick-bitmap word; call succeeded.\",\n },\n v3Migrator: {\n status: \"deployed\",\n name: \"PepuSwap V3Migrator\",\n address: \"0xFE406d6c3fc0BB3a6D195b089eFADfc8658206D5\",\n notes:\n \"factory() and WETH9() both resolve to the independently-verified \" +\n \"v3Factory/WPEPU addresses. No dedicated ABI is shipped for this \" +\n \"contract in ./abi/ — only these two getters were checked, which \" +\n \"is enough to confirm the address but not enough to type its \" +\n \"migration-specific functions. Pair with Uniswap's public \" +\n \"V3Migrator ABI if you need those.\",\n },\n v3Staker: {\n status: \"deployed\",\n name: \"PepuSwap V3Staker\",\n address: \"0x0a875d1C72cb4e1CD61401c3C49f85Df45071f83\",\n notes:\n \"factory() resolves to the independently-verified v3Factory \" +\n \"address (this contract has no WETH9() getter — it's a Uniswap \" +\n \"LP incentive-staking contract, unrelated to the general \\\"stake \" +\n \"PEPU\\\" product). No dedicated ABI is shipped for it in ./abi/ — \" +\n \"pair with Uniswap's public V3Staker ABI if you need one.\",\n },\n multicallNonCanonical: {\n status: \"deployed\",\n name: \"PepuSwap Multicall (UniswapInterfaceMulticall, non-canonical)\",\n address: \"0x927af2a6B76d2d8206d93004463F8C122701383B\",\n notes:\n \"PepuSwap's own multicall contract, NOT Multicall3 and NOT \" +\n \"interchangeable with pepuContracts.multicall3. Verified on \" +\n \"pepuscan as Uniswap's UniswapInterfaceMulticall (a Multicall2 \" +\n \"fork with a different function set/return shape — see \" +\n \"pepuSwapMulticallAbi in ./abi/pepuSwapMulticall.js for the \" +\n \"verified ABI and exactly which functions were confirmed live).\",\n },\n permit2NonCanonical: {\n status: \"deployed\",\n name: \"PepuSwap Permit2 (non-canonical)\",\n address: \"0xB461c05f76d7f919FF7A3Df2B0D2593F56538b4B\",\n notes:\n \"PepuSwap's own Permit2 deployment, NOT at the canonical Permit2 \" +\n \"address and NOT interchangeable with pepuContracts.permit2 \" +\n \"(which tracks the canonical Permit2, now deployed on mainnet at \" +\n \"0x000000000022D473030F116dDEE9F6B43aC78BA3 — see ../contracts.js). \" +\n \"Both DOMAIN_SEPARATOR() calls respond live but return different \" +\n \"values (different EIP-712 domains, since they're different \" +\n \"contracts). See pepuSwapPermit2Abi in ./abi/pepuSwapPermit2.js.\",\n },\n },\n};\n\n/** Look up one PepuSwap contract entry for a chain id. */\nexport function getPepuSwapContract(\n chainId: number,\n name: PepuSwapContractName,\n): ContractEntry | undefined {\n return pepuSwapContracts[chainId]?.[name];\n}\n\n/** List every tracked PepuSwap contract entry for a chain id, in registry order. */\nexport function listPepuSwapContracts(\n chainId: number,\n): readonly ContractEntry[] {\n const registry = pepuSwapContracts[chainId];\n return registry ? Object.values(registry) : [];\n}\n\n/** Narrow a {@link ContractEntry} to {@link DeployedContract} — re-exported for convenience so callers don't need to import both `./contracts.js` and `./dex.js` just to narrow a result. */\nexport { isDeployed } from \"./contracts.js\";\n","import type { Address } from \"viem\";\n\nimport { pepuMainnet } from \"./chains.js\";\n\n/**\n * Shape mirrors the `TokenInfo` definition in the Uniswap Token List\n * schema (https://uniswap.org/tokenlist.schema.json). Kept as a local\n * type (rather than importing one from `@uniswap/token-lists`) so\n * consumers of `@pepu-chain/sdk` never need that package installed just to\n * typecheck.\n */\nexport interface PepuTokenInfo {\n readonly chainId: number;\n readonly address: Address;\n readonly name: string;\n readonly symbol: string;\n readonly decimals: number;\n readonly logoURI?: string;\n readonly tags?: readonly string[];\n}\n\n/** Shape mirrors the top-level Uniswap Token List schema. */\nexport interface PepuTokenList {\n readonly name: string;\n readonly timestamp: string;\n readonly version: {\n readonly major: number;\n readonly minor: number;\n readonly patch: number;\n };\n readonly tokens: readonly PepuTokenInfo[];\n readonly keywords?: readonly string[];\n}\n\n/**\n * Canonical Pepe Unchained V2 token list, conforming to the Uniswap Token\n * List schema (see `test/tokens.test.ts` for schema validation against a\n * vendored copy of https://uniswap.org/tokenlist.schema.json).\n *\n * Deliberately minimal: every entry below is a token address independently\n * verified on-chain (see each entry's inline note), not copied from docs or\n * a third-party list without cross-checking. No other token address met\n * that bar at the time this list was written, and none are included here\n * as placeholders. See the README's \"Known gaps\" section.\n *\n * There is no verified token address for testnet (chain 97740) yet, so\n * this list currently only covers mainnet.\n */\nexport const pepuTokenList: PepuTokenList = {\n name: \"Pepe Unchained\",\n timestamp: \"2026-10-03T00:00:00.000Z\",\n version: { major: 1, minor: 2, patch: 0 },\n tokens: [\n {\n chainId: pepuMainnet.id,\n address: \"0xF9Cf4A16d26979b929Be7176bAc4e7084975FCB8\",\n name: \"Wrapped Pepe Unchained\",\n symbol: \"WPEPU\",\n decimals: 18,\n // Cross-verified across the project's own docs, Blockscout's token\n // list, and PepuSwap's deployment config, plus an on-chain\n // `eth_getCode` call and Blockscout's \"verified as WETH9\" source\n // match. See `wpepuAbi` in `./abi/wpepu.ts` for the ABI-level\n // verification (deposit/withdraw/decimals/symbol/name all confirmed\n // live).\n },\n {\n chainId: pepuMainnet.id,\n address: \"0x06f69A40C33C5A4Cd038BBE1DA689D4D636Ec448\",\n name: \"Tether USD\",\n symbol: \"USDT\",\n decimals: 6,\n // Verified live on 2026-09-24: discovered as the non-WPEPU leg of\n // PepuSwap's WPEPU/USDT 0.3% pool (`0x4bE3Af53800AADE09201654CD76D55063c7bdE70`,\n // itself returned by the independently-verified `pepuSwapV3FactoryAbi`\n // `getPool(WPEPU, USDT, 3000)` — see `../dex.ts`), then confirmed\n // directly against this address via `eth_call`: `name()` ->\n // \"Tether USD\", `symbol()` -> \"USDT\", `decimals()` -> `6`. Note the\n // 6 decimals (standard for USDT, unlike the 18-decimal PEPU/WPEPU) —\n // don't reuse `formatPepu`/`formatUnits(x, 18)` for this token.\n },\n {\n chainId: pepuMainnet.id,\n address: \"0x20fB684Bfc1aBAaD3AceC5712f2Aa30bd494dF74\",\n name: \"USD Coin\",\n symbol: \"USDC\",\n decimals: 6,\n // Verified live on 2026-10-03 (read-only): `eth_getCode` returns 835\n // bytes of code, and `eth_call` gives `name()` -> \"USD Coin\",\n // `symbol()` -> \"USDC\", `decimals()` -> `6`. One of the tokens PepuSwap\n // trades. 6 decimals, like USDT.\n },\n {\n chainId: pepuMainnet.id,\n address: \"0x7CCC51754216C04D4Bb1210630cCA16e5430Aa70\",\n name: \"Wrapped Ether\",\n symbol: \"WETH\",\n decimals: 18,\n // Verified live on 2026-10-03 (read-only): `eth_getCode` returns 835\n // bytes of code, and `eth_call` gives `name()` -> \"Wrapped Ether\",\n // `symbol()` -> \"WETH\", `decimals()` -> `18`. One of the tokens\n // PepuSwap trades.\n },\n ],\n};\n","import type { Abi, Address } from \"viem\";\n\nimport type { PepuChain } from \"./chains.js\";\n\n/**\n * A minimal client for pepuscan's (Blockscout's) public REST API —\n * deliberately narrow: **verified-ABI and token-metadata reads only**.\n * Blockscout's API surface is large (transaction history, logs, internal\n * txs, NFTs, account-abstraction data, ...); re-wrapping all of it here\n * would duplicate `@pepu-chain/mcp` (the Blockscout MCP server), which is the\n * right place for that. This client exists only for the two lookups a\n * dapp commonly needs synchronously and that this package's own ABI/token\n * modules can't provide (an address this package hasn't independently\n * verified, or a token not yet in {@link pepuTokenList}).\n *\n * Uses the platform `fetch` (Node 18+, every evergreen browser) — no HTTP\n * client dependency.\n */\nexport interface PepuscanClient {\n /**\n * Fetch a contract's verified ABI from pepuscan. Resolves `null` if the\n * contract is not verified (a 404 from Blockscout's\n * `/v2/smart-contracts/{address}`) rather than throwing, since \"not\n * verified\" is an expected, ordinary result — not an error.\n */\n getVerifiedAbi(address: Address): Promise<Abi | null>;\n /**\n * Fetch a token's on-chain metadata from pepuscan\n * (`/v2/tokens/{address}`). Resolves `null` if pepuscan has no record of\n * the address as a token (a 404) — the address may still be a valid\n * contract; it just isn't a token Blockscout has indexed as one.\n */\n getTokenMetadata(address: Address): Promise<PepuscanTokenMetadata | null>;\n}\n\n/** Token metadata as reported by pepuscan's `/v2/tokens/{address}`. */\nexport interface PepuscanTokenMetadata {\n readonly address: Address;\n readonly name: string | null;\n readonly symbol: string | null;\n /** `null` for token types that don't have a fixed decimals field (e.g. most ERC-721s). */\n readonly decimals: number | null;\n readonly totalSupply: string | null;\n /** Blockscout's token type string, e.g. `\"ERC-20\"`, `\"ERC-721\"`, `\"ERC-1155\"`. */\n readonly type: string | null;\n}\n\ninterface BlockscoutSmartContractResponse {\n readonly abi?: Abi | null;\n}\n\ninterface BlockscoutTokenResponse {\n readonly name?: string | null;\n readonly symbol?: string | null;\n readonly decimals?: string | null;\n readonly total_supply?: string | null;\n readonly type?: string | null;\n}\n\nfunction requireApiUrl(chain: PepuChain): string {\n const apiUrl = chain.blockExplorers?.default.apiUrl;\n if (!apiUrl) {\n throw new Error(\n `createPepuscanClient: no Blockscout API URL configured for chain \"${chain.name}\" (id ${chain.id}).`,\n );\n }\n return apiUrl;\n}\n\nasync function getJsonOrNull<T>(url: string): Promise<T | null> {\n const response = await fetch(url);\n if (response.status === 404) {\n return null;\n }\n if (!response.ok) {\n throw new Error(`pepuscan: GET ${url} failed with status ${response.status}`);\n }\n return (await response.json()) as T;\n}\n\n/**\n * Create a {@link PepuscanClient} bound to a {@link PepuChain}'s configured\n * Blockscout API URL (`chain.blockExplorers.default.apiUrl`). Throws\n * immediately if the chain has none configured (currently\n * {@link pepuTestnet} — see `chains.ts`) rather than deferring the failure\n * to the first call.\n */\nexport function createPepuscanClient(chain: PepuChain): PepuscanClient {\n const apiUrl = requireApiUrl(chain);\n\n return {\n async getVerifiedAbi(address) {\n const body = await getJsonOrNull<BlockscoutSmartContractResponse>(\n `${apiUrl}/v2/smart-contracts/${address}`,\n );\n return body?.abi ?? null;\n },\n async getTokenMetadata(address) {\n const body = await getJsonOrNull<BlockscoutTokenResponse>(\n `${apiUrl}/v2/tokens/${address}`,\n );\n if (!body) {\n return null;\n }\n return {\n address,\n name: body.name ?? null,\n symbol: body.symbol ?? null,\n decimals: body.decimals != null ? Number(body.decimals) : null,\n totalSupply: body.total_supply ?? null,\n type: body.type ?? null,\n };\n },\n };\n}\n","import type { AddEthereumChainParameter, EIP1193Provider } from \"viem\";\nimport { numberToHex } from \"viem\";\n\nimport type { PepuChain } from \"./chains.js\";\n\n/**\n * Build the parameter object for an EIP-3085 `wallet_addEthereumChain`\n * request from a {@link PepuChain}, so callers don't have to hand-assemble\n * (and risk mistyping) `chainId` hex encoding, `nativeCurrency`, RPC URLs,\n * and explorer URLs themselves.\n *\n * Omits `blockExplorerUrls` entirely when the chain has no configured\n * explorer (currently {@link pepuTestnet} — see `chains.ts`) rather than\n * sending an empty array or a guessed URL.\n */\nexport function toAddEthereumChainParameter(\n chain: PepuChain,\n): AddEthereumChainParameter {\n const explorerUrl = chain.blockExplorers?.default.url;\n return {\n chainId: numberToHex(chain.id),\n chainName: chain.name,\n nativeCurrency: chain.nativeCurrency,\n rpcUrls: chain.rpcUrls.default.http,\n ...(explorerUrl ? { blockExplorerUrls: [explorerUrl] } : {}),\n };\n}\n\n/**\n * The standard EIP-1193 error code a wallet returns from\n * `wallet_switchEthereumChain` when it doesn't recognize the target chain\n * yet (EIP-3326) — the signal to fall back to `wallet_addEthereumChain`.\n */\nconst CHAIN_NOT_RECOGNIZED_ERROR_CODE = 4902;\n\nfunction isChainNotRecognizedError(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code: unknown }).code === CHAIN_NOT_RECOGNIZED_ERROR_CODE\n );\n}\n\n/**\n * Switch an EIP-1193 provider (e.g. `window.ethereum`) to a\n * {@link PepuChain}, adding it first via `wallet_addEthereumChain` if the\n * wallet doesn't already recognize the chain (error code `4902` per\n * EIP-3326) — the two-step dance almost every dapp ends up hand-rolling.\n *\n * If you already have a viem `WalletClient`, its own `switchChain`/`addChain`\n * actions work the same way at the RPC level; this helper is for the plainer\n * \"I just have an injected provider\" case and does the fallback viem's\n * `switchChain` alone does not (see `viem/actions`' `switchChain.js` — it\n * only ever sends `wallet_switchEthereumChain`).\n *\n * Rethrows any other error unchanged (e.g. the user rejecting either\n * prompt), and rethrows the original switch error if the wallet doesn't\n * report the standard `4902` code for an unrecognized chain — some wallets\n * are known to deviate from the EIP-3326 error code, and this helper does\n * not attempt to paper over that.\n */\nexport async function switchOrAddPepuChain(\n provider: EIP1193Provider,\n chain: PepuChain,\n): Promise<void> {\n try {\n await provider.request({\n method: \"wallet_switchEthereumChain\",\n params: [{ chainId: numberToHex(chain.id) }],\n });\n } catch (error) {\n if (!isChainNotRecognizedError(error)) {\n throw error;\n }\n await provider.request({\n method: \"wallet_addEthereumChain\",\n params: [toAddEthereumChainParameter(chain)],\n });\n }\n}\n","import { parseAbi } from \"viem\";\n\n/**\n * Arbitrum Nitro's `ArbGasInfo` precompile — lives at the same fixed address\n * on every Arbitrum Orbit/Nitro chain, including PEPU. Exposes the L2\n * execution / L1 data-posting fee breakdown that {@link explainDualFeeModel}\n * (`../gas.js`) describes.\n *\n * Verified live against PEPU mainnet 2026-09-24 via `eth_call`:\n * - `getPricesInWei()` returns `(perL2Tx: 0, perL1CalldataUnit: 0,\n * perStorageAllocation: 250000000000000000, perArbGasBase: 12500000000000,\n * perArbGasCongestion: 0, perArbGasTotal: 12500000000000)`. `perArbGasBase`\n * / `perArbGasTotal` (12,500 gwei) match the block's own `baseFeePerGas`\n * at the same height, and `perL1CalldataUnit` is `0` — see the module doc\n * on `../gas.js` for what that means for PEPU's L1 data-posting fee today.\n * - `getL1BaseFeeEstimate()` returns `0`, consistent with the same reading.\n */\nexport const arbGasInfoAbi = parseAbi([\n \"function getPricesInWei() view returns (uint256 perL2Tx, uint256 perL1CalldataUnit, uint256 perStorageAllocation, uint256 perArbGasBase, uint256 perArbGasCongestion, uint256 perArbGasTotal)\",\n \"function getL1BaseFeeEstimate() view returns (uint256)\",\n \"function getMinimumGasPrice() view returns (uint256)\",\n]);\n\n/**\n * Fixed address of the `ArbGasInfo` precompile. Identical on every\n * Arbitrum Orbit/Nitro chain (it's a precompile, not a deployed contract),\n * confirmed responding on PEPU mainnet as noted above.\n */\nexport const ARB_GAS_INFO_ADDRESS =\n \"0x000000000000000000000000000000000000006C\" as const;\n","import type { Address, PublicClient, TransactionRequest, Transport } from \"viem\";\nimport { formatUnits } from \"viem\";\n\nimport { ARB_GAS_INFO_ADDRESS, arbGasInfoAbi } from \"./abi/arbGasInfo.js\";\nimport type { PepuChain } from \"./chains.js\";\n\n/**\n * PEPU's two-part Nitro gas price, read live from the `ArbGasInfo`\n * precompile (`0x...6C`, fixed on every Arbitrum Orbit/Nitro chain). See\n * {@link explainDualFeeModel} for what each field means and why, on PEPU\n * specifically, one of them is currently zero.\n */\nexport interface NitroFeeBreakdown {\n /**\n * L2 execution price, in wei per gas unit. This is `perArbGasTotal` from\n * `getPricesInWei()` — `perArbGasBase` (the network's floor) plus\n * `perArbGasCongestion` (demand surcharge, `0` when the chain isn't\n * congested). Tracks the block's own `baseFeePerGas`.\n */\n readonly l2PricePerGasWei: bigint;\n /**\n * L1 data-posting price, in wei per L1-calldata-unit (`perL1CalldataUnit`\n * from `getPricesInWei()`). Verified `0` on PEPU mainnet as of\n * 2026-09-24 — see {@link explainDualFeeModel}.\n */\n readonly l1PricePerCalldataUnitWei: bigint;\n /**\n * `ArbGasInfo`'s own estimate of the L1 base fee it would need to post\n * data at, in wei. Verified `0` on PEPU mainnet as of 2026-09-24,\n * consistent with `l1PricePerCalldataUnitWei` being `0`.\n */\n readonly l1BaseFeeEstimateWei: bigint;\n}\n\n/**\n * Read the current {@link NitroFeeBreakdown} from the `ArbGasInfo`\n * precompile. One `eth_call` (`getPricesInWei()`) plus one more\n * (`getL1BaseFeeEstimate()`) — no caching, since these can change block to\n * block under load.\n */\nexport async function getNitroFeeBreakdown(\n client: PublicClient<Transport, PepuChain>,\n): Promise<NitroFeeBreakdown> {\n const [prices, l1BaseFeeEstimateWei] = await Promise.all([\n client.readContract({\n address: ARB_GAS_INFO_ADDRESS,\n abi: arbGasInfoAbi,\n functionName: \"getPricesInWei\",\n }),\n client.readContract({\n address: ARB_GAS_INFO_ADDRESS,\n abi: arbGasInfoAbi,\n functionName: \"getL1BaseFeeEstimate\",\n }),\n ]);\n return {\n l2PricePerGasWei: prices[5], // perArbGasTotal\n l1PricePerCalldataUnitWei: prices[1], // perL1CalldataUnit\n l1BaseFeeEstimateWei,\n };\n}\n\n/** Plain-English explanation of Arbitrum Nitro's dual-fee model, as it currently behaves on PEPU. */\nexport interface DualFeeModelExplanation {\n readonly summary: string;\n readonly l2ExecutionFee: string;\n readonly l1DataPostingFee: string;\n readonly pepuStatus: string;\n}\n\n/**\n * Explain Arbitrum Nitro's dual-fee gas model in plain English, including\n * how it currently behaves on PEPU specifically (verified live against\n * mainnet 2026-09-24 — see the doc comment on `arbGasInfoAbi` in\n * `./abi/arbGasInfo.ts` for the exact call and response this is based on).\n *\n * This is a static explanation (no network call) — pair it with\n * {@link getNitroFeeBreakdown} for live numbers.\n */\nexport function explainDualFeeModel(): DualFeeModelExplanation {\n return {\n summary:\n \"Arbitrum Nitro chains (PEPU included — it's an Orbit chain built on \" +\n \"Nitro) charge gas as the sum of two independent components, unlike \" +\n \"a plain L1 chain where 'gas price' is a single number: an L2 \" +\n \"execution fee (compute + storage, priced in the chain's own gas \" +\n \"units) and an L1 data-posting fee (the cost of publishing the \" +\n \"transaction's calldata back to the settlement layer, priced \" +\n \"per byte of calldata, independent of how much EVM computation \" +\n \"the transaction does).\",\n l2ExecutionFee:\n \"Works like a normal EVM gas price: gasUsed * pricePerGas, where \" +\n \"pricePerGas is ArbGasInfo's perArbGasTotal (perArbGasBase, the \" +\n \"network floor, plus perArbGasCongestion, a demand surcharge that's \" +\n \"0 when the chain isn't congested). On PEPU mainnet this floor is \" +\n \"12,500 gwei (12,500,000,000,000 wei) — see the note on \" +\n \"l1DataPostingFee below for why that number looks alarming but \" +\n \"isn't.\",\n l1DataPostingFee:\n \"Normally: calldataBytes-derived 'L1 gas units' * perL1CalldataUnit, \" +\n \"recovering the cost of posting the tx's data to the settlement \" +\n \"layer (L1 for a vanilla Orbit chain, or the Data Availability \" +\n \"Committee for an AnyTrust chain like PEPU). Verified live on PEPU \" +\n \"mainnet 2026-09-24: both perL1CalldataUnit and getL1BaseFeeEstimate() \" +\n \"read 0. That means PEPU is not currently charging a separate L1/DA \" +\n \"data fee component at all — the full cost of a PEPU transaction \" +\n \"today is just the L2 execution fee above. This is a live chain \" +\n \"parameter, not a protocol guarantee; re-check with \" +\n \"getNitroFeeBreakdown() rather than assuming it stays 0 forever.\",\n pepuStatus:\n \"Net effect: a PEPU 'gas price' of 12,500 gwei looks like an \" +\n \"Ethereum-mainnet congestion spike if you only know Ethereum's \" +\n \"1-50 gwei range, but PEPU is a low-value token, so the same gas \" +\n \"price multiplied out is a tiny PEPU (and USD) amount. Naive gwei \" +\n \"formatting misleads on both ends — the gwei number reads as scary, \" +\n \"and formatting a total cost with the same few-decimal-places habit \" +\n \"people use for ETH rounds small-but-real PEPU amounts to '0'. Use \" +\n \"formatPepu() for totals and formatPepuGasPrice() when you want to \" +\n \"show the price-per-gas number with that context attached.\",\n };\n}\n\n/** Result of {@link estimateTransactionCost}. */\nexport interface TransactionCostEstimate {\n /** Estimated gas units, from `client.estimateGas`. */\n readonly gas: bigint;\n /** L2 execution price per gas unit, in wei, used for this estimate. */\n readonly gasPriceWei: bigint;\n /** `gas * gasPriceWei`, in wei. Does not include an L1 data-posting fee — see {@link explainDualFeeModel}. */\n readonly costWei: bigint;\n /** {@link costWei} formatted with {@link formatPepu}, for direct display. */\n readonly costFormatted: string;\n}\n\n/**\n * Estimate a transaction's PEPU cost: `client.estimateGas(request)` for the\n * gas units, multiplied by the current L2 execution price\n * (`getNitroFeeBreakdown`'s `l2PricePerGasWei`, which tracks the latest\n * block's `baseFeePerGas`).\n *\n * Deliberately excludes any L1 data-posting fee — see\n * {@link explainDualFeeModel} for why that component reads as `0` on PEPU\n * today, and re-derive this estimate if that ever changes.\n */\nexport async function estimateTransactionCost(\n client: PublicClient<Transport, PepuChain>,\n request: TransactionRequest & { account?: Address },\n): Promise<TransactionCostEstimate> {\n const [gas, { l2PricePerGasWei }] = await Promise.all([\n client.estimateGas(request),\n getNitroFeeBreakdown(client),\n ]);\n const costWei = gas * l2PricePerGasWei;\n return {\n gas,\n gasPriceWei: l2PricePerGasWei,\n costWei,\n costFormatted: formatPepu(costWei),\n };\n}\n\n/** Options for {@link formatPepu}. */\nexport interface FormatPepuOptions {\n /**\n * Maximum fractional digits to keep after trimming trailing zeros.\n * Default `8` — high enough that typical PEPU gas costs (a low-value\n * token at a 12,500 gwei base fee) don't round down to `\"0\"`, which is\n * exactly the failure mode a default ETH-style 4-decimal formatter hits\n * here.\n */\n readonly maxDecimals?: number;\n /** Append `\" PEPU\"` to the result. Default `true`. */\n readonly suffix?: boolean;\n}\n\n/**\n * Format a wei amount as PEPU, tuned for a low-value token on a chain with\n * a comparatively large (12,500 gwei) base fee — see\n * {@link explainDualFeeModel}. Plain `formatEther`-style formatting (a\n * handful of decimal places, as is reasonable for ETH) collapses typical\n * PEPU amounts to `\"0.0000\"`; this keeps up to `maxDecimals` significant\n * fractional digits instead, trimming only trailing zeros.\n *\n * This is a display formatter, not an arbitrary-precision one — it does\n * not round-trip back to the exact wei value, and is not meant to.\n */\nexport function formatPepu(wei: bigint, options?: FormatPepuOptions): string {\n const maxDecimals = options?.maxDecimals ?? 8;\n const suffix = options?.suffix ?? true;\n\n const negative = wei < 0n;\n const full = formatUnits(negative ? -wei : wei, 18);\n const [whole = \"0\", fraction = \"\"] = full.split(\".\");\n const truncatedFraction = fraction.slice(0, maxDecimals).replace(/0+$/, \"\");\n const body = truncatedFraction.length > 0 ? `${whole}.${truncatedFraction}` : whole;\n const withSign = negative ? `-${body}` : body;\n return suffix ? `${withSign} PEPU` : withSign;\n}\n\n/**\n * Format any token amount (smallest unit) as a short decimal string, for any\n * `decimals`. Truncates (never rounds) to `maxFractionDigits` (default 4) and\n * trims trailing zeros, like {@link formatPepu} but without the PEPU suffix and\n * 18-decimals assumption. Display only: it does not round-trip.\n *\n * @example\n * formatUnitsCompact(1_234_567n, 6); // \"1.2345\"\n * formatUnitsCompact(5n * 10n ** 18n, 18); // \"5\"\n */\nexport function formatUnitsCompact(value: bigint, decimals: number, maxFractionDigits = 4): string {\n const negative = value < 0n;\n const [whole = \"0\", fraction = \"\"] = formatUnits(negative ? -value : value, decimals).split(\".\");\n const frac = fraction.slice(0, maxFractionDigits).replace(/0+$/, \"\");\n const body = frac.length > 0 ? `${whole}.${frac}` : whole;\n return negative && body !== \"0\" ? `-${body}` : body;\n}\n\n/**\n * Format a wei-per-gas price for display, with an explicit note that\n * PEPU's baseline (~12,500 gwei) is not a congestion spike — see\n * {@link explainDualFeeModel}. Bare \"N gwei\" output, without that context,\n * is exactly the naive formatting this package's brief calls out as\n * misleading for PEPU.\n */\nexport function formatPepuGasPrice(weiPerGas: bigint): string {\n const gwei = formatUnits(weiPerGas, 9);\n return `${gwei} gwei/gas (PEPU's normal baseline is ~12,500 gwei — this is not a congestion spike; see explainDualFeeModel())`;\n}\n\n/**\n * Default safety margin applied on top of a raw gas estimate before\n * {@link maxSendableAmount} computes its answer, in basis points\n * (`2000` = 20%).\n *\n * Why a margin at all: the L2 price behind {@link estimateTransactionCost}\n * (`ArbGasInfo.getPricesInWei().perArbGasTotal`) is read live and tracks\n * the *current* block's `baseFeePerGas`. A \"max send\" button estimates\n * cost, fills `balance - cost` into the amount field, and then waits for\n * the user to review and confirm — by the time the signed transaction\n * actually lands, at least one block (often more, if the user pauses to\n * look at the number) has passed, and the price can have moved in that\n * gap. Spending every last wei on `value` against a stale estimate is\n * exactly the failure this button exists to prevent: a transaction that\n * reverts for insufficient funds after the user was told this amount was\n * safe.\n *\n * Why 20% specifically: this repo already uses a 20% margin for the\n * sibling problem of gas-*limit* drift between estimate and execution\n * (`templates/game-app/lib/tap-transaction.ts`'s `withGasLimitBuffer`),\n * and that figure — a standard, conservative buffer used broadly across\n * production transaction-sending code, not one tuned from measured PEPU\n * data — is reused here for gas-*price* drift for the same reason. Two\n * things make being generous here cheap specifically on PEPU: (1) this\n * package has only ever observed PEPU's base fee sitting flat at a\n * 12,500 gwei floor with a `0` congestion surcharge (see\n * {@link explainDualFeeModel}), so the realistic gap this margin covers\n * is currently close to zero; and (2) PEPU is a low-value token, so 20%\n * of an already-tiny gas cost is an even tinier absolute amount left\n * unspent. If PEPU's fee market ever becomes genuinely congested\n * (`perArbGasCongestion` reading nonzero), re-derive this default from\n * observed volatility rather than assuming 20% still covers it.\n */\nexport const DEFAULT_MAX_SEND_MARGIN_BPS = 2000;\n\nfunction assertValidMarginBps(marginBps: number): void {\n if (!Number.isInteger(marginBps) || marginBps < 0 || marginBps > 10_000) {\n throw new Error(\n `maxSendableAmount: marginBps must be an integer between 0 and 10000 (got ${marginBps})`,\n );\n }\n}\n\n/** Options for {@link maxSendableAmount}. */\nexport interface MaxSendableAmountOptions {\n /** Client to estimate gas against. */\n readonly client: PublicClient<Transport, PepuChain>;\n /**\n * The sender's address — used as `estimateGas`'s `account`, and (when\n * {@link MaxSendableAmountOptions.to} is omitted) as the estimate's\n * destination too. See `to`'s doc comment.\n */\n readonly from: Address;\n /**\n * The transfer's real destination, if the user has typed one in yet.\n * Estimating against the *actual* recipient matters whenever it's a\n * contract with a `receive()`/`fallback()` that does real work — a\n * generic placeholder address would silently under-estimate that case.\n *\n * Omit this (or don't call {@link maxSendableAmount} at all yet — the\n * caller decides when a \"recipient\" is valid enough to estimate\n * against) before the user has entered a recipient. This function then\n * falls back to estimating a self-transfer (`to: from`), the best\n * available stand-in for \"a plain native transfer to *some* EOA,\" which\n * is what most PEPU sends are.\n */\n readonly to?: Address;\n /**\n * The sender's current native balance, in wei (e.g. from wagmi's\n * `useBalance` or viem's `getBalance`).\n */\n readonly balanceWei: bigint;\n /**\n * Safety margin on top of the raw estimated cost, in basis points.\n * Default {@link DEFAULT_MAX_SEND_MARGIN_BPS} — see its doc comment for\n * why 20%. Must be an integer in `[0, 10000]`.\n */\n readonly marginBps?: number;\n}\n\n/**\n * Result of {@link maxSendableAmount} — a discriminated union on `status`\n * so callers can't accidentally read `amountWei` off a result where there\n * isn't one.\n */\nexport type MaxSendableAmountResult =\n | {\n readonly status: \"ok\";\n /** The amount safe to fill into a \"Max\" field: `balanceWei - totalReservedWei`. Always `> 0n`. */\n readonly amountWei: bigint;\n /** The gas estimate this result was computed from. */\n readonly estimate: TransactionCostEstimate;\n /** The safety margin on top of `estimate.costWei`, in wei. */\n readonly marginWei: bigint;\n /** `estimate.costWei + marginWei` — the total withheld from `balanceWei`. */\n readonly totalReservedWei: bigint;\n }\n | {\n /** `balanceWei` was `0` (or negative) — nothing to size a transfer from, no network call was made. */\n readonly status: \"zero-balance\";\n /** Human-readable explanation, safe to render directly. */\n readonly reason: string;\n }\n | {\n /** `balanceWei` doesn't cover even `estimate.costWei` plus the margin — a \"max\" send would be `<= 0`. */\n readonly status: \"insufficient-for-gas\";\n /** Human-readable explanation, safe to render directly. */\n readonly reason: string;\n /** The gas estimate this result was computed from. */\n readonly estimate: TransactionCostEstimate;\n /** `estimate.costWei + marginWei` — what the balance would have needed to cover. */\n readonly totalReservedWei: bigint;\n };\n\n/**\n * Compute the largest amount a sender can put in a native transfer's\n * `value` and still expect it to succeed: `balance - estimatedCost -\n * safetyMargin`.\n *\n * This is deliberately not `balance - gasLimit * gasPrice` computed by\n * hand — see {@link explainDualFeeModel} for why that naive formula is\n * wrong on an Arbitrum Nitro chain like PEPU in general (a second,\n * L1-data-posting fee component can apply on top of L2 execution). In\n * practice this function sidesteps the whole question by never\n * reimplementing Nitro's fee math itself: it hands the real transfer off\n * to {@link estimateTransactionCost}, which calls the chain's own\n * `eth_estimateGas` (Nitro-aware by construction — the node, not this\n * package, knows its own fee model) and reads the live L2 price from the\n * `ArbGasInfo` precompile. If PEPU ever starts charging a nonzero L1\n * component too, `estimateTransactionCost` documents exactly where that\n * would need to be added, and this function inherits the fix for free.\n *\n * THE CIRCULARITY THIS AVOIDS: the whole point of this call is to\n * discover what the max `value` should be, so it can't estimate gas\n * using that unknown value. It also can't reuse `balanceWei` as a stand-in\n * `value` for the estimate — most RPCs simulate `eth_estimateGas` against\n * the sender's real current balance, and a `value` equal to the full\n * balance leaves exactly `0` left over to cover the fee with, so the\n * simulation would itself fail with \"insufficient funds\" instead of\n * returning a usable number. Instead, this estimates with a nominal `1n`\n * wei placeholder. That's a safe stand-in because, for a plain native\n * transfer (no calldata), gas usage doesn't depend on *how much* value\n * moves — only on whether `to` has code that reacts to receiving value at\n * all, which `1n` (any nonzero amount) already exercises. The one case\n * this can still under-estimate: a recipient contract whose\n * `receive()`/`fallback()` branches on the exact `msg.value` it got\n * (e.g. cheaper for small amounts, pricier for large ones) — an inherent\n * limit of estimating \"the max\" before the max is known, not specific to\n * this implementation.\n *\n * Handles the edge cases a naive subtraction gets wrong:\n * - `balanceWei <= 0n` → `{ status: \"zero-balance\" }`, no network call.\n * - `balanceWei` covers less than `estimate.costWei` plus the margin →\n * `{ status: \"insufficient-for-gas\" }` rather than a negative or `0`\n * amount.\n * - Estimation itself failing (bad RPC, reverting recipient, etc.) →\n * this function does not catch that; the returned promise rejects with\n * whatever `estimateTransactionCost`/`client.estimateGas` threw, so a\n * caller can show the real reason instead of silently falling back to a\n * guess.\n *\n * NOT WIRED INTO `templates/consumer-app`: that template's send form\n * dropped its \"Max\" button rather than consume this helper. The reason\n * isn't a bug here — it's that Privy's transaction confirmation modal\n * runs its own, separately-implemented pre-flight balance check before\n * signing, and on PEPU that check has been observed to be over-conservative\n * enough to reject a transfer this function correctly sized as affordable\n * (e.g. a 0.7748 PEPU balance refused for a 0.2625 PEPU transfer). Since\n * Privy's modal has the final say on whether the transaction goes out, a\n * \"Max\" fill computed by this function can still bounce there, which makes\n * the button promise something the wallet UI can't reliably deliver. This\n * function stays correct and is still the right tool for any PEPU wallet\n * UI that isn't routing its send flow through Privy's modal — just don't\n * assume the absence of a \"Max\" button in that one template means this\n * helper is unused or unmaintained.\n */\nexport async function maxSendableAmount(\n options: MaxSendableAmountOptions,\n): Promise<MaxSendableAmountResult> {\n const {\n client,\n from,\n to,\n balanceWei,\n marginBps = DEFAULT_MAX_SEND_MARGIN_BPS,\n } = options;\n assertValidMarginBps(marginBps);\n\n if (balanceWei <= 0n) {\n return {\n status: \"zero-balance\",\n reason: \"This wallet has no PEPU to send.\",\n };\n }\n\n const estimate = await estimateTransactionCost(client, {\n account: from,\n to: to ?? from,\n value: 1n,\n });\n\n const marginWei = (estimate.costWei * BigInt(marginBps)) / 10_000n;\n const totalReservedWei = estimate.costWei + marginWei;\n\n if (balanceWei <= totalReservedWei) {\n return {\n status: \"insufficient-for-gas\",\n reason:\n `Balance (${formatPepu(balanceWei)}) doesn't cover the estimated ` +\n `cost of sending plus a safety margin (${formatPepu(totalReservedWei)} ` +\n `would need to be reserved for gas). Add more PEPU before sending.`,\n estimate,\n totalReservedWei,\n };\n }\n\n return {\n status: \"ok\",\n amountWei: balanceWei - totalReservedWei,\n estimate,\n marginWei,\n totalReservedWei,\n };\n}\n","import { parseAbi } from \"viem\";\n\n/**\n * ZeroDev Kernel v3 ECDSA validator module ABI, at\n * `0x845ADb2C711129d4f3966735eD98a9F09fC4cE57` (deployed on PEPU mainnet\n * only; see `pepuContracts.ecdsaValidator` in `../contracts.js`). This is\n * the ERC-7579 validator module that lets a Kernel account be controlled by\n * a plain ECDSA key (the common case — a Privy/embedded-wallet EOA signs\n * UserOperations on behalf of the smart account).\n *\n * Verified live against mainnet 2026-09-24 via `eth_call`:\n * - `ecdsaValidatorStorage(address)`, called with the zero address, returns\n * `address(0)` — the expected result for a kernel account that was never\n * registered, and confirmation the getter itself works.\n * - `isModuleType(1)` returns `true`. `1` is the ERC-7579 `MODULE_TYPE_VALIDATOR`\n * constant, so this independently confirms the contract both implements\n * the standard ERC-7579 `IModule` interface and self-reports as a\n * validator module — not just a contract that happens to expose a\n * same-named storage getter.\n *\n * `onInstall`/`onUninstall` are part of the same ERC-7579 `IModule`\n * interface `isModuleType` confirmed this contract implements; they take a\n * non-trivial `bytes` payload (the encoded owner address) and mutate state,\n * so — like EntryPoint's `depositTo`/`withdrawTo` — they were not\n * separately simulated. Included because a Kernel account's installation\n * flow calls them, so a caller building that flow needs the selectors.\n */\nexport const kernelEcdsaValidatorAbi = parseAbi([\n \"function ecdsaValidatorStorage(address kernel) view returns (address owner)\",\n \"function isModuleType(uint256 moduleTypeId) view returns (bool)\",\n \"function isInitialized(address kernel) view returns (bool)\",\n \"function onInstall(bytes calldata data) payable\",\n \"function onUninstall(bytes calldata data) payable\",\n]);\n\n/**\n * ERC-7579 module type IDs (EIP-7579 §Module Types). `isModuleType` on any\n * conforming module — including {@link kernelEcdsaValidatorAbi}'s contract,\n * confirmed live above — is called with one of these.\n */\nexport const ERC7579_MODULE_TYPE = {\n validator: 1n,\n executor: 2n,\n fallback: 3n,\n hook: 4n,\n} as const;\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's own multicall contract, at\n * `0x927af2a6B76d2d8206d93004463F8C122701383B` on mainnet (see\n * `pepuSwapContracts.multicallNonCanonical` in `../dex.js`). **Not**\n * Multicall3 and not interchangeable with `pepuContracts.multicall3` — see\n * that entry's notes.\n *\n * A first pass at verifying this contract tried a Multicall2-style\n * `getBlockNumber()` probe, which reverted, and concluded no ABI could be\n * shipped for it. That probe used the wrong function name: pepuscan\n * (Blockscout) has this contract verified as Uniswap's\n * `UniswapInterfaceMulticall` — \"a fork of Multicall2 specifically tailored\n * for the Uniswap Interface\" — which exposes `getCurrentBlockTimestamp()`\n * and `getEthBalance(address)` instead of Multicall2's `getBlockNumber()`/\n * `getEthBalance()` pair, plus a `multicall(Call[])` that returns\n * `(blockNumber, Result[])` rather than Multicall3's `(success, returnData)[]`\n * shape (its `Call`/`Result` structs also carry a per-call `gasLimit`/\n * `gasUsed`, which neither Multicall2 nor Multicall3 do the same way) — so\n * it is not a drop-in for either.\n *\n * Verified live against mainnet 2026-09-24:\n * - The ABI below is exactly what pepuscan reports as this contract's\n * verified source-matched interface.\n * - `getCurrentBlockTimestamp()` returns a value equal to the current\n * block's own `timestamp` (checked against the same block via\n * `eth_getBlockByNumber`).\n * - `getEthBalance(0x0)` returns a live, non-zero value (the zero address's\n * real native-PEPU balance).\n *\n * `multicall(Call[])` was not independently simulated (it needs real\n * `target`/`callData` values per call to return a meaningful result); the\n * two verified getters above are enough to confirm this is a genuine,\n * matching deployment of the verified source, not a same-address\n * coincidence.\n */\nexport const pepuSwapMulticallAbi = parseAbi([\n \"function getCurrentBlockTimestamp() view returns (uint256 timestamp)\",\n \"function getEthBalance(address addr) view returns (uint256 balance)\",\n \"function multicall((address target, uint256 gasLimit, bytes callData)[] calls) returns (uint256 blockNumber, (bool success, uint256 gasUsed, bytes returnData)[] returnData)\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's own Permit2 deployment, at\n * `0xB461c05f76d7f919FF7A3Df2B0D2593F56538b4B` on mainnet (see\n * `pepuSwapContracts.permit2` in `../dex.js`).\n *\n * **This is NOT the canonical Permit2** (`0x000000000022D473030F116dDEE9F6B43aC78BA3`).\n * The canonical address is now also deployed on PEPU (see\n * `pepuContracts.permit2` in `../contracts.js`, `status: \"deployed\"`), but\n * PepuSwap's own frontend was built against this separate, earlier\n * deployment and overrides the canonical address specifically for chain\n * 97741 to point at this contract instead. The two are different contracts\n * with different EIP-712 domains — do not assume a generic\n * canonical-Permit2-aware tool (e.g. a library that hardcodes the canonical\n * address) will interoperate with PepuSwap using it; approvals made against\n * one are not visible to the other.\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 18,306 bytes of bytecode.\n * - `DOMAIN_SEPARATOR()` returns a live 32-byte value without reverting —\n * confirming this contract implements Permit2's standard EIP-712 domain\n * separator getter, consistent with a genuine (if non-canonical) Permit2\n * deployment.\n *\n * `allowance`/`approve`/`permit` are Permit2's standard signatures; not\n * separately simulated here (each needs a real token/owner/spender to\n * return a meaningful result). Kept intentionally minimal — this package\n * does not ship a full Permit2 ABI, only enough to recognize and read from\n * this specific deployment.\n */\nexport const pepuSwapPermit2Abi = parseAbi([\n \"function DOMAIN_SEPARATOR() view returns (bytes32)\",\n \"function allowance(address owner, address token, address spender) view returns (uint160 amount, uint48 expiration, uint48 nonce)\",\n \"function approve(address token, address spender, uint160 amount, uint48 expiration)\",\n]);\n","import { erc721Abi, parseAbi } from \"viem\";\n\n/**\n * PepuSwap's `NonfungiblePositionManager` ABI subset, at\n * `0xe2060CbdE18b5e765c86e5Cd6EE68AF209a9faa7` on mainnet (see\n * `pepuSwapContracts.positionManager` in `../dex.js`). LP positions on\n * PepuSwap are ERC-721 tokens minted by this contract — on pepuscan they\n * show up as \"Launchpad V3 Positions NFT\" / `UNI-V3-POS`.\n *\n * Extends viem's own {@link erc721Abi} (this contract genuinely is an\n * ERC-721) with the one PepuSwap/Uniswap-V3-specific read, `positions`.\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 24,384 bytes of bytecode.\n * - `factory()` returns the verified `pepuSwapV3FactoryAbi` address.\n * - `WETH9()` returns the verified WPEPU address.\n *\n * `positions(tokenId)` is the standard Uniswap V3 signature; not\n * independently simulated here since it requires a minted `tokenId`; the\n * verified getters above confirm this is a genuine, matching deployment.\n */\nexport const pepuSwapPositionManagerAbi = [\n ...erc721Abi,\n ...parseAbi([\n \"function factory() view returns (address)\",\n \"function WETH9() view returns (address)\",\n \"function positions(uint256 tokenId) view returns (uint96 nonce, address operator, address token0, address token1, uint24 fee, int24 tickLower, int24 tickUpper, uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0, uint128 tokensOwed1)\",\n ]),\n] as const;\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's `QuoterV2` ABI subset, at\n * `0xd647b2D80b48e93613Aa6982b85f8909578b4829` on mainnet (see\n * `pepuSwapContracts.quoterV2` in `../dex.js`).\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 8,273 bytes of bytecode.\n * - `factory()` returns the verified `pepuSwapV3FactoryAbi` address.\n * - `WETH9()` returns the verified WPEPU address.\n *\n * `quoteExactInputSingle`/`quoteExactOutputSingle` are QuoterV2's standard\n * signatures. Like the router's swap functions, they weren't independently\n * simulated here (a quote needs a real, liquid pool + valid amounts to\n * return a meaningful result, not just \"doesn't revert\"); the two verified\n * getters above confirm this is a genuine, matching QuoterV2 deployment.\n * QuoterV2 is gas-inefficient by design (it's meant to be called off-chain\n * via `eth_call`, e.g. through `client.simulateContract`) — never send it a\n * real transaction.\n */\nexport const pepuSwapQuoterAbi = parseAbi([\n \"function factory() view returns (address)\",\n \"function WETH9() view returns (address)\",\n \"function quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint24 fee, uint160 sqrtPriceLimitX96) params) returns (uint256 amountOut, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)\",\n \"function quoteExactOutputSingle((address tokenIn, address tokenOut, uint256 amount, uint24 fee, uint160 sqrtPriceLimitX96) params) returns (uint256 amountIn, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's `SwapRouter02` ABI subset, at\n * `0x150c3F0f16C3D9EB34351d7af9c961FeDc97A0fb` on mainnet (see\n * `pepuSwapContracts.swapRouter02` in `../dex.js`).\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 24,497 bytes of bytecode.\n * - `factory()` returns `0x5984B8BF2d4dB9C0aCB1d7924762e4474D80C807` — the\n * independently-verified {@link pepuSwapV3FactoryAbi} address.\n * - `WETH9()` returns `0xF9Cf4A16d26979b929Be7176bAc4e7084975FCB8` — the\n * independently-verified WPEPU address (see `../abi/wpepu.js`).\n *\n * `exactInputSingle`/`exactOutputSingle` are Uniswap's standard SwapRouter02\n * signatures (unchanged across the many chains that run this exact\n * contract); they were not separately simulated because a real swap needs a\n * funded, approved caller. The two verified read functions above confirm\n * this is a genuine, matching SwapRouter02 deployment rather than a\n * same-address coincidence.\n */\nexport const pepuSwapRouterAbi = parseAbi([\n \"function factory() view returns (address)\",\n \"function WETH9() view returns (address)\",\n \"function exactInputSingle((address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 amountIn, uint256 amountOutMinimum, uint160 sqrtPriceLimitX96) params) payable returns (uint256 amountOut)\",\n \"function exactOutputSingle((address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 amountOut, uint256 amountInMaximum, uint160 sqrtPriceLimitX96) params) payable returns (uint256 amountIn)\",\n \"function multicall(uint256 deadline, bytes[] calldata data) payable returns (bytes[] memory results)\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's `TickLens` ABI, at\n * `0x4EB8aA84c066f9bf210eAfE33B30AE49BfafD9a6` on mainnet (see\n * `pepuSwapContracts.tickLens` in `../dex.js`). `TickLens` is stateless\n * (it takes a pool address as an argument to every call rather than storing\n * one), so it has no zero-argument getter to probe.\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 1,385 bytes of bytecode.\n * - `getPopulatedTicksInWord(pool, wordPosition)` was called against the\n * real WPEPU/USDT 0.3% pool (`0x4bE3Af53800AADE09201654CD76D55063c7bdE70`)\n * at the word position derived from that pool's own live `slot0().tick`\n * and `tickSpacing()`. It returned successfully (an empty populated-ticks\n * array for that particular word, which is itself a valid, non-reverting\n * result) — confirming the exact function selector against a real pool.\n */\nexport const pepuSwapTickLensAbi = parseAbi([\n \"function getPopulatedTicksInWord(address pool, int16 tickBitmapIndex) view returns ((int24 tick, int128 liquidityNet, uint128 liquidityGross)[] populatedTicks)\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's `UniversalRouter` ABI, at\n * `0x0dE72b751b77d3c74fB96C5fAd0320Cd8d133d36` on mainnet (see\n * `pepuSwapContracts.universalRouter` in `../dex.js`). UniversalRouter is a\n * command-dispatcher contract — almost everything routes through the one\n * `execute` entrypoint below, with a `commands` byte-string selecting which\n * internal actions run.\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 17,958 bytes of bytecode.\n * - Unlike the other PepuSwap contracts, UniversalRouter does not expose\n * its configured Permit2/factory addresses through public getters (a\n * `PERMIT2()`/`V2_FACTORY()`/`V3_FACTORY()`/`poolManager()` probe all\n * reverted — expected, since a dispatcher contract with no matching\n * function selector just reverts, it doesn't imply anything is wrong).\n * - Instead, `execute(bytes,bytes[],uint256)` was called directly via\n * `eth_call` with an empty `commands` byte-string, an empty `inputs`\n * array, and a far-future deadline. It returned successfully with no\n * revert — confirming the exact function selector Uniswap's\n * `UniversalRouter` uses, dispatched correctly with zero commands to run.\n */\nexport const pepuSwapUniversalRouterAbi = parseAbi([\n \"function execute(bytes commands, bytes[] inputs, uint256 deadline) payable\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's Uniswap V3 core factory ABI, at\n * `0x5984B8BF2d4dB9C0aCB1d7924762e4474D80C807` on mainnet (see\n * `pepuSwapContracts.v3Factory` in `../dex.js`). PepuSwap is a Uniswap V3\n * fork; this is a standard `UniswapV3Factory` ABI subset.\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 24,535 bytes of bytecode.\n * - `owner()` returns a live, non-zero address.\n * - `getPool(WPEPU, USDT, fee)` returns a real, non-zero pool address for\n * fee tiers 100/500/3000/10000, and that pool's own `token0()`/`token1()`\n * independently resolve to USDT/WPEPU.\n * - Four independent contracts on this chain (SwapRouter02,\n * NonfungiblePositionManager, QuoterV2, V3Migrator, V3Staker) each\n * read their own `factory()` immutable and all five return this exact\n * address — see the notes on each of their ABI files.\n */\nexport const pepuSwapV3FactoryAbi = parseAbi([\n \"function owner() view returns (address)\",\n \"function getPool(address tokenA, address tokenB, uint24 fee) view returns (address pool)\",\n \"function feeAmountTickSpacing(uint24 fee) view returns (int24)\",\n \"function createPool(address tokenA, address tokenB, uint24 fee) returns (address pool)\",\n \"event PoolCreated(address indexed token0, address indexed token1, uint24 indexed fee, int24 tickSpacing, address pool)\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * Minimal Uniswap V3 pool ABI for reading a PepuSwap pool's state — enough\n * to price a pair and locate its liquidity, without the full swap/mint/burn\n * surface.\n *\n * Verified live against mainnet 2026-09-24 against the real WPEPU/USDT\n * 0.3% pool (`0x4bE3Af53800AADE09201654CD76D55063c7bdE70`, returned by\n * `pepuSwapV3FactoryAbi`'s `getPool`):\n * - `slot0()` decodes cleanly into the standard 7-field tuple (a live tick\n * of 372469 at the time of verification).\n * - `tickSpacing()` returns `60`, the standard spacing for a 0.3% pool.\n * - `token0()`/`token1()` return USDT/WPEPU respectively, matching the\n * factory's `getPool` inputs.\n */\nexport const pepuSwapV3PoolAbi = parseAbi([\n \"function token0() view returns (address)\",\n \"function token1() view returns (address)\",\n \"function fee() view returns (uint24)\",\n \"function tickSpacing() view returns (int24)\",\n \"function liquidity() view returns (uint128)\",\n \"function slot0() view returns (uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked)\",\n]);\n","import { erc20Abi, parseAbi } from \"viem\";\n\n/**\n * WPEPU (Wrapped Pepe Unchained) ABI.\n *\n * WPEPU is a WETH9-style wrapper around the native PEPU gas token, deployed\n * at `0xF9Cf4A16d26979b929Be7176bAc4e7084975FCB8` on mainnet (see\n * `pepuTokenList` in `../tokens.js`). This extends viem's own {@link erc20Abi}\n * with the two WETH9-specific functions and their events, rather than\n * re-declaring the ERC-20 surface from scratch.\n *\n * Verified live against mainnet on 2026-09-24:\n * - `deposit()` and `withdraw(uint256)` both simulate successfully via\n * `eth_call` (a zero-value deposit and a zero-amount withdraw), confirming\n * both selectors exist and don't revert.\n * - `decimals()` -> `18`, `symbol()` -> `\"WPEPU\"`, `name()` -> `\"Wrapped PEPU\"`.\n * - The contract is verified on pepuscan against the canonical `WETH9`\n * source.\n */\nexport const wpepuAbi = [\n ...erc20Abi,\n ...parseAbi([\n \"function deposit() payable\",\n \"function withdraw(uint256 amount)\",\n \"event Deposit(address indexed dst, uint256 amount)\",\n \"event Withdrawal(address indexed src, uint256 amount)\",\n ]),\n] as const;\n","import { parseAbi } from \"viem\";\n\n/**\n * Minimal Multicall3 ABI (aggregate3 plus the common read helpers). Same\n * interface as canonical mds1/multicall3; on PEPU it lives at the\n * PEPU-specific `0x9CE19273Ae9c24437DFF512E8DFCAed4E4B001bd`, never at the\n * canonical `0xcA11...CA11`.\n */\nexport const multicall3Abi = parseAbi([\n \"struct Call3 { address target; bool allowFailure; bytes callData; }\",\n \"struct Result { bool success; bytes returnData; }\",\n \"function aggregate3(Call3[] calls) payable returns (Result[] returnData)\",\n \"function getEthBalance(address addr) view returns (uint256 balance)\",\n \"function getBlockNumber() view returns (uint256 blockNumber)\",\n \"function getChainId() view returns (uint256)\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * Canonical Permit2 ABI subset (AllowanceTransfer plus SignatureTransfer\n * nonce reads). For the canonical `0x000000000022D473030F116dDEE9F6B43aC78BA3`\n * deployed on PEPU. NOT PepuSwap's separate deployment (see `pepuSwapPermit2Abi`).\n */\nexport const permit2Abi = parseAbi([\n \"function DOMAIN_SEPARATOR() view returns (bytes32)\",\n \"function allowance(address owner, address token, address spender) view returns (uint160 amount, uint48 expiration, uint48 nonce)\",\n \"function approve(address token, address spender, uint160 amount, uint48 expiration)\",\n \"function nonceBitmap(address owner, uint256 wordPos) view returns (uint256)\",\n \"function invalidateNonces(address token, address spender, uint48 newNonce)\",\n]);\n","import {\n type Address,\n type ContractFunctionParameters,\n type Hex,\n type MulticallReturnType,\n type PublicClient,\n decodeFunctionResult,\n encodeFunctionData,\n isAddressEqual,\n} from \"viem\";\n\nimport { multicall3Abi } from \"./abi/multicall3.js\";\nimport { pepuMainnet } from \"./chains.js\";\nimport { type DeployedContract, getContract, isDeployed } from \"./contracts.js\";\nimport { PepuChainError } from \"./errors.js\";\n\n/** The canonical Multicall3 address, which is NOT deployed on PEPU. */\nexport const CANONICAL_MULTICALL3_ADDRESS =\n \"0xcA11bde05977b3631167028862bE2a173976CA11\" as const;\n\n/**\n * Guard: throws `MULTICALL3_CANONICAL_ADDRESS` if `address` is the canonical\n * Multicall3 address (which has no code on PEPU).\n *\n * @example\n * ```ts\n * assertNotCanonicalMulticall3(\"0x9CE19273Ae9c24437DFF512E8DFCAed4E4B001bd\"); // ok\n * ```\n */\nexport function assertNotCanonicalMulticall3(address: Address): void {\n if (isAddressEqual(address, CANONICAL_MULTICALL3_ADDRESS)) {\n throw new PepuChainError(\"MULTICALL3_CANONICAL_ADDRESS\");\n }\n}\n\n/**\n * The PEPU-specific Multicall3 registry entry. Never the canonical address.\n *\n * @example\n * ```ts\n * const { address } = getMulticall3(); // 0x9CE19273...01bd\n * ```\n */\nexport function getMulticall3(chainId: number = pepuMainnet.id): DeployedContract {\n const entry = getContract(chainId, \"multicall3\");\n if (!isDeployed(entry)) {\n throw new PepuChainError(\"UNKNOWN\", \"Multicall3 is not deployed on the requested chain.\");\n }\n assertNotCanonicalMulticall3(entry.address);\n return entry;\n}\n\n/**\n * viem `multicall` pinned to the PEPU Multicall3 address.\n *\n * @example\n * ```ts\n * const [name, supply] = await pepuMulticall(client, [\n * { address: token, abi: erc20Abi, functionName: \"name\" },\n * { address: token, abi: erc20Abi, functionName: \"totalSupply\" },\n * ], { allowFailure: false });\n * ```\n */\nexport function pepuMulticall<\n const T extends readonly ContractFunctionParameters[],\n A extends boolean = true,\n>(\n client: PublicClient,\n calls: T,\n o: { allowFailure?: A; blockNumber?: bigint } = {},\n): Promise<MulticallReturnType<T, A>> {\n const chainId = client.chain?.id ?? pepuMainnet.id;\n const multicallAddress = getMulticall3(chainId).address;\n return client.multicall({\n contracts: calls,\n multicallAddress,\n allowFailure: o.allowFailure ?? true,\n ...(o.blockNumber !== undefined ? { blockNumber: o.blockNumber } : {}),\n } as never) as Promise<MulticallReturnType<T, A>>;\n}\n\n/**\n * ABI-encode a Multicall3 `aggregate3` call.\n *\n * @example\n * ```ts\n * const data = encodeAggregate3([{ target: token, callData: \"0x18160ddd\" }]);\n * ```\n */\nexport function encodeAggregate3(\n calls: readonly { target: Address; allowFailure?: boolean; callData: Hex }[],\n): Hex {\n return encodeFunctionData({\n abi: multicall3Abi,\n functionName: \"aggregate3\",\n args: [\n calls.map((c) => ({\n target: c.target,\n allowFailure: c.allowFailure ?? false,\n callData: c.callData,\n })),\n ],\n });\n}\n\n/**\n * Decode the return data of `aggregate3`.\n *\n * @example\n * ```ts\n * const results = decodeAggregate3Result(returnData);\n * results[0]?.success;\n * ```\n */\nexport function decodeAggregate3Result(data: Hex): { success: boolean; returnData: Hex }[] {\n const out = decodeFunctionResult({\n abi: multicall3Abi,\n functionName: \"aggregate3\",\n data,\n });\n return out.map((r) => ({ success: r.success, returnData: r.returnData }));\n}\n","import type { Address, PublicClient, TypedDataDomain } from \"viem\";\n\nimport { permit2Abi } from \"./abi/permit2.js\";\nimport { pepuMainnet } from \"./chains.js\";\nimport { type DeployedContract, getContract, isDeployed } from \"./contracts.js\";\nimport { PepuChainError } from \"./errors.js\";\n\n/**\n * The canonical Permit2 registry entry (`0x000000000022D473...78BA3`).\n *\n * @example\n * ```ts\n * const { address } = getPermit2();\n * ```\n */\nexport function getPermit2(chainId: number = pepuMainnet.id): DeployedContract {\n const entry = getContract(chainId, \"permit2\");\n if (!isDeployed(entry)) {\n throw new PepuChainError(\"UNKNOWN\", \"Permit2 is not deployed on the requested chain.\");\n }\n return entry;\n}\n\n/**\n * EIP-712 domain for canonical Permit2: name \"Permit2\" (no version).\n *\n * @example\n * ```ts\n * const domain = permit2Domain(); // { name: \"Permit2\", chainId: 97741, verifyingContract }\n * ```\n */\nexport function permit2Domain(chainId: number = pepuMainnet.id): TypedDataDomain {\n return {\n name: \"Permit2\",\n chainId,\n verifyingContract: getPermit2(chainId).address,\n };\n}\n\n/** Typed-data definition accepted by viem `signTypedData`. */\nexport interface Permit2TypedData<P extends string, M extends Record<string, unknown>> {\n domain: TypedDataDomain;\n types: Record<string, readonly { name: string; type: string }[]>;\n primaryType: P;\n message: M;\n}\n\n/**\n * Typed data for Permit2 AllowanceTransfer `PermitSingle`.\n *\n * @example\n * ```ts\n * const td = buildPermitSingleTypedData({ token, amount: 1n, expiration: 1900000000, nonce: 0, spender, sigDeadline: 1900000000n });\n * ```\n */\nexport function buildPermitSingleTypedData(p: {\n token: Address;\n amount: bigint;\n expiration: number;\n nonce: number;\n spender: Address;\n sigDeadline: bigint;\n chainId?: number;\n}): Permit2TypedData<\n \"PermitSingle\",\n {\n details: { token: Address; amount: bigint; expiration: number; nonce: number };\n spender: Address;\n sigDeadline: bigint;\n }\n> {\n return {\n domain: permit2Domain(p.chainId),\n types: {\n PermitSingle: [\n { name: \"details\", type: \"PermitDetails\" },\n { name: \"spender\", type: \"address\" },\n { name: \"sigDeadline\", type: \"uint256\" },\n ],\n PermitDetails: [\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint160\" },\n { name: \"expiration\", type: \"uint48\" },\n { name: \"nonce\", type: \"uint48\" },\n ],\n },\n primaryType: \"PermitSingle\",\n message: {\n details: {\n token: p.token,\n amount: p.amount,\n expiration: p.expiration,\n nonce: p.nonce,\n },\n spender: p.spender,\n sigDeadline: p.sigDeadline,\n },\n };\n}\n\n/**\n * Typed data for Permit2 SignatureTransfer `PermitTransferFrom`.\n *\n * @example\n * ```ts\n * const td = buildPermitTransferFromTypedData({ token, amount: 1n, spender, nonce: 0n, deadline: 1900000000n });\n * ```\n */\nexport function buildPermitTransferFromTypedData(p: {\n token: Address;\n amount: bigint;\n spender: Address;\n nonce: bigint;\n deadline: bigint;\n chainId?: number;\n}): Permit2TypedData<\n \"PermitTransferFrom\",\n {\n permitted: { token: Address; amount: bigint };\n spender: Address;\n nonce: bigint;\n deadline: bigint;\n }\n> {\n return {\n domain: permit2Domain(p.chainId),\n types: {\n PermitTransferFrom: [\n { name: \"permitted\", type: \"TokenPermissions\" },\n { name: \"spender\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n ],\n TokenPermissions: [\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n },\n primaryType: \"PermitTransferFrom\",\n message: {\n permitted: { token: p.token, amount: p.amount },\n spender: p.spender,\n nonce: p.nonce,\n deadline: p.deadline,\n },\n };\n}\n\n/**\n * Read the Permit2 AllowanceTransfer allowance for (owner, token, spender).\n *\n * @example\n * ```ts\n * const { amount, expiration, nonce } = await readPermit2Allowance(client, { owner, token, spender });\n * ```\n */\nexport async function readPermit2Allowance(\n client: PublicClient,\n o: { owner: Address; token: Address; spender: Address },\n): Promise<{ amount: bigint; expiration: number; nonce: number }> {\n const [amount, expiration, nonce] = await client.readContract({\n address: getPermit2(client.chain?.id ?? pepuMainnet.id).address,\n abi: permit2Abi,\n functionName: \"allowance\",\n args: [o.owner, o.token, o.spender],\n });\n return { amount, expiration, nonce };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/dex.ts","../src/tokens.ts","../src/pepuscan.ts","../src/wallet.ts","../src/abi/arbGasInfo.ts","../src/gas.ts","../src/abi/kernelEcdsaValidator.ts","../src/abi/pepuSwapMulticall.ts","../src/abi/pepuSwapPermit2.ts","../src/abi/pepuSwapPositionManager.ts","../src/abi/pepuSwapQuoter.ts","../src/abi/pepuSwapRouter.ts","../src/abi/pepuSwapTickLens.ts","../src/abi/pepuSwapUniversalRouter.ts","../src/abi/pepuSwapV3Factory.ts","../src/abi/pepuSwapV3Pool.ts","../src/abi/wpepu.ts","../src/abi/multicall3.ts","../src/abi/permit2.ts","../src/multicall.ts","../src/permit2.ts"],"names":["pepuMainnet","explorerUrl","numberToHex","parseAbi","formatUnits","erc721Abi","erc20Abi","isAddressEqual","PepuChainError","getContract","isDeployed","encodeFunctionData","decodeFunctionResult"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ContractEntry } from \"./contracts.js\";\nimport { pepuMainnet } from \"./chains.js\";\n\n/**\n * PepuSwap is PEPU's flagship DEX and a Uniswap V3 fork. This registry is\n * deliberately separate from {@link pepuContracts} in `contracts.ts`:\n * `pepuContracts` tracks *chain infrastructure* (things any app might rely\n * on — Multicall3, the AA stack), while this tracks *one specific\n * application's* deployment. Mixing the two would make `pepuContracts`\n * ambiguous about what counts as \"the chain\" versus \"a dapp on the chain.\"\n *\n * Mainnet only — PepuSwap has no testnet deployment, and testnet (97740) is\n * out of scope for this package regardless (no faucet exists to fund\n * verification there).\n *\n * Every address below was independently verified on 2026-09-24 with both\n * an `eth_getCode` check (non-empty bytecode) and a successful `eth_call`\n * against a real function — see the doc comment on that contract's ABI file\n * in `./abi/` for the exact call and response. Two addresses\n * (`multicallNonCanonical`, `permit2NonCanonical`) are PepuSwap-specific\n * overrides of otherwise-canonical contracts; do not confuse them with\n * {@link pepuContracts}'s `multicall3`/`permit2` entries, which track the\n * *canonical* versions of those same standards.\n */\nexport type PepuSwapContractName =\n | \"v3Factory\"\n | \"swapRouter02\"\n | \"universalRouter\"\n | \"positionManager\"\n | \"quoterV2\"\n | \"tickLens\"\n | \"v3Migrator\"\n | \"v3Staker\"\n | \"multicallNonCanonical\"\n | \"permit2NonCanonical\";\n\nconst V3_FACTORY_NOTES =\n \"Uniswap V3 core factory. owner() returns a live address; getPool() \" +\n \"resolves real WPEPU/USDT pools at multiple fee tiers, and those pools' \" +\n \"own token0()/token1() match. Four other PepuSwap contracts \" +\n \"(swapRouter02, positionManager, quoterV2, v3Migrator) each read their \" +\n \"own factory() immutable and all agree on this exact address.\";\n\nexport const pepuSwapContracts: Readonly<\n Record<number, Readonly<Record<PepuSwapContractName, ContractEntry>>>\n> = {\n [pepuMainnet.id]: {\n v3Factory: {\n status: \"deployed\",\n name: \"PepuSwap V3 Factory\",\n address: \"0x5984B8BF2d4dB9C0aCB1d7924762e4474D80C807\",\n notes: V3_FACTORY_NOTES,\n },\n swapRouter02: {\n status: \"deployed\",\n name: \"PepuSwap SwapRouter02\",\n address: \"0x150c3F0f16C3D9EB34351d7af9c961FeDc97A0fb\",\n notes:\n \"factory() and WETH9() both resolve to the independently-verified \" +\n \"v3Factory/WPEPU addresses.\",\n },\n universalRouter: {\n status: \"deployed\",\n name: \"PepuSwap UniversalRouter\",\n address: \"0x0dE72b751b77d3c74fB96C5fAd0320Cd8d133d36\",\n notes:\n \"No public getters for its configured Permit2/factory addresses \" +\n \"(dispatcher contracts don't expose those). Verified instead by \" +\n \"simulating execute(\\\"0x\\\", [], farFutureDeadline) via eth_call, \" +\n \"which returned successfully under the exact UniversalRouter \" +\n \"selector.\",\n },\n positionManager: {\n status: \"deployed\",\n name: \"PepuSwap NonfungiblePositionManager\",\n address: \"0xe2060CbdE18b5e765c86e5Cd6EE68AF209a9faa7\",\n notes:\n \"factory() and WETH9() both resolve to the independently-verified \" +\n \"v3Factory/WPEPU addresses. LP positions are ERC-721 tokens minted \" +\n \"by this contract (pepuscan lists them as \\\"Launchpad V3 Positions \" +\n \"NFT\\\" / UNI-V3-POS).\",\n },\n quoterV2: {\n status: \"deployed\",\n name: \"PepuSwap QuoterV2\",\n address: \"0xd647b2D80b48e93613Aa6982b85f8909578b4829\",\n notes:\n \"factory() and WETH9() both resolve to the independently-verified \" +\n \"v3Factory/WPEPU addresses. Off-chain-quote contract — call via \" +\n \"eth_call/simulateContract only, never send it a real transaction.\",\n },\n tickLens: {\n status: \"deployed\",\n name: \"PepuSwap TickLens\",\n address: \"0x4EB8aA84c066f9bf210eAfE33B30AE49BfafD9a6\",\n notes:\n \"Stateless (no zero-arg getter to probe). Verified instead by \" +\n \"calling getPopulatedTicksInWord() against a real WPEPU/USDT pool \" +\n \"at that pool's own current tick-bitmap word; call succeeded.\",\n },\n v3Migrator: {\n status: \"deployed\",\n name: \"PepuSwap V3Migrator\",\n address: \"0xFE406d6c3fc0BB3a6D195b089eFADfc8658206D5\",\n notes:\n \"factory() and WETH9() both resolve to the independently-verified \" +\n \"v3Factory/WPEPU addresses. No dedicated ABI is shipped for this \" +\n \"contract in ./abi/ — only these two getters were checked, which \" +\n \"is enough to confirm the address but not enough to type its \" +\n \"migration-specific functions. Pair with Uniswap's public \" +\n \"V3Migrator ABI if you need those.\",\n },\n v3Staker: {\n status: \"deployed\",\n name: \"PepuSwap V3Staker\",\n address: \"0x0a875d1C72cb4e1CD61401c3C49f85Df45071f83\",\n notes:\n \"factory() resolves to the independently-verified v3Factory \" +\n \"address (this contract has no WETH9() getter — it's a Uniswap \" +\n \"LP incentive-staking contract, unrelated to the general \\\"stake \" +\n \"PEPU\\\" product). No dedicated ABI is shipped for it in ./abi/ — \" +\n \"pair with Uniswap's public V3Staker ABI if you need one.\",\n },\n multicallNonCanonical: {\n status: \"deployed\",\n name: \"PepuSwap Multicall (UniswapInterfaceMulticall, non-canonical)\",\n address: \"0x927af2a6B76d2d8206d93004463F8C122701383B\",\n notes:\n \"PepuSwap's own multicall contract, NOT Multicall3 and NOT \" +\n \"interchangeable with pepuContracts.multicall3. Verified on \" +\n \"pepuscan as Uniswap's UniswapInterfaceMulticall (a Multicall2 \" +\n \"fork with a different function set/return shape — see \" +\n \"pepuSwapMulticallAbi in ./abi/pepuSwapMulticall.js for the \" +\n \"verified ABI and exactly which functions were confirmed live).\",\n },\n permit2NonCanonical: {\n status: \"deployed\",\n name: \"PepuSwap Permit2 (non-canonical)\",\n address: \"0xB461c05f76d7f919FF7A3Df2B0D2593F56538b4B\",\n notes:\n \"PepuSwap's own Permit2 deployment, NOT at the canonical Permit2 \" +\n \"address and NOT interchangeable with pepuContracts.permit2 \" +\n \"(which tracks the canonical Permit2, now deployed on mainnet at \" +\n \"0x000000000022D473030F116dDEE9F6B43aC78BA3 — see ../contracts.js). \" +\n \"Both DOMAIN_SEPARATOR() calls respond live but return different \" +\n \"values (different EIP-712 domains, since they're different \" +\n \"contracts). See pepuSwapPermit2Abi in ./abi/pepuSwapPermit2.js.\",\n },\n },\n};\n\n/** Look up one PepuSwap contract entry for a chain id. */\nexport function getPepuSwapContract(\n chainId: number,\n name: PepuSwapContractName,\n): ContractEntry | undefined {\n return pepuSwapContracts[chainId]?.[name];\n}\n\n/** List every tracked PepuSwap contract entry for a chain id, in registry order. */\nexport function listPepuSwapContracts(\n chainId: number,\n): readonly ContractEntry[] {\n const registry = pepuSwapContracts[chainId];\n return registry ? Object.values(registry) : [];\n}\n\n/** Narrow a {@link ContractEntry} to {@link DeployedContract} — re-exported for convenience so callers don't need to import both `./contracts.js` and `./dex.js` just to narrow a result. */\nexport { isDeployed } from \"./contracts.js\";\n","import type { Address } from \"viem\";\n\nimport { pepuMainnet } from \"./chains.js\";\n\n/**\n * Shape mirrors the `TokenInfo` definition in the Uniswap Token List\n * schema (https://uniswap.org/tokenlist.schema.json). Kept as a local\n * type (rather than importing one from `@uniswap/token-lists`) so\n * consumers of `@pepu-chain/sdk` never need that package installed just to\n * typecheck.\n */\nexport interface PepuTokenInfo {\n readonly chainId: number;\n readonly address: Address;\n readonly name: string;\n readonly symbol: string;\n readonly decimals: number;\n readonly logoURI?: string;\n readonly tags?: readonly string[];\n}\n\n/** Shape mirrors the top-level Uniswap Token List schema. */\nexport interface PepuTokenList {\n readonly name: string;\n readonly timestamp: string;\n readonly version: {\n readonly major: number;\n readonly minor: number;\n readonly patch: number;\n };\n readonly tokens: readonly PepuTokenInfo[];\n readonly keywords?: readonly string[];\n}\n\n/**\n * Canonical Pepe Unchained V2 token list, conforming to the Uniswap Token\n * List schema (see `test/tokens.test.ts` for schema validation against a\n * vendored copy of https://uniswap.org/tokenlist.schema.json).\n *\n * Deliberately minimal: every entry below is a token address independently\n * verified on-chain (see each entry's inline note), not copied from docs or\n * a third-party list without cross-checking. No other token address met\n * that bar at the time this list was written, and none are included here\n * as placeholders. See the README's \"Known gaps\" section.\n *\n * There is no verified token address for testnet (chain 97740) yet, so\n * this list currently only covers mainnet.\n */\nexport const pepuTokenList: PepuTokenList = {\n name: \"Pepe Unchained\",\n timestamp: \"2026-10-03T00:00:00.000Z\",\n version: { major: 1, minor: 2, patch: 0 },\n tokens: [\n {\n chainId: pepuMainnet.id,\n address: \"0xF9Cf4A16d26979b929Be7176bAc4e7084975FCB8\",\n name: \"Wrapped Pepe Unchained\",\n symbol: \"WPEPU\",\n decimals: 18,\n // Cross-verified across the project's own docs, Blockscout's token\n // list, and PepuSwap's deployment config, plus an on-chain\n // `eth_getCode` call and Blockscout's \"verified as WETH9\" source\n // match. See `wpepuAbi` in `./abi/wpepu.ts` for the ABI-level\n // verification (deposit/withdraw/decimals/symbol/name all confirmed\n // live).\n },\n {\n chainId: pepuMainnet.id,\n address: \"0x06f69A40C33C5A4Cd038BBE1DA689D4D636Ec448\",\n name: \"Tether USD\",\n symbol: \"USDT\",\n decimals: 6,\n // Verified live on 2026-09-24: discovered as the non-WPEPU leg of\n // PepuSwap's WPEPU/USDT 0.3% pool (`0x4bE3Af53800AADE09201654CD76D55063c7bdE70`,\n // itself returned by the independently-verified `pepuSwapV3FactoryAbi`\n // `getPool(WPEPU, USDT, 3000)` — see `../dex.ts`), then confirmed\n // directly against this address via `eth_call`: `name()` ->\n // \"Tether USD\", `symbol()` -> \"USDT\", `decimals()` -> `6`. Note the\n // 6 decimals (standard for USDT, unlike the 18-decimal PEPU/WPEPU) —\n // don't reuse `formatPepu`/`formatUnits(x, 18)` for this token.\n },\n {\n chainId: pepuMainnet.id,\n address: \"0x20fB684Bfc1aBAaD3AceC5712f2Aa30bd494dF74\",\n name: \"USD Coin\",\n symbol: \"USDC\",\n decimals: 6,\n // Verified live on 2026-10-03 (read-only): `eth_getCode` returns 835\n // bytes of code, and `eth_call` gives `name()` -> \"USD Coin\",\n // `symbol()` -> \"USDC\", `decimals()` -> `6`. One of the tokens PepuSwap\n // trades. 6 decimals, like USDT.\n },\n {\n chainId: pepuMainnet.id,\n address: \"0x7CCC51754216C04D4Bb1210630cCA16e5430Aa70\",\n name: \"Wrapped Ether\",\n symbol: \"WETH\",\n decimals: 18,\n // Verified live on 2026-10-03 (read-only): `eth_getCode` returns 835\n // bytes of code, and `eth_call` gives `name()` -> \"Wrapped Ether\",\n // `symbol()` -> \"WETH\", `decimals()` -> `18`. One of the tokens\n // PepuSwap trades.\n },\n ],\n};\n","import type { Abi, Address } from \"viem\";\n\nimport type { PepuChain } from \"./chains.js\";\n\n/**\n * A minimal client for pepuscan's (Blockscout's) public REST API —\n * deliberately narrow: **verified-ABI and token-metadata reads only**.\n * Blockscout's API surface is large (transaction history, logs, internal\n * txs, NFTs, account-abstraction data, ...); re-wrapping all of it here\n * would duplicate `@pepu-chain/mcp` (the Blockscout MCP server), which is the\n * right place for that. This client exists only for the two lookups a\n * dapp commonly needs synchronously and that this package's own ABI/token\n * modules can't provide (an address this package hasn't independently\n * verified, or a token not yet in {@link pepuTokenList}).\n *\n * Uses the platform `fetch` (Node 18+, every evergreen browser) — no HTTP\n * client dependency.\n */\nexport interface PepuscanClient {\n /**\n * Fetch a contract's verified ABI from pepuscan. Resolves `null` if the\n * contract is not verified (a 404 from Blockscout's\n * `/v2/smart-contracts/{address}`) rather than throwing, since \"not\n * verified\" is an expected, ordinary result — not an error.\n */\n getVerifiedAbi(address: Address): Promise<Abi | null>;\n /**\n * Fetch a token's on-chain metadata from pepuscan\n * (`/v2/tokens/{address}`). Resolves `null` if pepuscan has no record of\n * the address as a token (a 404) — the address may still be a valid\n * contract; it just isn't a token Blockscout has indexed as one.\n */\n getTokenMetadata(address: Address): Promise<PepuscanTokenMetadata | null>;\n}\n\n/** Token metadata as reported by pepuscan's `/v2/tokens/{address}`. */\nexport interface PepuscanTokenMetadata {\n readonly address: Address;\n readonly name: string | null;\n readonly symbol: string | null;\n /** `null` for token types that don't have a fixed decimals field (e.g. most ERC-721s). */\n readonly decimals: number | null;\n readonly totalSupply: string | null;\n /** Blockscout's token type string, e.g. `\"ERC-20\"`, `\"ERC-721\"`, `\"ERC-1155\"`. */\n readonly type: string | null;\n}\n\ninterface BlockscoutSmartContractResponse {\n readonly abi?: Abi | null;\n}\n\ninterface BlockscoutTokenResponse {\n readonly name?: string | null;\n readonly symbol?: string | null;\n readonly decimals?: string | null;\n readonly total_supply?: string | null;\n readonly type?: string | null;\n}\n\nfunction requireApiUrl(chain: PepuChain): string {\n const apiUrl = chain.blockExplorers?.default.apiUrl;\n if (!apiUrl) {\n throw new Error(\n `createPepuscanClient: no Blockscout API URL configured for chain \"${chain.name}\" (id ${chain.id}).`,\n );\n }\n return apiUrl;\n}\n\nasync function getJsonOrNull<T>(url: string): Promise<T | null> {\n const response = await fetch(url);\n if (response.status === 404) {\n return null;\n }\n if (!response.ok) {\n throw new Error(`pepuscan: GET ${url} failed with status ${response.status}`);\n }\n return (await response.json()) as T;\n}\n\n/**\n * Create a {@link PepuscanClient} bound to a {@link PepuChain}'s configured\n * Blockscout API URL (`chain.blockExplorers.default.apiUrl`). Throws\n * immediately if the chain has none configured (currently\n * {@link pepuTestnet} — see `chains.ts`) rather than deferring the failure\n * to the first call.\n */\nexport function createPepuscanClient(chain: PepuChain): PepuscanClient {\n const apiUrl = requireApiUrl(chain);\n\n return {\n async getVerifiedAbi(address) {\n const body = await getJsonOrNull<BlockscoutSmartContractResponse>(\n `${apiUrl}/v2/smart-contracts/${address}`,\n );\n return body?.abi ?? null;\n },\n async getTokenMetadata(address) {\n const body = await getJsonOrNull<BlockscoutTokenResponse>(\n `${apiUrl}/v2/tokens/${address}`,\n );\n if (!body) {\n return null;\n }\n return {\n address,\n name: body.name ?? null,\n symbol: body.symbol ?? null,\n decimals: body.decimals != null ? Number(body.decimals) : null,\n totalSupply: body.total_supply ?? null,\n type: body.type ?? null,\n };\n },\n };\n}\n","import type { AddEthereumChainParameter, EIP1193Provider } from \"viem\";\nimport { numberToHex } from \"viem\";\n\nimport type { PepuChain } from \"./chains.js\";\n\n/**\n * Build the parameter object for an EIP-3085 `wallet_addEthereumChain`\n * request from a {@link PepuChain}, so callers don't have to hand-assemble\n * (and risk mistyping) `chainId` hex encoding, `nativeCurrency`, RPC URLs,\n * and explorer URLs themselves.\n *\n * Omits `blockExplorerUrls` entirely when the chain has no configured\n * explorer (currently {@link pepuTestnet} — see `chains.ts`) rather than\n * sending an empty array or a guessed URL.\n */\nexport function toAddEthereumChainParameter(\n chain: PepuChain,\n): AddEthereumChainParameter {\n const explorerUrl = chain.blockExplorers?.default.url;\n return {\n chainId: numberToHex(chain.id),\n chainName: chain.name,\n nativeCurrency: chain.nativeCurrency,\n rpcUrls: chain.rpcUrls.default.http,\n ...(explorerUrl ? { blockExplorerUrls: [explorerUrl] } : {}),\n };\n}\n\n/**\n * The standard EIP-1193 error code a wallet returns from\n * `wallet_switchEthereumChain` when it doesn't recognize the target chain\n * yet (EIP-3326) — the signal to fall back to `wallet_addEthereumChain`.\n */\nconst CHAIN_NOT_RECOGNIZED_ERROR_CODE = 4902;\n\nfunction isChainNotRecognizedError(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n \"code\" in error &&\n (error as { code: unknown }).code === CHAIN_NOT_RECOGNIZED_ERROR_CODE\n );\n}\n\n/**\n * Switch an EIP-1193 provider (e.g. `window.ethereum`) to a\n * {@link PepuChain}, adding it first via `wallet_addEthereumChain` if the\n * wallet doesn't already recognize the chain (error code `4902` per\n * EIP-3326) — the two-step dance almost every dapp ends up hand-rolling.\n *\n * If you already have a viem `WalletClient`, its own `switchChain`/`addChain`\n * actions work the same way at the RPC level; this helper is for the plainer\n * \"I just have an injected provider\" case and does the fallback viem's\n * `switchChain` alone does not (see `viem/actions`' `switchChain.js` — it\n * only ever sends `wallet_switchEthereumChain`).\n *\n * Rethrows any other error unchanged (e.g. the user rejecting either\n * prompt), and rethrows the original switch error if the wallet doesn't\n * report the standard `4902` code for an unrecognized chain — some wallets\n * are known to deviate from the EIP-3326 error code, and this helper does\n * not attempt to paper over that.\n */\nexport async function switchOrAddPepuChain(\n provider: EIP1193Provider,\n chain: PepuChain,\n): Promise<void> {\n try {\n await provider.request({\n method: \"wallet_switchEthereumChain\",\n params: [{ chainId: numberToHex(chain.id) }],\n });\n } catch (error) {\n if (!isChainNotRecognizedError(error)) {\n throw error;\n }\n await provider.request({\n method: \"wallet_addEthereumChain\",\n params: [toAddEthereumChainParameter(chain)],\n });\n }\n}\n","import { parseAbi } from \"viem\";\n\n/**\n * Arbitrum Nitro's `ArbGasInfo` precompile — lives at the same fixed address\n * on every Arbitrum Orbit/Nitro chain, including PEPU. Exposes the L2\n * execution / L1 data-posting fee breakdown that {@link explainDualFeeModel}\n * (`../gas.js`) describes.\n *\n * Verified live against PEPU mainnet 2026-09-24 via `eth_call`:\n * - `getPricesInWei()` returns `(perL2Tx: 0, perL1CalldataUnit: 0,\n * perStorageAllocation: 250000000000000000, perArbGasBase: 12500000000000,\n * perArbGasCongestion: 0, perArbGasTotal: 12500000000000)`. `perArbGasBase`\n * / `perArbGasTotal` (12,500 gwei) match the block's own `baseFeePerGas`\n * at the same height, and `perL1CalldataUnit` is `0` — see the module doc\n * on `../gas.js` for what that means for PEPU's L1 data-posting fee today.\n * - `getL1BaseFeeEstimate()` returns `0`, consistent with the same reading.\n */\nexport const arbGasInfoAbi = parseAbi([\n \"function getPricesInWei() view returns (uint256 perL2Tx, uint256 perL1CalldataUnit, uint256 perStorageAllocation, uint256 perArbGasBase, uint256 perArbGasCongestion, uint256 perArbGasTotal)\",\n \"function getL1BaseFeeEstimate() view returns (uint256)\",\n \"function getMinimumGasPrice() view returns (uint256)\",\n]);\n\n/**\n * Fixed address of the `ArbGasInfo` precompile. Identical on every\n * Arbitrum Orbit/Nitro chain (it's a precompile, not a deployed contract),\n * confirmed responding on PEPU mainnet as noted above.\n */\nexport const ARB_GAS_INFO_ADDRESS =\n \"0x000000000000000000000000000000000000006C\" as const;\n","import type { Address, PublicClient, TransactionRequest, Transport } from \"viem\";\nimport { formatUnits } from \"viem\";\n\nimport { ARB_GAS_INFO_ADDRESS, arbGasInfoAbi } from \"./abi/arbGasInfo.js\";\nimport type { PepuChain } from \"./chains.js\";\n\n/**\n * PEPU's two-part Nitro gas price, read live from the `ArbGasInfo`\n * precompile (`0x...6C`, fixed on every Arbitrum Orbit/Nitro chain). See\n * {@link explainDualFeeModel} for what each field means and why, on PEPU\n * specifically, one of them is currently zero.\n */\nexport interface NitroFeeBreakdown {\n /**\n * L2 execution price, in wei per gas unit. This is `perArbGasTotal` from\n * `getPricesInWei()` — `perArbGasBase` (the network's floor) plus\n * `perArbGasCongestion` (demand surcharge, `0` when the chain isn't\n * congested). Tracks the block's own `baseFeePerGas`.\n */\n readonly l2PricePerGasWei: bigint;\n /**\n * L1 data-posting price, in wei per L1-calldata-unit (`perL1CalldataUnit`\n * from `getPricesInWei()`). Verified `0` on PEPU mainnet as of\n * 2026-09-24 — see {@link explainDualFeeModel}.\n */\n readonly l1PricePerCalldataUnitWei: bigint;\n /**\n * `ArbGasInfo`'s own estimate of the L1 base fee it would need to post\n * data at, in wei. Verified `0` on PEPU mainnet as of 2026-09-24,\n * consistent with `l1PricePerCalldataUnitWei` being `0`.\n */\n readonly l1BaseFeeEstimateWei: bigint;\n}\n\n/**\n * Read the current {@link NitroFeeBreakdown} from the `ArbGasInfo`\n * precompile. One `eth_call` (`getPricesInWei()`) plus one more\n * (`getL1BaseFeeEstimate()`) — no caching, since these can change block to\n * block under load.\n */\nexport async function getNitroFeeBreakdown(\n client: PublicClient<Transport, PepuChain>,\n): Promise<NitroFeeBreakdown> {\n const [prices, l1BaseFeeEstimateWei] = await Promise.all([\n client.readContract({\n address: ARB_GAS_INFO_ADDRESS,\n abi: arbGasInfoAbi,\n functionName: \"getPricesInWei\",\n }),\n client.readContract({\n address: ARB_GAS_INFO_ADDRESS,\n abi: arbGasInfoAbi,\n functionName: \"getL1BaseFeeEstimate\",\n }),\n ]);\n return {\n l2PricePerGasWei: prices[5], // perArbGasTotal\n l1PricePerCalldataUnitWei: prices[1], // perL1CalldataUnit\n l1BaseFeeEstimateWei,\n };\n}\n\n/** Plain-English explanation of Arbitrum Nitro's dual-fee model, as it currently behaves on PEPU. */\nexport interface DualFeeModelExplanation {\n readonly summary: string;\n readonly l2ExecutionFee: string;\n readonly l1DataPostingFee: string;\n readonly pepuStatus: string;\n}\n\n/**\n * Explain Arbitrum Nitro's dual-fee gas model in plain English, including\n * how it currently behaves on PEPU specifically (verified live against\n * mainnet 2026-09-24 — see the doc comment on `arbGasInfoAbi` in\n * `./abi/arbGasInfo.ts` for the exact call and response this is based on).\n *\n * This is a static explanation (no network call) — pair it with\n * {@link getNitroFeeBreakdown} for live numbers.\n */\nexport function explainDualFeeModel(): DualFeeModelExplanation {\n return {\n summary:\n \"Arbitrum Nitro chains (PEPU included — it's an Orbit chain built on \" +\n \"Nitro) charge gas as the sum of two independent components, unlike \" +\n \"a plain L1 chain where 'gas price' is a single number: an L2 \" +\n \"execution fee (compute + storage, priced in the chain's own gas \" +\n \"units) and an L1 data-posting fee (the cost of publishing the \" +\n \"transaction's calldata back to the settlement layer, priced \" +\n \"per byte of calldata, independent of how much EVM computation \" +\n \"the transaction does).\",\n l2ExecutionFee:\n \"Works like a normal EVM gas price: gasUsed * pricePerGas, where \" +\n \"pricePerGas is ArbGasInfo's perArbGasTotal (perArbGasBase, the \" +\n \"network floor, plus perArbGasCongestion, a demand surcharge that's \" +\n \"0 when the chain isn't congested). On PEPU mainnet this floor is \" +\n \"12,500 gwei (12,500,000,000,000 wei) — see the note on \" +\n \"l1DataPostingFee below for why that number looks alarming but \" +\n \"isn't.\",\n l1DataPostingFee:\n \"Normally: calldataBytes-derived 'L1 gas units' * perL1CalldataUnit, \" +\n \"recovering the cost of posting the tx's data to the settlement \" +\n \"layer (L1 for a vanilla Orbit chain, or the Data Availability \" +\n \"Committee for an AnyTrust chain like PEPU). Verified live on PEPU \" +\n \"mainnet 2026-09-24: both perL1CalldataUnit and getL1BaseFeeEstimate() \" +\n \"read 0. That means PEPU is not currently charging a separate L1/DA \" +\n \"data fee component at all — the full cost of a PEPU transaction \" +\n \"today is just the L2 execution fee above. This is a live chain \" +\n \"parameter, not a protocol guarantee; re-check with \" +\n \"getNitroFeeBreakdown() rather than assuming it stays 0 forever.\",\n pepuStatus:\n \"Net effect: a PEPU 'gas price' of 12,500 gwei looks like an \" +\n \"Ethereum-mainnet congestion spike if you only know Ethereum's \" +\n \"1-50 gwei range, but PEPU is a low-value token, so the same gas \" +\n \"price multiplied out is a tiny PEPU (and USD) amount. Naive gwei \" +\n \"formatting misleads on both ends — the gwei number reads as scary, \" +\n \"and formatting a total cost with the same few-decimal-places habit \" +\n \"people use for ETH rounds small-but-real PEPU amounts to '0'. Use \" +\n \"formatPepu() for totals and formatPepuGasPrice() when you want to \" +\n \"show the price-per-gas number with that context attached.\",\n };\n}\n\n/** Result of {@link estimateTransactionCost}. */\nexport interface TransactionCostEstimate {\n /** Estimated gas units, from `client.estimateGas`. */\n readonly gas: bigint;\n /** L2 execution price per gas unit, in wei, used for this estimate. */\n readonly gasPriceWei: bigint;\n /** `gas * gasPriceWei`, in wei. Does not include an L1 data-posting fee — see {@link explainDualFeeModel}. */\n readonly costWei: bigint;\n /** {@link costWei} formatted with {@link formatPepu}, for direct display. */\n readonly costFormatted: string;\n}\n\n/**\n * Estimate a transaction's PEPU cost: `client.estimateGas(request)` for the\n * gas units, multiplied by the current L2 execution price\n * (`getNitroFeeBreakdown`'s `l2PricePerGasWei`, which tracks the latest\n * block's `baseFeePerGas`).\n *\n * Deliberately excludes any L1 data-posting fee — see\n * {@link explainDualFeeModel} for why that component reads as `0` on PEPU\n * today, and re-derive this estimate if that ever changes.\n */\nexport async function estimateTransactionCost(\n client: PublicClient<Transport, PepuChain>,\n request: TransactionRequest & { account?: Address },\n): Promise<TransactionCostEstimate> {\n const [gas, { l2PricePerGasWei }] = await Promise.all([\n client.estimateGas(request),\n getNitroFeeBreakdown(client),\n ]);\n const costWei = gas * l2PricePerGasWei;\n return {\n gas,\n gasPriceWei: l2PricePerGasWei,\n costWei,\n costFormatted: formatPepu(costWei),\n };\n}\n\n/** Options for {@link formatPepu}. */\nexport interface FormatPepuOptions {\n /**\n * Maximum fractional digits to keep after trimming trailing zeros.\n * Default `8` — high enough that typical PEPU gas costs (a low-value\n * token at a 12,500 gwei base fee) don't round down to `\"0\"`, which is\n * exactly the failure mode a default ETH-style 4-decimal formatter hits\n * here.\n */\n readonly maxDecimals?: number;\n /** Append `\" PEPU\"` to the result. Default `true`. */\n readonly suffix?: boolean;\n}\n\n/**\n * Format a wei amount as PEPU, tuned for a low-value token on a chain with\n * a comparatively large (12,500 gwei) base fee — see\n * {@link explainDualFeeModel}. Plain `formatEther`-style formatting (a\n * handful of decimal places, as is reasonable for ETH) collapses typical\n * PEPU amounts to `\"0.0000\"`; this keeps up to `maxDecimals` significant\n * fractional digits instead, trimming only trailing zeros.\n *\n * This is a display formatter, not an arbitrary-precision one — it does\n * not round-trip back to the exact wei value, and is not meant to.\n */\nexport function formatPepu(wei: bigint, options?: FormatPepuOptions): string {\n const maxDecimals = options?.maxDecimals ?? 8;\n const suffix = options?.suffix ?? true;\n\n const negative = wei < 0n;\n const full = formatUnits(negative ? -wei : wei, 18);\n const [whole = \"0\", fraction = \"\"] = full.split(\".\");\n const truncatedFraction = fraction.slice(0, maxDecimals).replace(/0+$/, \"\");\n const body = truncatedFraction.length > 0 ? `${whole}.${truncatedFraction}` : whole;\n const withSign = negative ? `-${body}` : body;\n return suffix ? `${withSign} PEPU` : withSign;\n}\n\n/**\n * Format any token amount (smallest unit) as a short decimal string, for any\n * `decimals`. Truncates (never rounds) to `maxFractionDigits` (default 4) and\n * trims trailing zeros, like {@link formatPepu} but without the PEPU suffix and\n * 18-decimals assumption. Display only: it does not round-trip.\n *\n * @example\n * formatUnitsCompact(1_234_567n, 6); // \"1.2345\"\n * formatUnitsCompact(5n * 10n ** 18n, 18); // \"5\"\n */\nexport function formatUnitsCompact(value: bigint, decimals: number, maxFractionDigits = 4): string {\n const negative = value < 0n;\n const [whole = \"0\", fraction = \"\"] = formatUnits(negative ? -value : value, decimals).split(\".\");\n const frac = fraction.slice(0, maxFractionDigits).replace(/0+$/, \"\");\n const body = frac.length > 0 ? `${whole}.${frac}` : whole;\n return negative && body !== \"0\" ? `-${body}` : body;\n}\n\n/**\n * Format a wei-per-gas price for display, with an explicit note that\n * PEPU's baseline (~12,500 gwei) is not a congestion spike — see\n * {@link explainDualFeeModel}. Bare \"N gwei\" output, without that context,\n * is exactly the naive formatting this package's brief calls out as\n * misleading for PEPU.\n */\nexport function formatPepuGasPrice(weiPerGas: bigint): string {\n const gwei = formatUnits(weiPerGas, 9);\n return `${gwei} gwei/gas (PEPU's normal baseline is ~12,500 gwei — this is not a congestion spike; see explainDualFeeModel())`;\n}\n\n/**\n * Default safety margin applied on top of a raw gas estimate before\n * {@link maxSendableAmount} computes its answer, in basis points\n * (`2000` = 20%).\n *\n * Why a margin at all: the L2 price behind {@link estimateTransactionCost}\n * (`ArbGasInfo.getPricesInWei().perArbGasTotal`) is read live and tracks\n * the *current* block's `baseFeePerGas`. A \"max send\" button estimates\n * cost, fills `balance - cost` into the amount field, and then waits for\n * the user to review and confirm — by the time the signed transaction\n * actually lands, at least one block (often more, if the user pauses to\n * look at the number) has passed, and the price can have moved in that\n * gap. Spending every last wei on `value` against a stale estimate is\n * exactly the failure this button exists to prevent: a transaction that\n * reverts for insufficient funds after the user was told this amount was\n * safe.\n *\n * Why 20% specifically: this repo already uses a 20% margin for the\n * sibling problem of gas-*limit* drift between estimate and execution\n * (`templates/game-app/lib/tap-transaction.ts`'s `withGasLimitBuffer`),\n * and that figure — a standard, conservative buffer used broadly across\n * production transaction-sending code, not one tuned from measured PEPU\n * data — is reused here for gas-*price* drift for the same reason. Two\n * things make being generous here cheap specifically on PEPU: (1) this\n * package has only ever observed PEPU's base fee sitting flat at a\n * 12,500 gwei floor with a `0` congestion surcharge (see\n * {@link explainDualFeeModel}), so the realistic gap this margin covers\n * is currently close to zero; and (2) PEPU is a low-value token, so 20%\n * of an already-tiny gas cost is an even tinier absolute amount left\n * unspent. If PEPU's fee market ever becomes genuinely congested\n * (`perArbGasCongestion` reading nonzero), re-derive this default from\n * observed volatility rather than assuming 20% still covers it.\n */\nexport const DEFAULT_MAX_SEND_MARGIN_BPS = 2000;\n\nfunction assertValidMarginBps(marginBps: number): void {\n if (!Number.isInteger(marginBps) || marginBps < 0 || marginBps > 10_000) {\n throw new Error(\n `maxSendableAmount: marginBps must be an integer between 0 and 10000 (got ${marginBps})`,\n );\n }\n}\n\n/** Options for {@link maxSendableAmount}. */\nexport interface MaxSendableAmountOptions {\n /** Client to estimate gas against. */\n readonly client: PublicClient<Transport, PepuChain>;\n /**\n * The sender's address — used as `estimateGas`'s `account`, and (when\n * {@link MaxSendableAmountOptions.to} is omitted) as the estimate's\n * destination too. See `to`'s doc comment.\n */\n readonly from: Address;\n /**\n * The transfer's real destination, if the user has typed one in yet.\n * Estimating against the *actual* recipient matters whenever it's a\n * contract with a `receive()`/`fallback()` that does real work — a\n * generic placeholder address would silently under-estimate that case.\n *\n * Omit this (or don't call {@link maxSendableAmount} at all yet — the\n * caller decides when a \"recipient\" is valid enough to estimate\n * against) before the user has entered a recipient. This function then\n * falls back to estimating a self-transfer (`to: from`), the best\n * available stand-in for \"a plain native transfer to *some* EOA,\" which\n * is what most PEPU sends are.\n */\n readonly to?: Address;\n /**\n * The sender's current native balance, in wei (e.g. from wagmi's\n * `useBalance` or viem's `getBalance`).\n */\n readonly balanceWei: bigint;\n /**\n * Safety margin on top of the raw estimated cost, in basis points.\n * Default {@link DEFAULT_MAX_SEND_MARGIN_BPS} — see its doc comment for\n * why 20%. Must be an integer in `[0, 10000]`.\n */\n readonly marginBps?: number;\n}\n\n/**\n * Result of {@link maxSendableAmount} — a discriminated union on `status`\n * so callers can't accidentally read `amountWei` off a result where there\n * isn't one.\n */\nexport type MaxSendableAmountResult =\n | {\n readonly status: \"ok\";\n /** The amount safe to fill into a \"Max\" field: `balanceWei - totalReservedWei`. Always `> 0n`. */\n readonly amountWei: bigint;\n /** The gas estimate this result was computed from. */\n readonly estimate: TransactionCostEstimate;\n /** The safety margin on top of `estimate.costWei`, in wei. */\n readonly marginWei: bigint;\n /** `estimate.costWei + marginWei` — the total withheld from `balanceWei`. */\n readonly totalReservedWei: bigint;\n }\n | {\n /** `balanceWei` was `0` (or negative) — nothing to size a transfer from, no network call was made. */\n readonly status: \"zero-balance\";\n /** Human-readable explanation, safe to render directly. */\n readonly reason: string;\n }\n | {\n /** `balanceWei` doesn't cover even `estimate.costWei` plus the margin — a \"max\" send would be `<= 0`. */\n readonly status: \"insufficient-for-gas\";\n /** Human-readable explanation, safe to render directly. */\n readonly reason: string;\n /** The gas estimate this result was computed from. */\n readonly estimate: TransactionCostEstimate;\n /** `estimate.costWei + marginWei` — what the balance would have needed to cover. */\n readonly totalReservedWei: bigint;\n };\n\n/**\n * Compute the largest amount a sender can put in a native transfer's\n * `value` and still expect it to succeed: `balance - estimatedCost -\n * safetyMargin`.\n *\n * This is deliberately not `balance - gasLimit * gasPrice` computed by\n * hand — see {@link explainDualFeeModel} for why that naive formula is\n * wrong on an Arbitrum Nitro chain like PEPU in general (a second,\n * L1-data-posting fee component can apply on top of L2 execution). In\n * practice this function sidesteps the whole question by never\n * reimplementing Nitro's fee math itself: it hands the real transfer off\n * to {@link estimateTransactionCost}, which calls the chain's own\n * `eth_estimateGas` (Nitro-aware by construction — the node, not this\n * package, knows its own fee model) and reads the live L2 price from the\n * `ArbGasInfo` precompile. If PEPU ever starts charging a nonzero L1\n * component too, `estimateTransactionCost` documents exactly where that\n * would need to be added, and this function inherits the fix for free.\n *\n * THE CIRCULARITY THIS AVOIDS: the whole point of this call is to\n * discover what the max `value` should be, so it can't estimate gas\n * using that unknown value. It also can't reuse `balanceWei` as a stand-in\n * `value` for the estimate — most RPCs simulate `eth_estimateGas` against\n * the sender's real current balance, and a `value` equal to the full\n * balance leaves exactly `0` left over to cover the fee with, so the\n * simulation would itself fail with \"insufficient funds\" instead of\n * returning a usable number. Instead, this estimates with a nominal `1n`\n * wei placeholder. That's a safe stand-in because, for a plain native\n * transfer (no calldata), gas usage doesn't depend on *how much* value\n * moves — only on whether `to` has code that reacts to receiving value at\n * all, which `1n` (any nonzero amount) already exercises. The one case\n * this can still under-estimate: a recipient contract whose\n * `receive()`/`fallback()` branches on the exact `msg.value` it got\n * (e.g. cheaper for small amounts, pricier for large ones) — an inherent\n * limit of estimating \"the max\" before the max is known, not specific to\n * this implementation.\n *\n * Handles the edge cases a naive subtraction gets wrong:\n * - `balanceWei <= 0n` → `{ status: \"zero-balance\" }`, no network call.\n * - `balanceWei` covers less than `estimate.costWei` plus the margin →\n * `{ status: \"insufficient-for-gas\" }` rather than a negative or `0`\n * amount.\n * - Estimation itself failing (bad RPC, reverting recipient, etc.) →\n * this function does not catch that; the returned promise rejects with\n * whatever `estimateTransactionCost`/`client.estimateGas` threw, so a\n * caller can show the real reason instead of silently falling back to a\n * guess.\n *\n * NOT WIRED INTO `templates/consumer-app`: that template's send form\n * dropped its \"Max\" button rather than consume this helper. The reason\n * isn't a bug here — it's that Privy's transaction confirmation modal\n * runs its own, separately-implemented pre-flight balance check before\n * signing, and on PEPU that check has been observed to be over-conservative\n * enough to reject a transfer this function correctly sized as affordable\n * (e.g. a 0.7748 PEPU balance refused for a 0.2625 PEPU transfer). Since\n * Privy's modal has the final say on whether the transaction goes out, a\n * \"Max\" fill computed by this function can still bounce there, which makes\n * the button promise something the wallet UI can't reliably deliver. This\n * function stays correct and is still the right tool for any PEPU wallet\n * UI that isn't routing its send flow through Privy's modal — just don't\n * assume the absence of a \"Max\" button in that one template means this\n * helper is unused or unmaintained.\n */\nexport async function maxSendableAmount(\n options: MaxSendableAmountOptions,\n): Promise<MaxSendableAmountResult> {\n const {\n client,\n from,\n to,\n balanceWei,\n marginBps = DEFAULT_MAX_SEND_MARGIN_BPS,\n } = options;\n assertValidMarginBps(marginBps);\n\n if (balanceWei <= 0n) {\n return {\n status: \"zero-balance\",\n reason: \"This wallet has no PEPU to send.\",\n };\n }\n\n const estimate = await estimateTransactionCost(client, {\n account: from,\n to: to ?? from,\n value: 1n,\n });\n\n const marginWei = (estimate.costWei * BigInt(marginBps)) / 10_000n;\n const totalReservedWei = estimate.costWei + marginWei;\n\n if (balanceWei <= totalReservedWei) {\n return {\n status: \"insufficient-for-gas\",\n reason:\n `Balance (${formatPepu(balanceWei)}) doesn't cover the estimated ` +\n `cost of sending plus a safety margin (${formatPepu(totalReservedWei)} ` +\n `would need to be reserved for gas). Add more PEPU before sending.`,\n estimate,\n totalReservedWei,\n };\n }\n\n return {\n status: \"ok\",\n amountWei: balanceWei - totalReservedWei,\n estimate,\n marginWei,\n totalReservedWei,\n };\n}\n","import { parseAbi } from \"viem\";\n\n/**\n * ZeroDev Kernel v3 ECDSA validator module ABI, at\n * `0x845ADb2C711129d4f3966735eD98a9F09fC4cE57` (deployed on PEPU mainnet\n * only; see `pepuContracts.ecdsaValidator` in `../contracts.js`). This is\n * the ERC-7579 validator module that lets a Kernel account be controlled by\n * a plain ECDSA key (the common case — a Privy/embedded-wallet EOA signs\n * UserOperations on behalf of the smart account).\n *\n * Verified live against mainnet 2026-09-24 via `eth_call`:\n * - `ecdsaValidatorStorage(address)`, called with the zero address, returns\n * `address(0)` — the expected result for a kernel account that was never\n * registered, and confirmation the getter itself works.\n * - `isModuleType(1)` returns `true`. `1` is the ERC-7579 `MODULE_TYPE_VALIDATOR`\n * constant, so this independently confirms the contract both implements\n * the standard ERC-7579 `IModule` interface and self-reports as a\n * validator module — not just a contract that happens to expose a\n * same-named storage getter.\n *\n * `onInstall`/`onUninstall` are part of the same ERC-7579 `IModule`\n * interface `isModuleType` confirmed this contract implements; they take a\n * non-trivial `bytes` payload (the encoded owner address) and mutate state,\n * so — like EntryPoint's `depositTo`/`withdrawTo` — they were not\n * separately simulated. Included because a Kernel account's installation\n * flow calls them, so a caller building that flow needs the selectors.\n */\nexport const kernelEcdsaValidatorAbi = parseAbi([\n \"function ecdsaValidatorStorage(address kernel) view returns (address owner)\",\n \"function isModuleType(uint256 moduleTypeId) view returns (bool)\",\n \"function isInitialized(address kernel) view returns (bool)\",\n \"function onInstall(bytes calldata data) payable\",\n \"function onUninstall(bytes calldata data) payable\",\n]);\n\n/**\n * ERC-7579 module type IDs (EIP-7579 §Module Types). `isModuleType` on any\n * conforming module — including {@link kernelEcdsaValidatorAbi}'s contract,\n * confirmed live above — is called with one of these.\n */\nexport const ERC7579_MODULE_TYPE = {\n validator: 1n,\n executor: 2n,\n fallback: 3n,\n hook: 4n,\n} as const;\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's own multicall contract, at\n * `0x927af2a6B76d2d8206d93004463F8C122701383B` on mainnet (see\n * `pepuSwapContracts.multicallNonCanonical` in `../dex.js`). **Not**\n * Multicall3 and not interchangeable with `pepuContracts.multicall3` — see\n * that entry's notes.\n *\n * A first pass at verifying this contract tried a Multicall2-style\n * `getBlockNumber()` probe, which reverted, and concluded no ABI could be\n * shipped for it. That probe used the wrong function name: pepuscan\n * (Blockscout) has this contract verified as Uniswap's\n * `UniswapInterfaceMulticall` — \"a fork of Multicall2 specifically tailored\n * for the Uniswap Interface\" — which exposes `getCurrentBlockTimestamp()`\n * and `getEthBalance(address)` instead of Multicall2's `getBlockNumber()`/\n * `getEthBalance()` pair, plus a `multicall(Call[])` that returns\n * `(blockNumber, Result[])` rather than Multicall3's `(success, returnData)[]`\n * shape (its `Call`/`Result` structs also carry a per-call `gasLimit`/\n * `gasUsed`, which neither Multicall2 nor Multicall3 do the same way) — so\n * it is not a drop-in for either.\n *\n * Verified live against mainnet 2026-09-24:\n * - The ABI below is exactly what pepuscan reports as this contract's\n * verified source-matched interface.\n * - `getCurrentBlockTimestamp()` returns a value equal to the current\n * block's own `timestamp` (checked against the same block via\n * `eth_getBlockByNumber`).\n * - `getEthBalance(0x0)` returns a live, non-zero value (the zero address's\n * real native-PEPU balance).\n *\n * `multicall(Call[])` was not independently simulated (it needs real\n * `target`/`callData` values per call to return a meaningful result); the\n * two verified getters above are enough to confirm this is a genuine,\n * matching deployment of the verified source, not a same-address\n * coincidence.\n */\nexport const pepuSwapMulticallAbi = parseAbi([\n \"function getCurrentBlockTimestamp() view returns (uint256 timestamp)\",\n \"function getEthBalance(address addr) view returns (uint256 balance)\",\n \"function multicall((address target, uint256 gasLimit, bytes callData)[] calls) returns (uint256 blockNumber, (bool success, uint256 gasUsed, bytes returnData)[] returnData)\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's own Permit2 deployment, at\n * `0xB461c05f76d7f919FF7A3Df2B0D2593F56538b4B` on mainnet (see\n * `pepuSwapContracts.permit2` in `../dex.js`).\n *\n * **This is NOT the canonical Permit2** (`0x000000000022D473030F116dDEE9F6B43aC78BA3`).\n * The canonical address is now also deployed on PEPU (see\n * `pepuContracts.permit2` in `../contracts.js`, `status: \"deployed\"`), but\n * PepuSwap's own frontend was built against this separate, earlier\n * deployment and overrides the canonical address specifically for chain\n * 97741 to point at this contract instead. The two are different contracts\n * with different EIP-712 domains — do not assume a generic\n * canonical-Permit2-aware tool (e.g. a library that hardcodes the canonical\n * address) will interoperate with PepuSwap using it; approvals made against\n * one are not visible to the other.\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 18,306 bytes of bytecode.\n * - `DOMAIN_SEPARATOR()` returns a live 32-byte value without reverting —\n * confirming this contract implements Permit2's standard EIP-712 domain\n * separator getter, consistent with a genuine (if non-canonical) Permit2\n * deployment.\n *\n * `allowance`/`approve`/`permit` are Permit2's standard signatures; not\n * separately simulated here (each needs a real token/owner/spender to\n * return a meaningful result). Kept intentionally minimal — this package\n * does not ship a full Permit2 ABI, only enough to recognize and read from\n * this specific deployment.\n */\nexport const pepuSwapPermit2Abi = parseAbi([\n \"function DOMAIN_SEPARATOR() view returns (bytes32)\",\n \"function allowance(address owner, address token, address spender) view returns (uint160 amount, uint48 expiration, uint48 nonce)\",\n \"function approve(address token, address spender, uint160 amount, uint48 expiration)\",\n]);\n","import { erc721Abi, parseAbi } from \"viem\";\n\n/**\n * PepuSwap's `NonfungiblePositionManager` ABI subset, at\n * `0xe2060CbdE18b5e765c86e5Cd6EE68AF209a9faa7` on mainnet (see\n * `pepuSwapContracts.positionManager` in `../dex.js`). LP positions on\n * PepuSwap are ERC-721 tokens minted by this contract — on pepuscan they\n * show up as \"Launchpad V3 Positions NFT\" / `UNI-V3-POS`.\n *\n * Extends viem's own {@link erc721Abi} (this contract genuinely is an\n * ERC-721) with the one PepuSwap/Uniswap-V3-specific read, `positions`.\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 24,384 bytes of bytecode.\n * - `factory()` returns the verified `pepuSwapV3FactoryAbi` address.\n * - `WETH9()` returns the verified WPEPU address.\n *\n * `positions(tokenId)` is the standard Uniswap V3 signature; not\n * independently simulated here since it requires a minted `tokenId`; the\n * verified getters above confirm this is a genuine, matching deployment.\n */\nexport const pepuSwapPositionManagerAbi = [\n ...erc721Abi,\n ...parseAbi([\n \"function factory() view returns (address)\",\n \"function WETH9() view returns (address)\",\n \"function positions(uint256 tokenId) view returns (uint96 nonce, address operator, address token0, address token1, uint24 fee, int24 tickLower, int24 tickUpper, uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0, uint128 tokensOwed1)\",\n ]),\n] as const;\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's `QuoterV2` ABI subset, at\n * `0xd647b2D80b48e93613Aa6982b85f8909578b4829` on mainnet (see\n * `pepuSwapContracts.quoterV2` in `../dex.js`).\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 8,273 bytes of bytecode.\n * - `factory()` returns the verified `pepuSwapV3FactoryAbi` address.\n * - `WETH9()` returns the verified WPEPU address.\n *\n * `quoteExactInputSingle`/`quoteExactOutputSingle` are QuoterV2's standard\n * signatures. Like the router's swap functions, they weren't independently\n * simulated here (a quote needs a real, liquid pool + valid amounts to\n * return a meaningful result, not just \"doesn't revert\"); the two verified\n * getters above confirm this is a genuine, matching QuoterV2 deployment.\n * QuoterV2 is gas-inefficient by design (it's meant to be called off-chain\n * via `eth_call`, e.g. through `client.simulateContract`) — never send it a\n * real transaction.\n */\nexport const pepuSwapQuoterAbi = parseAbi([\n \"function factory() view returns (address)\",\n \"function WETH9() view returns (address)\",\n \"function quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint24 fee, uint160 sqrtPriceLimitX96) params) returns (uint256 amountOut, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)\",\n \"function quoteExactOutputSingle((address tokenIn, address tokenOut, uint256 amount, uint24 fee, uint160 sqrtPriceLimitX96) params) returns (uint256 amountIn, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's `SwapRouter02` ABI subset, at\n * `0x150c3F0f16C3D9EB34351d7af9c961FeDc97A0fb` on mainnet (see\n * `pepuSwapContracts.swapRouter02` in `../dex.js`).\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 24,497 bytes of bytecode.\n * - `factory()` returns `0x5984B8BF2d4dB9C0aCB1d7924762e4474D80C807` — the\n * independently-verified {@link pepuSwapV3FactoryAbi} address.\n * - `WETH9()` returns `0xF9Cf4A16d26979b929Be7176bAc4e7084975FCB8` — the\n * independently-verified WPEPU address (see `../abi/wpepu.js`).\n *\n * `exactInputSingle`/`exactOutputSingle` are Uniswap's standard SwapRouter02\n * signatures (unchanged across the many chains that run this exact\n * contract); they were not separately simulated because a real swap needs a\n * funded, approved caller. The two verified read functions above confirm\n * this is a genuine, matching SwapRouter02 deployment rather than a\n * same-address coincidence.\n */\nexport const pepuSwapRouterAbi = parseAbi([\n \"function factory() view returns (address)\",\n \"function WETH9() view returns (address)\",\n \"function exactInputSingle((address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 amountIn, uint256 amountOutMinimum, uint160 sqrtPriceLimitX96) params) payable returns (uint256 amountOut)\",\n \"function exactOutputSingle((address tokenIn, address tokenOut, uint24 fee, address recipient, uint256 amountOut, uint256 amountInMaximum, uint160 sqrtPriceLimitX96) params) payable returns (uint256 amountIn)\",\n \"function multicall(uint256 deadline, bytes[] calldata data) payable returns (bytes[] memory results)\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's `TickLens` ABI, at\n * `0x4EB8aA84c066f9bf210eAfE33B30AE49BfafD9a6` on mainnet (see\n * `pepuSwapContracts.tickLens` in `../dex.js`). `TickLens` is stateless\n * (it takes a pool address as an argument to every call rather than storing\n * one), so it has no zero-argument getter to probe.\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 1,385 bytes of bytecode.\n * - `getPopulatedTicksInWord(pool, wordPosition)` was called against the\n * real WPEPU/USDT 0.3% pool (`0x4bE3Af53800AADE09201654CD76D55063c7bdE70`)\n * at the word position derived from that pool's own live `slot0().tick`\n * and `tickSpacing()`. It returned successfully (an empty populated-ticks\n * array for that particular word, which is itself a valid, non-reverting\n * result) — confirming the exact function selector against a real pool.\n */\nexport const pepuSwapTickLensAbi = parseAbi([\n \"function getPopulatedTicksInWord(address pool, int16 tickBitmapIndex) view returns ((int24 tick, int128 liquidityNet, uint128 liquidityGross)[] populatedTicks)\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's `UniversalRouter` ABI, at\n * `0x0dE72b751b77d3c74fB96C5fAd0320Cd8d133d36` on mainnet (see\n * `pepuSwapContracts.universalRouter` in `../dex.js`). UniversalRouter is a\n * command-dispatcher contract — almost everything routes through the one\n * `execute` entrypoint below, with a `commands` byte-string selecting which\n * internal actions run.\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 17,958 bytes of bytecode.\n * - Unlike the other PepuSwap contracts, UniversalRouter does not expose\n * its configured Permit2/factory addresses through public getters (a\n * `PERMIT2()`/`V2_FACTORY()`/`V3_FACTORY()`/`poolManager()` probe all\n * reverted — expected, since a dispatcher contract with no matching\n * function selector just reverts, it doesn't imply anything is wrong).\n * - Instead, `execute(bytes,bytes[],uint256)` was called directly via\n * `eth_call` with an empty `commands` byte-string, an empty `inputs`\n * array, and a far-future deadline. It returned successfully with no\n * revert — confirming the exact function selector Uniswap's\n * `UniversalRouter` uses, dispatched correctly with zero commands to run.\n */\nexport const pepuSwapUniversalRouterAbi = parseAbi([\n \"function execute(bytes commands, bytes[] inputs, uint256 deadline) payable\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * PepuSwap's Uniswap V3 core factory ABI, at\n * `0x5984B8BF2d4dB9C0aCB1d7924762e4474D80C807` on mainnet (see\n * `pepuSwapContracts.v3Factory` in `../dex.js`). PepuSwap is a Uniswap V3\n * fork; this is a standard `UniswapV3Factory` ABI subset.\n *\n * Verified live against mainnet 2026-09-24:\n * - `eth_getCode` returns 24,535 bytes of bytecode.\n * - `owner()` returns a live, non-zero address.\n * - `getPool(WPEPU, USDT, fee)` returns a real, non-zero pool address for\n * fee tiers 100/500/3000/10000, and that pool's own `token0()`/`token1()`\n * independently resolve to USDT/WPEPU.\n * - Four independent contracts on this chain (SwapRouter02,\n * NonfungiblePositionManager, QuoterV2, V3Migrator, V3Staker) each\n * read their own `factory()` immutable and all five return this exact\n * address — see the notes on each of their ABI files.\n */\nexport const pepuSwapV3FactoryAbi = parseAbi([\n \"function owner() view returns (address)\",\n \"function getPool(address tokenA, address tokenB, uint24 fee) view returns (address pool)\",\n \"function feeAmountTickSpacing(uint24 fee) view returns (int24)\",\n \"function createPool(address tokenA, address tokenB, uint24 fee) returns (address pool)\",\n \"event PoolCreated(address indexed token0, address indexed token1, uint24 indexed fee, int24 tickSpacing, address pool)\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * Minimal Uniswap V3 pool ABI for reading a PepuSwap pool's state — enough\n * to price a pair and locate its liquidity, without the full swap/mint/burn\n * surface.\n *\n * Verified live against mainnet 2026-09-24 against the real WPEPU/USDT\n * 0.3% pool (`0x4bE3Af53800AADE09201654CD76D55063c7bdE70`, returned by\n * `pepuSwapV3FactoryAbi`'s `getPool`):\n * - `slot0()` decodes cleanly into the standard 7-field tuple (a live tick\n * of 372469 at the time of verification).\n * - `tickSpacing()` returns `60`, the standard spacing for a 0.3% pool.\n * - `token0()`/`token1()` return USDT/WPEPU respectively, matching the\n * factory's `getPool` inputs.\n */\nexport const pepuSwapV3PoolAbi = parseAbi([\n \"function token0() view returns (address)\",\n \"function token1() view returns (address)\",\n \"function fee() view returns (uint24)\",\n \"function tickSpacing() view returns (int24)\",\n \"function liquidity() view returns (uint128)\",\n \"function slot0() view returns (uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked)\",\n]);\n","import { erc20Abi, parseAbi } from \"viem\";\n\n/**\n * WPEPU (Wrapped Pepe Unchained) ABI.\n *\n * WPEPU is a WETH9-style wrapper around the native PEPU gas token, deployed\n * at `0xF9Cf4A16d26979b929Be7176bAc4e7084975FCB8` on mainnet (see\n * `pepuTokenList` in `../tokens.js`). This extends viem's own {@link erc20Abi}\n * with the two WETH9-specific functions and their events, rather than\n * re-declaring the ERC-20 surface from scratch.\n *\n * Verified live against mainnet on 2026-09-24:\n * - `deposit()` and `withdraw(uint256)` both simulate successfully via\n * `eth_call` (a zero-value deposit and a zero-amount withdraw), confirming\n * both selectors exist and don't revert.\n * - `decimals()` -> `18`, `symbol()` -> `\"WPEPU\"`, `name()` -> `\"Wrapped PEPU\"`.\n * - The contract is verified on pepuscan against the canonical `WETH9`\n * source.\n */\nexport const wpepuAbi = [\n ...erc20Abi,\n ...parseAbi([\n \"function deposit() payable\",\n \"function withdraw(uint256 amount)\",\n \"event Deposit(address indexed dst, uint256 amount)\",\n \"event Withdrawal(address indexed src, uint256 amount)\",\n ]),\n] as const;\n","import { parseAbi } from \"viem\";\n\n/**\n * Minimal Multicall3 ABI (aggregate3 plus the common read helpers). Same\n * interface as canonical mds1/multicall3; on PEPU it lives at the\n * PEPU-specific `0x9CE19273Ae9c24437DFF512E8DFCAed4E4B001bd`, never at the\n * canonical `0xcA11...CA11`.\n */\nexport const multicall3Abi = parseAbi([\n \"struct Call3 { address target; bool allowFailure; bytes callData; }\",\n \"struct Result { bool success; bytes returnData; }\",\n \"function aggregate3(Call3[] calls) payable returns (Result[] returnData)\",\n \"function getEthBalance(address addr) view returns (uint256 balance)\",\n \"function getBlockNumber() view returns (uint256 blockNumber)\",\n \"function getChainId() view returns (uint256)\",\n]);\n","import { parseAbi } from \"viem\";\n\n/**\n * Canonical Permit2 ABI subset (AllowanceTransfer plus SignatureTransfer\n * nonce reads). For the canonical `0x000000000022D473030F116dDEE9F6B43aC78BA3`\n * deployed on PEPU. NOT PepuSwap's separate deployment (see `pepuSwapPermit2Abi`).\n */\nexport const permit2Abi = parseAbi([\n \"function DOMAIN_SEPARATOR() view returns (bytes32)\",\n \"function allowance(address owner, address token, address spender) view returns (uint160 amount, uint48 expiration, uint48 nonce)\",\n \"function approve(address token, address spender, uint160 amount, uint48 expiration)\",\n \"function nonceBitmap(address owner, uint256 wordPos) view returns (uint256)\",\n \"function invalidateNonces(address token, address spender, uint48 newNonce)\",\n]);\n","import {\n type Address,\n type ContractFunctionParameters,\n type Hex,\n type MulticallReturnType,\n type PublicClient,\n decodeFunctionResult,\n encodeFunctionData,\n isAddressEqual,\n} from \"viem\";\n\nimport { multicall3Abi } from \"./abi/multicall3.js\";\nimport { pepuMainnet } from \"./chains.js\";\nimport { type DeployedContract, getContract, isDeployed } from \"./contracts.js\";\nimport { PepuChainError } from \"./errors.js\";\n\n/** The canonical Multicall3 address, which is NOT deployed on PEPU. */\nexport const CANONICAL_MULTICALL3_ADDRESS =\n \"0xcA11bde05977b3631167028862bE2a173976CA11\" as const;\n\n/**\n * Guard: throws `MULTICALL3_CANONICAL_ADDRESS` if `address` is the canonical\n * Multicall3 address (which has no code on PEPU).\n *\n * @example\n * ```ts\n * assertNotCanonicalMulticall3(\"0x9CE19273Ae9c24437DFF512E8DFCAed4E4B001bd\"); // ok\n * ```\n */\nexport function assertNotCanonicalMulticall3(address: Address): void {\n if (isAddressEqual(address, CANONICAL_MULTICALL3_ADDRESS)) {\n throw new PepuChainError(\"MULTICALL3_CANONICAL_ADDRESS\");\n }\n}\n\n/**\n * The PEPU-specific Multicall3 registry entry. Never the canonical address.\n *\n * @example\n * ```ts\n * const { address } = getMulticall3(); // 0x9CE19273...01bd\n * ```\n */\nexport function getMulticall3(chainId: number = pepuMainnet.id): DeployedContract {\n const entry = getContract(chainId, \"multicall3\");\n if (!isDeployed(entry)) {\n throw new PepuChainError(\"UNKNOWN\", \"Multicall3 is not deployed on the requested chain.\");\n }\n assertNotCanonicalMulticall3(entry.address);\n return entry;\n}\n\n/**\n * viem `multicall` pinned to the PEPU Multicall3 address.\n *\n * @example\n * ```ts\n * const [name, supply] = await pepuMulticall(client, [\n * { address: token, abi: erc20Abi, functionName: \"name\" },\n * { address: token, abi: erc20Abi, functionName: \"totalSupply\" },\n * ], { allowFailure: false });\n * ```\n */\nexport function pepuMulticall<\n const T extends readonly ContractFunctionParameters[],\n A extends boolean = true,\n>(\n client: PublicClient,\n calls: T,\n o: { allowFailure?: A; blockNumber?: bigint } = {},\n): Promise<MulticallReturnType<T, A>> {\n const chainId = client.chain?.id ?? pepuMainnet.id;\n const multicallAddress = getMulticall3(chainId).address;\n return client.multicall({\n contracts: calls,\n multicallAddress,\n allowFailure: o.allowFailure ?? true,\n ...(o.blockNumber !== undefined ? { blockNumber: o.blockNumber } : {}),\n } as never) as Promise<MulticallReturnType<T, A>>;\n}\n\n/**\n * ABI-encode a Multicall3 `aggregate3` call.\n *\n * @example\n * ```ts\n * const data = encodeAggregate3([{ target: token, callData: \"0x18160ddd\" }]);\n * ```\n */\nexport function encodeAggregate3(\n calls: readonly { target: Address; allowFailure?: boolean; callData: Hex }[],\n): Hex {\n return encodeFunctionData({\n abi: multicall3Abi,\n functionName: \"aggregate3\",\n args: [\n calls.map((c) => ({\n target: c.target,\n allowFailure: c.allowFailure ?? false,\n callData: c.callData,\n })),\n ],\n });\n}\n\n/**\n * Decode the return data of `aggregate3`.\n *\n * @example\n * ```ts\n * const results = decodeAggregate3Result(returnData);\n * results[0]?.success;\n * ```\n */\nexport function decodeAggregate3Result(data: Hex): { success: boolean; returnData: Hex }[] {\n const out = decodeFunctionResult({\n abi: multicall3Abi,\n functionName: \"aggregate3\",\n data,\n });\n return out.map((r) => ({ success: r.success, returnData: r.returnData }));\n}\n","import type { Address, PublicClient, TypedDataDomain } from \"viem\";\n\nimport { permit2Abi } from \"./abi/permit2.js\";\nimport { pepuMainnet } from \"./chains.js\";\nimport { type DeployedContract, getContract, isDeployed } from \"./contracts.js\";\nimport { PepuChainError } from \"./errors.js\";\n\n/**\n * The canonical Permit2 registry entry (`0x000000000022D473...78BA3`).\n *\n * @example\n * ```ts\n * const { address } = getPermit2();\n * ```\n */\nexport function getPermit2(chainId: number = pepuMainnet.id): DeployedContract {\n const entry = getContract(chainId, \"permit2\");\n if (!isDeployed(entry)) {\n throw new PepuChainError(\"UNKNOWN\", \"Permit2 is not deployed on the requested chain.\");\n }\n return entry;\n}\n\n/**\n * EIP-712 domain for canonical Permit2: name \"Permit2\" (no version).\n *\n * @example\n * ```ts\n * const domain = permit2Domain(); // { name: \"Permit2\", chainId: 97741, verifyingContract }\n * ```\n */\nexport function permit2Domain(chainId: number = pepuMainnet.id): TypedDataDomain {\n return {\n name: \"Permit2\",\n chainId,\n verifyingContract: getPermit2(chainId).address,\n };\n}\n\n/** Typed-data definition accepted by viem `signTypedData`. */\nexport interface Permit2TypedData<P extends string, M extends Record<string, unknown>> {\n domain: TypedDataDomain;\n types: Record<string, readonly { name: string; type: string }[]>;\n primaryType: P;\n message: M;\n}\n\n/**\n * Typed data for Permit2 AllowanceTransfer `PermitSingle`.\n *\n * @example\n * ```ts\n * const td = buildPermitSingleTypedData({ token, amount: 1n, expiration: 1900000000, nonce: 0, spender, sigDeadline: 1900000000n });\n * ```\n */\nexport function buildPermitSingleTypedData(p: {\n token: Address;\n amount: bigint;\n expiration: number;\n nonce: number;\n spender: Address;\n sigDeadline: bigint;\n chainId?: number;\n}): Permit2TypedData<\n \"PermitSingle\",\n {\n details: { token: Address; amount: bigint; expiration: number; nonce: number };\n spender: Address;\n sigDeadline: bigint;\n }\n> {\n return {\n domain: permit2Domain(p.chainId),\n types: {\n PermitSingle: [\n { name: \"details\", type: \"PermitDetails\" },\n { name: \"spender\", type: \"address\" },\n { name: \"sigDeadline\", type: \"uint256\" },\n ],\n PermitDetails: [\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint160\" },\n { name: \"expiration\", type: \"uint48\" },\n { name: \"nonce\", type: \"uint48\" },\n ],\n },\n primaryType: \"PermitSingle\",\n message: {\n details: {\n token: p.token,\n amount: p.amount,\n expiration: p.expiration,\n nonce: p.nonce,\n },\n spender: p.spender,\n sigDeadline: p.sigDeadline,\n },\n };\n}\n\n/**\n * Typed data for Permit2 SignatureTransfer `PermitTransferFrom`.\n *\n * @example\n * ```ts\n * const td = buildPermitTransferFromTypedData({ token, amount: 1n, spender, nonce: 0n, deadline: 1900000000n });\n * ```\n */\nexport function buildPermitTransferFromTypedData(p: {\n token: Address;\n amount: bigint;\n spender: Address;\n nonce: bigint;\n deadline: bigint;\n chainId?: number;\n}): Permit2TypedData<\n \"PermitTransferFrom\",\n {\n permitted: { token: Address; amount: bigint };\n spender: Address;\n nonce: bigint;\n deadline: bigint;\n }\n> {\n return {\n domain: permit2Domain(p.chainId),\n types: {\n PermitTransferFrom: [\n { name: \"permitted\", type: \"TokenPermissions\" },\n { name: \"spender\", type: \"address\" },\n { name: \"nonce\", type: \"uint256\" },\n { name: \"deadline\", type: \"uint256\" },\n ],\n TokenPermissions: [\n { name: \"token\", type: \"address\" },\n { name: \"amount\", type: \"uint256\" },\n ],\n },\n primaryType: \"PermitTransferFrom\",\n message: {\n permitted: { token: p.token, amount: p.amount },\n spender: p.spender,\n nonce: p.nonce,\n deadline: p.deadline,\n },\n };\n}\n\n/**\n * Read the Permit2 AllowanceTransfer allowance for (owner, token, spender).\n *\n * @example\n * ```ts\n * const { amount, expiration, nonce } = await readPermit2Allowance(client, { owner, token, spender });\n * ```\n */\nexport async function readPermit2Allowance(\n client: PublicClient,\n o: { owner: Address; token: Address; spender: Address },\n): Promise<{ amount: bigint; expiration: number; nonce: number }> {\n const [amount, expiration, nonce] = await client.readContract({\n address: getPermit2(client.chain?.id ?? pepuMainnet.id).address,\n abi: permit2Abi,\n functionName: \"allowance\",\n args: [o.owner, o.token, o.spender],\n });\n return { amount, expiration, nonce };\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export { buildPaymasterContext, buildPaymasterDataRequest, buildPaymasterStubDataRequest } from './chunk-7PVR7QSE.js';
|
|
2
|
-
export { KERNEL_V3_1_IMPLEMENTATION_ADDRESS, checkSponsorship, entryPointV07Abi, getKernelAccountAddress, getPepuKernelStack, getSponsorshipStatus, kernelFactoryAbi } from './chunk-
|
|
3
|
-
import './chunk-
|
|
2
|
+
export { KERNEL_V3_1_IMPLEMENTATION_ADDRESS, checkSponsorship, entryPointV07Abi, getKernelAccountAddress, getPepuKernelStack, getSponsorshipStatus, kernelFactoryAbi } from './chunk-XR5ONV2Y.js';
|
|
3
|
+
import './chunk-GFKIM7HT.js';
|
|
4
4
|
import { getContract, isDeployed } from './chunk-KJYNF5KH.js';
|
|
5
5
|
export { getContract, getPepuAddressMap, getPepuAddresses, isDeployed, listContracts, pepuContracts } from './chunk-KJYNF5KH.js';
|
|
6
|
+
import './chunk-GIZNH65Q.js';
|
|
6
7
|
export { getPublicClient } from './chunk-OH3QMAIB.js';
|
|
7
8
|
export { addressUrl, blockUrl, explorerLinks, explorerUrl, tokenUrl, txUrl } from './chunk-J6UXXHBE.js';
|
|
8
9
|
export { PEPU_ENV, PEPU_HOSTED, PEPU_PUBLIC_ENV, hostedFreeTierUrl, isHostedSponsorshipLive, paymasterBaseOf, resolvePepuEndpoints } from './chunk-XC4IBCI2.js';
|