@dynamic-labs/ethereum-aa-zksync 4.18.6 → 4.18.8
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/CHANGELOG.md +27 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +9 -9
- package/src/connector/ZKsyncConnector.cjs +176 -47
- package/src/connector/ZKsyncConnector.d.ts +14 -9
- package/src/connector/ZKsyncConnector.js +177 -48
- package/src/index.d.ts +1 -0
- package/src/types/index.d.ts +26 -0
- package/src/utils/index.d.ts +1 -0
- package/src/utils/session.cjs +52 -0
- package/src/utils/session.d.ts +11 -0
- package/src/utils/session.js +44 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,31 @@
|
|
|
1
1
|
|
|
2
|
+
### [4.18.8](https://github.com/dynamic-labs/dynamic-auth/compare/v4.18.7...v4.18.8) (2025-05-22)
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* allow closing widget right after login ([#8760](https://github.com/dynamic-labs/dynamic-auth/issues/8760)) ([a9afff0](https://github.com/dynamic-labs/dynamic-auth/commit/a9afff0ab2a685853b39aed88e10bf1e700e4c8c))
|
|
7
|
+
* user wallets turning empty when linking new wallets ([#8775](https://github.com/dynamic-labs/dynamic-auth/issues/8775)) ([04215f5](https://github.com/dynamic-labs/dynamic-auth/commit/04215f5307e16ec4e1a7ff235a0d7df2340c3447))
|
|
8
|
+
|
|
9
|
+
### [4.18.7](https://github.com/dynamic-labs/dynamic-auth/compare/v4.18.6...v4.18.7) (2025-05-21)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
* add zero dev kernel migration to v3.3 ([#8747](https://github.com/dynamic-labs/dynamic-auth/issues/8747)) ([ce10ef8](https://github.com/dynamic-labs/dynamic-auth/commit/ce10ef85d12452c2c21758c909f1e28f9fa5fbae))
|
|
15
|
+
* bump [@dynamic-labs-wallet](https://github.com/dynamic-labs-wallet) to v0.0.74 ([#8746](https://github.com/dynamic-labs/dynamic-auth/issues/8746)) ([98e3a0b](https://github.com/dynamic-labs/dynamic-auth/commit/98e3a0b845e7d6c34a2c748597198825713f4bcf))
|
|
16
|
+
* support kernel versio 0.3.2 and 0.3.3 ([#8738](https://github.com/dynamic-labs/dynamic-auth/issues/8738)) ([1115830](https://github.com/dynamic-labs/dynamic-auth/commit/1115830966318960d39a497c8b29188d9d9a447f))
|
|
17
|
+
* v3 solana confirmation ui ([#8731](https://github.com/dynamic-labs/dynamic-auth/issues/8731)) ([cfa5ba0](https://github.com/dynamic-labs/dynamic-auth/commit/cfa5ba07a946b847e60388c80afbd8aa233e9ebf))
|
|
18
|
+
* v3 svm send balance ([#8726](https://github.com/dynamic-labs/dynamic-auth/issues/8726)) ([236ec48](https://github.com/dynamic-labs/dynamic-auth/commit/236ec4843152f4b720aa7332e650db68c2d111b2))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
### Bug Fixes
|
|
22
|
+
|
|
23
|
+
* **alex/qntm-3201:** send empty data field when using zksync sendbalance ([#8733](https://github.com/dynamic-labs/dynamic-auth/issues/8733)) ([4c42035](https://github.com/dynamic-labs/dynamic-auth/commit/4c420350cf7404ac80db8b552594233a3de9fb57))
|
|
24
|
+
* allow for continuing signing if zksync account exists while attempting to deploy ([#8736](https://github.com/dynamic-labs/dynamic-auth/issues/8736)) ([1ff82e4](https://github.com/dynamic-labs/dynamic-auth/commit/1ff82e418e14300b9dec662fba517c5533c1caac))
|
|
25
|
+
* api kernel version on react native extension ([#8754](https://github.com/dynamic-labs/dynamic-auth/issues/8754)) ([c2f0bb4](https://github.com/dynamic-labs/dynamic-auth/commit/c2f0bb4ac86214f4e3bbdac5cf4b481a7a304449))
|
|
26
|
+
* CTRL wallet eip6963 detection ([#8727](https://github.com/dynamic-labs/dynamic-auth/issues/8727)) ([194334f](https://github.com/dynamic-labs/dynamic-auth/commit/194334f7fd541917d9a7f6b452145a47cf7ae853))
|
|
27
|
+
* **QNTM-3249:** fix mobile layout alignment in send view ([#8740](https://github.com/dynamic-labs/dynamic-auth/issues/8740)) ([7d8e02c](https://github.com/dynamic-labs/dynamic-auth/commit/7d8e02c11830f547b6fcfbc7b518ee3f045df41a))
|
|
28
|
+
|
|
2
29
|
### [4.18.6](https://github.com/dynamic-labs/dynamic-auth/compare/v4.18.5...v4.18.6) (2025-05-16)
|
|
3
30
|
|
|
4
31
|
|
package/package.cjs
CHANGED
package/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/ethereum-aa-zksync",
|
|
3
|
-
"version": "4.18.
|
|
3
|
+
"version": "4.18.8",
|
|
4
4
|
"description": "Core package for Ethereum Account Abstraction utilities and types",
|
|
5
5
|
"author": "Dynamic Labs, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
},
|
|
19
19
|
"homepage": "https://www.dynamic.xyz/",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@dynamic-labs/sdk-api-core": "0.0.
|
|
21
|
+
"@dynamic-labs/sdk-api-core": "0.0.672",
|
|
22
22
|
"zksync-sso": "0.1.0",
|
|
23
|
-
"@dynamic-labs/assert-package-version": "4.18.
|
|
24
|
-
"@dynamic-labs/ethereum-aa-core": "4.18.
|
|
25
|
-
"@dynamic-labs/ethereum-core": "4.18.
|
|
26
|
-
"@dynamic-labs/types": "4.18.
|
|
27
|
-
"@dynamic-labs/utils": "4.18.
|
|
28
|
-
"@dynamic-labs/wallet-book": "4.18.
|
|
29
|
-
"@dynamic-labs/wallet-connector-core": "4.18.
|
|
23
|
+
"@dynamic-labs/assert-package-version": "4.18.8",
|
|
24
|
+
"@dynamic-labs/ethereum-aa-core": "4.18.8",
|
|
25
|
+
"@dynamic-labs/ethereum-core": "4.18.8",
|
|
26
|
+
"@dynamic-labs/types": "4.18.8",
|
|
27
|
+
"@dynamic-labs/utils": "4.18.8",
|
|
28
|
+
"@dynamic-labs/wallet-book": "4.18.8",
|
|
29
|
+
"@dynamic-labs/wallet-connector-core": "4.18.8"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"viem": "^2.21.60"
|
|
@@ -6,17 +6,21 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
6
6
|
var _tslib = require('../../_virtual/_tslib.cjs');
|
|
7
7
|
var viem = require('viem');
|
|
8
8
|
var zksync = require('viem/zksync');
|
|
9
|
+
var abi = require('zksync-sso/abi');
|
|
9
10
|
var passkey = require('zksync-sso/client/passkey');
|
|
10
11
|
var utils$1 = require('zksync-sso/utils');
|
|
11
12
|
var client = require('zksync-sso/client');
|
|
12
13
|
var ecdsa = require('zksync-sso/client/ecdsa');
|
|
14
|
+
var accounts = require('viem/accounts');
|
|
13
15
|
var ethereumCore = require('@dynamic-labs/ethereum-core');
|
|
14
16
|
var utils = require('@dynamic-labs/utils');
|
|
17
|
+
var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
|
|
15
18
|
var ethereumAaCore = require('@dynamic-labs/ethereum-aa-core');
|
|
16
19
|
var getSalt = require('../utils/getSalt.cjs');
|
|
17
20
|
var passkeys = require('../utils/passkeys.cjs');
|
|
18
21
|
var deployment = require('../utils/deployment.cjs');
|
|
19
22
|
var network = require('../utils/network.cjs');
|
|
23
|
+
var session = require('../utils/session.cjs');
|
|
20
24
|
|
|
21
25
|
class ZKsyncConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
|
|
22
26
|
constructor(props) {
|
|
@@ -315,33 +319,18 @@ class ZKsyncConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
|
|
|
315
319
|
}
|
|
316
320
|
deploySmartAccount(_a) {
|
|
317
321
|
return _tslib.__awaiter(this, arguments, void 0, function* ({ withPaymaster, }) {
|
|
322
|
+
var _b, _c;
|
|
318
323
|
if (!this.chainId) {
|
|
319
324
|
throw new Error('Chain ID is not initialized');
|
|
320
325
|
}
|
|
321
|
-
if (!this.eoaConnector) {
|
|
326
|
+
if (!this.eoaConnector || !this.eoaAddress) {
|
|
322
327
|
throw new Error('EOA connector is not initialized');
|
|
323
328
|
}
|
|
324
|
-
yield network.ensureEoaConnectorNetwork(this.eoaConnector, this.chainId);
|
|
325
|
-
if (withPaymaster && this.paymasterAddress) {
|
|
326
|
-
yield this.deploySmartAccountWithPaymaster();
|
|
327
|
-
}
|
|
328
|
-
else {
|
|
329
|
-
yield this.deploySmartAccountWithoutPaymaster();
|
|
330
|
-
}
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
deploySmartAccountWithPaymaster() {
|
|
334
|
-
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
335
|
-
if (!this.paymasterAddress) {
|
|
336
|
-
throw new Error('Paymaster address is not initialized');
|
|
337
|
-
}
|
|
338
329
|
if (!this.smartAccountAddress) {
|
|
339
330
|
throw new Error('Smart account address is not initialized');
|
|
340
331
|
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
}
|
|
344
|
-
const paymaster = this.paymasterAddress;
|
|
332
|
+
yield network.ensureEoaConnectorNetwork(this.eoaConnector, this.chainId);
|
|
333
|
+
const deployWithPaymaster = withPaymaster && this.paymasterAddress;
|
|
345
334
|
const publicClient = yield this.getTypedPublicClient();
|
|
346
335
|
const walletClient = yield this.getTypedWalletClient();
|
|
347
336
|
const deploymentParams = yield deployment.getDeploymentParameters({
|
|
@@ -351,36 +340,23 @@ class ZKsyncConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
|
|
|
351
340
|
saltText: this.saltText,
|
|
352
341
|
sessionKeyAddress: this.sessionKeyAddress,
|
|
353
342
|
});
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
364
|
-
/**
|
|
365
|
-
* Deploys a new smart account contract
|
|
366
|
-
* @throws {ZkSyncConnectorError} If deployment fails
|
|
367
|
-
* @testable This method can be mocked in tests
|
|
368
|
-
*/
|
|
369
|
-
deploySmartAccountWithoutPaymaster() {
|
|
370
|
-
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
371
|
-
if (!this.eoaConnector) {
|
|
372
|
-
throw new Error('EOA connector is not initialized');
|
|
343
|
+
try {
|
|
344
|
+
let { request } = yield deployment.simulateAccountDeployment(publicClient, walletClient, deploymentParams, this.factoryAddress, !deployWithPaymaster);
|
|
345
|
+
if (deployWithPaymaster) {
|
|
346
|
+
const paymasterInput = zksync.getGeneralPaymasterInput({
|
|
347
|
+
innerInput: new Uint8Array(),
|
|
348
|
+
});
|
|
349
|
+
request = Object.assign(Object.assign({}, request), { paymaster: this.paymasterAddress, paymasterInput });
|
|
350
|
+
}
|
|
351
|
+
yield deployment.executeAccountDeployment(walletClient, publicClient, request, this.smartAccountAddress);
|
|
373
352
|
}
|
|
374
|
-
|
|
375
|
-
|
|
353
|
+
catch (error) {
|
|
354
|
+
// If the account already exists, we don't want to throw an error and continue
|
|
355
|
+
if (((_c = (_b = error === null || error === void 0 ? void 0 : error.cause) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.errorName) !== 'ACCOUNT_ALREADY_EXISTS') {
|
|
356
|
+
throw error;
|
|
357
|
+
}
|
|
376
358
|
}
|
|
377
|
-
|
|
378
|
-
const publicClient = yield this.getTypedPublicClient();
|
|
379
|
-
const deploymentParams = yield this.getDeploymentParameters();
|
|
380
|
-
// Simulate the contract deployment first
|
|
381
|
-
const { request } = yield deployment.simulateAccountDeployment(publicClient, walletClient, deploymentParams, this.factoryAddress, false);
|
|
382
|
-
// Execute the deployment transaction
|
|
383
|
-
yield deployment.executeAccountDeployment(walletClient, publicClient, request, this.smartAccountAddress);
|
|
359
|
+
this._isSmartAccountDeployed = true;
|
|
384
360
|
});
|
|
385
361
|
}
|
|
386
362
|
/**
|
|
@@ -489,6 +465,106 @@ class ZKsyncConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
|
|
|
489
465
|
return isDeployed;
|
|
490
466
|
});
|
|
491
467
|
}
|
|
468
|
+
getSmartAccountCreationBlock() {
|
|
469
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
470
|
+
if (!this.smartAccountAddress) {
|
|
471
|
+
throw new Error('Smart account address is not initialized');
|
|
472
|
+
}
|
|
473
|
+
// check cache first
|
|
474
|
+
const cachedBlock = utils.StorageService.getItem(`smart-account-creation-block-${this.smartAccountAddress}`);
|
|
475
|
+
if (cachedBlock) {
|
|
476
|
+
return Number(cachedBlock);
|
|
477
|
+
}
|
|
478
|
+
const publicClient = yield this.getPublicClient();
|
|
479
|
+
try {
|
|
480
|
+
const createAccountLogs = yield publicClient.getContractEvents({
|
|
481
|
+
abi: abi.AAFactoryAbi,
|
|
482
|
+
address: this.factoryAddress,
|
|
483
|
+
args: {
|
|
484
|
+
accountAddress: this.smartAccountAddress,
|
|
485
|
+
},
|
|
486
|
+
eventName: 'AccountCreated',
|
|
487
|
+
fromBlock: BigInt(0),
|
|
488
|
+
});
|
|
489
|
+
if (createAccountLogs.length === 0) {
|
|
490
|
+
return 0;
|
|
491
|
+
}
|
|
492
|
+
// cache the block number
|
|
493
|
+
utils.StorageService.setItem(`smart-account-creation-block-${this.smartAccountAddress}`, createAccountLogs[0].blockNumber.toString());
|
|
494
|
+
return Number(createAccountLogs[0].blockNumber);
|
|
495
|
+
}
|
|
496
|
+
catch (error) {
|
|
497
|
+
walletConnectorCore.logger.error('[ZKsyncConnector] Error getting smart account creation block: ', error);
|
|
498
|
+
return 0;
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
listSessions() {
|
|
503
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
504
|
+
if (!this.smartAccount) {
|
|
505
|
+
throw new Error('Smart account is not initialized');
|
|
506
|
+
}
|
|
507
|
+
if (!this._isSmartAccountDeployed) {
|
|
508
|
+
return [];
|
|
509
|
+
}
|
|
510
|
+
const smartAccountCreationBlock = yield this.getSmartAccountCreationBlock();
|
|
511
|
+
const publicClient = yield this.getPublicClient();
|
|
512
|
+
try {
|
|
513
|
+
// Get all created session information
|
|
514
|
+
const createSessionLogs = (yield publicClient.getContractEvents({
|
|
515
|
+
abi: abi.SessionKeyValidatorAbi,
|
|
516
|
+
address: this.sessionKeyAddress,
|
|
517
|
+
args: {
|
|
518
|
+
account: this.smartAccountAddress,
|
|
519
|
+
},
|
|
520
|
+
eventName: 'SessionCreated',
|
|
521
|
+
// only get sessions from the block when the smart account was created
|
|
522
|
+
fromBlock: BigInt(smartAccountCreationBlock),
|
|
523
|
+
})).filter((log) => log.args.sessionSpec && log.args.sessionHash);
|
|
524
|
+
// Get all revoked session hashes
|
|
525
|
+
const revokedSessionHashes = (yield publicClient.getContractEvents({
|
|
526
|
+
abi: abi.SessionKeyValidatorAbi,
|
|
527
|
+
address: this.sessionKeyAddress,
|
|
528
|
+
args: {
|
|
529
|
+
account: this.smartAccountAddress,
|
|
530
|
+
},
|
|
531
|
+
eventName: 'SessionRevoked',
|
|
532
|
+
// only get sessions from the block when the smart account was created
|
|
533
|
+
fromBlock: BigInt(smartAccountCreationBlock),
|
|
534
|
+
}))
|
|
535
|
+
.filter((log) => log.args.sessionHash)
|
|
536
|
+
.map((log) => log.args.sessionHash);
|
|
537
|
+
const activeSessions = createSessionLogs
|
|
538
|
+
.filter((log) => log.args.sessionHash &&
|
|
539
|
+
// filter out the sessions that have been revoked
|
|
540
|
+
!revokedSessionHashes.includes(log.args.sessionHash))
|
|
541
|
+
.map((log) => ({
|
|
542
|
+
blockNumber: log.blockNumber,
|
|
543
|
+
session: log.args.sessionSpec,
|
|
544
|
+
sessionId: log.args.sessionHash,
|
|
545
|
+
timestamp: new Date(
|
|
546
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
547
|
+
parseInt(log.blockTimestamp, 16) * 1000).getTime(),
|
|
548
|
+
transactionHash: log.transactionHash,
|
|
549
|
+
}))
|
|
550
|
+
.sort((a, b) => {
|
|
551
|
+
if (a.blockNumber < b.blockNumber)
|
|
552
|
+
return 1;
|
|
553
|
+
if (a.blockNumber > b.blockNumber)
|
|
554
|
+
return -1;
|
|
555
|
+
return 0;
|
|
556
|
+
});
|
|
557
|
+
return activeSessions.map((session$1) => {
|
|
558
|
+
var _a;
|
|
559
|
+
return (Object.assign(Object.assign({}, session$1), { origin: (_a = session.retrieveSessionFromStorage(session$1.sessionId)) === null || _a === void 0 ? void 0 : _a.origin }));
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
catch (error) {
|
|
563
|
+
walletConnectorCore.logger.error('[ZKsyncConnector] Error listing sessions: ', error);
|
|
564
|
+
return [];
|
|
565
|
+
}
|
|
566
|
+
});
|
|
567
|
+
}
|
|
492
568
|
getAddress() {
|
|
493
569
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
494
570
|
var _a;
|
|
@@ -499,6 +575,59 @@ class ZKsyncConnector extends ethereumAaCore.AccountAbstractionBaseConnector {
|
|
|
499
575
|
return this.smartAccountAddress;
|
|
500
576
|
});
|
|
501
577
|
}
|
|
578
|
+
revokeSession(sessionId) {
|
|
579
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
580
|
+
if (!this.smartAccount) {
|
|
581
|
+
throw new Error('Smart account is not initialized');
|
|
582
|
+
}
|
|
583
|
+
const params = {
|
|
584
|
+
sessionId,
|
|
585
|
+
};
|
|
586
|
+
if (this.paymasterAddress) {
|
|
587
|
+
params.paymaster = {
|
|
588
|
+
address: this.paymasterAddress,
|
|
589
|
+
paymasterInput: zksync.getGeneralPaymasterInput({
|
|
590
|
+
innerInput: new Uint8Array(),
|
|
591
|
+
}),
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
yield this.smartAccount.revokeSession(params);
|
|
595
|
+
utils.StorageService.removeItem(`zksync-session-${sessionId}`);
|
|
596
|
+
});
|
|
597
|
+
}
|
|
598
|
+
createSession(_a) {
|
|
599
|
+
return _tslib.__awaiter(this, arguments, void 0, function* ({ sessionConfig, origin, }) {
|
|
600
|
+
if (!this.smartAccount) {
|
|
601
|
+
throw new Error('Smart account is not initialized');
|
|
602
|
+
}
|
|
603
|
+
const safeSessionConfig = session.enforceSessionConfigRestrictions(sessionConfig);
|
|
604
|
+
const privateKey = accounts.generatePrivateKey();
|
|
605
|
+
const signer = accounts.privateKeyToAccount(privateKey);
|
|
606
|
+
const params = {
|
|
607
|
+
sessionConfig: Object.assign(Object.assign({}, safeSessionConfig), { signer: signer.address }),
|
|
608
|
+
};
|
|
609
|
+
if (this.paymasterAddress) {
|
|
610
|
+
params.paymaster = {
|
|
611
|
+
address: this.paymasterAddress,
|
|
612
|
+
paymasterInput: zksync.getGeneralPaymasterInput({
|
|
613
|
+
innerInput: new Uint8Array(),
|
|
614
|
+
}),
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
yield this.smartAccount.createSession(params);
|
|
618
|
+
const sessionHash = session.getSessionHash(params.sessionConfig);
|
|
619
|
+
const serializedSessionConfig = session.stringifySessionConfig(params.sessionConfig);
|
|
620
|
+
const originURI = origin
|
|
621
|
+
? new URL(origin).hostname
|
|
622
|
+
: utils.PlatformService.getHostname();
|
|
623
|
+
utils.StorageService.setItem(`zksync-session-${sessionHash}`, {
|
|
624
|
+
origin: originURI,
|
|
625
|
+
sessionConfig: serializedSessionConfig,
|
|
626
|
+
sessionKey: privateKey,
|
|
627
|
+
});
|
|
628
|
+
return { expiresAt: safeSessionConfig.expiresAt, sessionId: sessionHash };
|
|
629
|
+
});
|
|
630
|
+
}
|
|
502
631
|
validateActiveWallet(expectedAddress) {
|
|
503
632
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
504
633
|
const currentAddress = yield this.getAddress();
|
|
@@ -3,6 +3,7 @@ import { ZksyncSsoPasskeyClient } from 'zksync-sso/client/passkey';
|
|
|
3
3
|
import { SessionConfig } from 'zksync-sso/utils';
|
|
4
4
|
import { ZksyncSsoSessionClient } from 'zksync-sso/client';
|
|
5
5
|
import { ZksyncSsoEcdsaClient } from 'zksync-sso/client/ecdsa';
|
|
6
|
+
import { CreateSessionArgs, RevokeSessionArgs } from 'node_modules/zksync-sso/dist/_types/client/session/actions/session';
|
|
6
7
|
import { EthereumWallet, RegisterEvmProvidersConfig } from '@dynamic-labs/ethereum-core';
|
|
7
8
|
import { ProjectSettings, Provider, ProviderEnum } from '@dynamic-labs/sdk-api-core';
|
|
8
9
|
import { EvmNetwork, GenericNetwork, WalletUiUtils } from '@dynamic-labs/types';
|
|
@@ -10,6 +11,7 @@ import { WalletBookSchema } from '@dynamic-labs/wallet-book';
|
|
|
10
11
|
import { Chain, IAccountAbstractionWalletConnector, InternalWalletConnector, WalletConnector } from '@dynamic-labs/wallet-connector-core';
|
|
11
12
|
import { AccountAbstractionBaseConnector, AccountAbstractionConnectorProps } from '@dynamic-labs/ethereum-aa-core';
|
|
12
13
|
import { DeploymentParams } from '../utils';
|
|
14
|
+
import { SessionInformation, SessionConfigWithoutSigner } from '../types';
|
|
13
15
|
type ZKsyncConnectorProps = AccountAbstractionConnectorProps & {
|
|
14
16
|
apiProviders: {
|
|
15
17
|
[key in ProviderEnum]?: Provider;
|
|
@@ -16528,8 +16530,8 @@ export declare class ZKsyncConnector extends AccountAbstractionBaseConnector imp
|
|
|
16528
16530
|
sourceId?: number | undefined;
|
|
16529
16531
|
testnet?: boolean | undefined;
|
|
16530
16532
|
} & import("viem").ChainConfig<import("viem").ChainFormatters | undefined, Record<string, unknown> | undefined>, Account, chainOverride_9>) => Promise<`0x${string}`>;
|
|
16531
|
-
createSession: (args: Omit<
|
|
16532
|
-
revokeSession: (args: Omit<
|
|
16533
|
+
createSession: (args: Omit<CreateSessionArgs, "contracts">) => Promise<import("node_modules/zksync-sso/dist/_types/client/session/actions/session").CreateSessionReturnType>;
|
|
16534
|
+
revokeSession: (args: Omit<RevokeSessionArgs, "contracts">) => Promise<import("node_modules/zksync-sso/dist/_types/client/session/actions/session").RevokeSessionReturnType>;
|
|
16533
16535
|
extend: <const client extends {
|
|
16534
16536
|
[x: string]: unknown;
|
|
16535
16537
|
account?: undefined;
|
|
@@ -17668,13 +17670,6 @@ export declare class ZKsyncConnector extends AccountAbstractionBaseConnector imp
|
|
|
17668
17670
|
deploySmartAccount({ withPaymaster, }: {
|
|
17669
17671
|
withPaymaster: boolean;
|
|
17670
17672
|
}): Promise<void>;
|
|
17671
|
-
private deploySmartAccountWithPaymaster;
|
|
17672
|
-
/**
|
|
17673
|
-
* Deploys a new smart account contract
|
|
17674
|
-
* @throws {ZkSyncConnectorError} If deployment fails
|
|
17675
|
-
* @testable This method can be mocked in tests
|
|
17676
|
-
*/
|
|
17677
|
-
private deploySmartAccountWithoutPaymaster;
|
|
17678
17673
|
/**
|
|
17679
17674
|
* Gets typed public client from EOA connector
|
|
17680
17675
|
* @throws {ZkSyncConnectorError} If public client cannot be obtained
|
|
@@ -17700,7 +17695,17 @@ export declare class ZKsyncConnector extends AccountAbstractionBaseConnector imp
|
|
|
17700
17695
|
* @returns Promise that resolves when the check is complete
|
|
17701
17696
|
*/
|
|
17702
17697
|
protected checkIsDeployed(): Promise<boolean>;
|
|
17698
|
+
private getSmartAccountCreationBlock;
|
|
17699
|
+
listSessions(): Promise<SessionInformation[]>;
|
|
17703
17700
|
getAddress(): Promise<string | undefined>;
|
|
17701
|
+
revokeSession(sessionId: `0x${string}`): Promise<void>;
|
|
17702
|
+
createSession({ sessionConfig, origin, }: {
|
|
17703
|
+
sessionConfig: SessionConfigWithoutSigner;
|
|
17704
|
+
origin?: string;
|
|
17705
|
+
}): Promise<{
|
|
17706
|
+
expiresAt: bigint;
|
|
17707
|
+
sessionId: `0x${string}`;
|
|
17708
|
+
}>;
|
|
17704
17709
|
validateActiveWallet(expectedAddress: string): Promise<void>;
|
|
17705
17710
|
isSmartAccountDeployed(refetch?: boolean): Promise<boolean>;
|
|
17706
17711
|
}
|
|
@@ -2,17 +2,21 @@
|
|
|
2
2
|
import { __awaiter } from '../../_virtual/_tslib.js';
|
|
3
3
|
import { createWalletClient, custom, publicActions, createPublicClient, http, walletActions, toHex } from 'viem';
|
|
4
4
|
import { getGeneralPaymasterInput, eip712WalletActions } from 'viem/zksync';
|
|
5
|
+
import { AAFactoryAbi, SessionKeyValidatorAbi } from 'zksync-sso/abi';
|
|
5
6
|
import { createZksyncPasskeyClient, registerNewPasskey } from 'zksync-sso/client/passkey';
|
|
6
7
|
import { encodeModuleData } from 'zksync-sso/utils';
|
|
7
8
|
import { createZksyncSessionClient } from 'zksync-sso/client';
|
|
8
9
|
import { createZksyncEcdsaClient, zksyncSsoEcdsaWalletActions } from 'zksync-sso/client/ecdsa';
|
|
10
|
+
import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
|
|
9
11
|
import { EthereumWallet, chainsMap, confirmationTransport, getOrMapViemChain } from '@dynamic-labs/ethereum-core';
|
|
10
|
-
import { parseEvmNetworks, DeferredPromise, StorageService, DynamicError } from '@dynamic-labs/utils';
|
|
12
|
+
import { parseEvmNetworks, DeferredPromise, StorageService, PlatformService, DynamicError } from '@dynamic-labs/utils';
|
|
13
|
+
import { logger } from '@dynamic-labs/wallet-connector-core';
|
|
11
14
|
import { AccountAbstractionBaseConnector } from '@dynamic-labs/ethereum-aa-core';
|
|
12
15
|
import { getSalt } from '../utils/getSalt.js';
|
|
13
16
|
import { getEncodedPasskeyModuleData } from '../utils/passkeys.js';
|
|
14
17
|
import { getDeploymentParameters, simulateAccountDeployment, executeAccountDeployment } from '../utils/deployment.js';
|
|
15
18
|
import { ensureEoaConnectorNetwork } from '../utils/network.js';
|
|
19
|
+
import { retrieveSessionFromStorage, enforceSessionConfigRestrictions, getSessionHash, stringifySessionConfig } from '../utils/session.js';
|
|
16
20
|
|
|
17
21
|
class ZKsyncConnector extends AccountAbstractionBaseConnector {
|
|
18
22
|
constructor(props) {
|
|
@@ -311,33 +315,18 @@ class ZKsyncConnector extends AccountAbstractionBaseConnector {
|
|
|
311
315
|
}
|
|
312
316
|
deploySmartAccount(_a) {
|
|
313
317
|
return __awaiter(this, arguments, void 0, function* ({ withPaymaster, }) {
|
|
318
|
+
var _b, _c;
|
|
314
319
|
if (!this.chainId) {
|
|
315
320
|
throw new Error('Chain ID is not initialized');
|
|
316
321
|
}
|
|
317
|
-
if (!this.eoaConnector) {
|
|
322
|
+
if (!this.eoaConnector || !this.eoaAddress) {
|
|
318
323
|
throw new Error('EOA connector is not initialized');
|
|
319
324
|
}
|
|
320
|
-
yield ensureEoaConnectorNetwork(this.eoaConnector, this.chainId);
|
|
321
|
-
if (withPaymaster && this.paymasterAddress) {
|
|
322
|
-
yield this.deploySmartAccountWithPaymaster();
|
|
323
|
-
}
|
|
324
|
-
else {
|
|
325
|
-
yield this.deploySmartAccountWithoutPaymaster();
|
|
326
|
-
}
|
|
327
|
-
});
|
|
328
|
-
}
|
|
329
|
-
deploySmartAccountWithPaymaster() {
|
|
330
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
331
|
-
if (!this.paymasterAddress) {
|
|
332
|
-
throw new Error('Paymaster address is not initialized');
|
|
333
|
-
}
|
|
334
325
|
if (!this.smartAccountAddress) {
|
|
335
326
|
throw new Error('Smart account address is not initialized');
|
|
336
327
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
const paymaster = this.paymasterAddress;
|
|
328
|
+
yield ensureEoaConnectorNetwork(this.eoaConnector, this.chainId);
|
|
329
|
+
const deployWithPaymaster = withPaymaster && this.paymasterAddress;
|
|
341
330
|
const publicClient = yield this.getTypedPublicClient();
|
|
342
331
|
const walletClient = yield this.getTypedWalletClient();
|
|
343
332
|
const deploymentParams = yield getDeploymentParameters({
|
|
@@ -347,36 +336,23 @@ class ZKsyncConnector extends AccountAbstractionBaseConnector {
|
|
|
347
336
|
saltText: this.saltText,
|
|
348
337
|
sessionKeyAddress: this.sessionKeyAddress,
|
|
349
338
|
});
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
}
|
|
360
|
-
/**
|
|
361
|
-
* Deploys a new smart account contract
|
|
362
|
-
* @throws {ZkSyncConnectorError} If deployment fails
|
|
363
|
-
* @testable This method can be mocked in tests
|
|
364
|
-
*/
|
|
365
|
-
deploySmartAccountWithoutPaymaster() {
|
|
366
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
367
|
-
if (!this.eoaConnector) {
|
|
368
|
-
throw new Error('EOA connector is not initialized');
|
|
339
|
+
try {
|
|
340
|
+
let { request } = yield simulateAccountDeployment(publicClient, walletClient, deploymentParams, this.factoryAddress, !deployWithPaymaster);
|
|
341
|
+
if (deployWithPaymaster) {
|
|
342
|
+
const paymasterInput = getGeneralPaymasterInput({
|
|
343
|
+
innerInput: new Uint8Array(),
|
|
344
|
+
});
|
|
345
|
+
request = Object.assign(Object.assign({}, request), { paymaster: this.paymasterAddress, paymasterInput });
|
|
346
|
+
}
|
|
347
|
+
yield executeAccountDeployment(walletClient, publicClient, request, this.smartAccountAddress);
|
|
369
348
|
}
|
|
370
|
-
|
|
371
|
-
|
|
349
|
+
catch (error) {
|
|
350
|
+
// If the account already exists, we don't want to throw an error and continue
|
|
351
|
+
if (((_c = (_b = error === null || error === void 0 ? void 0 : error.cause) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.errorName) !== 'ACCOUNT_ALREADY_EXISTS') {
|
|
352
|
+
throw error;
|
|
353
|
+
}
|
|
372
354
|
}
|
|
373
|
-
|
|
374
|
-
const publicClient = yield this.getTypedPublicClient();
|
|
375
|
-
const deploymentParams = yield this.getDeploymentParameters();
|
|
376
|
-
// Simulate the contract deployment first
|
|
377
|
-
const { request } = yield simulateAccountDeployment(publicClient, walletClient, deploymentParams, this.factoryAddress, false);
|
|
378
|
-
// Execute the deployment transaction
|
|
379
|
-
yield executeAccountDeployment(walletClient, publicClient, request, this.smartAccountAddress);
|
|
355
|
+
this._isSmartAccountDeployed = true;
|
|
380
356
|
});
|
|
381
357
|
}
|
|
382
358
|
/**
|
|
@@ -485,6 +461,106 @@ class ZKsyncConnector extends AccountAbstractionBaseConnector {
|
|
|
485
461
|
return isDeployed;
|
|
486
462
|
});
|
|
487
463
|
}
|
|
464
|
+
getSmartAccountCreationBlock() {
|
|
465
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
466
|
+
if (!this.smartAccountAddress) {
|
|
467
|
+
throw new Error('Smart account address is not initialized');
|
|
468
|
+
}
|
|
469
|
+
// check cache first
|
|
470
|
+
const cachedBlock = StorageService.getItem(`smart-account-creation-block-${this.smartAccountAddress}`);
|
|
471
|
+
if (cachedBlock) {
|
|
472
|
+
return Number(cachedBlock);
|
|
473
|
+
}
|
|
474
|
+
const publicClient = yield this.getPublicClient();
|
|
475
|
+
try {
|
|
476
|
+
const createAccountLogs = yield publicClient.getContractEvents({
|
|
477
|
+
abi: AAFactoryAbi,
|
|
478
|
+
address: this.factoryAddress,
|
|
479
|
+
args: {
|
|
480
|
+
accountAddress: this.smartAccountAddress,
|
|
481
|
+
},
|
|
482
|
+
eventName: 'AccountCreated',
|
|
483
|
+
fromBlock: BigInt(0),
|
|
484
|
+
});
|
|
485
|
+
if (createAccountLogs.length === 0) {
|
|
486
|
+
return 0;
|
|
487
|
+
}
|
|
488
|
+
// cache the block number
|
|
489
|
+
StorageService.setItem(`smart-account-creation-block-${this.smartAccountAddress}`, createAccountLogs[0].blockNumber.toString());
|
|
490
|
+
return Number(createAccountLogs[0].blockNumber);
|
|
491
|
+
}
|
|
492
|
+
catch (error) {
|
|
493
|
+
logger.error('[ZKsyncConnector] Error getting smart account creation block: ', error);
|
|
494
|
+
return 0;
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
listSessions() {
|
|
499
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
500
|
+
if (!this.smartAccount) {
|
|
501
|
+
throw new Error('Smart account is not initialized');
|
|
502
|
+
}
|
|
503
|
+
if (!this._isSmartAccountDeployed) {
|
|
504
|
+
return [];
|
|
505
|
+
}
|
|
506
|
+
const smartAccountCreationBlock = yield this.getSmartAccountCreationBlock();
|
|
507
|
+
const publicClient = yield this.getPublicClient();
|
|
508
|
+
try {
|
|
509
|
+
// Get all created session information
|
|
510
|
+
const createSessionLogs = (yield publicClient.getContractEvents({
|
|
511
|
+
abi: SessionKeyValidatorAbi,
|
|
512
|
+
address: this.sessionKeyAddress,
|
|
513
|
+
args: {
|
|
514
|
+
account: this.smartAccountAddress,
|
|
515
|
+
},
|
|
516
|
+
eventName: 'SessionCreated',
|
|
517
|
+
// only get sessions from the block when the smart account was created
|
|
518
|
+
fromBlock: BigInt(smartAccountCreationBlock),
|
|
519
|
+
})).filter((log) => log.args.sessionSpec && log.args.sessionHash);
|
|
520
|
+
// Get all revoked session hashes
|
|
521
|
+
const revokedSessionHashes = (yield publicClient.getContractEvents({
|
|
522
|
+
abi: SessionKeyValidatorAbi,
|
|
523
|
+
address: this.sessionKeyAddress,
|
|
524
|
+
args: {
|
|
525
|
+
account: this.smartAccountAddress,
|
|
526
|
+
},
|
|
527
|
+
eventName: 'SessionRevoked',
|
|
528
|
+
// only get sessions from the block when the smart account was created
|
|
529
|
+
fromBlock: BigInt(smartAccountCreationBlock),
|
|
530
|
+
}))
|
|
531
|
+
.filter((log) => log.args.sessionHash)
|
|
532
|
+
.map((log) => log.args.sessionHash);
|
|
533
|
+
const activeSessions = createSessionLogs
|
|
534
|
+
.filter((log) => log.args.sessionHash &&
|
|
535
|
+
// filter out the sessions that have been revoked
|
|
536
|
+
!revokedSessionHashes.includes(log.args.sessionHash))
|
|
537
|
+
.map((log) => ({
|
|
538
|
+
blockNumber: log.blockNumber,
|
|
539
|
+
session: log.args.sessionSpec,
|
|
540
|
+
sessionId: log.args.sessionHash,
|
|
541
|
+
timestamp: new Date(
|
|
542
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
543
|
+
parseInt(log.blockTimestamp, 16) * 1000).getTime(),
|
|
544
|
+
transactionHash: log.transactionHash,
|
|
545
|
+
}))
|
|
546
|
+
.sort((a, b) => {
|
|
547
|
+
if (a.blockNumber < b.blockNumber)
|
|
548
|
+
return 1;
|
|
549
|
+
if (a.blockNumber > b.blockNumber)
|
|
550
|
+
return -1;
|
|
551
|
+
return 0;
|
|
552
|
+
});
|
|
553
|
+
return activeSessions.map((session) => {
|
|
554
|
+
var _a;
|
|
555
|
+
return (Object.assign(Object.assign({}, session), { origin: (_a = retrieveSessionFromStorage(session.sessionId)) === null || _a === void 0 ? void 0 : _a.origin }));
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
catch (error) {
|
|
559
|
+
logger.error('[ZKsyncConnector] Error listing sessions: ', error);
|
|
560
|
+
return [];
|
|
561
|
+
}
|
|
562
|
+
});
|
|
563
|
+
}
|
|
488
564
|
getAddress() {
|
|
489
565
|
return __awaiter(this, void 0, void 0, function* () {
|
|
490
566
|
var _a;
|
|
@@ -495,6 +571,59 @@ class ZKsyncConnector extends AccountAbstractionBaseConnector {
|
|
|
495
571
|
return this.smartAccountAddress;
|
|
496
572
|
});
|
|
497
573
|
}
|
|
574
|
+
revokeSession(sessionId) {
|
|
575
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
576
|
+
if (!this.smartAccount) {
|
|
577
|
+
throw new Error('Smart account is not initialized');
|
|
578
|
+
}
|
|
579
|
+
const params = {
|
|
580
|
+
sessionId,
|
|
581
|
+
};
|
|
582
|
+
if (this.paymasterAddress) {
|
|
583
|
+
params.paymaster = {
|
|
584
|
+
address: this.paymasterAddress,
|
|
585
|
+
paymasterInput: getGeneralPaymasterInput({
|
|
586
|
+
innerInput: new Uint8Array(),
|
|
587
|
+
}),
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
yield this.smartAccount.revokeSession(params);
|
|
591
|
+
StorageService.removeItem(`zksync-session-${sessionId}`);
|
|
592
|
+
});
|
|
593
|
+
}
|
|
594
|
+
createSession(_a) {
|
|
595
|
+
return __awaiter(this, arguments, void 0, function* ({ sessionConfig, origin, }) {
|
|
596
|
+
if (!this.smartAccount) {
|
|
597
|
+
throw new Error('Smart account is not initialized');
|
|
598
|
+
}
|
|
599
|
+
const safeSessionConfig = enforceSessionConfigRestrictions(sessionConfig);
|
|
600
|
+
const privateKey = generatePrivateKey();
|
|
601
|
+
const signer = privateKeyToAccount(privateKey);
|
|
602
|
+
const params = {
|
|
603
|
+
sessionConfig: Object.assign(Object.assign({}, safeSessionConfig), { signer: signer.address }),
|
|
604
|
+
};
|
|
605
|
+
if (this.paymasterAddress) {
|
|
606
|
+
params.paymaster = {
|
|
607
|
+
address: this.paymasterAddress,
|
|
608
|
+
paymasterInput: getGeneralPaymasterInput({
|
|
609
|
+
innerInput: new Uint8Array(),
|
|
610
|
+
}),
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
yield this.smartAccount.createSession(params);
|
|
614
|
+
const sessionHash = getSessionHash(params.sessionConfig);
|
|
615
|
+
const serializedSessionConfig = stringifySessionConfig(params.sessionConfig);
|
|
616
|
+
const originURI = origin
|
|
617
|
+
? new URL(origin).hostname
|
|
618
|
+
: PlatformService.getHostname();
|
|
619
|
+
StorageService.setItem(`zksync-session-${sessionHash}`, {
|
|
620
|
+
origin: originURI,
|
|
621
|
+
sessionConfig: serializedSessionConfig,
|
|
622
|
+
sessionKey: privateKey,
|
|
623
|
+
});
|
|
624
|
+
return { expiresAt: safeSessionConfig.expiresAt, sessionId: sessionHash };
|
|
625
|
+
});
|
|
626
|
+
}
|
|
498
627
|
validateActiveWallet(expectedAddress) {
|
|
499
628
|
return __awaiter(this, void 0, void 0, function* () {
|
|
500
629
|
const currentAddress = yield this.getAddress();
|
package/src/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { WalletConnectorConstructor } from '@dynamic-labs/wallet-connector-core';
|
|
2
2
|
export { isZKsyncConnector } from './utils';
|
|
3
|
+
export { type SessionInformation } from './types';
|
|
3
4
|
export declare const ZKsyncSmartWalletConnectors: (props: any) => WalletConnectorConstructor[];
|
package/src/types/index.d.ts
CHANGED
|
@@ -1,8 +1,34 @@
|
|
|
1
|
+
import { SessionConfig } from 'zksync-sso/utils';
|
|
1
2
|
import { GenericNetwork, WalletUiUtils } from '@dynamic-labs/types';
|
|
2
3
|
import { WalletBookSchema } from '@dynamic-labs/wallet-book';
|
|
3
4
|
import { InternalWalletConnector } from '@dynamic-labs/wallet-connector-core';
|
|
5
|
+
export type SessionConfigWithoutSigner = Omit<SessionConfig, 'signer'>;
|
|
6
|
+
export type ConvertBigIntToString<T> = T extends bigint ? string : T extends Array<infer U> ? Array<ConvertBigIntToString<U>> : T extends object ? {
|
|
7
|
+
[K in keyof T]: ConvertBigIntToString<T[K]>;
|
|
8
|
+
} : T;
|
|
9
|
+
export type SessionConfigJSON = ConvertBigIntToString<SessionConfig>;
|
|
4
10
|
export type AccountAbstractionConnectorProps = {
|
|
5
11
|
walletUiUtils: WalletUiUtils<InternalWalletConnector>;
|
|
6
12
|
walletBook: WalletBookSchema;
|
|
7
13
|
evmNetworks: GenericNetwork[];
|
|
8
14
|
};
|
|
15
|
+
export type SessionInformation = {
|
|
16
|
+
blockNumber: bigint;
|
|
17
|
+
session: SessionConfig;
|
|
18
|
+
sessionId: string;
|
|
19
|
+
timestamp: number;
|
|
20
|
+
transactionHash: string;
|
|
21
|
+
origin?: string;
|
|
22
|
+
};
|
|
23
|
+
export type ChainSessionInformation = {
|
|
24
|
+
blockNumber: bigint;
|
|
25
|
+
session: SessionConfig;
|
|
26
|
+
sessionId: `0x${string}`;
|
|
27
|
+
timestamp: number;
|
|
28
|
+
transactionHash: `0x${string}`;
|
|
29
|
+
};
|
|
30
|
+
export type SessionStorageItem = {
|
|
31
|
+
origin?: string;
|
|
32
|
+
sessionConfig: SessionConfigJSON;
|
|
33
|
+
sessionKey: string;
|
|
34
|
+
};
|
package/src/utils/index.d.ts
CHANGED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var viem = require('viem');
|
|
7
|
+
var utils = require('zksync-sso/utils');
|
|
8
|
+
var utils$1 = require('@dynamic-labs/utils');
|
|
9
|
+
|
|
10
|
+
const DEFAULT_EXPIRATION_TIME = 86400; // 1 day
|
|
11
|
+
const enforceSessionConfigRestrictions = (sessionConfig) => {
|
|
12
|
+
const now = Math.floor(Date.now() / 1000);
|
|
13
|
+
const maxExpirationTime = now + DEFAULT_EXPIRATION_TIME;
|
|
14
|
+
if (!sessionConfig.expiresAt ||
|
|
15
|
+
Number(sessionConfig.expiresAt) > maxExpirationTime) {
|
|
16
|
+
sessionConfig.expiresAt = BigInt(maxExpirationTime);
|
|
17
|
+
}
|
|
18
|
+
return sessionConfig;
|
|
19
|
+
};
|
|
20
|
+
const getSessionHash = (sessionConfig) => {
|
|
21
|
+
const sessionHash = utils.encodeSession(sessionConfig);
|
|
22
|
+
return viem.keccak256(sessionHash);
|
|
23
|
+
};
|
|
24
|
+
const parseSessionConfigJSON = (sessionConfig) => {
|
|
25
|
+
const serializeLimit = (limit) => ({
|
|
26
|
+
limit: BigInt(limit.limit),
|
|
27
|
+
limitType: limit.limitType,
|
|
28
|
+
period: BigInt(limit.period),
|
|
29
|
+
});
|
|
30
|
+
return Object.assign(Object.assign({}, sessionConfig), { callPolicies: sessionConfig.callPolicies.map((policy) => (Object.assign(Object.assign({}, policy), { constraints: policy.constraints.map((constraint) => (Object.assign(Object.assign({}, constraint), { index: BigInt(constraint.index), limit: serializeLimit(constraint.limit) }))), maxValuePerUse: BigInt(policy.maxValuePerUse), valueLimit: serializeLimit(policy.valueLimit) }))), expiresAt: BigInt(sessionConfig.expiresAt), feeLimit: serializeLimit(sessionConfig.feeLimit), transferPolicies: sessionConfig.transferPolicies.map((policy) => (Object.assign(Object.assign({}, policy), { maxValuePerUse: BigInt(policy.maxValuePerUse), valueLimit: serializeLimit(policy.valueLimit) }))) });
|
|
31
|
+
};
|
|
32
|
+
const stringifySessionConfig = (sessionConfig) => {
|
|
33
|
+
const stringifyLimit = (limit) => ({
|
|
34
|
+
limit: limit.limit.toString(),
|
|
35
|
+
limitType: limit.limitType,
|
|
36
|
+
period: limit.period.toString(),
|
|
37
|
+
});
|
|
38
|
+
return Object.assign(Object.assign({}, sessionConfig), { callPolicies: sessionConfig.callPolicies.map((policy) => (Object.assign(Object.assign({}, policy), { constraints: policy.constraints.map((constraint) => (Object.assign(Object.assign({}, constraint), { index: constraint.index.toString(), limit: stringifyLimit(constraint.limit) }))), maxValuePerUse: policy.maxValuePerUse.toString(), valueLimit: stringifyLimit(policy.valueLimit) }))), expiresAt: sessionConfig.expiresAt.toString(), feeLimit: stringifyLimit(sessionConfig.feeLimit), transferPolicies: sessionConfig.transferPolicies.map((policy) => (Object.assign(Object.assign({}, policy), { maxValuePerUse: policy.maxValuePerUse.toString(), valueLimit: stringifyLimit(policy.valueLimit) }))) });
|
|
39
|
+
};
|
|
40
|
+
const retrieveSessionFromStorage = (sessionId) => {
|
|
41
|
+
const session = utils$1.StorageService.getItem(`zksync-session-${sessionId}`);
|
|
42
|
+
if (!session) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
return Object.assign(Object.assign({}, session), { sessionConfig: parseSessionConfigJSON(session.sessionConfig) });
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
exports.enforceSessionConfigRestrictions = enforceSessionConfigRestrictions;
|
|
49
|
+
exports.getSessionHash = getSessionHash;
|
|
50
|
+
exports.parseSessionConfigJSON = parseSessionConfigJSON;
|
|
51
|
+
exports.retrieveSessionFromStorage = retrieveSessionFromStorage;
|
|
52
|
+
exports.stringifySessionConfig = stringifySessionConfig;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { SessionConfig } from 'zksync-sso/utils';
|
|
2
|
+
import { SessionConfigJSON, SessionConfigWithoutSigner } from '../types';
|
|
3
|
+
export declare const enforceSessionConfigRestrictions: (sessionConfig: SessionConfigWithoutSigner) => SessionConfigWithoutSigner;
|
|
4
|
+
export declare const getSessionHash: (sessionConfig: SessionConfig) => `0x${string}`;
|
|
5
|
+
export declare const parseSessionConfigJSON: (sessionConfig: SessionConfigJSON) => SessionConfig;
|
|
6
|
+
export declare const stringifySessionConfig: (sessionConfig: SessionConfig) => SessionConfigJSON;
|
|
7
|
+
export declare const retrieveSessionFromStorage: (sessionId: string) => {
|
|
8
|
+
sessionConfig: SessionConfig;
|
|
9
|
+
origin?: string | undefined;
|
|
10
|
+
sessionKey: string;
|
|
11
|
+
} | undefined;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { keccak256 } from 'viem';
|
|
3
|
+
import { encodeSession } from 'zksync-sso/utils';
|
|
4
|
+
import { StorageService } from '@dynamic-labs/utils';
|
|
5
|
+
|
|
6
|
+
const DEFAULT_EXPIRATION_TIME = 86400; // 1 day
|
|
7
|
+
const enforceSessionConfigRestrictions = (sessionConfig) => {
|
|
8
|
+
const now = Math.floor(Date.now() / 1000);
|
|
9
|
+
const maxExpirationTime = now + DEFAULT_EXPIRATION_TIME;
|
|
10
|
+
if (!sessionConfig.expiresAt ||
|
|
11
|
+
Number(sessionConfig.expiresAt) > maxExpirationTime) {
|
|
12
|
+
sessionConfig.expiresAt = BigInt(maxExpirationTime);
|
|
13
|
+
}
|
|
14
|
+
return sessionConfig;
|
|
15
|
+
};
|
|
16
|
+
const getSessionHash = (sessionConfig) => {
|
|
17
|
+
const sessionHash = encodeSession(sessionConfig);
|
|
18
|
+
return keccak256(sessionHash);
|
|
19
|
+
};
|
|
20
|
+
const parseSessionConfigJSON = (sessionConfig) => {
|
|
21
|
+
const serializeLimit = (limit) => ({
|
|
22
|
+
limit: BigInt(limit.limit),
|
|
23
|
+
limitType: limit.limitType,
|
|
24
|
+
period: BigInt(limit.period),
|
|
25
|
+
});
|
|
26
|
+
return Object.assign(Object.assign({}, sessionConfig), { callPolicies: sessionConfig.callPolicies.map((policy) => (Object.assign(Object.assign({}, policy), { constraints: policy.constraints.map((constraint) => (Object.assign(Object.assign({}, constraint), { index: BigInt(constraint.index), limit: serializeLimit(constraint.limit) }))), maxValuePerUse: BigInt(policy.maxValuePerUse), valueLimit: serializeLimit(policy.valueLimit) }))), expiresAt: BigInt(sessionConfig.expiresAt), feeLimit: serializeLimit(sessionConfig.feeLimit), transferPolicies: sessionConfig.transferPolicies.map((policy) => (Object.assign(Object.assign({}, policy), { maxValuePerUse: BigInt(policy.maxValuePerUse), valueLimit: serializeLimit(policy.valueLimit) }))) });
|
|
27
|
+
};
|
|
28
|
+
const stringifySessionConfig = (sessionConfig) => {
|
|
29
|
+
const stringifyLimit = (limit) => ({
|
|
30
|
+
limit: limit.limit.toString(),
|
|
31
|
+
limitType: limit.limitType,
|
|
32
|
+
period: limit.period.toString(),
|
|
33
|
+
});
|
|
34
|
+
return Object.assign(Object.assign({}, sessionConfig), { callPolicies: sessionConfig.callPolicies.map((policy) => (Object.assign(Object.assign({}, policy), { constraints: policy.constraints.map((constraint) => (Object.assign(Object.assign({}, constraint), { index: constraint.index.toString(), limit: stringifyLimit(constraint.limit) }))), maxValuePerUse: policy.maxValuePerUse.toString(), valueLimit: stringifyLimit(policy.valueLimit) }))), expiresAt: sessionConfig.expiresAt.toString(), feeLimit: stringifyLimit(sessionConfig.feeLimit), transferPolicies: sessionConfig.transferPolicies.map((policy) => (Object.assign(Object.assign({}, policy), { maxValuePerUse: policy.maxValuePerUse.toString(), valueLimit: stringifyLimit(policy.valueLimit) }))) });
|
|
35
|
+
};
|
|
36
|
+
const retrieveSessionFromStorage = (sessionId) => {
|
|
37
|
+
const session = StorageService.getItem(`zksync-session-${sessionId}`);
|
|
38
|
+
if (!session) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
return Object.assign(Object.assign({}, session), { sessionConfig: parseSessionConfigJSON(session.sessionConfig) });
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export { enforceSessionConfigRestrictions, getSessionHash, parseSessionConfigJSON, retrieveSessionFromStorage, stringifySessionConfig };
|