@trustvc/trustvc 2.15.0-beta.1 → 2.15.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
CHANGED
|
@@ -28,6 +28,15 @@ TrustVC is a comprehensive wrapper library designed to simplify the signing and
|
|
|
28
28
|
- [8. **Document Builder**](#8-document-builder)
|
|
29
29
|
- [9. **Document Store**](#9-document-store)
|
|
30
30
|
- [10. **Transaction Cancel**](#10-transaction-cancel)
|
|
31
|
+
- [11. **Gasless Operations (EIP-7702)**](#11-gasless-operations-eip-7702)
|
|
32
|
+
- [Overview](#overview-1)
|
|
33
|
+
- [deployPlatformPaymaster](#deployplatformpaymaster)
|
|
34
|
+
- [deployTokenRegistryGasless](#deploytokenregistrygasless)
|
|
35
|
+
- [mintGasless](#mintgasless)
|
|
36
|
+
- [Transfer Functions](#transfer-functions)
|
|
37
|
+
- [Reject Transfer Functions](#reject-transfer-functions)
|
|
38
|
+
- [Return to Issuer Functions](#return-to-issuer-functions)
|
|
39
|
+
- [Admin Functions](#admin-functions)
|
|
31
40
|
|
|
32
41
|
## Installation
|
|
33
42
|
|
|
@@ -1203,3 +1212,297 @@ const replacementHash2 = await cancelTransaction(signer, {
|
|
|
1203
1212
|
gasPrice: '25000000000', // 25 gwei in wei
|
|
1204
1213
|
});
|
|
1205
1214
|
```
|
|
1215
|
+
|
|
1216
|
+
---
|
|
1217
|
+
|
|
1218
|
+
## 11. **Gasless Operations (EIP-7702)**
|
|
1219
|
+
|
|
1220
|
+
> **Beta:** Gasless transactions are currently in beta. APIs and contract addresses may change before the stable release. Use on testnet only.
|
|
1221
|
+
|
|
1222
|
+
### Overview
|
|
1223
|
+
|
|
1224
|
+
TrustVC supports gasless trade document operations via **EIP-7702** (smart account delegation) and **ERC-4337** (account abstraction). Users can deploy token registries, mint documents, and perform all title escrow operations without holding ETH — gas is sponsored by a **PlatformPaymaster** deployed per platform.
|
|
1225
|
+
|
|
1226
|
+
**How it works:**
|
|
1227
|
+
|
|
1228
|
+
1. An EOA signs an EIP-7702 authorization, delegating to the `EIP7702Implementation` contract. Its bytecode becomes `0xef0100 || impl_address` while keeping the same address and private key.
|
|
1229
|
+
2. The platform deploys a `PlatformPaymaster` clone via `PlatformAccountFactory`.
|
|
1230
|
+
3. Users submit `UserOperation`s through a bundler (Pimlico). The paymaster validates and sponsors gas for authorized operations.
|
|
1231
|
+
|
|
1232
|
+
All gasless functions accept a `smartAccountClient` built with [permissionless](https://docs.pimlico.io/permissionless) and return `Promise<string>` (transaction hash).
|
|
1233
|
+
|
|
1234
|
+
```ts
|
|
1235
|
+
import { buildSmartAccountClient } from './your-pimlico-setup';
|
|
1236
|
+
|
|
1237
|
+
const { smartAccountClient } = await buildSmartAccountClient(
|
|
1238
|
+
ownerAddress, // delegated EOA
|
|
1239
|
+
paymasterAddress, // platform's PlatformPaymaster
|
|
1240
|
+
);
|
|
1241
|
+
```
|
|
1242
|
+
|
|
1243
|
+
---
|
|
1244
|
+
|
|
1245
|
+
### deployPlatformPaymaster
|
|
1246
|
+
|
|
1247
|
+
Deploys a new `PlatformPaymaster` clone for your platform via `PlatformAccountFactory`. Accepts a viem `WalletClient` or ethers v5/v6 signer.
|
|
1248
|
+
|
|
1249
|
+
```ts
|
|
1250
|
+
import { deployPlatformPaymaster } from '@trustvc/trustvc';
|
|
1251
|
+
import { createWalletClient, createPublicClient, http } from 'viem';
|
|
1252
|
+
import { sepolia } from 'viem/chains';
|
|
1253
|
+
|
|
1254
|
+
const { txHash, paymasterAddress } = await deployPlatformPaymaster(
|
|
1255
|
+
walletClient,
|
|
1256
|
+
{
|
|
1257
|
+
platformAddress: '0xYourPlatformOwner...',
|
|
1258
|
+
dailyLimit: 0n, // 0n = unlimited; set in wei to cap per-user daily spend
|
|
1259
|
+
salt: `0x${'ab'.repeat(32)}`, // bytes32 CREATE2 salt — must be unique per platform
|
|
1260
|
+
},
|
|
1261
|
+
publicClient,
|
|
1262
|
+
);
|
|
1263
|
+
|
|
1264
|
+
console.log('Paymaster deployed at:', paymasterAddress);
|
|
1265
|
+
```
|
|
1266
|
+
|
|
1267
|
+
---
|
|
1268
|
+
|
|
1269
|
+
### deployTokenRegistryGasless
|
|
1270
|
+
|
|
1271
|
+
Deploys a new `TradeTrustToken` registry clone through the paymaster. The caller must have at least 1 deployment credit (`setUserWhitelist`). Emits `RegistryDeployed(user, deployed, creditsLeft)`.
|
|
1272
|
+
|
|
1273
|
+
```ts
|
|
1274
|
+
import { deployTokenRegistryGasless } from '@trustvc/trustvc';
|
|
1275
|
+
|
|
1276
|
+
const txHash = await deployTokenRegistryGasless(
|
|
1277
|
+
'My Shipping Line', // registry name
|
|
1278
|
+
'MSL', // registry symbol
|
|
1279
|
+
smartAccountClient,
|
|
1280
|
+
{
|
|
1281
|
+
paymasterAddress: '0xYourPaymaster...',
|
|
1282
|
+
tokenRegistryImplAddress: '0x64bc665056DC8bE4092e569ED13a7F273Be28cD2', // TDocDeployer on Sepolia
|
|
1283
|
+
},
|
|
1284
|
+
);
|
|
1285
|
+
```
|
|
1286
|
+
|
|
1287
|
+
---
|
|
1288
|
+
|
|
1289
|
+
### mintGasless
|
|
1290
|
+
|
|
1291
|
+
Mints a new trade document on an authorized registry. Automatically authorizes the beneficiary, holder, and the new `TitleEscrow` on the paymaster. Emits `TitleEscrowLinked(titleEscrow, registry)`.
|
|
1292
|
+
|
|
1293
|
+
```ts
|
|
1294
|
+
import { mintGasless } from '@trustvc/trustvc';
|
|
1295
|
+
|
|
1296
|
+
const txHash = await mintGasless(
|
|
1297
|
+
{
|
|
1298
|
+
paymasterAddress: '0xYourPaymaster...',
|
|
1299
|
+
tokenRegistryAddress: '0xYourRegistry...',
|
|
1300
|
+
},
|
|
1301
|
+
smartAccountClient,
|
|
1302
|
+
{
|
|
1303
|
+
beneficiaryAddress: '0xBeneficiary...',
|
|
1304
|
+
holderAddress: '0xHolder...',
|
|
1305
|
+
tokenId: '0xdeadbeef',
|
|
1306
|
+
remarks: 'Initial issuance', // optional — encrypted on-chain with options.id
|
|
1307
|
+
},
|
|
1308
|
+
{ id: 'document-uuid' },
|
|
1309
|
+
);
|
|
1310
|
+
```
|
|
1311
|
+
|
|
1312
|
+
---
|
|
1313
|
+
|
|
1314
|
+
### Transfer Functions
|
|
1315
|
+
|
|
1316
|
+
All transfer functions target the `TitleEscrow` contract. Remarks are automatically encrypted with `options.id` before being sent on-chain.
|
|
1317
|
+
|
|
1318
|
+
#### transferHolderGasless
|
|
1319
|
+
|
|
1320
|
+
Transfers the **holder** role. Caller must be the current holder.
|
|
1321
|
+
|
|
1322
|
+
```ts
|
|
1323
|
+
import { transferHolderGasless } from '@trustvc/trustvc';
|
|
1324
|
+
|
|
1325
|
+
const txHash = await transferHolderGasless(
|
|
1326
|
+
{ titleEscrowAddress: '0xTitleEscrow...' },
|
|
1327
|
+
smartAccountClient,
|
|
1328
|
+
{ holderAddress: '0xNewHolder...', remarks: 'Transferring to forwarder' },
|
|
1329
|
+
{ id: 'document-uuid' },
|
|
1330
|
+
);
|
|
1331
|
+
```
|
|
1332
|
+
|
|
1333
|
+
#### transferBeneficiaryGasless
|
|
1334
|
+
|
|
1335
|
+
Transfers the **beneficiary** role. Caller must be the current beneficiary.
|
|
1336
|
+
|
|
1337
|
+
```ts
|
|
1338
|
+
import { transferBeneficiaryGasless } from '@trustvc/trustvc';
|
|
1339
|
+
|
|
1340
|
+
const txHash = await transferBeneficiaryGasless(
|
|
1341
|
+
{ titleEscrowAddress: '0xTitleEscrow...' },
|
|
1342
|
+
smartAccountClient,
|
|
1343
|
+
{ newBeneficiaryAddress: '0xNewBeneficiary...', remarks: 'Endorsing to buyer' },
|
|
1344
|
+
{ id: 'document-uuid' },
|
|
1345
|
+
);
|
|
1346
|
+
```
|
|
1347
|
+
|
|
1348
|
+
#### transferOwnersGasless
|
|
1349
|
+
|
|
1350
|
+
Transfers both holder and beneficiary in one transaction. Caller must be both.
|
|
1351
|
+
|
|
1352
|
+
```ts
|
|
1353
|
+
import { transferOwnersGasless } from '@trustvc/trustvc';
|
|
1354
|
+
|
|
1355
|
+
const txHash = await transferOwnersGasless(
|
|
1356
|
+
{ titleEscrowAddress: '0xTitleEscrow...' },
|
|
1357
|
+
smartAccountClient,
|
|
1358
|
+
{
|
|
1359
|
+
newBeneficiaryAddress: '0xNewBeneficiary...',
|
|
1360
|
+
newHolderAddress: '0xNewHolder...',
|
|
1361
|
+
remarks: 'Full transfer',
|
|
1362
|
+
},
|
|
1363
|
+
{ id: 'document-uuid' },
|
|
1364
|
+
);
|
|
1365
|
+
```
|
|
1366
|
+
|
|
1367
|
+
#### nominateGasless
|
|
1368
|
+
|
|
1369
|
+
Nominates a new beneficiary without immediately completing the transfer.
|
|
1370
|
+
|
|
1371
|
+
```ts
|
|
1372
|
+
import { nominateGasless } from '@trustvc/trustvc';
|
|
1373
|
+
|
|
1374
|
+
const txHash = await nominateGasless(
|
|
1375
|
+
{ titleEscrowAddress: '0xTitleEscrow...' },
|
|
1376
|
+
smartAccountClient,
|
|
1377
|
+
{ newBeneficiaryAddress: '0xNominated...', remarks: 'Nomination' },
|
|
1378
|
+
{ id: 'document-uuid' },
|
|
1379
|
+
);
|
|
1380
|
+
```
|
|
1381
|
+
|
|
1382
|
+
---
|
|
1383
|
+
|
|
1384
|
+
### Reject Transfer Functions
|
|
1385
|
+
|
|
1386
|
+
Mirror of Token Registry v5's rejection methods — see [section 7](#b-token-registry-v5) for the on-chain rules.
|
|
1387
|
+
|
|
1388
|
+
```ts
|
|
1389
|
+
import {
|
|
1390
|
+
rejectTransferHolderGasless,
|
|
1391
|
+
rejectTransferBeneficiaryGasless,
|
|
1392
|
+
rejectTransferOwnersGasless,
|
|
1393
|
+
} from '@trustvc/trustvc';
|
|
1394
|
+
|
|
1395
|
+
// Reject a pending holder transfer (caller = current holder)
|
|
1396
|
+
await rejectTransferHolderGasless(
|
|
1397
|
+
{ titleEscrowAddress: '0xTitleEscrow...' },
|
|
1398
|
+
smartAccountClient,
|
|
1399
|
+
{ remarks: 'Rejecting transfer' },
|
|
1400
|
+
{ id: 'document-uuid' },
|
|
1401
|
+
);
|
|
1402
|
+
|
|
1403
|
+
// Reject a pending beneficiary nomination (caller = current beneficiary)
|
|
1404
|
+
await rejectTransferBeneficiaryGasless(
|
|
1405
|
+
{ titleEscrowAddress: '0xTitleEscrow...' },
|
|
1406
|
+
smartAccountClient,
|
|
1407
|
+
{ remarks: 'Rejecting nomination' },
|
|
1408
|
+
{ id: 'document-uuid' },
|
|
1409
|
+
);
|
|
1410
|
+
|
|
1411
|
+
// Reject a combined transfer (caller = both holder and beneficiary)
|
|
1412
|
+
await rejectTransferOwnersGasless(
|
|
1413
|
+
{ titleEscrowAddress: '0xTitleEscrow...' },
|
|
1414
|
+
smartAccountClient,
|
|
1415
|
+
{ remarks: 'Rejecting combined transfer' },
|
|
1416
|
+
{ id: 'document-uuid' },
|
|
1417
|
+
);
|
|
1418
|
+
```
|
|
1419
|
+
|
|
1420
|
+
---
|
|
1421
|
+
|
|
1422
|
+
### Return to Issuer Functions
|
|
1423
|
+
|
|
1424
|
+
#### returnToIssuerGasless
|
|
1425
|
+
|
|
1426
|
+
Returns the document to the issuer. Caller must be both holder and beneficiary.
|
|
1427
|
+
|
|
1428
|
+
```ts
|
|
1429
|
+
import { returnToIssuerGasless } from '@trustvc/trustvc';
|
|
1430
|
+
|
|
1431
|
+
await returnToIssuerGasless(
|
|
1432
|
+
{ titleEscrowAddress: '0xTitleEscrow...' },
|
|
1433
|
+
smartAccountClient,
|
|
1434
|
+
{ remarks: 'Surrendering document' },
|
|
1435
|
+
{ id: 'document-uuid' },
|
|
1436
|
+
);
|
|
1437
|
+
```
|
|
1438
|
+
|
|
1439
|
+
#### rejectReturnedGasless
|
|
1440
|
+
|
|
1441
|
+
Restores the document back to the title escrow (registry admin rejects the return).
|
|
1442
|
+
|
|
1443
|
+
```ts
|
|
1444
|
+
import { rejectReturnedGasless } from '@trustvc/trustvc';
|
|
1445
|
+
|
|
1446
|
+
await rejectReturnedGasless(
|
|
1447
|
+
{ tokenRegistryAddress: '0xYourRegistry...' },
|
|
1448
|
+
smartAccountClient,
|
|
1449
|
+
{ tokenId: '0xdeadbeef', remarks: 'Return rejected' },
|
|
1450
|
+
{ id: 'document-uuid' },
|
|
1451
|
+
);
|
|
1452
|
+
```
|
|
1453
|
+
|
|
1454
|
+
#### acceptReturnedGasless
|
|
1455
|
+
|
|
1456
|
+
Burns the document (registry admin accepts the return).
|
|
1457
|
+
|
|
1458
|
+
```ts
|
|
1459
|
+
import { acceptReturnedGasless } from '@trustvc/trustvc';
|
|
1460
|
+
|
|
1461
|
+
await acceptReturnedGasless(
|
|
1462
|
+
{ tokenRegistryAddress: '0xYourRegistry...' },
|
|
1463
|
+
smartAccountClient,
|
|
1464
|
+
{ tokenId: '0xdeadbeef', remarks: 'Document accepted and destroyed' },
|
|
1465
|
+
{ id: 'document-uuid' },
|
|
1466
|
+
);
|
|
1467
|
+
```
|
|
1468
|
+
|
|
1469
|
+
---
|
|
1470
|
+
|
|
1471
|
+
### Admin Functions
|
|
1472
|
+
|
|
1473
|
+
`onlyOwner` functions for managing the `PlatformPaymaster`. All accept a viem `WalletClient` or ethers v5/v6 signer and return `Promise<string>` (tx hash).
|
|
1474
|
+
|
|
1475
|
+
```ts
|
|
1476
|
+
import {
|
|
1477
|
+
setUserWhitelist,
|
|
1478
|
+
removeUserFromWhitelist,
|
|
1479
|
+
addRegistry,
|
|
1480
|
+
removeRegistry,
|
|
1481
|
+
addTitleEscrow,
|
|
1482
|
+
removeTitleEscrow,
|
|
1483
|
+
addAuthorizedCaller,
|
|
1484
|
+
removeAuthorizedCaller,
|
|
1485
|
+
setDailyLimit,
|
|
1486
|
+
} from '@trustvc/trustvc';
|
|
1487
|
+
|
|
1488
|
+
// Grant a user 2 registry deployment credits (max 3)
|
|
1489
|
+
await setUserWhitelist(ownerSigner, paymasterAddress, '0xUser...', 2n);
|
|
1490
|
+
|
|
1491
|
+
// Remove a user from the whitelist
|
|
1492
|
+
await removeUserFromWhitelist(ownerSigner, paymasterAddress, '0xUser...');
|
|
1493
|
+
|
|
1494
|
+
// Authorize a registry so the paymaster will sponsor its calls
|
|
1495
|
+
await addRegistry(ownerSigner, paymasterAddress, '0xRegistry...');
|
|
1496
|
+
await removeRegistry(ownerSigner, paymasterAddress, '0xRegistry...');
|
|
1497
|
+
|
|
1498
|
+
// Authorize a title escrow
|
|
1499
|
+
await addTitleEscrow(ownerSigner, paymasterAddress, '0xTitleEscrow...');
|
|
1500
|
+
await removeTitleEscrow(ownerSigner, paymasterAddress, '0xTitleEscrow...');
|
|
1501
|
+
|
|
1502
|
+
// Manage authorized callers (beneficiary / holder addresses for Path A)
|
|
1503
|
+
await addAuthorizedCaller(ownerSigner, paymasterAddress, '0xCaller...');
|
|
1504
|
+
await removeAuthorizedCaller(ownerSigner, paymasterAddress, '0xCaller...');
|
|
1505
|
+
|
|
1506
|
+
// Update the per-user daily gas spend cap (0n = unlimited)
|
|
1507
|
+
await setDailyLimit(ownerSigner, paymasterAddress, 0n);
|
|
1508
|
+
```
|
|
@@ -3,24 +3,29 @@
|
|
|
3
3
|
var tokenRegistryFunctionsGasless = require('./token-registry-functions-gasless');
|
|
4
4
|
var deploy = require('./deploy');
|
|
5
5
|
var platformPaymasterFunctions = require('./platform-paymaster-functions');
|
|
6
|
+
var eip7702 = require('@trustvc/eip7702');
|
|
6
7
|
|
|
7
8
|
|
|
8
9
|
|
|
10
|
+
Object.defineProperty(exports, "eip7702Abis", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function () { return eip7702.abis; }
|
|
13
|
+
});
|
|
9
14
|
Object.keys(tokenRegistryFunctionsGasless).forEach(function (k) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return tokenRegistryFunctionsGasless[k]; }
|
|
18
|
+
});
|
|
14
19
|
});
|
|
15
20
|
Object.keys(deploy).forEach(function (k) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
get: function () { return deploy[k]; }
|
|
24
|
+
});
|
|
20
25
|
});
|
|
21
26
|
Object.keys(platformPaymasterFunctions).forEach(function (k) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
28
|
+
enumerable: true,
|
|
29
|
+
get: function () { return platformPaymasterFunctions[k]; }
|
|
30
|
+
});
|
|
26
31
|
});
|
|
@@ -5,6 +5,7 @@ export { nominateGasless, transferBeneficiaryGasless, transferHolderGasless, tra
|
|
|
5
5
|
export { DeployPlatformPaymasterOptions, DeployPlatformPaymasterResult, deployPlatformPaymaster } from './deploy/platform-paymaster.js';
|
|
6
6
|
export { DeployTokenRegistryGaslessOptions, deployTokenRegistryGasless } from './deploy/token-registry.js';
|
|
7
7
|
export { addAuthorizedCaller, addRegistry, addTitleEscrow, removeAuthorizedCaller, removeRegistry, removeTitleEscrow, removeUserFromWhitelist, setDailyLimit, setUserWhitelist } from './platform-paymaster-functions/admin.js';
|
|
8
|
+
export { abis as eip7702Abis } from '@trustvc/eip7702';
|
|
8
9
|
import '../token-registry-functions/types.js';
|
|
9
10
|
import '../utils/supportedChains/index.js';
|
|
10
11
|
import '../utils/gasStation/index.js';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -33,6 +33,7 @@ export { nominateGasless, transferBeneficiaryGasless, transferHolderGasless, tra
|
|
|
33
33
|
export { DeployPlatformPaymasterOptions, DeployPlatformPaymasterResult, deployPlatformPaymaster } from './eip7702-functions/deploy/platform-paymaster.js';
|
|
34
34
|
export { DeployTokenRegistryGaslessOptions, deployTokenRegistryGasless } from './eip7702-functions/deploy/token-registry.js';
|
|
35
35
|
export { addAuthorizedCaller, addRegistry, addTitleEscrow, removeAuthorizedCaller, removeRegistry, removeTitleEscrow, removeUserFromWhitelist, setDailyLimit, setUserWhitelist } from './eip7702-functions/platform-paymaster-functions/admin.js';
|
|
36
|
+
export { abis as eip7702Abis } from '@trustvc/eip7702';
|
|
36
37
|
export { decrypt } from './core/decrypt.js';
|
|
37
38
|
export { encrypt } from './core/encrypt.js';
|
|
38
39
|
export { verifyDocument } from './core/verify.js';
|