@trustvc/eip7702 1.0.0-beta.2 → 1.1.0-beta.2
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/README.md +44 -6
- package/contracts/Factory.sol +20 -4
- package/contracts/PlatformPaymaster.sol +24 -6
- package/dist/index.d.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +8 -2
- package/dist/index.mjs +8 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -138,16 +138,54 @@ npx hardhat run scripts/mintDocumentGasless.ts --network sepolia
|
|
|
138
138
|
|
|
139
139
|
## Environment variables
|
|
140
140
|
|
|
141
|
+
Deploy/registry/paymaster addresses are network-scoped — suffix the variable with `_SEPOLIA` or `_AMOY` (e.g. `FACTORY_ADDRESS_SEPOLIA`, `FACTORY_ADDRESS_AMOY`). `scripts/lib/network.ts` resolves the suffix from `--network <name>` (hardhat scripts) or the `NETWORK` env var (viem/permissionless scripts). See `.env.example` for the full annotated list.
|
|
142
|
+
|
|
143
|
+
### Wallets & RPC
|
|
144
|
+
|
|
141
145
|
| Variable | Description |
|
|
142
146
|
| --- | --- |
|
|
143
|
-
| `PRIVATE_KEY` | Deployer wallet
|
|
147
|
+
| `PRIVATE_KEY` | Deployer/gas-payer wallet — pays for deployments, delegation txs, staking |
|
|
148
|
+
| `PRIVATE_KEY2` | Secondary wallet (optional — testing with a second account) |
|
|
149
|
+
| `OWNER_PRIVATE_KEY` | Platform owner / whitelisted user — signs UserOps, needs no ETH for gasless ops |
|
|
144
150
|
| `SEPOLIA_RPC_URL` | Sepolia RPC endpoint |
|
|
151
|
+
| `AMOY_RPC_URL` | Polygon Amoy RPC endpoint |
|
|
145
152
|
| `PIMLICO_API_KEY` | Pimlico bundler API key |
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
153
|
+
| `NETWORK` | `sepolia` \| `amoy` — target network for viem/permissionless scripts (default: `sepolia`) |
|
|
154
|
+
| `ENTRY_POINT` | EntryPoint v0.8 address (default: `0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108`, same on all supported chains) |
|
|
155
|
+
|
|
156
|
+
### Deployed addresses (network-suffixed)
|
|
157
|
+
|
|
158
|
+
| Variable | Description |
|
|
159
|
+
| --- | --- |
|
|
160
|
+
| `EIP7702_IMPL_ADDRESS_<NETWORK>` | Deployed `EIP7702Implementation` address |
|
|
161
|
+
| `PAYMASTER_IMPLEMENTATION_<NETWORK>` | Deployed `PlatformPaymaster` implementation address |
|
|
162
|
+
| `FACTORY_ADDRESS_<NETWORK>` | Deployed `PlatformAccountFactory` address |
|
|
163
|
+
| `PAYMASTER_ADDRESS_<NETWORK>` | Deployed paymaster clone address |
|
|
164
|
+
| `TDOC_DEPLOYER_ADDRESS_<NETWORK>` | TrustVC `TDocDeployer` address (pre-deployed infra) |
|
|
165
|
+
| `TDOC_IMPLEMENTATION_<NETWORK>` | TDoc implementation to clone via `deployRegistry` |
|
|
166
|
+
| `REGISTRY_ADDRESS_<NETWORK>` | Registry deployed via `deployRegistryGasless.ts` |
|
|
167
|
+
| `TITLE_ESCROW_ADDRESS_<NETWORK>` | Title escrow captured via `mintDocumentGasless.ts` |
|
|
168
|
+
|
|
169
|
+
### Gasless script inputs
|
|
170
|
+
|
|
171
|
+
| Variable | Description |
|
|
172
|
+
| --- | --- |
|
|
173
|
+
| `TOKEN_NAME` / `TOKEN_SYMBOL` | Name/symbol for the TradeTrust token registry (`deployRegistryGasless.ts`) |
|
|
174
|
+
| `TOKEN_ID` | Document token ID as `uint256` (`mintDocumentGasless.ts`) |
|
|
175
|
+
| `BENEFICIARY_ADDRESS` / `HOLDER_ADDRESS` | Document beneficiary/holder (`mintDocumentGasless.ts`) |
|
|
176
|
+
| `REMARK` | Optional remark bytes/text attached to the document |
|
|
177
|
+
| `NOMINEE_ADDR` / `NEW_HOLDER_ADDR` | Used by the `scripts/trFunctions/*` title-escrow helpers |
|
|
178
|
+
|
|
179
|
+
### Optional deploy/stake overrides
|
|
180
|
+
|
|
181
|
+
| Variable | Description |
|
|
182
|
+
| --- | --- |
|
|
183
|
+
| `PLATFORM_ADDRESS` | Paymaster owner EOA for `deployPlatformPaymaster.ts` (default: deployer) |
|
|
184
|
+
| `DAILY_LIMIT_ETH` | Per-user daily gas limit in ETH (default: `0` = unlimited) |
|
|
185
|
+
| `DEPLOY_SALT` | Hex `bytes32` CREATE2 salt (default: random) |
|
|
186
|
+
| `STAKE_AMOUNT_ETH` | ETH locked as EntryPoint stake (default: `0.01`) |
|
|
187
|
+
| `DEPOSIT_AMOUNT_ETH` | ETH deposited into the gas pool (default: `0.05`) |
|
|
188
|
+
| `UNSTAKE_DELAY_SEC` | Stake lock period in seconds (default: `86400` = 1 day) |
|
|
151
189
|
|
|
152
190
|
## Tech stack
|
|
153
191
|
|
package/contracts/Factory.sol
CHANGED
|
@@ -9,7 +9,10 @@ contract PlatformAccountFactory is Ownable {
|
|
|
9
9
|
address public tdocDeployer;
|
|
10
10
|
address public paymasterImplementation;
|
|
11
11
|
|
|
12
|
-
event PlatformOnboarded(
|
|
12
|
+
event PlatformOnboarded(
|
|
13
|
+
address indexed platformAddress,
|
|
14
|
+
address indexed paymaster
|
|
15
|
+
);
|
|
13
16
|
event TdocDeployerUpdated(address indexed newDeployer);
|
|
14
17
|
event ImplementationUpdated(address indexed newImplementation);
|
|
15
18
|
|
|
@@ -17,6 +20,8 @@ contract PlatformAccountFactory is Ownable {
|
|
|
17
20
|
address _tdocDeployer,
|
|
18
21
|
address _paymasterImplementation
|
|
19
22
|
) Ownable(msg.sender) {
|
|
23
|
+
require(_tdocDeployer != address(0), "Zero address");
|
|
24
|
+
require(_paymasterImplementation != address(0), "Zero address");
|
|
20
25
|
tdocDeployer = _tdocDeployer;
|
|
21
26
|
paymasterImplementation = _paymasterImplementation;
|
|
22
27
|
}
|
|
@@ -39,12 +44,23 @@ contract PlatformAccountFactory is Ownable {
|
|
|
39
44
|
bytes32 salt
|
|
40
45
|
) external returns (address paymaster) {
|
|
41
46
|
paymaster = Clones.cloneDeterministic(paymasterImplementation, salt);
|
|
42
|
-
PlatformPaymaster(payable(paymaster)).initialize(
|
|
47
|
+
PlatformPaymaster(payable(paymaster)).initialize(
|
|
48
|
+
platformAddress,
|
|
49
|
+
dailyLimit,
|
|
50
|
+
tdocDeployer
|
|
51
|
+
);
|
|
43
52
|
emit PlatformOnboarded(platformAddress, paymaster);
|
|
44
53
|
}
|
|
45
54
|
|
|
46
55
|
// Address is determined solely by implementation + salt (not by constructor args).
|
|
47
|
-
function computePaymasterAddress(
|
|
48
|
-
|
|
56
|
+
function computePaymasterAddress(
|
|
57
|
+
bytes32 salt
|
|
58
|
+
) external view returns (address) {
|
|
59
|
+
return
|
|
60
|
+
Clones.predictDeterministicAddress(
|
|
61
|
+
paymasterImplementation,
|
|
62
|
+
salt,
|
|
63
|
+
address(this)
|
|
64
|
+
);
|
|
49
65
|
}
|
|
50
66
|
}
|
|
@@ -49,6 +49,9 @@ contract PlatformPaymaster is BasePaymaster {
|
|
|
49
49
|
);
|
|
50
50
|
|
|
51
51
|
bytes32 private constant DEFAULT_ADMIN_ROLE = bytes32(0);
|
|
52
|
+
bytes32 private constant RESTORER_ROLE = keccak256("RESTORER_ROLE");
|
|
53
|
+
bytes32 private constant ACCEPTER_ROLE = keccak256("ACCEPTER_ROLE");
|
|
54
|
+
bytes32 private constant MINTER_ROLE = keccak256("MINTER_ROLE");
|
|
52
55
|
|
|
53
56
|
ITDocDeployer public tdocDeployer;
|
|
54
57
|
|
|
@@ -141,13 +144,11 @@ contract PlatformPaymaster is BasePaymaster {
|
|
|
141
144
|
bytes memory params = abi.encode(name, symbol, address(this));
|
|
142
145
|
deployed = tdocDeployer.deploy(implementation, params);
|
|
143
146
|
|
|
144
|
-
// Hand admin to the calling EOA
|
|
145
147
|
IAccessControl(deployed).grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
|
|
148
|
+
IAccessControl(deployed).grantRole(RESTORER_ROLE, msg.sender);
|
|
149
|
+
IAccessControl(deployed).grantRole(ACCEPTER_ROLE, msg.sender);
|
|
150
|
+
IAccessControl(deployed).grantRole(MINTER_ROLE, msg.sender);
|
|
146
151
|
|
|
147
|
-
// Paymaster keeps only the operational roles it needs
|
|
148
|
-
// (MINTER_ROLE, RESTORER_ROLE, ACCEPTER_ROLE were granted to address(this) via initialize)
|
|
149
|
-
|
|
150
|
-
// Relinquish admin — EOA is now sole admin
|
|
151
152
|
IAccessControl(deployed).renounceRole(
|
|
152
153
|
DEFAULT_ADMIN_ROLE,
|
|
153
154
|
address(this)
|
|
@@ -169,6 +170,12 @@ contract PlatformPaymaster is BasePaymaster {
|
|
|
169
170
|
bytes calldata remark
|
|
170
171
|
) external returns (address titleEscrow) {
|
|
171
172
|
require(authorizedRegistries[registry], "registry not authorized");
|
|
173
|
+
require(
|
|
174
|
+
authorizedCallers[msg.sender] ||
|
|
175
|
+
userWhitelist[msg.sender] > 0 ||
|
|
176
|
+
msg.sender == owner(),
|
|
177
|
+
"caller not authorized"
|
|
178
|
+
);
|
|
172
179
|
|
|
173
180
|
titleEscrow = ITradeTrustToken(registry).mint(
|
|
174
181
|
beneficiary,
|
|
@@ -290,7 +297,18 @@ contract PlatformPaymaster is BasePaymaster {
|
|
|
290
297
|
}
|
|
291
298
|
|
|
292
299
|
if (innerSel == MINT_DOCUMENT_SEL) {
|
|
293
|
-
|
|
300
|
+
if (
|
|
301
|
+
!authorizedCallers[sender] &&
|
|
302
|
+
userWhitelist[sender] == 0 &&
|
|
303
|
+
sender != owner()
|
|
304
|
+
) {
|
|
305
|
+
emit UserOpRejected(sender, "caller not authorized");
|
|
306
|
+
return ("", _packValidationData(true, 0, 0));
|
|
307
|
+
}
|
|
308
|
+
if (dailyLimit > 0 && dailySpend[sender] + maxCost > dailyLimit) {
|
|
309
|
+
emit UserOpRejected(sender, "daily limit exceeded");
|
|
310
|
+
return ("", _packValidationData(true, 0, 0));
|
|
311
|
+
}
|
|
294
312
|
return (
|
|
295
313
|
abi.encode(sender, maxCost, false),
|
|
296
314
|
_packValidationData(false, 0, 0)
|
package/dist/index.d.mts
CHANGED
|
@@ -1139,11 +1139,17 @@ declare namespace index$1 {
|
|
|
1139
1139
|
|
|
1140
1140
|
declare const ChainId: {
|
|
1141
1141
|
readonly Sepolia: 11155111;
|
|
1142
|
+
readonly Amoy: 80002;
|
|
1142
1143
|
};
|
|
1143
1144
|
/** Deployed contract addresses indexed by chainId */
|
|
1144
1145
|
declare const contractAddress: {
|
|
1146
|
+
readonly PaymasterImplementation: {
|
|
1147
|
+
readonly 11155111: "0x5ca5652025ca77d13323ed4887b4cbee6098dd8f";
|
|
1148
|
+
readonly 80002: "0xf47d58D3adc642DaD23966698A7A60b8b34D72f8";
|
|
1149
|
+
};
|
|
1145
1150
|
readonly PlatformAccountFactory: {
|
|
1146
|
-
readonly 11155111: "
|
|
1151
|
+
readonly 11155111: "0x1fe801f6af6e9a6c76431db08b121a7de70bc895";
|
|
1152
|
+
readonly 80002: "0x2762abf6fa22314ebcab41dd4666836038d29341";
|
|
1147
1153
|
};
|
|
1148
1154
|
};
|
|
1149
1155
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1139,11 +1139,17 @@ declare namespace index$1 {
|
|
|
1139
1139
|
|
|
1140
1140
|
declare const ChainId: {
|
|
1141
1141
|
readonly Sepolia: 11155111;
|
|
1142
|
+
readonly Amoy: 80002;
|
|
1142
1143
|
};
|
|
1143
1144
|
/** Deployed contract addresses indexed by chainId */
|
|
1144
1145
|
declare const contractAddress: {
|
|
1146
|
+
readonly PaymasterImplementation: {
|
|
1147
|
+
readonly 11155111: "0x5ca5652025ca77d13323ed4887b4cbee6098dd8f";
|
|
1148
|
+
readonly 80002: "0xf47d58D3adc642DaD23966698A7A60b8b34D72f8";
|
|
1149
|
+
};
|
|
1145
1150
|
readonly PlatformAccountFactory: {
|
|
1146
|
-
readonly 11155111: "
|
|
1151
|
+
readonly 11155111: "0x1fe801f6af6e9a6c76431db08b121a7de70bc895";
|
|
1152
|
+
readonly 80002: "0x2762abf6fa22314ebcab41dd4666836038d29341";
|
|
1147
1153
|
};
|
|
1148
1154
|
};
|
|
1149
1155
|
|
package/dist/index.js
CHANGED
|
@@ -1491,11 +1491,17 @@ __export(constants_exports, {
|
|
|
1491
1491
|
contractAddress: () => contractAddress
|
|
1492
1492
|
});
|
|
1493
1493
|
var ChainId = {
|
|
1494
|
-
Sepolia: 11155111
|
|
1494
|
+
Sepolia: 11155111,
|
|
1495
|
+
Amoy: 80002
|
|
1495
1496
|
};
|
|
1496
1497
|
var contractAddress = {
|
|
1498
|
+
PaymasterImplementation: {
|
|
1499
|
+
[ChainId.Sepolia]: "0x5ca5652025ca77d13323ed4887b4cbee6098dd8f",
|
|
1500
|
+
[ChainId.Amoy]: "0xf47d58D3adc642DaD23966698A7A60b8b34D72f8"
|
|
1501
|
+
},
|
|
1497
1502
|
PlatformAccountFactory: {
|
|
1498
|
-
[ChainId.Sepolia]: "
|
|
1503
|
+
[ChainId.Sepolia]: "0x1fe801f6af6e9a6c76431db08b121a7de70bc895",
|
|
1504
|
+
[ChainId.Amoy]: "0x2762abf6fa22314ebcab41dd4666836038d29341"
|
|
1499
1505
|
}
|
|
1500
1506
|
};
|
|
1501
1507
|
|
package/dist/index.mjs
CHANGED
|
@@ -1489,11 +1489,17 @@ __export(constants_exports, {
|
|
|
1489
1489
|
contractAddress: () => contractAddress
|
|
1490
1490
|
});
|
|
1491
1491
|
var ChainId = {
|
|
1492
|
-
Sepolia: 11155111
|
|
1492
|
+
Sepolia: 11155111,
|
|
1493
|
+
Amoy: 80002
|
|
1493
1494
|
};
|
|
1494
1495
|
var contractAddress = {
|
|
1496
|
+
PaymasterImplementation: {
|
|
1497
|
+
[ChainId.Sepolia]: "0x5ca5652025ca77d13323ed4887b4cbee6098dd8f",
|
|
1498
|
+
[ChainId.Amoy]: "0xf47d58D3adc642DaD23966698A7A60b8b34D72f8"
|
|
1499
|
+
},
|
|
1495
1500
|
PlatformAccountFactory: {
|
|
1496
|
-
[ChainId.Sepolia]: "
|
|
1501
|
+
[ChainId.Sepolia]: "0x1fe801f6af6e9a6c76431db08b121a7de70bc895",
|
|
1502
|
+
[ChainId.Amoy]: "0x2762abf6fa22314ebcab41dd4666836038d29341"
|
|
1497
1503
|
}
|
|
1498
1504
|
};
|
|
1499
1505
|
|