-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of github.com:pimlicolabs/docs
- Loading branch information
Showing
30 changed files
with
1,258 additions
and
872 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
# ERC-20 Paymaster Guides | ||
|
||
## Estimating Approval Amounts | ||
|
||
When using Pimlico's ERC20-paymaster, the paymaster needs approval to spend funds on the payer's behalf. The amount to approve must be atleast equal to the userOperation's prefund value. | ||
|
||
You can use the helper function below to get the required approval amount. | ||
|
||
```ts | ||
// Calculates amount of tokens that need to be approved for ERC20 paymaster to sponsor userOperation | ||
const getApprovalAmount = async ({ | ||
publicClient, | ||
paymasterAddress, | ||
userOperation, | ||
}: EstimateParams) => { | ||
const erc20Paymaster = getContract({ | ||
client: publicClient, | ||
address: paymasterAddress, | ||
abi: parseAbi([ | ||
"function getPrice() view returns (uint192)", | ||
"function priceMarkup() view returns (uint32)", | ||
"function refundPostOpCost() view returns (uint)", | ||
]), | ||
}); | ||
|
||
const requiredGas = | ||
userOperation.verificationGasLimit + | ||
userOperation.callGasLimit + | ||
(userOperation.paymasterVerificationGasLimit || 0n) + | ||
(userOperation.paymasterPostOpGasLimit || 0n) + | ||
userOperation.preVerificationGas; | ||
|
||
const requiredPreFund = requiredGas * userOperation.maxFeePerGas; | ||
|
||
// fetch onchain info | ||
const markup = BigInt(await erc20Paymaster.read.priceMarkup()); | ||
const refundPostOpCost = BigInt(await erc20Paymaster.read.refundPostOpCost()); | ||
const tokenPrice = BigInt(await erc20Paymaster.read.getPrice()); | ||
|
||
const maxFeePerGas = userOperation.maxFeePerGas; | ||
|
||
return ( | ||
((requiredPreFund + refundPostOpCost * maxFeePerGas) * | ||
markup * | ||
tokenPrice) / | ||
(BigInt(1e18) * BigInt(1e6)) | ||
); | ||
}; | ||
``` | ||
|
||
## Estimating Gas Cost | ||
|
||
The helper function below shows an example on how to accurately estimate the gas cost of a UserOperation when using Pimlico's paymasters. The function expects a valid and signed UserOperation. | ||
|
||
```ts | ||
// Returns the cost of the UserOperation (denominated in token) | ||
export const estimateCost = async ({ | ||
userOperation, | ||
publicClient, | ||
paymasterAddress, | ||
}: EstimateParams) => { | ||
const beneficiary = privateKeyToAddress(generatePrivateKey()); | ||
|
||
const erc20Paymaster = getContract({ | ||
address: paymasterAddress, | ||
abi: parseAbi(["function token() view returns (address)"]), | ||
client: publicClient, | ||
}); | ||
const erc20Token = await erc20Paymaster.read.token(); | ||
|
||
const multicall3Abi = parseAbi([ | ||
"struct Result { bool success; bytes returnData; }", | ||
"struct Call3 { address target; bool allowFailure; bytes callData; }", | ||
"function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData)", | ||
]); | ||
|
||
const entrypointAbi = parseAbi([ | ||
"struct PackedUserOperation { address sender; uint256 nonce; bytes initCode; bytes callData; bytes32 accountGasLimits; uint256 preVerificationGas; bytes32 gasFees; bytes paymasterAndData; bytes signature; }", | ||
"function handleOps(PackedUserOperation[] calldata ops, address beneficiary)", | ||
"error FailedOp(uint256 opIndex, string reason)", | ||
"error FailedOpWithRevert(uint256 opIndex, string reason, bytes inner)", | ||
"error PostOpReverted(bytes returnData)", | ||
"error SignatureValidationFailed(address aggregator)", | ||
]); | ||
const handleOpsData = encodeFunctionData({ | ||
abi: entrypointAbi, | ||
functionName: "handleOps", | ||
args: [[getPackedUserOperation(userOperation)], beneficiary], | ||
}); | ||
|
||
const getTokenBalanceData = encodeFunctionData({ | ||
abi: parseAbi(["function balanceOf(address) returns (uint)"]), | ||
args: [userOperation.sender], | ||
}); | ||
|
||
const multicallPayload = encodeFunctionData({ | ||
abi: multicall3Abi, | ||
functionName: "aggregate3", | ||
args: [ | ||
[ | ||
{ | ||
target: erc20Token, | ||
callData: getTokenBalanceData, | ||
allowFailure: true, | ||
}, | ||
{ | ||
target: ENTRYPOINT_ADDRESS_V07, | ||
callData: handleOpsData, | ||
allowFailure: true, | ||
}, | ||
{ | ||
target: erc20Token, | ||
callData: getTokenBalanceData, | ||
allowFailure: true, | ||
}, | ||
], | ||
], | ||
}); | ||
|
||
const response = await publicClient.call({ | ||
to: "0xca11bde05977b3631167028862be2a173976ca11", | ||
data: multicallPayload, | ||
gasPrice: await publicClient.getGasPrice(), | ||
}); | ||
|
||
if (!response.data) { | ||
throw new Error("Failed to estimate erc20Paymaster's gas cost"); | ||
} | ||
|
||
const [balBefore, handleOps, balAfter] = decodeAbiParameters( | ||
multicall3Abi[0].outputs, | ||
response.data, | ||
)[0]; | ||
|
||
if (!balBefore.success || !balAfter.success) { | ||
throw new Error("Failed to estimate erc20Paymaster's gas cost"); | ||
} | ||
|
||
if (!handleOps.success) { | ||
const parsedError = decodeErrorResult({ | ||
abi: entrypointAbi, | ||
data: handleOps.returnData, | ||
}); | ||
|
||
throw new Error( | ||
`Failed to estimate erc20Paymaster's gas cost due to ${parsedError.args}`, | ||
); | ||
} | ||
|
||
return hexToBigInt(balBefore.returnData) - hexToBigInt(balAfter.returnData); | ||
}; | ||
``` |
7 changes: 7 additions & 0 deletions
7
docs/pages/infra/platform/debugging/dropped-user-operations.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# How to debug dropped user operations | ||
|
||
If a user operation is dropped in the mempool of the bundler after initially being accepted by it, the error can not be propagated by the bundler to the user. To debug what happened to these user operations, we recommend using the [User Operation Tracking](https://dashboard.pimlico.io/debugging/tracking) page on our dashboard, which will show you the exact flow of the user operation stage-by-stage through Pimlico's bundler with timestamps, including any errors it encounters. | ||
|
||
An example screenshot of the User Operation Tracking page is shown below: | ||
|
||
 |
27 changes: 27 additions & 0 deletions
27
docs/pages/infra/platform/sponsorship-policies/webhook.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# How to use Sponsorship Policy webhook | ||
|
||
Webhook allows you to receive real-time notifications when a sponsorship policy is triggered. You can use webhooks to approve or reject sponsoring userops. Start by going to the [sponsorship policies page](https://dashboard.pimlico.io/sponsorship-policies) on the Pimlico dashboard, clicking on the existing policy and clicking on the "Edit button". | ||
|
||
Request is sent with POST, where body is a JSON object with the following structure: | ||
|
||
```typescript | ||
const body = { | ||
type: 'sponsorshipPolicy.webhook', | ||
data: { | ||
object: { | ||
userOperation, | ||
entryPoint, | ||
chainId, | ||
sponsorshipPolicyId: sponsorshipPolicy.id | ||
} | ||
} | ||
}; | ||
``` | ||
|
||
The returned value should be a JSON with the following structure: | ||
|
||
```json | ||
{ | ||
"sponsor": true // Boolean | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# Why Pimlico | ||
|
||
Are you looking to improve your app's user experience and wondering why you should use Pimlico as your account abstraction infrastructure provider? | ||
|
||
Below are some reasons some of the best teams in crypto have chosen to build on Pimlico | ||
|
||
## Developer-first experience | ||
|
||
Pimlico is a platform built by developers for developers. We understand the importance of a great developer experience and have built our platform with that in mind. | ||
|
||
This means you can expect clean, modern, well-typed SDKs, comprehensive documentation, and a support team that's comprised of devleopers who can help you with any issues you might encounter. | ||
|
||
## Powerful features | ||
|
||
When you build on Pimlico, you're not just getting a simple account abstraction platform. You're getting a powerful set of tools that can help you build the best user experience with the most powerful infrastructure in the space. | ||
|
||
This means a comprehensive set of tools, charts, logs, configurations to give you all the scale, observability, security, and debugging capabilities you need to build with smart accounts, as well as accesss to 70+ chains with one API key and one, centrally-managed balance. | ||
|
||
## Expert, veteran team | ||
|
||
Our team has been working in the account abstraction space for years, and we have a deep understanding of the space. We are co-authors of some of the most important smart account standards, are constantly innovating at the frontier and can make sure you're always ahead of the curve. Our developer-focused team also means you can expect fast, helpful support whenever you need it, and new features being constantly added daily rather than quarterly. | ||
|
||
## What's next? | ||
|
||
If you're ready to get started, you can sign up to the [Pimlico dashboard](https://dashboard.pimlico.io) or [contact us](https://cal.com/team/pimlico/20min) to start building with Pimlico today, and join the ranks of some of the best teams in crypto such as Zora, WalletConnect, Daimo, Safe, and more. |
10 changes: 5 additions & 5 deletions
10
.../how-to/accounts/user-erc7579-actions.mdx → ...s/how-to/accounts/use-erc7579-account.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.