@pafi-dev/core 0.3.0-beta.7 → 0.3.0-beta.8
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.cjs +107 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +197 -1
- package/dist/index.d.ts +197 -1
- package/dist/index.js +103 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -538,6 +538,202 @@ interface CheckEthAndBranchParams {
|
|
|
538
538
|
*/
|
|
539
539
|
declare function checkEthAndBranch(params: CheckEthAndBranchParams): Promise<SubmissionPath>;
|
|
540
540
|
|
|
541
|
+
/**
|
|
542
|
+
* Identifies the user-flow scenario the sponsorship covers. Used by
|
|
543
|
+
* sponsor-relayer for per-scenario rate limits + by Privy verifier
|
|
544
|
+
* to log sponsorship reason.
|
|
545
|
+
*
|
|
546
|
+
* Keep in sync with `SponsorshipScenario` in the paymaster module —
|
|
547
|
+
* SponsorAuth replaces the Coinbase paymaster flow but reuses the
|
|
548
|
+
* scenario taxonomy.
|
|
549
|
+
*/
|
|
550
|
+
type SponsorAuthScenario = "mint" | "burn" | "swap" | "perp_deposit";
|
|
551
|
+
/**
|
|
552
|
+
* Canonical SponsorAuth payload — the EIP-712 message that PAFI
|
|
553
|
+
* sponsor-relayer signs and Privy native verifies before funding gas.
|
|
554
|
+
*
|
|
555
|
+
* See `SPONSOR_AUTH_DESIGN.md` for full architecture.
|
|
556
|
+
*
|
|
557
|
+
* ## Replay protection layers
|
|
558
|
+
*
|
|
559
|
+
* - `nonce` — per-(sender, scenario), allocated by sponsor-relayer
|
|
560
|
+
* - `expiresAt` — short window (60-120s recommended)
|
|
561
|
+
* - `callDataHash` — binds payload to ONE specific UserOp callData
|
|
562
|
+
* - `sender` — binds to one EOA
|
|
563
|
+
* - `chainId` — binds to one chain
|
|
564
|
+
*
|
|
565
|
+
* Mutation of any field invalidates the signature.
|
|
566
|
+
*/
|
|
567
|
+
interface SponsorAuthPayload {
|
|
568
|
+
chainId: number;
|
|
569
|
+
sender: Address;
|
|
570
|
+
/** keccak256(userOp.callData) — caller computes from the UserOp they intend to submit. */
|
|
571
|
+
callDataHash: Hex;
|
|
572
|
+
/** Per-(sender, scenario) monotonic counter from sponsor-relayer. */
|
|
573
|
+
nonce: bigint;
|
|
574
|
+
/** Unix seconds. After this, Privy verifier rejects. */
|
|
575
|
+
expiresAt: number;
|
|
576
|
+
scenario: SponsorAuthScenario;
|
|
577
|
+
/** Issuer that originated this sponsorship request (e.g. "gg56"). */
|
|
578
|
+
issuerId: string;
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Optional extension fields — keep separate so the canonical payload
|
|
582
|
+
* stays minimal. Privy verifier may or may not enforce these depending
|
|
583
|
+
* on dashboard config.
|
|
584
|
+
*/
|
|
585
|
+
interface SponsorAuthPayloadExtended extends SponsorAuthPayload {
|
|
586
|
+
/** Max gas (units) sponsor-relayer pre-approved. */
|
|
587
|
+
maxGasLimit?: bigint;
|
|
588
|
+
/** Max gas price (wei) sponsor-relayer pre-approved. */
|
|
589
|
+
maxGasPrice?: bigint;
|
|
590
|
+
/** Audit metadata — surfaced in logs only, not used for verification. */
|
|
591
|
+
intent?: {
|
|
592
|
+
amount?: string;
|
|
593
|
+
pointToken?: Address;
|
|
594
|
+
targetContract?: Address;
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* EIP-712 domain for SponsorAuth signatures.
|
|
599
|
+
*
|
|
600
|
+
* `verifyingContract` is `0x0` because verification is OFF-CHAIN
|
|
601
|
+
* (Privy native verifier reads sig + payload, recovers signer,
|
|
602
|
+
* compares with PAFI public key registered in Privy dashboard).
|
|
603
|
+
* The domain is still EIP-712 to leverage existing tooling.
|
|
604
|
+
*/
|
|
605
|
+
declare const SPONSOR_AUTH_DOMAIN_NAME: "PAFI SponsorAuth";
|
|
606
|
+
declare const SPONSOR_AUTH_DOMAIN_VERSION: "1";
|
|
607
|
+
/** EIP-712 typed-data shape — matches `SponsorAuthPayload` field order. */
|
|
608
|
+
declare const SPONSOR_AUTH_TYPES: {
|
|
609
|
+
readonly SponsorAuth: readonly [{
|
|
610
|
+
readonly name: "chainId";
|
|
611
|
+
readonly type: "uint256";
|
|
612
|
+
}, {
|
|
613
|
+
readonly name: "sender";
|
|
614
|
+
readonly type: "address";
|
|
615
|
+
}, {
|
|
616
|
+
readonly name: "callDataHash";
|
|
617
|
+
readonly type: "bytes32";
|
|
618
|
+
}, {
|
|
619
|
+
readonly name: "nonce";
|
|
620
|
+
readonly type: "uint256";
|
|
621
|
+
}, {
|
|
622
|
+
readonly name: "expiresAt";
|
|
623
|
+
readonly type: "uint256";
|
|
624
|
+
}, {
|
|
625
|
+
readonly name: "scenario";
|
|
626
|
+
readonly type: "string";
|
|
627
|
+
}, {
|
|
628
|
+
readonly name: "issuerId";
|
|
629
|
+
readonly type: "string";
|
|
630
|
+
}];
|
|
631
|
+
};
|
|
632
|
+
/**
|
|
633
|
+
* Build the EIP-712 domain object Privy verifier expects. Same
|
|
634
|
+
* `chainId` as the SponsorAuth payload.
|
|
635
|
+
*/
|
|
636
|
+
declare function buildSponsorAuthDomain(chainId: number): {
|
|
637
|
+
readonly name: "PAFI SponsorAuth";
|
|
638
|
+
readonly version: "1";
|
|
639
|
+
readonly chainId: number;
|
|
640
|
+
readonly verifyingContract: Address;
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Build the EIP-712 typed data object for a SponsorAuth payload.
|
|
645
|
+
* Returned shape is compatible with `walletClient.signTypedData()`,
|
|
646
|
+
* `viem.recoverTypedDataAddress()`, and any other EIP-712 tooling.
|
|
647
|
+
*
|
|
648
|
+
* Use this when you need the full typed-data object (e.g. to display
|
|
649
|
+
* to a hardware-wallet user, or to feed into an off-chain audit log).
|
|
650
|
+
* Most callers only need `signSponsorAuth` / `verifySponsorAuth` below.
|
|
651
|
+
*/
|
|
652
|
+
declare function buildSponsorAuthTypedData(payload: SponsorAuthPayload): {
|
|
653
|
+
domain: {
|
|
654
|
+
readonly name: "PAFI SponsorAuth";
|
|
655
|
+
readonly version: "1";
|
|
656
|
+
readonly chainId: number;
|
|
657
|
+
readonly verifyingContract: Address;
|
|
658
|
+
};
|
|
659
|
+
types: {
|
|
660
|
+
readonly SponsorAuth: readonly [{
|
|
661
|
+
readonly name: "chainId";
|
|
662
|
+
readonly type: "uint256";
|
|
663
|
+
}, {
|
|
664
|
+
readonly name: "sender";
|
|
665
|
+
readonly type: "address";
|
|
666
|
+
}, {
|
|
667
|
+
readonly name: "callDataHash";
|
|
668
|
+
readonly type: "bytes32";
|
|
669
|
+
}, {
|
|
670
|
+
readonly name: "nonce";
|
|
671
|
+
readonly type: "uint256";
|
|
672
|
+
}, {
|
|
673
|
+
readonly name: "expiresAt";
|
|
674
|
+
readonly type: "uint256";
|
|
675
|
+
}, {
|
|
676
|
+
readonly name: "scenario";
|
|
677
|
+
readonly type: "string";
|
|
678
|
+
}, {
|
|
679
|
+
readonly name: "issuerId";
|
|
680
|
+
readonly type: "string";
|
|
681
|
+
}];
|
|
682
|
+
};
|
|
683
|
+
primaryType: "SponsorAuth";
|
|
684
|
+
message: {
|
|
685
|
+
chainId: bigint;
|
|
686
|
+
sender: `0x${string}`;
|
|
687
|
+
callDataHash: `0x${string}`;
|
|
688
|
+
nonce: bigint;
|
|
689
|
+
expiresAt: bigint;
|
|
690
|
+
scenario: SponsorAuthScenario;
|
|
691
|
+
issuerId: string;
|
|
692
|
+
};
|
|
693
|
+
};
|
|
694
|
+
/**
|
|
695
|
+
* Sign a SponsorAuth payload using a viem `WalletClient`. Production
|
|
696
|
+
* sponsor-relayer should use a KMS-backed signer instead — this helper
|
|
697
|
+
* is for tests + local dev where you hold a raw private key.
|
|
698
|
+
*
|
|
699
|
+
* Returns the **serialized 65-byte signature** ready to put into
|
|
700
|
+
* `SponsorAuthResponse.sponsorAuth`.
|
|
701
|
+
*/
|
|
702
|
+
declare function signSponsorAuth(walletClient: WalletClient, payload: SponsorAuthPayload): Promise<Hex>;
|
|
703
|
+
/**
|
|
704
|
+
* Verify a SponsorAuth signature offline. Use to:
|
|
705
|
+
*
|
|
706
|
+
* - Smoke-test that sponsor-relayer's output is well-formed (FE)
|
|
707
|
+
* - Unit tests in SDK
|
|
708
|
+
* - Defense-in-depth check before submitting to Privy
|
|
709
|
+
*
|
|
710
|
+
* Privy verifier does the same check on their side — this is NOT a
|
|
711
|
+
* substitute for Privy verification. It exists so consumers can fail
|
|
712
|
+
* fast on a mangled sig before round-tripping through Privy.
|
|
713
|
+
*
|
|
714
|
+
* @param payload The exact payload PAFI BE returned
|
|
715
|
+
* @param signature The serialized signature (sponsorAuth field)
|
|
716
|
+
* @param expectedSigner PAFI's SponsorAuth signing-key address
|
|
717
|
+
* (registered in Privy dashboard)
|
|
718
|
+
*
|
|
719
|
+
* @returns `true` if signature recovers to `expectedSigner`,
|
|
720
|
+
* and the payload hasn't expired (`expiresAt > now`).
|
|
721
|
+
* Returns `false` on any failure — does NOT throw.
|
|
722
|
+
*/
|
|
723
|
+
declare function verifySponsorAuth(payload: SponsorAuthPayload, signature: Hex, expectedSigner: Address): Promise<{
|
|
724
|
+
ok: boolean;
|
|
725
|
+
reason?: "INVALID_SIGNER" | "EXPIRED" | "INVALID_SIGNATURE_FORMAT";
|
|
726
|
+
recoveredAddress?: Address;
|
|
727
|
+
}>;
|
|
728
|
+
/**
|
|
729
|
+
* Helper — compute `callDataHash` from a UserOperation's `callData`.
|
|
730
|
+
* Same hash function (`keccak256`) Privy verifier uses.
|
|
731
|
+
*
|
|
732
|
+
* Bind this hash into the SponsorAuth payload BEFORE signing, so the
|
|
733
|
+
* sig is invalid for any other UserOp.
|
|
734
|
+
*/
|
|
735
|
+
declare function computeCallDataHash(callData: Hex): Hex;
|
|
736
|
+
|
|
541
737
|
/**
|
|
542
738
|
* Real `PointToken` ABI — matches the contract deployed on Base mainnet
|
|
543
739
|
* (POINT at `0x7d25E7156E51F865D522fd3ef257a6B5DD41b97e`). Sourced from
|
|
@@ -1293,4 +1489,4 @@ declare class PafiSDK {
|
|
|
1293
1489
|
signLoginMessage(message: string): Promise<Hex>;
|
|
1294
1490
|
}
|
|
1295
1491
|
|
|
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 };
|
|
1492
|
+
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, SPONSOR_AUTH_DOMAIN_NAME, SPONSOR_AUTH_DOMAIN_VERSION, SPONSOR_AUTH_TYPES, SUPPORTED_CHAINS, type SignatureStruct, SignatureVerification, SigningError, SimulationError, type SponsorAuthPayload, type SponsorAuthPayloadExtended, type SponsorAuthScenario, type SponsorshipScenario, type SubmissionPath, SwapSimulationResult, TOKEN_HASHES, UNIVERSAL_ROUTER_ADDRESSES, UserOperation, V4_QUOTER_ADDRESSES, type VaultDepositFE, _resetPaymasterConfigForTests, assembleUserOperation, buildPartialUserOperation, buildPerpDepositWithGasDeduction, buildSponsorAuthDomain, buildSponsorAuthTypedData, burnRequestTypes, checkEthAndBranch, computeAccountId, computeCallDataHash, encodeBatchExecute, erc20ApproveOp, erc20BurnOp, erc20TransferOp, getContractAddresses, getPafiWebModalAdapter, getPaymasterConfig, isPaymasterConfigured, mintRequestTypes, openPafiWebModal, openWebPopup, rawCallOp, receiverConsentTypes, setPafiWebModalAdapter, setPaymasterConfig, signSponsorAuth, verifySponsorAuth, webPopupAdapter };
|
package/dist/index.d.ts
CHANGED
|
@@ -538,6 +538,202 @@ interface CheckEthAndBranchParams {
|
|
|
538
538
|
*/
|
|
539
539
|
declare function checkEthAndBranch(params: CheckEthAndBranchParams): Promise<SubmissionPath>;
|
|
540
540
|
|
|
541
|
+
/**
|
|
542
|
+
* Identifies the user-flow scenario the sponsorship covers. Used by
|
|
543
|
+
* sponsor-relayer for per-scenario rate limits + by Privy verifier
|
|
544
|
+
* to log sponsorship reason.
|
|
545
|
+
*
|
|
546
|
+
* Keep in sync with `SponsorshipScenario` in the paymaster module —
|
|
547
|
+
* SponsorAuth replaces the Coinbase paymaster flow but reuses the
|
|
548
|
+
* scenario taxonomy.
|
|
549
|
+
*/
|
|
550
|
+
type SponsorAuthScenario = "mint" | "burn" | "swap" | "perp_deposit";
|
|
551
|
+
/**
|
|
552
|
+
* Canonical SponsorAuth payload — the EIP-712 message that PAFI
|
|
553
|
+
* sponsor-relayer signs and Privy native verifies before funding gas.
|
|
554
|
+
*
|
|
555
|
+
* See `SPONSOR_AUTH_DESIGN.md` for full architecture.
|
|
556
|
+
*
|
|
557
|
+
* ## Replay protection layers
|
|
558
|
+
*
|
|
559
|
+
* - `nonce` — per-(sender, scenario), allocated by sponsor-relayer
|
|
560
|
+
* - `expiresAt` — short window (60-120s recommended)
|
|
561
|
+
* - `callDataHash` — binds payload to ONE specific UserOp callData
|
|
562
|
+
* - `sender` — binds to one EOA
|
|
563
|
+
* - `chainId` — binds to one chain
|
|
564
|
+
*
|
|
565
|
+
* Mutation of any field invalidates the signature.
|
|
566
|
+
*/
|
|
567
|
+
interface SponsorAuthPayload {
|
|
568
|
+
chainId: number;
|
|
569
|
+
sender: Address;
|
|
570
|
+
/** keccak256(userOp.callData) — caller computes from the UserOp they intend to submit. */
|
|
571
|
+
callDataHash: Hex;
|
|
572
|
+
/** Per-(sender, scenario) monotonic counter from sponsor-relayer. */
|
|
573
|
+
nonce: bigint;
|
|
574
|
+
/** Unix seconds. After this, Privy verifier rejects. */
|
|
575
|
+
expiresAt: number;
|
|
576
|
+
scenario: SponsorAuthScenario;
|
|
577
|
+
/** Issuer that originated this sponsorship request (e.g. "gg56"). */
|
|
578
|
+
issuerId: string;
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* Optional extension fields — keep separate so the canonical payload
|
|
582
|
+
* stays minimal. Privy verifier may or may not enforce these depending
|
|
583
|
+
* on dashboard config.
|
|
584
|
+
*/
|
|
585
|
+
interface SponsorAuthPayloadExtended extends SponsorAuthPayload {
|
|
586
|
+
/** Max gas (units) sponsor-relayer pre-approved. */
|
|
587
|
+
maxGasLimit?: bigint;
|
|
588
|
+
/** Max gas price (wei) sponsor-relayer pre-approved. */
|
|
589
|
+
maxGasPrice?: bigint;
|
|
590
|
+
/** Audit metadata — surfaced in logs only, not used for verification. */
|
|
591
|
+
intent?: {
|
|
592
|
+
amount?: string;
|
|
593
|
+
pointToken?: Address;
|
|
594
|
+
targetContract?: Address;
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
/**
|
|
598
|
+
* EIP-712 domain for SponsorAuth signatures.
|
|
599
|
+
*
|
|
600
|
+
* `verifyingContract` is `0x0` because verification is OFF-CHAIN
|
|
601
|
+
* (Privy native verifier reads sig + payload, recovers signer,
|
|
602
|
+
* compares with PAFI public key registered in Privy dashboard).
|
|
603
|
+
* The domain is still EIP-712 to leverage existing tooling.
|
|
604
|
+
*/
|
|
605
|
+
declare const SPONSOR_AUTH_DOMAIN_NAME: "PAFI SponsorAuth";
|
|
606
|
+
declare const SPONSOR_AUTH_DOMAIN_VERSION: "1";
|
|
607
|
+
/** EIP-712 typed-data shape — matches `SponsorAuthPayload` field order. */
|
|
608
|
+
declare const SPONSOR_AUTH_TYPES: {
|
|
609
|
+
readonly SponsorAuth: readonly [{
|
|
610
|
+
readonly name: "chainId";
|
|
611
|
+
readonly type: "uint256";
|
|
612
|
+
}, {
|
|
613
|
+
readonly name: "sender";
|
|
614
|
+
readonly type: "address";
|
|
615
|
+
}, {
|
|
616
|
+
readonly name: "callDataHash";
|
|
617
|
+
readonly type: "bytes32";
|
|
618
|
+
}, {
|
|
619
|
+
readonly name: "nonce";
|
|
620
|
+
readonly type: "uint256";
|
|
621
|
+
}, {
|
|
622
|
+
readonly name: "expiresAt";
|
|
623
|
+
readonly type: "uint256";
|
|
624
|
+
}, {
|
|
625
|
+
readonly name: "scenario";
|
|
626
|
+
readonly type: "string";
|
|
627
|
+
}, {
|
|
628
|
+
readonly name: "issuerId";
|
|
629
|
+
readonly type: "string";
|
|
630
|
+
}];
|
|
631
|
+
};
|
|
632
|
+
/**
|
|
633
|
+
* Build the EIP-712 domain object Privy verifier expects. Same
|
|
634
|
+
* `chainId` as the SponsorAuth payload.
|
|
635
|
+
*/
|
|
636
|
+
declare function buildSponsorAuthDomain(chainId: number): {
|
|
637
|
+
readonly name: "PAFI SponsorAuth";
|
|
638
|
+
readonly version: "1";
|
|
639
|
+
readonly chainId: number;
|
|
640
|
+
readonly verifyingContract: Address;
|
|
641
|
+
};
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Build the EIP-712 typed data object for a SponsorAuth payload.
|
|
645
|
+
* Returned shape is compatible with `walletClient.signTypedData()`,
|
|
646
|
+
* `viem.recoverTypedDataAddress()`, and any other EIP-712 tooling.
|
|
647
|
+
*
|
|
648
|
+
* Use this when you need the full typed-data object (e.g. to display
|
|
649
|
+
* to a hardware-wallet user, or to feed into an off-chain audit log).
|
|
650
|
+
* Most callers only need `signSponsorAuth` / `verifySponsorAuth` below.
|
|
651
|
+
*/
|
|
652
|
+
declare function buildSponsorAuthTypedData(payload: SponsorAuthPayload): {
|
|
653
|
+
domain: {
|
|
654
|
+
readonly name: "PAFI SponsorAuth";
|
|
655
|
+
readonly version: "1";
|
|
656
|
+
readonly chainId: number;
|
|
657
|
+
readonly verifyingContract: Address;
|
|
658
|
+
};
|
|
659
|
+
types: {
|
|
660
|
+
readonly SponsorAuth: readonly [{
|
|
661
|
+
readonly name: "chainId";
|
|
662
|
+
readonly type: "uint256";
|
|
663
|
+
}, {
|
|
664
|
+
readonly name: "sender";
|
|
665
|
+
readonly type: "address";
|
|
666
|
+
}, {
|
|
667
|
+
readonly name: "callDataHash";
|
|
668
|
+
readonly type: "bytes32";
|
|
669
|
+
}, {
|
|
670
|
+
readonly name: "nonce";
|
|
671
|
+
readonly type: "uint256";
|
|
672
|
+
}, {
|
|
673
|
+
readonly name: "expiresAt";
|
|
674
|
+
readonly type: "uint256";
|
|
675
|
+
}, {
|
|
676
|
+
readonly name: "scenario";
|
|
677
|
+
readonly type: "string";
|
|
678
|
+
}, {
|
|
679
|
+
readonly name: "issuerId";
|
|
680
|
+
readonly type: "string";
|
|
681
|
+
}];
|
|
682
|
+
};
|
|
683
|
+
primaryType: "SponsorAuth";
|
|
684
|
+
message: {
|
|
685
|
+
chainId: bigint;
|
|
686
|
+
sender: `0x${string}`;
|
|
687
|
+
callDataHash: `0x${string}`;
|
|
688
|
+
nonce: bigint;
|
|
689
|
+
expiresAt: bigint;
|
|
690
|
+
scenario: SponsorAuthScenario;
|
|
691
|
+
issuerId: string;
|
|
692
|
+
};
|
|
693
|
+
};
|
|
694
|
+
/**
|
|
695
|
+
* Sign a SponsorAuth payload using a viem `WalletClient`. Production
|
|
696
|
+
* sponsor-relayer should use a KMS-backed signer instead — this helper
|
|
697
|
+
* is for tests + local dev where you hold a raw private key.
|
|
698
|
+
*
|
|
699
|
+
* Returns the **serialized 65-byte signature** ready to put into
|
|
700
|
+
* `SponsorAuthResponse.sponsorAuth`.
|
|
701
|
+
*/
|
|
702
|
+
declare function signSponsorAuth(walletClient: WalletClient, payload: SponsorAuthPayload): Promise<Hex>;
|
|
703
|
+
/**
|
|
704
|
+
* Verify a SponsorAuth signature offline. Use to:
|
|
705
|
+
*
|
|
706
|
+
* - Smoke-test that sponsor-relayer's output is well-formed (FE)
|
|
707
|
+
* - Unit tests in SDK
|
|
708
|
+
* - Defense-in-depth check before submitting to Privy
|
|
709
|
+
*
|
|
710
|
+
* Privy verifier does the same check on their side — this is NOT a
|
|
711
|
+
* substitute for Privy verification. It exists so consumers can fail
|
|
712
|
+
* fast on a mangled sig before round-tripping through Privy.
|
|
713
|
+
*
|
|
714
|
+
* @param payload The exact payload PAFI BE returned
|
|
715
|
+
* @param signature The serialized signature (sponsorAuth field)
|
|
716
|
+
* @param expectedSigner PAFI's SponsorAuth signing-key address
|
|
717
|
+
* (registered in Privy dashboard)
|
|
718
|
+
*
|
|
719
|
+
* @returns `true` if signature recovers to `expectedSigner`,
|
|
720
|
+
* and the payload hasn't expired (`expiresAt > now`).
|
|
721
|
+
* Returns `false` on any failure — does NOT throw.
|
|
722
|
+
*/
|
|
723
|
+
declare function verifySponsorAuth(payload: SponsorAuthPayload, signature: Hex, expectedSigner: Address): Promise<{
|
|
724
|
+
ok: boolean;
|
|
725
|
+
reason?: "INVALID_SIGNER" | "EXPIRED" | "INVALID_SIGNATURE_FORMAT";
|
|
726
|
+
recoveredAddress?: Address;
|
|
727
|
+
}>;
|
|
728
|
+
/**
|
|
729
|
+
* Helper — compute `callDataHash` from a UserOperation's `callData`.
|
|
730
|
+
* Same hash function (`keccak256`) Privy verifier uses.
|
|
731
|
+
*
|
|
732
|
+
* Bind this hash into the SponsorAuth payload BEFORE signing, so the
|
|
733
|
+
* sig is invalid for any other UserOp.
|
|
734
|
+
*/
|
|
735
|
+
declare function computeCallDataHash(callData: Hex): Hex;
|
|
736
|
+
|
|
541
737
|
/**
|
|
542
738
|
* Real `PointToken` ABI — matches the contract deployed on Base mainnet
|
|
543
739
|
* (POINT at `0x7d25E7156E51F865D522fd3ef257a6B5DD41b97e`). Sourced from
|
|
@@ -1293,4 +1489,4 @@ declare class PafiSDK {
|
|
|
1293
1489
|
signLoginMessage(message: string): Promise<Hex>;
|
|
1294
1490
|
}
|
|
1295
1491
|
|
|
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 };
|
|
1492
|
+
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, SPONSOR_AUTH_DOMAIN_NAME, SPONSOR_AUTH_DOMAIN_VERSION, SPONSOR_AUTH_TYPES, SUPPORTED_CHAINS, type SignatureStruct, SignatureVerification, SigningError, SimulationError, type SponsorAuthPayload, type SponsorAuthPayloadExtended, type SponsorAuthScenario, type SponsorshipScenario, type SubmissionPath, SwapSimulationResult, TOKEN_HASHES, UNIVERSAL_ROUTER_ADDRESSES, UserOperation, V4_QUOTER_ADDRESSES, type VaultDepositFE, _resetPaymasterConfigForTests, assembleUserOperation, buildPartialUserOperation, buildPerpDepositWithGasDeduction, buildSponsorAuthDomain, buildSponsorAuthTypedData, burnRequestTypes, checkEthAndBranch, computeAccountId, computeCallDataHash, encodeBatchExecute, erc20ApproveOp, erc20BurnOp, erc20TransferOp, getContractAddresses, getPafiWebModalAdapter, getPaymasterConfig, isPaymasterConfigured, mintRequestTypes, openPafiWebModal, openWebPopup, rawCallOp, receiverConsentTypes, setPafiWebModalAdapter, setPaymasterConfig, signSponsorAuth, verifySponsorAuth, webPopupAdapter };
|
package/dist/index.js
CHANGED
|
@@ -280,6 +280,101 @@ async function checkEthAndBranch(params) {
|
|
|
280
280
|
return balance >= required ? "normal" : "paymaster";
|
|
281
281
|
}
|
|
282
282
|
|
|
283
|
+
// src/sponsor-auth/types.ts
|
|
284
|
+
var SPONSOR_AUTH_DOMAIN_NAME = "PAFI SponsorAuth";
|
|
285
|
+
var SPONSOR_AUTH_DOMAIN_VERSION = "1";
|
|
286
|
+
var SPONSOR_AUTH_TYPES = {
|
|
287
|
+
SponsorAuth: [
|
|
288
|
+
{ name: "chainId", type: "uint256" },
|
|
289
|
+
{ name: "sender", type: "address" },
|
|
290
|
+
{ name: "callDataHash", type: "bytes32" },
|
|
291
|
+
{ name: "nonce", type: "uint256" },
|
|
292
|
+
{ name: "expiresAt", type: "uint256" },
|
|
293
|
+
{ name: "scenario", type: "string" },
|
|
294
|
+
{ name: "issuerId", type: "string" }
|
|
295
|
+
]
|
|
296
|
+
};
|
|
297
|
+
function buildSponsorAuthDomain(chainId) {
|
|
298
|
+
return {
|
|
299
|
+
name: SPONSOR_AUTH_DOMAIN_NAME,
|
|
300
|
+
version: SPONSOR_AUTH_DOMAIN_VERSION,
|
|
301
|
+
chainId,
|
|
302
|
+
verifyingContract: "0x0000000000000000000000000000000000000000"
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// src/sponsor-auth/sign.ts
|
|
307
|
+
import {
|
|
308
|
+
keccak256 as keccak2562,
|
|
309
|
+
parseSignature,
|
|
310
|
+
recoverTypedDataAddress
|
|
311
|
+
} from "viem";
|
|
312
|
+
function buildSponsorAuthTypedData(payload) {
|
|
313
|
+
return {
|
|
314
|
+
domain: buildSponsorAuthDomain(payload.chainId),
|
|
315
|
+
types: SPONSOR_AUTH_TYPES,
|
|
316
|
+
primaryType: "SponsorAuth",
|
|
317
|
+
// viem strictly types uint256 fields as `bigint`. Our payload keeps
|
|
318
|
+
// `chainId` + `expiresAt` as `number` for ergonomic JS use; cast
|
|
319
|
+
// here at the EIP-712 boundary. Runtime conversion handled by viem.
|
|
320
|
+
message: toEip712Message(payload)
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
async function signSponsorAuth(walletClient, payload) {
|
|
324
|
+
return walletClient.signTypedData({
|
|
325
|
+
account: walletClient.account,
|
|
326
|
+
domain: buildSponsorAuthDomain(payload.chainId),
|
|
327
|
+
types: SPONSOR_AUTH_TYPES,
|
|
328
|
+
primaryType: "SponsorAuth",
|
|
329
|
+
// See note in buildSponsorAuthTypedData about the cast.
|
|
330
|
+
message: toEip712Message(payload)
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
async function verifySponsorAuth(payload, signature, expectedSigner) {
|
|
334
|
+
try {
|
|
335
|
+
parseSignature(signature);
|
|
336
|
+
} catch {
|
|
337
|
+
return { ok: false, reason: "INVALID_SIGNATURE_FORMAT" };
|
|
338
|
+
}
|
|
339
|
+
if (payload.expiresAt < Math.floor(Date.now() / 1e3)) {
|
|
340
|
+
return { ok: false, reason: "EXPIRED" };
|
|
341
|
+
}
|
|
342
|
+
let recovered;
|
|
343
|
+
try {
|
|
344
|
+
recovered = await recoverTypedDataAddress({
|
|
345
|
+
domain: buildSponsorAuthDomain(payload.chainId),
|
|
346
|
+
types: SPONSOR_AUTH_TYPES,
|
|
347
|
+
primaryType: "SponsorAuth",
|
|
348
|
+
message: toEip712Message(payload),
|
|
349
|
+
signature
|
|
350
|
+
});
|
|
351
|
+
} catch {
|
|
352
|
+
return { ok: false, reason: "INVALID_SIGNATURE_FORMAT" };
|
|
353
|
+
}
|
|
354
|
+
if (recovered.toLowerCase() !== expectedSigner.toLowerCase()) {
|
|
355
|
+
return {
|
|
356
|
+
ok: false,
|
|
357
|
+
reason: "INVALID_SIGNER",
|
|
358
|
+
recoveredAddress: recovered
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
return { ok: true, recoveredAddress: recovered };
|
|
362
|
+
}
|
|
363
|
+
function computeCallDataHash(callData) {
|
|
364
|
+
return keccak2562(callData);
|
|
365
|
+
}
|
|
366
|
+
function toEip712Message(payload) {
|
|
367
|
+
return {
|
|
368
|
+
chainId: BigInt(payload.chainId),
|
|
369
|
+
sender: payload.sender,
|
|
370
|
+
callDataHash: payload.callDataHash,
|
|
371
|
+
nonce: payload.nonce,
|
|
372
|
+
expiresAt: BigInt(payload.expiresAt),
|
|
373
|
+
scenario: payload.scenario,
|
|
374
|
+
issuerId: payload.issuerId
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
|
|
283
378
|
// src/contracts/real/pointToken.ts
|
|
284
379
|
import { parseAbi } from "viem";
|
|
285
380
|
var POINT_TOKEN_ABI = parseAbi([
|
|
@@ -706,6 +801,9 @@ export {
|
|
|
706
801
|
PafiSDK,
|
|
707
802
|
PafiSDKError,
|
|
708
803
|
SETTLE_ALL,
|
|
804
|
+
SPONSOR_AUTH_DOMAIN_NAME,
|
|
805
|
+
SPONSOR_AUTH_DOMAIN_VERSION,
|
|
806
|
+
SPONSOR_AUTH_TYPES,
|
|
709
807
|
SUPPORTED_CHAINS,
|
|
710
808
|
SWAP_EXACT_IN,
|
|
711
809
|
SigningError,
|
|
@@ -727,6 +825,8 @@ export {
|
|
|
727
825
|
buildPermit2ApprovalCalldata,
|
|
728
826
|
buildPerpDepositWithGasDeduction,
|
|
729
827
|
buildReceiverConsentTypedData,
|
|
828
|
+
buildSponsorAuthDomain,
|
|
829
|
+
buildSponsorAuthTypedData,
|
|
730
830
|
buildSwapFromQuote,
|
|
731
831
|
buildSwapWithGasDeduction,
|
|
732
832
|
buildUniversalRouterExecuteArgs,
|
|
@@ -736,6 +836,7 @@ export {
|
|
|
736
836
|
checkEthAndBranch,
|
|
737
837
|
combineRoutes,
|
|
738
838
|
computeAccountId,
|
|
839
|
+
computeCallDataHash,
|
|
739
840
|
createLoginMessage,
|
|
740
841
|
encodeBatchExecute,
|
|
741
842
|
erc20Abi,
|
|
@@ -775,6 +876,7 @@ export {
|
|
|
775
876
|
signBurnRequest,
|
|
776
877
|
signMintRequest,
|
|
777
878
|
signReceiverConsent,
|
|
879
|
+
signSponsorAuth,
|
|
778
880
|
simulateSwap,
|
|
779
881
|
universalRouterAbi,
|
|
780
882
|
v4QuoterAbi,
|
|
@@ -783,6 +885,7 @@ export {
|
|
|
783
885
|
verifyMintCap,
|
|
784
886
|
verifyMintRequest,
|
|
785
887
|
verifyReceiverConsent,
|
|
888
|
+
verifySponsorAuth,
|
|
786
889
|
webPopupAdapter
|
|
787
890
|
};
|
|
788
891
|
//# sourceMappingURL=index.js.map
|