diff --git a/docs/diagrams/approve.md b/docs/diagrams/approve.md new file mode 100644 index 0000000..46aaf10 --- /dev/null +++ b/docs/diagrams/approve.md @@ -0,0 +1,23 @@ +# Approve Permissions + +While the default experience is for apps to [request spend permissions](requestSpendPermission.md) and [approve with signatures](./approveWithSignature.md), it can also be valuable to approve permissions via direct calls to `SpendPermissionManager.approve`. For example, paying now to start a subscription and approving a permission to pay the same amount every month. + +```mermaid +sequenceDiagram + autonumber + participant E as Entrypoint + participant A as Account + participant PM as Permission Manager + participant EC as External Contract + + Note over E: Validation phase + E->>A: validateUserOp + A-->>E: validation data + Note over E: Execution phase + E->>A: executeBatch + opt + A->>EC: call + end + A->>PM: approve + Note over A,PM: SpendPermission data +``` diff --git a/docs/diagrams/approveWithSignature.md b/docs/diagrams/approveWithSignature.md new file mode 100644 index 0000000..24f8af0 --- /dev/null +++ b/docs/diagrams/approveWithSignature.md @@ -0,0 +1,24 @@ +# Approve Permission With Signature + +Spenders (apps) approve their permission by calling `SpendPermissionManager.approveWithSignature` using the signature returned from the wallet when [requesting spend permissions](requestSpendPermission.md). + +If the signature is [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492) formatted, `SpendPermissionManager` will automatically detect this and deploy the account on behalf of the app. Afterwards, it will call `isValidSignature` to verify the account signed the permission. + +```mermaid +sequenceDiagram + autonumber + participant S as Spender + participant PM as Permission Manager + participant A as Account + participant F as Factory + + S->>PM: approveWithSignature + Note over PM: validate signature + opt if 6492 initCode + PM->>F: createAccount + F->>A: create2 + end + PM->>A: isValidSignature + A-->>PM: EIP-1271 magic value + Note over PM: revert or store approval +``` diff --git a/docs/diagrams/requestSpendPermission.md b/docs/diagrams/requestSpendPermission.md new file mode 100644 index 0000000..0e9c1d0 --- /dev/null +++ b/docs/diagrams/requestSpendPermission.md @@ -0,0 +1,32 @@ +# Request Spend Permission + +Apps request spend permissions from users by sending an `eth_signTypedData` request containing the permission details. + +Users are guided to sign the permission hash and add the `SpendPermissionManager` contract as an owner if it is not already. + +If a users account is not yet deployed, but has the `SpendPermissionManager` as an initial owner in its `initCode`, the returned signature is formatted according to [ERC-6492](https://eips.ethereum.org/EIPS/eip-6492) with the `CoinbaseSmartWalletFactory` address and this `initCode`. + +This entire process takes place offchain and requires no transactions or network fees. + +```mermaid +sequenceDiagram + autonumber + participant A as App + participant WF as Wallet Frontend + participant U as User + participant WB as Wallet Backend + + A->>WF: eth_signTypedData + WF->>U: approve permission + U-->>WF: signature + WF->>WB: get account status + WB-->>WF: deploy status, initCode, current + pending owners + alt account deployed && manager is owner + else account not deployed && manager in initCode + Note right of WF: wrap signature in ERC-6492 + else manager not in initCode && manager not owner + WF->>U: add manager + U-->>WF: signature + end + WF-->>A: signature +``` diff --git a/docs/diagrams/revoke.md b/docs/diagrams/revoke.md new file mode 100644 index 0000000..5db531c --- /dev/null +++ b/docs/diagrams/revoke.md @@ -0,0 +1,21 @@ +# Revoke Permissions + +Users can revoke permissions at any time by calling `SpendPermissionManager.revoke`, which can also be batched via `CoinbaseSmartWallet.executeBatch`. + +```mermaid +sequenceDiagram + autonumber + participant E as Entrypoint + participant A as Account + participant PM as Permission Manager + + Note over E: Validation phase + E->>A: validateUserOp + A-->>E: validation data + Note over E: Execution phase + E->>A: executeBatch + loop + A->>PM: revoke + Note over A,PM: SpendPermission data + end +``` diff --git a/docs/diagrams/spend.md b/docs/diagrams/spend.md new file mode 100644 index 0000000..9b2b50f --- /dev/null +++ b/docs/diagrams/spend.md @@ -0,0 +1,32 @@ +# Spend Tokens + +Spenders (apps) spend tokens by calling `SpendPermissionManager.spend` with their spend permission values, a recipient, and an amount of tokens to spend. + +Spenders may want to batch this call with an additionally prepended call to [approve their permission via user signature](./approveWithSignature.md) or the convenience function `SpendPermissionManager.spendWithSignature`. After a permission is approved, it is cheaper to avoid re-validating the signature and approval by just calling `SpendPermissionManager.spend` for repeated use. + +When executing a spend, `SpendPermissionManager` calls `CoinbaseSmartWallet.execute` with either a call to transfer native or ERC-20 tokens to the recipient. Only these two kinds of calls are allowed by the `SpendPermissionManager` on a `CoinbaseSmartWallet` for reduced risk. + +```mermaid +sequenceDiagram + autonumber + participant S as Spender + participant PM as Permission Manager + participant A as Account + participant ERC20 + + opt + S->>PM: approveWithSignature + Note over PM: validate signature and store approval + end + S->>PM: spend + Note over PM: validate permission approved
and spend value within allowance + PM->>A: execute + Note over PM,A: transfer tokens + alt token is ERC-7528 address + A->>S: call{value}() + Note over A,S: transfer native token to spender + else else is ERC20 contract + A->>ERC20: transfer(spender, value) + Note over A,ERC20: transfer ERC20 to spender + end +```