@pafi-dev/issuer 0.7.5 → 0.7.7
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 +128 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +79 -49
- package/dist/index.d.ts +79 -49
- package/dist/index.js +125 -63
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PafiSdkError, SdkErrorHttpStatus, PointTokenDomainConfig, PartialUserOperation, BurnRequest, PoolKey, UserOpTypedData, decodeBatchExecuteCalls, BROKER_HASHES,
|
|
1
|
+
import { PafiSdkError, SdkErrorHttpStatus, PointTokenDomainConfig, PartialUserOperation, BurnRequest, PoolKey, UserOpTypedData, decodeBatchExecuteCalls, BROKER_HASHES, BuiltSponsorAuth, ENTRY_POINT_V08 } from '@pafi-dev/core';
|
|
2
2
|
export { PAFI_SUBGRAPH_URL, PafiSdkError, SdkErrorHttpStatus, ValidationError } from '@pafi-dev/core';
|
|
3
3
|
import { Address, Hex, PublicClient, WalletClient } from 'viem';
|
|
4
4
|
|
|
@@ -1481,6 +1481,25 @@ interface PendingUserOpEntry {
|
|
|
1481
1481
|
preVerificationGas: string;
|
|
1482
1482
|
userOpHash: Hex;
|
|
1483
1483
|
};
|
|
1484
|
+
/**
|
|
1485
|
+
* EIP-7702 authorization tuple — present only on the `delegate`
|
|
1486
|
+
* scenario where the UserOp anchors the EOA's one-time delegation
|
|
1487
|
+
* to a 7702 implementation. Embedded into the eth_sendUserOperation
|
|
1488
|
+
* payload at submit time so Pimlico bundler applies the bytecode
|
|
1489
|
+
* atomically with the UserOp execution. Pre-computed at prepare
|
|
1490
|
+
* time from the user's `signAuthorization` signature so submit
|
|
1491
|
+
* doesn't need to re-derive it.
|
|
1492
|
+
*
|
|
1493
|
+
* v0.7.7 — added per delegate-flow refactor (mobile prepare/submit).
|
|
1494
|
+
*/
|
|
1495
|
+
eip7702Auth?: {
|
|
1496
|
+
chainId: string;
|
|
1497
|
+
address: string;
|
|
1498
|
+
nonce: string;
|
|
1499
|
+
r: string;
|
|
1500
|
+
s: string;
|
|
1501
|
+
yParity: string;
|
|
1502
|
+
};
|
|
1484
1503
|
}
|
|
1485
1504
|
/**
|
|
1486
1505
|
* Storage backend for pending UserOps in the mobile prepare/submit pattern.
|
|
@@ -1969,55 +1988,30 @@ declare class PerpDepositHandler {
|
|
|
1969
1988
|
handle(request: PerpDepositRequest): Promise<PerpDepositResponse>;
|
|
1970
1989
|
}
|
|
1971
1990
|
|
|
1972
|
-
/**
|
|
1973
|
-
* Pure mechanics for the EIP-7702 delegation submit flow. Builds the
|
|
1974
|
-
* delegation-anchor UserOp via `buildDelegationUserOp` (self-call EOA
|
|
1975
|
-
* with empty calldata), attaches paymaster sponsorship, splits the
|
|
1976
|
-
* user's authorization signature into the JSON-RPC tuple, and relays
|
|
1977
|
-
* via the PAFI sponsor-relayer.
|
|
1978
|
-
*
|
|
1979
|
-
* The UserOp itself is a no-op — a self-call to the user's EOA with
|
|
1980
|
-
* `data: "0x"`. The work is in the `eip7702Auth` object: the bundler
|
|
1981
|
-
* picks it up, runs the EIP-7702 path, and installs the delegation on
|
|
1982
|
-
* the user's EOA atomically with the (no-op) UserOp.
|
|
1983
|
-
*
|
|
1984
|
-
* v0.7.1 — switched from `encodeBatchExecute([])` (which throws
|
|
1985
|
-
* "operations array must not be empty") to `buildDelegationUserOp`
|
|
1986
|
-
* (self-call pattern). See SDK_CORE_TRADING_AUDIT.md C1.
|
|
1987
|
-
*
|
|
1988
|
-
* Throws the same `BundlerNotConfiguredError` / `BundlerRejectedError`
|
|
1989
|
-
* as other relay paths so issuer controllers can use one error mapper.
|
|
1990
|
-
*/
|
|
1991
1991
|
interface HandleDelegateSubmitParams {
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
/** 65-byte secp256k1 signature over the EIP-7702 authorization hash. */
|
|
1999
|
-
authSig: Hex | string;
|
|
2000
|
-
/** EIP-1559 fees from `provider.estimateFeesPerGas()` (or RPC equivalent). */
|
|
2001
|
-
fees: {
|
|
2002
|
-
maxFeePerGas?: bigint;
|
|
2003
|
-
maxPriorityFeePerGas?: bigint;
|
|
2004
|
-
};
|
|
1992
|
+
lockId: string;
|
|
1993
|
+
/** Authenticated user EOA — must match the entry's `sender`. */
|
|
1994
|
+
authenticatedAddress: Address;
|
|
1995
|
+
/** User signature over the persisted userOpHash. */
|
|
1996
|
+
userOpSig: Hex;
|
|
1997
|
+
store: IPendingUserOpStore;
|
|
2005
1998
|
pafiBackendClient?: PafiBackendClient | null;
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
gasLimits?: {
|
|
2009
|
-
callGasLimit?: bigint;
|
|
2010
|
-
verificationGasLimit?: bigint;
|
|
2011
|
-
preVerificationGas?: bigint;
|
|
2012
|
-
};
|
|
1999
|
+
/** Defaults to `ENTRY_POINT_V08`. */
|
|
2000
|
+
entryPoint?: string;
|
|
2013
2001
|
}
|
|
2014
2002
|
interface HandleDelegateSubmitResult {
|
|
2015
2003
|
userOpHash: Hex;
|
|
2016
|
-
/** True when paymaster sponsorship was applied (gas is free). */
|
|
2017
|
-
isSponsored: boolean;
|
|
2018
|
-
/** The authorization tuple actually sent to the bundler. */
|
|
2019
|
-
authorization: Eip7702AuthorizationJsonRpc;
|
|
2020
2004
|
}
|
|
2005
|
+
/**
|
|
2006
|
+
* Retrieve the persisted delegate UserOp, embed the user's signature,
|
|
2007
|
+
* and submit to the bundler with the cached `eip7702Auth` field.
|
|
2008
|
+
*
|
|
2009
|
+
* Throws:
|
|
2010
|
+
* - `PendingUserOpNotFoundError` — entry expired or already submitted (404)
|
|
2011
|
+
* - `PendingUserOpForbiddenError` — sender mismatch (403)
|
|
2012
|
+
* - `BundlerNotConfiguredError` — `pafiBackendClient` missing (503)
|
|
2013
|
+
* - `BundlerRejectedError` — bundler rejected the UserOp (422)
|
|
2014
|
+
*/
|
|
2021
2015
|
declare function handleDelegateSubmit(params: HandleDelegateSubmitParams): Promise<HandleDelegateSubmitResult>;
|
|
2022
2016
|
|
|
2023
2017
|
/**
|
|
@@ -2312,7 +2306,24 @@ interface DelegateStatusDto {
|
|
|
2312
2306
|
batchExecutorAddress: Address;
|
|
2313
2307
|
}
|
|
2314
2308
|
interface DelegatePrepareDto {
|
|
2315
|
-
|
|
2309
|
+
/**
|
|
2310
|
+
* v0.7.7 — refactored to mobile prepare/submit pattern. Mobile signs
|
|
2311
|
+
* the EIP-7702 authorization LOCALLY (Privy `signAuthorization`),
|
|
2312
|
+
* then signs `userOpHash` (or `typedData`) BEFORE submit. See
|
|
2313
|
+
* `handleDelegatePrepare` for rationale.
|
|
2314
|
+
*
|
|
2315
|
+
* Pre-v0.7.7 callers expected `{ authorizationHash, delegationNonce,
|
|
2316
|
+
* batchExecutorAddress, chainId }` — `delegationNonce` +
|
|
2317
|
+
* `batchExecutorAddress` retained for back-compat so mobile can
|
|
2318
|
+
* compute the authorization hash if needed; `authorizationHash`
|
|
2319
|
+
* removed (mobile's Privy hook computes it locally).
|
|
2320
|
+
*/
|
|
2321
|
+
lockId: string;
|
|
2322
|
+
userOpHash: Hex;
|
|
2323
|
+
typedData: SerializedUserOpTypedData;
|
|
2324
|
+
expiresInSeconds: number;
|
|
2325
|
+
isSponsored: boolean;
|
|
2326
|
+
/** Echoed for mobile to recompute the authorization hash if desired. */
|
|
2316
2327
|
delegationNonce: string;
|
|
2317
2328
|
batchExecutorAddress: Address;
|
|
2318
2329
|
chainId: number;
|
|
@@ -2379,13 +2390,32 @@ declare class IssuerApiAdapter {
|
|
|
2379
2390
|
claimStatus(authenticatedAddress: Address, lockId: string): Promise<MintStatusResponse>;
|
|
2380
2391
|
redeemStatus(authenticatedAddress: Address, lockId: string): Promise<BurnStatusResponse>;
|
|
2381
2392
|
delegateStatus(authenticatedAddress: Address, chainId: number): Promise<DelegateStatusDto>;
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2393
|
+
/**
|
|
2394
|
+
* Build the delegation-anchor UserOp + obtain paymaster sponsorship
|
|
2395
|
+
* + persist as a pending entry. Mobile must:
|
|
2396
|
+
*
|
|
2397
|
+
* 1. Sign EIP-7702 authorization LOCALLY (Privy `signAuthorization`
|
|
2398
|
+
* with `{contractAddress: batchExecutorAddress, chainId,
|
|
2399
|
+
* nonce: delegationNonce}`) → 65-byte authSig hex.
|
|
2400
|
+
* 2. POST `/delegate/prepare` with `{ chainId, delegationNonce,
|
|
2401
|
+
* authSig }` → this method.
|
|
2402
|
+
* 3. Sign returned `userOpHash` LOCALLY (`signTypedData(typedData)`).
|
|
2403
|
+
* 4. POST `/delegate/submit` with `{ lockId, userOpSig }`.
|
|
2404
|
+
*
|
|
2405
|
+
* v0.7.7 — replaces single-shot delegateSubmit that tried to relay
|
|
2406
|
+
* a UserOp with empty `signature: "0x"` (Simple7702Account's
|
|
2407
|
+
* validateUserOp reverts `ECDSAInvalidSignatureLength` 0xfce698f7).
|
|
2408
|
+
*/
|
|
2409
|
+
delegatePrepare(authenticatedAddress: Address, input: {
|
|
2385
2410
|
chainId: number;
|
|
2386
2411
|
delegationNonce: bigint;
|
|
2387
|
-
aaNonce: bigint;
|
|
2388
2412
|
authSig: Hex | string;
|
|
2413
|
+
aaNonce: bigint;
|
|
2414
|
+
}): Promise<DelegatePrepareDto>;
|
|
2415
|
+
delegateSubmit(input: {
|
|
2416
|
+
authenticatedAddress: Address;
|
|
2417
|
+
lockId: string;
|
|
2418
|
+
userOpSig: Hex;
|
|
2389
2419
|
}): Promise<MobileSubmitDto>;
|
|
2390
2420
|
/**
|
|
2391
2421
|
* Build + sign a SponsorAuth payload. Returns `undefined` when no
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PafiSdkError, SdkErrorHttpStatus, PointTokenDomainConfig, PartialUserOperation, BurnRequest, PoolKey, UserOpTypedData, decodeBatchExecuteCalls, BROKER_HASHES,
|
|
1
|
+
import { PafiSdkError, SdkErrorHttpStatus, PointTokenDomainConfig, PartialUserOperation, BurnRequest, PoolKey, UserOpTypedData, decodeBatchExecuteCalls, BROKER_HASHES, BuiltSponsorAuth, ENTRY_POINT_V08 } from '@pafi-dev/core';
|
|
2
2
|
export { PAFI_SUBGRAPH_URL, PafiSdkError, SdkErrorHttpStatus, ValidationError } from '@pafi-dev/core';
|
|
3
3
|
import { Address, Hex, PublicClient, WalletClient } from 'viem';
|
|
4
4
|
|
|
@@ -1481,6 +1481,25 @@ interface PendingUserOpEntry {
|
|
|
1481
1481
|
preVerificationGas: string;
|
|
1482
1482
|
userOpHash: Hex;
|
|
1483
1483
|
};
|
|
1484
|
+
/**
|
|
1485
|
+
* EIP-7702 authorization tuple — present only on the `delegate`
|
|
1486
|
+
* scenario where the UserOp anchors the EOA's one-time delegation
|
|
1487
|
+
* to a 7702 implementation. Embedded into the eth_sendUserOperation
|
|
1488
|
+
* payload at submit time so Pimlico bundler applies the bytecode
|
|
1489
|
+
* atomically with the UserOp execution. Pre-computed at prepare
|
|
1490
|
+
* time from the user's `signAuthorization` signature so submit
|
|
1491
|
+
* doesn't need to re-derive it.
|
|
1492
|
+
*
|
|
1493
|
+
* v0.7.7 — added per delegate-flow refactor (mobile prepare/submit).
|
|
1494
|
+
*/
|
|
1495
|
+
eip7702Auth?: {
|
|
1496
|
+
chainId: string;
|
|
1497
|
+
address: string;
|
|
1498
|
+
nonce: string;
|
|
1499
|
+
r: string;
|
|
1500
|
+
s: string;
|
|
1501
|
+
yParity: string;
|
|
1502
|
+
};
|
|
1484
1503
|
}
|
|
1485
1504
|
/**
|
|
1486
1505
|
* Storage backend for pending UserOps in the mobile prepare/submit pattern.
|
|
@@ -1969,55 +1988,30 @@ declare class PerpDepositHandler {
|
|
|
1969
1988
|
handle(request: PerpDepositRequest): Promise<PerpDepositResponse>;
|
|
1970
1989
|
}
|
|
1971
1990
|
|
|
1972
|
-
/**
|
|
1973
|
-
* Pure mechanics for the EIP-7702 delegation submit flow. Builds the
|
|
1974
|
-
* delegation-anchor UserOp via `buildDelegationUserOp` (self-call EOA
|
|
1975
|
-
* with empty calldata), attaches paymaster sponsorship, splits the
|
|
1976
|
-
* user's authorization signature into the JSON-RPC tuple, and relays
|
|
1977
|
-
* via the PAFI sponsor-relayer.
|
|
1978
|
-
*
|
|
1979
|
-
* The UserOp itself is a no-op — a self-call to the user's EOA with
|
|
1980
|
-
* `data: "0x"`. The work is in the `eip7702Auth` object: the bundler
|
|
1981
|
-
* picks it up, runs the EIP-7702 path, and installs the delegation on
|
|
1982
|
-
* the user's EOA atomically with the (no-op) UserOp.
|
|
1983
|
-
*
|
|
1984
|
-
* v0.7.1 — switched from `encodeBatchExecute([])` (which throws
|
|
1985
|
-
* "operations array must not be empty") to `buildDelegationUserOp`
|
|
1986
|
-
* (self-call pattern). See SDK_CORE_TRADING_AUDIT.md C1.
|
|
1987
|
-
*
|
|
1988
|
-
* Throws the same `BundlerNotConfiguredError` / `BundlerRejectedError`
|
|
1989
|
-
* as other relay paths so issuer controllers can use one error mapper.
|
|
1990
|
-
*/
|
|
1991
1991
|
interface HandleDelegateSubmitParams {
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
/** 65-byte secp256k1 signature over the EIP-7702 authorization hash. */
|
|
1999
|
-
authSig: Hex | string;
|
|
2000
|
-
/** EIP-1559 fees from `provider.estimateFeesPerGas()` (or RPC equivalent). */
|
|
2001
|
-
fees: {
|
|
2002
|
-
maxFeePerGas?: bigint;
|
|
2003
|
-
maxPriorityFeePerGas?: bigint;
|
|
2004
|
-
};
|
|
1992
|
+
lockId: string;
|
|
1993
|
+
/** Authenticated user EOA — must match the entry's `sender`. */
|
|
1994
|
+
authenticatedAddress: Address;
|
|
1995
|
+
/** User signature over the persisted userOpHash. */
|
|
1996
|
+
userOpSig: Hex;
|
|
1997
|
+
store: IPendingUserOpStore;
|
|
2005
1998
|
pafiBackendClient?: PafiBackendClient | null;
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
gasLimits?: {
|
|
2009
|
-
callGasLimit?: bigint;
|
|
2010
|
-
verificationGasLimit?: bigint;
|
|
2011
|
-
preVerificationGas?: bigint;
|
|
2012
|
-
};
|
|
1999
|
+
/** Defaults to `ENTRY_POINT_V08`. */
|
|
2000
|
+
entryPoint?: string;
|
|
2013
2001
|
}
|
|
2014
2002
|
interface HandleDelegateSubmitResult {
|
|
2015
2003
|
userOpHash: Hex;
|
|
2016
|
-
/** True when paymaster sponsorship was applied (gas is free). */
|
|
2017
|
-
isSponsored: boolean;
|
|
2018
|
-
/** The authorization tuple actually sent to the bundler. */
|
|
2019
|
-
authorization: Eip7702AuthorizationJsonRpc;
|
|
2020
2004
|
}
|
|
2005
|
+
/**
|
|
2006
|
+
* Retrieve the persisted delegate UserOp, embed the user's signature,
|
|
2007
|
+
* and submit to the bundler with the cached `eip7702Auth` field.
|
|
2008
|
+
*
|
|
2009
|
+
* Throws:
|
|
2010
|
+
* - `PendingUserOpNotFoundError` — entry expired or already submitted (404)
|
|
2011
|
+
* - `PendingUserOpForbiddenError` — sender mismatch (403)
|
|
2012
|
+
* - `BundlerNotConfiguredError` — `pafiBackendClient` missing (503)
|
|
2013
|
+
* - `BundlerRejectedError` — bundler rejected the UserOp (422)
|
|
2014
|
+
*/
|
|
2021
2015
|
declare function handleDelegateSubmit(params: HandleDelegateSubmitParams): Promise<HandleDelegateSubmitResult>;
|
|
2022
2016
|
|
|
2023
2017
|
/**
|
|
@@ -2312,7 +2306,24 @@ interface DelegateStatusDto {
|
|
|
2312
2306
|
batchExecutorAddress: Address;
|
|
2313
2307
|
}
|
|
2314
2308
|
interface DelegatePrepareDto {
|
|
2315
|
-
|
|
2309
|
+
/**
|
|
2310
|
+
* v0.7.7 — refactored to mobile prepare/submit pattern. Mobile signs
|
|
2311
|
+
* the EIP-7702 authorization LOCALLY (Privy `signAuthorization`),
|
|
2312
|
+
* then signs `userOpHash` (or `typedData`) BEFORE submit. See
|
|
2313
|
+
* `handleDelegatePrepare` for rationale.
|
|
2314
|
+
*
|
|
2315
|
+
* Pre-v0.7.7 callers expected `{ authorizationHash, delegationNonce,
|
|
2316
|
+
* batchExecutorAddress, chainId }` — `delegationNonce` +
|
|
2317
|
+
* `batchExecutorAddress` retained for back-compat so mobile can
|
|
2318
|
+
* compute the authorization hash if needed; `authorizationHash`
|
|
2319
|
+
* removed (mobile's Privy hook computes it locally).
|
|
2320
|
+
*/
|
|
2321
|
+
lockId: string;
|
|
2322
|
+
userOpHash: Hex;
|
|
2323
|
+
typedData: SerializedUserOpTypedData;
|
|
2324
|
+
expiresInSeconds: number;
|
|
2325
|
+
isSponsored: boolean;
|
|
2326
|
+
/** Echoed for mobile to recompute the authorization hash if desired. */
|
|
2316
2327
|
delegationNonce: string;
|
|
2317
2328
|
batchExecutorAddress: Address;
|
|
2318
2329
|
chainId: number;
|
|
@@ -2379,13 +2390,32 @@ declare class IssuerApiAdapter {
|
|
|
2379
2390
|
claimStatus(authenticatedAddress: Address, lockId: string): Promise<MintStatusResponse>;
|
|
2380
2391
|
redeemStatus(authenticatedAddress: Address, lockId: string): Promise<BurnStatusResponse>;
|
|
2381
2392
|
delegateStatus(authenticatedAddress: Address, chainId: number): Promise<DelegateStatusDto>;
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2393
|
+
/**
|
|
2394
|
+
* Build the delegation-anchor UserOp + obtain paymaster sponsorship
|
|
2395
|
+
* + persist as a pending entry. Mobile must:
|
|
2396
|
+
*
|
|
2397
|
+
* 1. Sign EIP-7702 authorization LOCALLY (Privy `signAuthorization`
|
|
2398
|
+
* with `{contractAddress: batchExecutorAddress, chainId,
|
|
2399
|
+
* nonce: delegationNonce}`) → 65-byte authSig hex.
|
|
2400
|
+
* 2. POST `/delegate/prepare` with `{ chainId, delegationNonce,
|
|
2401
|
+
* authSig }` → this method.
|
|
2402
|
+
* 3. Sign returned `userOpHash` LOCALLY (`signTypedData(typedData)`).
|
|
2403
|
+
* 4. POST `/delegate/submit` with `{ lockId, userOpSig }`.
|
|
2404
|
+
*
|
|
2405
|
+
* v0.7.7 — replaces single-shot delegateSubmit that tried to relay
|
|
2406
|
+
* a UserOp with empty `signature: "0x"` (Simple7702Account's
|
|
2407
|
+
* validateUserOp reverts `ECDSAInvalidSignatureLength` 0xfce698f7).
|
|
2408
|
+
*/
|
|
2409
|
+
delegatePrepare(authenticatedAddress: Address, input: {
|
|
2385
2410
|
chainId: number;
|
|
2386
2411
|
delegationNonce: bigint;
|
|
2387
|
-
aaNonce: bigint;
|
|
2388
2412
|
authSig: Hex | string;
|
|
2413
|
+
aaNonce: bigint;
|
|
2414
|
+
}): Promise<DelegatePrepareDto>;
|
|
2415
|
+
delegateSubmit(input: {
|
|
2416
|
+
authenticatedAddress: Address;
|
|
2417
|
+
lockId: string;
|
|
2418
|
+
userOpSig: Hex;
|
|
2389
2419
|
}): Promise<MobileSubmitDto>;
|
|
2390
2420
|
/**
|
|
2391
2421
|
* Build + sign a SponsorAuth payload. Returns `undefined` when no
|
package/dist/index.js
CHANGED
|
@@ -2283,15 +2283,18 @@ import {
|
|
|
2283
2283
|
ENTRY_POINT_V08 as ENTRY_POINT_V082,
|
|
2284
2284
|
buildDelegationUserOp,
|
|
2285
2285
|
buildEip7702Authorization,
|
|
2286
|
+
computeUserOpHash as computeUserOpHash2,
|
|
2287
|
+
buildUserOpTypedData as buildUserOpTypedData2,
|
|
2286
2288
|
getContractAddresses as getContractAddresses5,
|
|
2287
2289
|
serializeUserOpToJsonRpc as serializeUserOpToJsonRpc2
|
|
2288
2290
|
} from "@pafi-dev/core";
|
|
2291
|
+
import { getAddress as getAddress9 } from "viem";
|
|
2289
2292
|
var DEFAULT_DELEGATE_GAS = {
|
|
2290
2293
|
callGasLimit: 100000n,
|
|
2291
2294
|
verificationGasLimit: 150000n,
|
|
2292
2295
|
preVerificationGas: 50000n
|
|
2293
2296
|
};
|
|
2294
|
-
async function
|
|
2297
|
+
async function handleDelegatePrepare(params) {
|
|
2295
2298
|
const { batchExecutor } = getContractAddresses5(params.chainId);
|
|
2296
2299
|
const partial = buildDelegationUserOp({
|
|
2297
2300
|
userAddress: params.userAddress,
|
|
@@ -2328,39 +2331,76 @@ async function handleDelegateSubmit(params) {
|
|
|
2328
2331
|
onWarning: params.onWarning
|
|
2329
2332
|
});
|
|
2330
2333
|
const merged = {
|
|
2331
|
-
|
|
2332
|
-
|
|
2334
|
+
sender: userOp.sender,
|
|
2335
|
+
nonce: userOp.nonce,
|
|
2336
|
+
callData: userOp.callData,
|
|
2337
|
+
callGasLimit: paymasterFields?.callGasLimit ?? userOp.callGasLimit,
|
|
2338
|
+
verificationGasLimit: paymasterFields?.verificationGasLimit ?? userOp.verificationGasLimit,
|
|
2339
|
+
preVerificationGas: paymasterFields?.preVerificationGas ?? userOp.preVerificationGas,
|
|
2340
|
+
maxFeePerGas: paymasterFields?.maxFeePerGas ?? userOp.maxFeePerGas,
|
|
2341
|
+
maxPriorityFeePerGas: paymasterFields?.maxPriorityFeePerGas ?? userOp.maxPriorityFeePerGas,
|
|
2342
|
+
paymaster: paymasterFields?.paymaster,
|
|
2343
|
+
paymasterVerificationGasLimit: paymasterFields?.paymasterVerificationGasLimit,
|
|
2344
|
+
paymasterPostOpGasLimit: paymasterFields?.paymasterPostOpGasLimit,
|
|
2345
|
+
paymasterData: paymasterFields?.paymasterData
|
|
2333
2346
|
};
|
|
2334
|
-
const
|
|
2347
|
+
const userOpHash = computeUserOpHash2(merged, params.chainId);
|
|
2348
|
+
const typed = buildUserOpTypedData2(merged, params.chainId);
|
|
2349
|
+
await params.store.save(
|
|
2350
|
+
params.lockId,
|
|
2335
2351
|
{
|
|
2336
2352
|
sender: merged.sender,
|
|
2337
|
-
nonce: merged.nonce,
|
|
2353
|
+
nonce: merged.nonce.toString(10),
|
|
2338
2354
|
callData: merged.callData,
|
|
2339
|
-
callGasLimit: merged.callGasLimit,
|
|
2340
|
-
verificationGasLimit: merged.verificationGasLimit,
|
|
2341
|
-
preVerificationGas: merged.preVerificationGas,
|
|
2342
|
-
maxFeePerGas: merged.maxFeePerGas,
|
|
2343
|
-
maxPriorityFeePerGas: merged.maxPriorityFeePerGas,
|
|
2344
|
-
paymaster:
|
|
2345
|
-
paymasterVerificationGasLimit
|
|
2346
|
-
|
|
2347
|
-
|
|
2355
|
+
callGasLimit: merged.callGasLimit.toString(10),
|
|
2356
|
+
verificationGasLimit: merged.verificationGasLimit.toString(10),
|
|
2357
|
+
preVerificationGas: merged.preVerificationGas.toString(10),
|
|
2358
|
+
maxFeePerGas: merged.maxFeePerGas.toString(10),
|
|
2359
|
+
maxPriorityFeePerGas: merged.maxPriorityFeePerGas.toString(10),
|
|
2360
|
+
...merged.paymaster ? { paymaster: merged.paymaster } : {},
|
|
2361
|
+
...merged.paymasterVerificationGasLimit ? {
|
|
2362
|
+
paymasterVerificationGasLimit: merged.paymasterVerificationGasLimit.toString(10)
|
|
2363
|
+
} : {},
|
|
2364
|
+
...merged.paymasterPostOpGasLimit ? {
|
|
2365
|
+
paymasterPostOpGasLimit: merged.paymasterPostOpGasLimit.toString(10)
|
|
2366
|
+
} : {},
|
|
2367
|
+
...merged.paymasterData ? { paymasterData: merged.paymasterData } : {},
|
|
2368
|
+
chainId: params.chainId,
|
|
2369
|
+
userOpHash,
|
|
2370
|
+
eip7702Auth: authorization
|
|
2348
2371
|
},
|
|
2349
|
-
|
|
2350
|
-
// is the user's "consent"; no separate AA signature is needed.
|
|
2351
|
-
"0x"
|
|
2372
|
+
params.ttlSeconds
|
|
2352
2373
|
);
|
|
2374
|
+
return {
|
|
2375
|
+
lockId: params.lockId,
|
|
2376
|
+
userOpHash,
|
|
2377
|
+
typedData: serializeUserOpTypedData(typed),
|
|
2378
|
+
expiresInSeconds: params.ttlSeconds,
|
|
2379
|
+
isSponsored: !!paymasterFields
|
|
2380
|
+
};
|
|
2381
|
+
}
|
|
2382
|
+
async function handleDelegateSubmit(params) {
|
|
2383
|
+
const entry = await params.store.get(params.lockId);
|
|
2384
|
+
if (!entry) {
|
|
2385
|
+
throw new PendingUserOpNotFoundError(params.lockId);
|
|
2386
|
+
}
|
|
2387
|
+
if (getAddress9(entry.sender) !== getAddress9(params.authenticatedAddress)) {
|
|
2388
|
+
throw new PendingUserOpForbiddenError(params.lockId);
|
|
2389
|
+
}
|
|
2390
|
+
if (!entry.eip7702Auth) {
|
|
2391
|
+
throw new Error(
|
|
2392
|
+
`delegate entry ${params.lockId} missing eip7702Auth \u2014 prepare step did not run correctly`
|
|
2393
|
+
);
|
|
2394
|
+
}
|
|
2395
|
+
const userOpJson = serializeEntryToJsonRpc(entry, params.userOpSig, "sponsored");
|
|
2353
2396
|
const result = await relayUserOp({
|
|
2354
2397
|
client: params.pafiBackendClient,
|
|
2355
2398
|
userOp: userOpJson,
|
|
2356
|
-
entryPoint: ENTRY_POINT_V082,
|
|
2357
|
-
eip7702Auth:
|
|
2399
|
+
entryPoint: params.entryPoint ?? ENTRY_POINT_V082,
|
|
2400
|
+
eip7702Auth: entry.eip7702Auth
|
|
2358
2401
|
});
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
isSponsored: !!paymasterFields,
|
|
2362
|
-
authorization
|
|
2363
|
-
};
|
|
2402
|
+
await params.store.delete(params.lockId);
|
|
2403
|
+
return { userOpHash: result.userOpHash };
|
|
2364
2404
|
}
|
|
2365
2405
|
|
|
2366
2406
|
// src/api/errorMapper.ts
|
|
@@ -2389,10 +2429,10 @@ function createSdkErrorMapper(factories) {
|
|
|
2389
2429
|
}
|
|
2390
2430
|
|
|
2391
2431
|
// src/api/issuerApiAdapter.ts
|
|
2392
|
-
import {
|
|
2432
|
+
import { randomUUID } from "crypto";
|
|
2433
|
+
import { getAddress as getAddress10 } from "viem";
|
|
2393
2434
|
import {
|
|
2394
2435
|
buildAndSignSponsorAuth,
|
|
2395
|
-
computeAuthorizationHash,
|
|
2396
2436
|
decodeBatchExecuteCalls as decodeBatchExecuteCalls3,
|
|
2397
2437
|
encodeBatchExecute,
|
|
2398
2438
|
ENTRY_POINT_V08 as ENTRY_POINT_V083,
|
|
@@ -2455,7 +2495,7 @@ var IssuerApiAdapter = class {
|
|
|
2455
2495
|
async pools(authenticatedAddress, chainId, pointTokenAddress) {
|
|
2456
2496
|
const result = await this.cfg.issuerService.api.handlePools(
|
|
2457
2497
|
authenticatedAddress,
|
|
2458
|
-
{ chainId, pointTokenAddress:
|
|
2498
|
+
{ chainId, pointTokenAddress: getAddress10(pointTokenAddress) }
|
|
2459
2499
|
);
|
|
2460
2500
|
return { pools: result.pools };
|
|
2461
2501
|
}
|
|
@@ -2464,8 +2504,8 @@ var IssuerApiAdapter = class {
|
|
|
2464
2504
|
authenticatedAddress,
|
|
2465
2505
|
{
|
|
2466
2506
|
chainId,
|
|
2467
|
-
userAddress:
|
|
2468
|
-
pointTokenAddress:
|
|
2507
|
+
userAddress: getAddress10(userAddress),
|
|
2508
|
+
pointTokenAddress: getAddress10(pointTokenAddress)
|
|
2469
2509
|
}
|
|
2470
2510
|
);
|
|
2471
2511
|
return {
|
|
@@ -2487,7 +2527,7 @@ var IssuerApiAdapter = class {
|
|
|
2487
2527
|
"ptClaimHandler",
|
|
2488
2528
|
"claim"
|
|
2489
2529
|
);
|
|
2490
|
-
const pointTokenAddress =
|
|
2530
|
+
const pointTokenAddress = getAddress10(input.pointTokenAddress);
|
|
2491
2531
|
const result = await ptClaimHandler.handle({
|
|
2492
2532
|
authenticatedAddress: input.authenticatedAddress,
|
|
2493
2533
|
userAddress: input.authenticatedAddress,
|
|
@@ -2582,7 +2622,7 @@ var IssuerApiAdapter = class {
|
|
|
2582
2622
|
"ptClaimHandler",
|
|
2583
2623
|
"claimPrepare"
|
|
2584
2624
|
);
|
|
2585
|
-
const pointTokenAddress =
|
|
2625
|
+
const pointTokenAddress = getAddress10(input.pointTokenAddress);
|
|
2586
2626
|
const claimResult = await ptClaimHandler.handle({
|
|
2587
2627
|
authenticatedAddress: input.authenticatedAddress,
|
|
2588
2628
|
userAddress: input.authenticatedAddress,
|
|
@@ -2628,7 +2668,7 @@ var IssuerApiAdapter = class {
|
|
|
2628
2668
|
}
|
|
2629
2669
|
async redeemPrepare(input) {
|
|
2630
2670
|
this.assertRedeemHandler();
|
|
2631
|
-
const pointTokenAddress =
|
|
2671
|
+
const pointTokenAddress = getAddress10(input.pointTokenAddress);
|
|
2632
2672
|
const redeemResponse = await this.cfg.ptRedeemHandler.handle({
|
|
2633
2673
|
userAddress: input.authenticatedAddress,
|
|
2634
2674
|
authenticatedAddress: input.authenticatedAddress,
|
|
@@ -2701,37 +2741,59 @@ var IssuerApiAdapter = class {
|
|
|
2701
2741
|
batchExecutorAddress: batchExecutor
|
|
2702
2742
|
};
|
|
2703
2743
|
}
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
};
|
|
2722
|
-
}
|
|
2723
|
-
async delegateSubmit(input) {
|
|
2744
|
+
/**
|
|
2745
|
+
* Build the delegation-anchor UserOp + obtain paymaster sponsorship
|
|
2746
|
+
* + persist as a pending entry. Mobile must:
|
|
2747
|
+
*
|
|
2748
|
+
* 1. Sign EIP-7702 authorization LOCALLY (Privy `signAuthorization`
|
|
2749
|
+
* with `{contractAddress: batchExecutorAddress, chainId,
|
|
2750
|
+
* nonce: delegationNonce}`) → 65-byte authSig hex.
|
|
2751
|
+
* 2. POST `/delegate/prepare` with `{ chainId, delegationNonce,
|
|
2752
|
+
* authSig }` → this method.
|
|
2753
|
+
* 3. Sign returned `userOpHash` LOCALLY (`signTypedData(typedData)`).
|
|
2754
|
+
* 4. POST `/delegate/submit` with `{ lockId, userOpSig }`.
|
|
2755
|
+
*
|
|
2756
|
+
* v0.7.7 — replaces single-shot delegateSubmit that tried to relay
|
|
2757
|
+
* a UserOp with empty `signature: "0x"` (Simple7702Account's
|
|
2758
|
+
* validateUserOp reverts `ECDSAInvalidSignatureLength` 0xfce698f7).
|
|
2759
|
+
*/
|
|
2760
|
+
async delegatePrepare(authenticatedAddress, input) {
|
|
2761
|
+
const { batchExecutor } = getContractAddresses6(input.chainId);
|
|
2724
2762
|
const fees = await this.cfg.provider.estimateFeesPerGas();
|
|
2725
|
-
const
|
|
2726
|
-
|
|
2763
|
+
const lockId = randomUUID();
|
|
2764
|
+
const result = await handleDelegatePrepare({
|
|
2765
|
+
userAddress: authenticatedAddress,
|
|
2727
2766
|
chainId: input.chainId,
|
|
2728
2767
|
delegationNonce: input.delegationNonce,
|
|
2729
2768
|
aaNonce: input.aaNonce,
|
|
2730
2769
|
authSig: input.authSig,
|
|
2731
2770
|
fees,
|
|
2771
|
+
lockId,
|
|
2772
|
+
store: this.cfg.pendingUserOpStore,
|
|
2773
|
+
ttlSeconds: 15 * 60,
|
|
2774
|
+
// 15min — match claim/redeem mobile lock duration
|
|
2732
2775
|
pafiBackendClient: this.cfg.pafiBackendClient,
|
|
2733
2776
|
onWarning: this.cfg.onWarning
|
|
2734
2777
|
});
|
|
2778
|
+
return {
|
|
2779
|
+
lockId: result.lockId,
|
|
2780
|
+
userOpHash: result.userOpHash,
|
|
2781
|
+
typedData: result.typedData,
|
|
2782
|
+
expiresInSeconds: result.expiresInSeconds,
|
|
2783
|
+
isSponsored: result.isSponsored,
|
|
2784
|
+
delegationNonce: input.delegationNonce.toString(),
|
|
2785
|
+
batchExecutorAddress: batchExecutor,
|
|
2786
|
+
chainId: input.chainId
|
|
2787
|
+
};
|
|
2788
|
+
}
|
|
2789
|
+
async delegateSubmit(input) {
|
|
2790
|
+
const result = await handleDelegateSubmit({
|
|
2791
|
+
lockId: input.lockId,
|
|
2792
|
+
authenticatedAddress: input.authenticatedAddress,
|
|
2793
|
+
userOpSig: input.userOpSig,
|
|
2794
|
+
store: this.cfg.pendingUserOpStore,
|
|
2795
|
+
pafiBackendClient: this.cfg.pafiBackendClient
|
|
2796
|
+
});
|
|
2735
2797
|
return { userOpHash: result.userOpHash };
|
|
2736
2798
|
}
|
|
2737
2799
|
// ------------------------------ Internal helpers -------------------------
|
|
@@ -3372,7 +3434,7 @@ var PafiBackendClient = class {
|
|
|
3372
3434
|
};
|
|
3373
3435
|
|
|
3374
3436
|
// src/config.ts
|
|
3375
|
-
import { getAddress as
|
|
3437
|
+
import { getAddress as getAddress11 } from "viem";
|
|
3376
3438
|
import { getContractAddresses as getContractAddresses7 } from "@pafi-dev/core";
|
|
3377
3439
|
function createIssuerService(config) {
|
|
3378
3440
|
if (!config.provider) {
|
|
@@ -3393,7 +3455,7 @@ function createIssuerService(config) {
|
|
|
3393
3455
|
"createIssuerService: at least one of pointTokenAddress / pointTokenAddresses is required"
|
|
3394
3456
|
);
|
|
3395
3457
|
}
|
|
3396
|
-
const tokenAddresses = rawAddresses.map((a) =>
|
|
3458
|
+
const tokenAddresses = rawAddresses.map((a) => getAddress11(a));
|
|
3397
3459
|
const ledger = config.ledger;
|
|
3398
3460
|
const sessionStore = config.sessionStore ?? new MemorySessionStore();
|
|
3399
3461
|
const policy = config.policy ?? new DefaultPolicyEngine({ ledger });
|
|
@@ -3482,7 +3544,7 @@ function createIssuerService(config) {
|
|
|
3482
3544
|
}
|
|
3483
3545
|
|
|
3484
3546
|
// src/issuer-state/validator.ts
|
|
3485
|
-
import { getAddress as
|
|
3547
|
+
import { getAddress as getAddress12 } from "viem";
|
|
3486
3548
|
import {
|
|
3487
3549
|
POINT_TOKEN_V2_ABI as POINT_TOKEN_V2_ABI3,
|
|
3488
3550
|
issuerRegistryGetIssuerFlatAbi,
|
|
@@ -3513,7 +3575,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
|
|
|
3513
3575
|
*/
|
|
3514
3576
|
invalidate(pointToken) {
|
|
3515
3577
|
if (pointToken) {
|
|
3516
|
-
const key =
|
|
3578
|
+
const key = getAddress12(pointToken);
|
|
3517
3579
|
this.pointTokenIssuerCache.delete(key);
|
|
3518
3580
|
this.stateCache.delete(key);
|
|
3519
3581
|
this.inflight.delete(key);
|
|
@@ -3528,7 +3590,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
|
|
|
3528
3590
|
* The issuer field is set at `initialize()` and never changes.
|
|
3529
3591
|
*/
|
|
3530
3592
|
async getIssuerAddressForPointToken(pointToken) {
|
|
3531
|
-
const key =
|
|
3593
|
+
const key = getAddress12(pointToken);
|
|
3532
3594
|
const cached = this.pointTokenIssuerCache.get(key);
|
|
3533
3595
|
if (cached) return cached;
|
|
3534
3596
|
const issuer = await this.provider.readContract({
|
|
@@ -3536,15 +3598,15 @@ var IssuerStateValidator = class _IssuerStateValidator {
|
|
|
3536
3598
|
abi: POINT_TOKEN_V2_ABI3,
|
|
3537
3599
|
functionName: "issuer"
|
|
3538
3600
|
});
|
|
3539
|
-
this.pointTokenIssuerCache.set(key,
|
|
3540
|
-
return
|
|
3601
|
+
this.pointTokenIssuerCache.set(key, getAddress12(issuer));
|
|
3602
|
+
return getAddress12(issuer);
|
|
3541
3603
|
}
|
|
3542
3604
|
/**
|
|
3543
3605
|
* Read registry record + totalSupply, with 30s cache and in-flight
|
|
3544
3606
|
* deduplication. Does NOT throw on inactive/missing — returns raw state.
|
|
3545
3607
|
*/
|
|
3546
3608
|
async getIssuerState(pointToken) {
|
|
3547
|
-
const tokenAddr =
|
|
3609
|
+
const tokenAddr = getAddress12(pointToken);
|
|
3548
3610
|
const now = Date.now();
|
|
3549
3611
|
const cached = this.stateCache.get(tokenAddr);
|
|
3550
3612
|
if (cached && cached.expiresAt > now) return cached.value;
|
|
@@ -3642,7 +3704,7 @@ var IssuerStateValidator = class _IssuerStateValidator {
|
|
|
3642
3704
|
};
|
|
3643
3705
|
|
|
3644
3706
|
// src/index.ts
|
|
3645
|
-
var PAFI_ISSUER_SDK_VERSION = true ? "0.7.
|
|
3707
|
+
var PAFI_ISSUER_SDK_VERSION = true ? "0.7.7" : "dev";
|
|
3646
3708
|
export {
|
|
3647
3709
|
AdapterMisconfiguredError,
|
|
3648
3710
|
AuthError,
|