@pafi-dev/core 0.3.0-beta.10 → 0.3.0-beta.12

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/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { Address, Hex, PublicClient, WalletClient } from 'viem';
1
+ import { Address, Hex, PublicClient, HttpTransport, WalletClient } from 'viem';
2
2
  import { P as PoolKey, C as ChainConfig, a as PafiSDKConfig, b as PointTokenDomainConfig, M as MintRequest, R as ReceiverConsent, E as EIP712Signature, S as SignatureVerification, B as BestQuote, Q as QuoteResult } from './types-b5_Tokjl.cjs';
3
3
  export { c as BurnRequest, I as Issuer, d as PathKey } from './types-b5_Tokjl.cjs';
4
4
  export { erc20Abi, issuerRegistryAbi, mintingOracleAbi, permit2Abi, pointTokenAbi, pointTokenFactoryAbi, universalRouterAbi, v4QuoterAbi } from './abi/index.cjs';
@@ -538,6 +538,182 @@ interface CheckEthAndBranchParams {
538
538
  */
539
539
  declare function checkEthAndBranch(params: CheckEthAndBranchParams): Promise<SubmissionPath>;
540
540
 
541
+ /**
542
+ * Parse the implementation address out of an EIP-7702 delegation designator.
543
+ *
544
+ * Returns `null` when:
545
+ * - `code` is undefined / empty / `"0x"` (plain EOA, no code)
546
+ * - `code` does not contain the EIP-7702 magic prefix (regular contract)
547
+ *
548
+ * @param code - bytecode returned by `eth_getCode` / `client.getCode()`
549
+ * @returns the 20-byte implementation address (checksummed), or `null`
550
+ *
551
+ * @example
552
+ * const code = await client.getCode({ address });
553
+ * const impl = parseEip7702DelegatedAddress(code);
554
+ * // null → not delegated
555
+ * // '0x7702cb554e6bFb442cb743A7dF23154544a7176C' → delegated to BatchExecutor
556
+ */
557
+ declare function parseEip7702DelegatedAddress(code: Hex | string | null | undefined): Address | null;
558
+ /**
559
+ * Read the EIP-7702 delegation status of an EOA from the chain.
560
+ *
561
+ * @param client - viem PublicClient (any provider — only `eth_getCode` is called)
562
+ * @param address - EOA address to inspect
563
+ * @returns the implementation address the EOA is delegated to, or `null`
564
+ *
565
+ * @example
566
+ * const impl = await checkDelegation(publicClient, userAddress);
567
+ * if (impl === null) {
568
+ * // show "Setup Wallet" button
569
+ * } else {
570
+ * // EOA already delegated; safe to send UserOps
571
+ * }
572
+ */
573
+ declare function checkDelegation(client: PublicClient, address: Address): Promise<Address | null>;
574
+ /**
575
+ * Return `true` when the EOA at `address` is currently delegated to `target`.
576
+ *
577
+ * Useful for asserting that the delegation points specifically at the expected
578
+ * BatchExecutor rather than some other implementation (e.g. old deployment).
579
+ *
580
+ * @example
581
+ * import { BATCH_EXECUTOR_ADDRESS_BASE_MAINNET } from '@pafi-dev/core';
582
+ * const ok = await isDelegatedTo(client, userAddress, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET);
583
+ */
584
+ declare function isDelegatedTo(client: PublicClient, address: Address, target: Address): Promise<boolean>;
585
+
586
+ /**
587
+ * Parameters for building a delegation-only UserOperation.
588
+ *
589
+ * This UserOp carries no calldata — its sole purpose is to anchor the
590
+ * EIP-7702 authorization (signed externally via `signAuthorization`) into
591
+ * a sponsored transaction so the user doesn't need native ETH to delegate.
592
+ */
593
+ interface BuildDelegationUserOpParams {
594
+ /** User EOA to delegate. */
595
+ userAddress: Address;
596
+ /** ERC-4337 account nonce — fetched from EntryPoint. Pass 0n on first ever op. */
597
+ aaNonce: bigint;
598
+ gasLimits?: {
599
+ callGasLimit?: bigint;
600
+ verificationGasLimit?: bigint;
601
+ preVerificationGas?: bigint;
602
+ };
603
+ }
604
+ /**
605
+ * Build the minimal `PartialUserOperation` used to sponsor the one-time
606
+ * EIP-7702 delegation.
607
+ *
608
+ * The caller must:
609
+ * 1. Sign the EIP-7702 authorization via `signAuthorization()` (Privy hook).
610
+ * 2. Pass the authorization as `authorization` alongside `calls` (or alone)
611
+ * to `smartClient.sendTransaction()`.
612
+ *
613
+ * The permissionless SDK + Pimlico bundler handle the rest: they detect the
614
+ * `authorization` field and submit an EIP-7702 type-4 transaction that sets
615
+ * the EOA's bytecode to `0xef0100<batchExecutorAddress>`.
616
+ *
617
+ * This builder is a convenience wrapper — in practice you can also pass
618
+ * `{ to: userAddress, value: 0n, data: '0x', authorization }` directly to
619
+ * `smartClient.sendTransaction()` without calling this function at all.
620
+ * Use it when you need a `PartialUserOperation` struct for inspection or
621
+ * custom paymaster flows.
622
+ *
623
+ * @example
624
+ * // Typical flow — no need to call this builder directly:
625
+ * const nonce = await publicClient.getTransactionCount({ address, blockTag: 'pending' });
626
+ * const authorization = await signAuthorization({ contractAddress: BATCH_EXECUTOR, chainId: 8453, nonce });
627
+ * const txHash = await smartClient.sendTransaction({
628
+ * to: address,
629
+ * value: 0n,
630
+ * data: '0x',
631
+ * authorization,
632
+ * paymasterContext: { sponsorshipPolicyId },
633
+ * });
634
+ */
635
+ declare function buildDelegationUserOp(params: BuildDelegationUserOpParams): PartialUserOperation;
636
+ /**
637
+ * Fetch the AA nonce for a user EOA from the EntryPoint v0.7.
638
+ *
639
+ * Convenience helper so callers don't need to import the EntryPoint ABI
640
+ * themselves when building the delegation UserOp.
641
+ *
642
+ * @param client - viem PublicClient
643
+ * @param userAddress - EOA to query
644
+ * @returns bigint nonce (0n on first-ever UserOp)
645
+ */
646
+ declare function getAaNonce(client: PublicClient, userAddress: Address): Promise<bigint>;
647
+
648
+ /**
649
+ * Parameters for `createPafiProxyTransport`.
650
+ */
651
+ interface PafiProxyTransportParams {
652
+ /**
653
+ * Full URL of the PAFI sponsor-relayer Pimlico proxy endpoint.
654
+ * @example "https://sponsor-relayer.pacificfinance.org/pimlico"
655
+ * @example "http://localhost:4000/pimlico"
656
+ */
657
+ proxyUrl: string;
658
+ /**
659
+ * Called on every request to get the current Privy identity token.
660
+ * Use a getter (or a ref's `.current`) so the transport always sends
661
+ * the latest token without needing to be rebuilt when it rotates.
662
+ *
663
+ * @example () => identityTokenRef.current
664
+ * @example () => privyHook.identityToken
665
+ */
666
+ getIdentityToken: () => string | null | undefined;
667
+ /**
668
+ * Issuer ID sent as `X-Issuer-Id` header.
669
+ * sponsor-relayer uses this to look up per-issuer rate limits and policy.
670
+ * Obtain from PAFI team during onboarding.
671
+ */
672
+ issuerId: string;
673
+ }
674
+ /**
675
+ * Create a viem `HttpTransport` that proxies all Pimlico JSON-RPC calls
676
+ * through the PAFI sponsor-relayer (`POST /pimlico`).
677
+ *
678
+ * The transport:
679
+ * - Sets `Authorization: Bearer <identityToken>` on every request
680
+ * - Sets `X-Issuer-Id: <issuerId>` on every request
681
+ * - Reads the identity token lazily via `getIdentityToken()` so it is
682
+ * always fresh without rebuilding the SmartAccountClient on each rotation
683
+ *
684
+ * Pass the returned transport to both `createPimlicoClient` and
685
+ * `createSmartAccountClient` so ALL Pimlico RPC calls (paymaster + bundler)
686
+ * go through the proxy with auth headers attached.
687
+ *
688
+ * @example
689
+ * ```ts
690
+ * import { createPafiProxyTransport, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET } from '@pafi-dev/core';
691
+ * import { createSmartAccountClient } from 'permissionless';
692
+ * import { createPimlicoClient } from 'permissionless/clients/pimlico';
693
+ * import { useIdentityToken } from '@privy-io/react-auth';
694
+ *
695
+ * const { identityToken } = useIdentityToken();
696
+ * const identityTokenRef = useRef<string | null>(null);
697
+ * useEffect(() => { identityTokenRef.current = identityToken; }, [identityToken]);
698
+ *
699
+ * const proxyTransport = createPafiProxyTransport({
700
+ * proxyUrl: process.env.NEXT_PUBLIC_PIMLICO_PROXY_URL!,
701
+ * getIdentityToken: () => identityTokenRef.current,
702
+ * issuerId: process.env.NEXT_PUBLIC_ISSUER_ID!,
703
+ * });
704
+ *
705
+ * const pimlicoClient = createPimlicoClient({ chain: base, transport: proxyTransport });
706
+ * const smartClient = createSmartAccountClient({
707
+ * client: publicClient,
708
+ * chain: base,
709
+ * account,
710
+ * paymaster: pimlicoClient,
711
+ * bundlerTransport: proxyTransport,
712
+ * });
713
+ * ```
714
+ */
715
+ declare function createPafiProxyTransport(params: PafiProxyTransportParams): HttpTransport;
716
+
541
717
  /**
542
718
  * Real `PointToken` ABI — matches the contract deployed on Base mainnet
543
719
  * (POINT at `0x7d25E7156E51F865D522fd3ef257a6B5DD41b97e`). Sourced from
@@ -1293,4 +1469,4 @@ declare class PafiSDK {
1293
1469
  signLoginMessage(message: string): Promise<Hex>;
1294
1470
  }
1295
1471
 
1296
- export { ApiError, BATCH_EXECUTOR_ABI, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET, BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA, BROKER_HASHES, BestQuote, type BuildPartialUserOpParams, type BuildPerpDepositWithGasDeductionParams, COMMON_POOLS, COMMON_TOKENS, CONTRACT_ADDRESSES, ChainConfig, type CheckEthAndBranchParams, ConfigurationError, type ContractAddresses, EIP712Signature, LoginMessageParams, MintRequest, type ModalOpenOptions, ORDERLY_VAULT_ABI, ORDERLY_VAULT_ADDRESSES, ORDERLY_VAULT_BASE_MAINNET, Operation, POINT_TOKEN_FACTORY_ADDRESSES, POINT_TOKEN_IMPL_ADDRESSES, POINT_TOKEN_POOLS, POINT_TOKEN_ABI as POINT_TOKEN_V2_ABI, PafiSDK, PafiSDKConfig, PafiSDKError, type PafiWebModalAdapter, type PafiWebModalHandle, PartialUserOperation, type PaymasterConfig, PointTokenDomainConfig, PoolKey, QuoteResult, ReceiverConsent, SUPPORTED_CHAINS, type SignatureStruct, SignatureVerification, SigningError, SimulationError, type SponsorshipScenario, type SubmissionPath, SwapSimulationResult, TOKEN_HASHES, UNIVERSAL_ROUTER_ADDRESSES, UserOperation, V4_QUOTER_ADDRESSES, type VaultDepositFE, _resetPaymasterConfigForTests, assembleUserOperation, buildPartialUserOperation, buildPerpDepositWithGasDeduction, burnRequestTypes, checkEthAndBranch, computeAccountId, encodeBatchExecute, erc20ApproveOp, erc20BurnOp, erc20TransferOp, getContractAddresses, getPafiWebModalAdapter, getPaymasterConfig, isPaymasterConfigured, mintRequestTypes, openPafiWebModal, openWebPopup, rawCallOp, receiverConsentTypes, setPafiWebModalAdapter, setPaymasterConfig, webPopupAdapter };
1472
+ export { ApiError, BATCH_EXECUTOR_ABI, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET, BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA, BROKER_HASHES, BestQuote, type BuildDelegationUserOpParams, type BuildPartialUserOpParams, type BuildPerpDepositWithGasDeductionParams, COMMON_POOLS, COMMON_TOKENS, CONTRACT_ADDRESSES, ChainConfig, type CheckEthAndBranchParams, ConfigurationError, type ContractAddresses, EIP712Signature, LoginMessageParams, MintRequest, type ModalOpenOptions, ORDERLY_VAULT_ABI, ORDERLY_VAULT_ADDRESSES, ORDERLY_VAULT_BASE_MAINNET, Operation, POINT_TOKEN_FACTORY_ADDRESSES, POINT_TOKEN_IMPL_ADDRESSES, POINT_TOKEN_POOLS, POINT_TOKEN_ABI as POINT_TOKEN_V2_ABI, type PafiProxyTransportParams, PafiSDK, PafiSDKConfig, PafiSDKError, type PafiWebModalAdapter, type PafiWebModalHandle, PartialUserOperation, type PaymasterConfig, PointTokenDomainConfig, PoolKey, QuoteResult, ReceiverConsent, SUPPORTED_CHAINS, type SignatureStruct, SignatureVerification, SigningError, SimulationError, type SponsorshipScenario, type SubmissionPath, SwapSimulationResult, TOKEN_HASHES, UNIVERSAL_ROUTER_ADDRESSES, UserOperation, V4_QUOTER_ADDRESSES, type VaultDepositFE, _resetPaymasterConfigForTests, assembleUserOperation, buildDelegationUserOp, buildPartialUserOperation, buildPerpDepositWithGasDeduction, burnRequestTypes, checkDelegation, checkEthAndBranch, computeAccountId, createPafiProxyTransport, encodeBatchExecute, erc20ApproveOp, erc20BurnOp, erc20TransferOp, getAaNonce, getContractAddresses, getPafiWebModalAdapter, getPaymasterConfig, isDelegatedTo, isPaymasterConfigured, mintRequestTypes, openPafiWebModal, openWebPopup, parseEip7702DelegatedAddress, rawCallOp, receiverConsentTypes, setPafiWebModalAdapter, setPaymasterConfig, webPopupAdapter };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Address, Hex, PublicClient, WalletClient } from 'viem';
1
+ import { Address, Hex, PublicClient, HttpTransport, WalletClient } from 'viem';
2
2
  import { P as PoolKey, C as ChainConfig, a as PafiSDKConfig, b as PointTokenDomainConfig, M as MintRequest, R as ReceiverConsent, E as EIP712Signature, S as SignatureVerification, B as BestQuote, Q as QuoteResult } from './types-b5_Tokjl.js';
3
3
  export { c as BurnRequest, I as Issuer, d as PathKey } from './types-b5_Tokjl.js';
4
4
  export { erc20Abi, issuerRegistryAbi, mintingOracleAbi, permit2Abi, pointTokenAbi, pointTokenFactoryAbi, universalRouterAbi, v4QuoterAbi } from './abi/index.js';
@@ -538,6 +538,182 @@ interface CheckEthAndBranchParams {
538
538
  */
539
539
  declare function checkEthAndBranch(params: CheckEthAndBranchParams): Promise<SubmissionPath>;
540
540
 
541
+ /**
542
+ * Parse the implementation address out of an EIP-7702 delegation designator.
543
+ *
544
+ * Returns `null` when:
545
+ * - `code` is undefined / empty / `"0x"` (plain EOA, no code)
546
+ * - `code` does not contain the EIP-7702 magic prefix (regular contract)
547
+ *
548
+ * @param code - bytecode returned by `eth_getCode` / `client.getCode()`
549
+ * @returns the 20-byte implementation address (checksummed), or `null`
550
+ *
551
+ * @example
552
+ * const code = await client.getCode({ address });
553
+ * const impl = parseEip7702DelegatedAddress(code);
554
+ * // null → not delegated
555
+ * // '0x7702cb554e6bFb442cb743A7dF23154544a7176C' → delegated to BatchExecutor
556
+ */
557
+ declare function parseEip7702DelegatedAddress(code: Hex | string | null | undefined): Address | null;
558
+ /**
559
+ * Read the EIP-7702 delegation status of an EOA from the chain.
560
+ *
561
+ * @param client - viem PublicClient (any provider — only `eth_getCode` is called)
562
+ * @param address - EOA address to inspect
563
+ * @returns the implementation address the EOA is delegated to, or `null`
564
+ *
565
+ * @example
566
+ * const impl = await checkDelegation(publicClient, userAddress);
567
+ * if (impl === null) {
568
+ * // show "Setup Wallet" button
569
+ * } else {
570
+ * // EOA already delegated; safe to send UserOps
571
+ * }
572
+ */
573
+ declare function checkDelegation(client: PublicClient, address: Address): Promise<Address | null>;
574
+ /**
575
+ * Return `true` when the EOA at `address` is currently delegated to `target`.
576
+ *
577
+ * Useful for asserting that the delegation points specifically at the expected
578
+ * BatchExecutor rather than some other implementation (e.g. old deployment).
579
+ *
580
+ * @example
581
+ * import { BATCH_EXECUTOR_ADDRESS_BASE_MAINNET } from '@pafi-dev/core';
582
+ * const ok = await isDelegatedTo(client, userAddress, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET);
583
+ */
584
+ declare function isDelegatedTo(client: PublicClient, address: Address, target: Address): Promise<boolean>;
585
+
586
+ /**
587
+ * Parameters for building a delegation-only UserOperation.
588
+ *
589
+ * This UserOp carries no calldata — its sole purpose is to anchor the
590
+ * EIP-7702 authorization (signed externally via `signAuthorization`) into
591
+ * a sponsored transaction so the user doesn't need native ETH to delegate.
592
+ */
593
+ interface BuildDelegationUserOpParams {
594
+ /** User EOA to delegate. */
595
+ userAddress: Address;
596
+ /** ERC-4337 account nonce — fetched from EntryPoint. Pass 0n on first ever op. */
597
+ aaNonce: bigint;
598
+ gasLimits?: {
599
+ callGasLimit?: bigint;
600
+ verificationGasLimit?: bigint;
601
+ preVerificationGas?: bigint;
602
+ };
603
+ }
604
+ /**
605
+ * Build the minimal `PartialUserOperation` used to sponsor the one-time
606
+ * EIP-7702 delegation.
607
+ *
608
+ * The caller must:
609
+ * 1. Sign the EIP-7702 authorization via `signAuthorization()` (Privy hook).
610
+ * 2. Pass the authorization as `authorization` alongside `calls` (or alone)
611
+ * to `smartClient.sendTransaction()`.
612
+ *
613
+ * The permissionless SDK + Pimlico bundler handle the rest: they detect the
614
+ * `authorization` field and submit an EIP-7702 type-4 transaction that sets
615
+ * the EOA's bytecode to `0xef0100<batchExecutorAddress>`.
616
+ *
617
+ * This builder is a convenience wrapper — in practice you can also pass
618
+ * `{ to: userAddress, value: 0n, data: '0x', authorization }` directly to
619
+ * `smartClient.sendTransaction()` without calling this function at all.
620
+ * Use it when you need a `PartialUserOperation` struct for inspection or
621
+ * custom paymaster flows.
622
+ *
623
+ * @example
624
+ * // Typical flow — no need to call this builder directly:
625
+ * const nonce = await publicClient.getTransactionCount({ address, blockTag: 'pending' });
626
+ * const authorization = await signAuthorization({ contractAddress: BATCH_EXECUTOR, chainId: 8453, nonce });
627
+ * const txHash = await smartClient.sendTransaction({
628
+ * to: address,
629
+ * value: 0n,
630
+ * data: '0x',
631
+ * authorization,
632
+ * paymasterContext: { sponsorshipPolicyId },
633
+ * });
634
+ */
635
+ declare function buildDelegationUserOp(params: BuildDelegationUserOpParams): PartialUserOperation;
636
+ /**
637
+ * Fetch the AA nonce for a user EOA from the EntryPoint v0.7.
638
+ *
639
+ * Convenience helper so callers don't need to import the EntryPoint ABI
640
+ * themselves when building the delegation UserOp.
641
+ *
642
+ * @param client - viem PublicClient
643
+ * @param userAddress - EOA to query
644
+ * @returns bigint nonce (0n on first-ever UserOp)
645
+ */
646
+ declare function getAaNonce(client: PublicClient, userAddress: Address): Promise<bigint>;
647
+
648
+ /**
649
+ * Parameters for `createPafiProxyTransport`.
650
+ */
651
+ interface PafiProxyTransportParams {
652
+ /**
653
+ * Full URL of the PAFI sponsor-relayer Pimlico proxy endpoint.
654
+ * @example "https://sponsor-relayer.pacificfinance.org/pimlico"
655
+ * @example "http://localhost:4000/pimlico"
656
+ */
657
+ proxyUrl: string;
658
+ /**
659
+ * Called on every request to get the current Privy identity token.
660
+ * Use a getter (or a ref's `.current`) so the transport always sends
661
+ * the latest token without needing to be rebuilt when it rotates.
662
+ *
663
+ * @example () => identityTokenRef.current
664
+ * @example () => privyHook.identityToken
665
+ */
666
+ getIdentityToken: () => string | null | undefined;
667
+ /**
668
+ * Issuer ID sent as `X-Issuer-Id` header.
669
+ * sponsor-relayer uses this to look up per-issuer rate limits and policy.
670
+ * Obtain from PAFI team during onboarding.
671
+ */
672
+ issuerId: string;
673
+ }
674
+ /**
675
+ * Create a viem `HttpTransport` that proxies all Pimlico JSON-RPC calls
676
+ * through the PAFI sponsor-relayer (`POST /pimlico`).
677
+ *
678
+ * The transport:
679
+ * - Sets `Authorization: Bearer <identityToken>` on every request
680
+ * - Sets `X-Issuer-Id: <issuerId>` on every request
681
+ * - Reads the identity token lazily via `getIdentityToken()` so it is
682
+ * always fresh without rebuilding the SmartAccountClient on each rotation
683
+ *
684
+ * Pass the returned transport to both `createPimlicoClient` and
685
+ * `createSmartAccountClient` so ALL Pimlico RPC calls (paymaster + bundler)
686
+ * go through the proxy with auth headers attached.
687
+ *
688
+ * @example
689
+ * ```ts
690
+ * import { createPafiProxyTransport, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET } from '@pafi-dev/core';
691
+ * import { createSmartAccountClient } from 'permissionless';
692
+ * import { createPimlicoClient } from 'permissionless/clients/pimlico';
693
+ * import { useIdentityToken } from '@privy-io/react-auth';
694
+ *
695
+ * const { identityToken } = useIdentityToken();
696
+ * const identityTokenRef = useRef<string | null>(null);
697
+ * useEffect(() => { identityTokenRef.current = identityToken; }, [identityToken]);
698
+ *
699
+ * const proxyTransport = createPafiProxyTransport({
700
+ * proxyUrl: process.env.NEXT_PUBLIC_PIMLICO_PROXY_URL!,
701
+ * getIdentityToken: () => identityTokenRef.current,
702
+ * issuerId: process.env.NEXT_PUBLIC_ISSUER_ID!,
703
+ * });
704
+ *
705
+ * const pimlicoClient = createPimlicoClient({ chain: base, transport: proxyTransport });
706
+ * const smartClient = createSmartAccountClient({
707
+ * client: publicClient,
708
+ * chain: base,
709
+ * account,
710
+ * paymaster: pimlicoClient,
711
+ * bundlerTransport: proxyTransport,
712
+ * });
713
+ * ```
714
+ */
715
+ declare function createPafiProxyTransport(params: PafiProxyTransportParams): HttpTransport;
716
+
541
717
  /**
542
718
  * Real `PointToken` ABI — matches the contract deployed on Base mainnet
543
719
  * (POINT at `0x7d25E7156E51F865D522fd3ef257a6B5DD41b97e`). Sourced from
@@ -1293,4 +1469,4 @@ declare class PafiSDK {
1293
1469
  signLoginMessage(message: string): Promise<Hex>;
1294
1470
  }
1295
1471
 
1296
- export { ApiError, BATCH_EXECUTOR_ABI, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET, BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA, BROKER_HASHES, BestQuote, type BuildPartialUserOpParams, type BuildPerpDepositWithGasDeductionParams, COMMON_POOLS, COMMON_TOKENS, CONTRACT_ADDRESSES, ChainConfig, type CheckEthAndBranchParams, ConfigurationError, type ContractAddresses, EIP712Signature, LoginMessageParams, MintRequest, type ModalOpenOptions, ORDERLY_VAULT_ABI, ORDERLY_VAULT_ADDRESSES, ORDERLY_VAULT_BASE_MAINNET, Operation, POINT_TOKEN_FACTORY_ADDRESSES, POINT_TOKEN_IMPL_ADDRESSES, POINT_TOKEN_POOLS, POINT_TOKEN_ABI as POINT_TOKEN_V2_ABI, PafiSDK, PafiSDKConfig, PafiSDKError, type PafiWebModalAdapter, type PafiWebModalHandle, PartialUserOperation, type PaymasterConfig, PointTokenDomainConfig, PoolKey, QuoteResult, ReceiverConsent, SUPPORTED_CHAINS, type SignatureStruct, SignatureVerification, SigningError, SimulationError, type SponsorshipScenario, type SubmissionPath, SwapSimulationResult, TOKEN_HASHES, UNIVERSAL_ROUTER_ADDRESSES, UserOperation, V4_QUOTER_ADDRESSES, type VaultDepositFE, _resetPaymasterConfigForTests, assembleUserOperation, buildPartialUserOperation, buildPerpDepositWithGasDeduction, burnRequestTypes, checkEthAndBranch, computeAccountId, encodeBatchExecute, erc20ApproveOp, erc20BurnOp, erc20TransferOp, getContractAddresses, getPafiWebModalAdapter, getPaymasterConfig, isPaymasterConfigured, mintRequestTypes, openPafiWebModal, openWebPopup, rawCallOp, receiverConsentTypes, setPafiWebModalAdapter, setPaymasterConfig, webPopupAdapter };
1472
+ export { ApiError, BATCH_EXECUTOR_ABI, BATCH_EXECUTOR_ADDRESS_BASE_MAINNET, BATCH_EXECUTOR_ADDRESS_BASE_SEPOLIA, BROKER_HASHES, BestQuote, type BuildDelegationUserOpParams, type BuildPartialUserOpParams, type BuildPerpDepositWithGasDeductionParams, COMMON_POOLS, COMMON_TOKENS, CONTRACT_ADDRESSES, ChainConfig, type CheckEthAndBranchParams, ConfigurationError, type ContractAddresses, EIP712Signature, LoginMessageParams, MintRequest, type ModalOpenOptions, ORDERLY_VAULT_ABI, ORDERLY_VAULT_ADDRESSES, ORDERLY_VAULT_BASE_MAINNET, Operation, POINT_TOKEN_FACTORY_ADDRESSES, POINT_TOKEN_IMPL_ADDRESSES, POINT_TOKEN_POOLS, POINT_TOKEN_ABI as POINT_TOKEN_V2_ABI, type PafiProxyTransportParams, PafiSDK, PafiSDKConfig, PafiSDKError, type PafiWebModalAdapter, type PafiWebModalHandle, PartialUserOperation, type PaymasterConfig, PointTokenDomainConfig, PoolKey, QuoteResult, ReceiverConsent, SUPPORTED_CHAINS, type SignatureStruct, SignatureVerification, SigningError, SimulationError, type SponsorshipScenario, type SubmissionPath, SwapSimulationResult, TOKEN_HASHES, UNIVERSAL_ROUTER_ADDRESSES, UserOperation, V4_QUOTER_ADDRESSES, type VaultDepositFE, _resetPaymasterConfigForTests, assembleUserOperation, buildDelegationUserOp, buildPartialUserOperation, buildPerpDepositWithGasDeduction, burnRequestTypes, checkDelegation, checkEthAndBranch, computeAccountId, createPafiProxyTransport, encodeBatchExecute, erc20ApproveOp, erc20BurnOp, erc20TransferOp, getAaNonce, getContractAddresses, getPafiWebModalAdapter, getPaymasterConfig, isDelegatedTo, isPaymasterConfigured, mintRequestTypes, openPafiWebModal, openWebPopup, parseEip7702DelegatedAddress, rawCallOp, receiverConsentTypes, setPafiWebModalAdapter, setPaymasterConfig, webPopupAdapter };
package/dist/index.js CHANGED
@@ -91,7 +91,7 @@ import {
91
91
  } from "./chunk-2PIXFXA2.js";
92
92
 
93
93
  // src/index.ts
94
- import { createPublicClient, http } from "viem";
94
+ import { createPublicClient, http as http2 } from "viem";
95
95
 
96
96
  // src/perp/buildPerpDepositWithGasDeduction.ts
97
97
  import { encodeFunctionData } from "viem";
@@ -280,6 +280,93 @@ async function checkEthAndBranch(params) {
280
280
  return balance >= required ? "normal" : "paymaster";
281
281
  }
282
282
 
283
+ // src/delegation/checkDelegation.ts
284
+ var EIP7702_MAGIC = "0xef0100";
285
+ function parseEip7702DelegatedAddress(code) {
286
+ if (!code || code === "0x" || code === "0x0") return null;
287
+ const normalized = code.toLowerCase();
288
+ const magic = EIP7702_MAGIC.toLowerCase();
289
+ const idx = normalized.indexOf(magic);
290
+ if (idx === -1) return null;
291
+ const raw = normalized.slice(idx + magic.length, idx + magic.length + 40);
292
+ if (raw.length !== 40) return null;
293
+ return `0x${raw}`;
294
+ }
295
+ async function checkDelegation(client, address) {
296
+ const code = await client.getCode({ address });
297
+ return parseEip7702DelegatedAddress(code);
298
+ }
299
+ async function isDelegatedTo(client, address, target) {
300
+ const impl = await checkDelegation(client, address);
301
+ if (!impl) return false;
302
+ return impl.toLowerCase() === target.toLowerCase();
303
+ }
304
+
305
+ // src/delegation/buildDelegationUserOp.ts
306
+ function buildDelegationUserOp(params) {
307
+ return buildPartialUserOperation({
308
+ sender: params.userAddress,
309
+ nonce: params.aaNonce,
310
+ operations: [
311
+ {
312
+ // Self-call with no data — triggers EIP-7702 delegation without
313
+ // executing any inner logic. The BatchExecutor.execute([]) call with
314
+ // an empty array would revert, so we target the EOA itself (which
315
+ // forwards to BatchExecutor that then no-ops on empty input).
316
+ target: params.userAddress,
317
+ value: 0n,
318
+ data: "0x"
319
+ }
320
+ ],
321
+ gasLimits: {
322
+ callGasLimit: params.gasLimits?.callGasLimit ?? 50000n,
323
+ verificationGasLimit: params.gasLimits?.verificationGasLimit ?? 150000n,
324
+ preVerificationGas: params.gasLimits?.preVerificationGas ?? 50000n
325
+ }
326
+ });
327
+ }
328
+ async function getAaNonce(client, userAddress) {
329
+ const ENTRY_POINT = "0x0000000071727De22E5E9d8BAf0edAc6f37da032";
330
+ const NONCE_ABI = [
331
+ {
332
+ inputs: [
333
+ { name: "sender", type: "address" },
334
+ { name: "key", type: "uint192" }
335
+ ],
336
+ name: "getNonce",
337
+ outputs: [{ name: "nonce", type: "uint256" }],
338
+ stateMutability: "view",
339
+ type: "function"
340
+ }
341
+ ];
342
+ return client.readContract({
343
+ address: ENTRY_POINT,
344
+ abi: NONCE_ABI,
345
+ functionName: "getNonce",
346
+ args: [userAddress, 0n]
347
+ });
348
+ }
349
+
350
+ // src/transport/proxyTransport.ts
351
+ import { http } from "viem";
352
+ function createPafiProxyTransport(params) {
353
+ const { proxyUrl, getIdentityToken, issuerId } = params;
354
+ return http(proxyUrl, {
355
+ fetchOptions: {},
356
+ // fetchFn intercepts every fetch call the viem http transport makes,
357
+ // injecting the auth headers before the request leaves the browser.
358
+ fetchFn: (input, init) => {
359
+ const headers = new Headers(init?.headers);
360
+ const token = getIdentityToken();
361
+ if (token) {
362
+ headers.set("authorization", `Bearer ${token}`);
363
+ }
364
+ headers.set("x-issuer-id", issuerId);
365
+ return fetch(input, { ...init, headers });
366
+ }
367
+ });
368
+ }
369
+
283
370
  // src/contracts/real/pointToken.ts
284
371
  import { parseAbi } from "viem";
285
372
  var POINT_TOKEN_ABI = parseAbi([
@@ -513,7 +600,7 @@ var PafiSDK = class {
513
600
  this._provider = config.provider;
514
601
  } else if (config.rpcUrl) {
515
602
  this._provider = createPublicClient({
516
- transport: http(config.rpcUrl)
603
+ transport: http2(config.rpcUrl)
517
604
  });
518
605
  }
519
606
  }
@@ -720,6 +807,7 @@ export {
720
807
  assembleUserOperation,
721
808
  buildAllPaths,
722
809
  buildBurnRequestTypedData,
810
+ buildDelegationUserOp,
723
811
  buildDomain,
724
812
  buildErc20ApprovalCalldata,
725
813
  buildMintRequestTypedData,
@@ -733,16 +821,19 @@ export {
733
821
  buildV4SwapInput,
734
822
  burnRequestTypes,
735
823
  checkAllowance,
824
+ checkDelegation,
736
825
  checkEthAndBranch,
737
826
  combineRoutes,
738
827
  computeAccountId,
739
828
  createLoginMessage,
829
+ createPafiProxyTransport,
740
830
  encodeBatchExecute,
741
831
  erc20Abi,
742
832
  erc20ApproveOp,
743
833
  erc20BurnOp,
744
834
  erc20TransferOp,
745
835
  findBestQuote,
836
+ getAaNonce,
746
837
  getContractAddresses,
747
838
  getIssuer2 as getIssuer,
748
839
  getMintRequestNonce,
@@ -754,6 +845,7 @@ export {
754
845
  getReceiverConsentNonce,
755
846
  getTokenName,
756
847
  isActiveIssuer,
848
+ isDelegatedTo,
757
849
  isMinter,
758
850
  isPaymasterConfigured,
759
851
  issuerRegistryAbi,
@@ -761,6 +853,7 @@ export {
761
853
  mintingOracleAbi,
762
854
  openPafiWebModal,
763
855
  openWebPopup,
856
+ parseEip7702DelegatedAddress,
764
857
  parseLoginMessage,
765
858
  permit2Abi,
766
859
  pointTokenAbi,