@dynamic-labs/waas-evm 5.4.0 → 5.5.0
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 -8
- package/src/DynamicWaasEVMConnector.cjs +125 -35
- package/src/DynamicWaasEVMConnector.d.ts +41 -63
- package/src/DynamicWaasEVMConnector.js +126 -36
- package/src/gasless/toSponsoredTransactionCalls/toSponsoredTransactionCalls.cjs +39 -0
- package/src/gasless/toSponsoredTransactionCalls/toSponsoredTransactionCalls.d.ts +13 -0
- package/src/gasless/toSponsoredTransactionCalls/toSponsoredTransactionCalls.js +35 -0
- package/src/gasless/withBigintSafeSignTypedData/withBigintSafeSignTypedData.cjs +37 -0
- package/src/gasless/withBigintSafeSignTypedData/withBigintSafeSignTypedData.d.ts +7 -0
- package/src/gasless/withBigintSafeSignTypedData/withBigintSafeSignTypedData.js +33 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,31 @@
|
|
|
1
1
|
|
|
2
|
+
## [5.5.0](https://github.com/dynamic-labs/dynamic-auth/compare/v5.4.1...v5.5.0) (2026-08-31)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* **waas-evm:** route embedded EVM sends through gas sponsorship when enabled ([#12306](https://github.com/dynamic-labs/dynamic-auth/issues/12306)) ([6046ff3](https://github.com/dynamic-labs/dynamic-auth/commit/6046ff362d8de9402793bdaa7319fda645ff4c04))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
### Bug Fixes
|
|
11
|
+
|
|
12
|
+
* **bitcoin:** resolve the active BTC wallet and network correctly across the widget ([#12308](https://github.com/dynamic-labs/dynamic-auth/issues/12308)) ([13e9eae](https://github.com/dynamic-labs/dynamic-auth/commit/13e9eaec19b3925db507c878988cfd82da5a6de6))
|
|
13
|
+
* **btc:** unbreak BTC transaction confirmation, testnet balances and taproot testnet switching ([#12305](https://github.com/dynamic-labs/dynamic-auth/issues/12305)) ([5fd999c](https://github.com/dynamic-labs/dynamic-auth/commit/5fd999c4c819d3a74e967c0cfa77c5877a74906b))
|
|
14
|
+
* **react-native-extension:** stop leaking expo-secure-store into consumer autolinking ([#12296](https://github.com/dynamic-labs/dynamic-auth/issues/12296)) ([1e0396a](https://github.com/dynamic-labs/dynamic-auth/commit/1e0396ab00c79aa0b2f45b6d7b1d339c1dac1203)), closes [#12254](https://github.com/dynamic-labs/dynamic-auth/issues/12254)
|
|
15
|
+
* **screening:** wire connected-wallet screening into the Send Balance UI (DYNT-1663) ([#12303](https://github.com/dynamic-labs/dynamic-auth/issues/12303)) ([5d26ff3](https://github.com/dynamic-labs/dynamic-auth/commit/5d26ff375118302522c39bd2f1fa9e04f7378eaf))
|
|
16
|
+
|
|
17
|
+
### [5.4.1](https://github.com/dynamic-labs/dynamic-auth/compare/v5.4.0...v5.4.1) (2026-08-26)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* **webview-controller:** resolve which keychain key a session belongs to ([#12246](https://github.com/dynamic-labs/dynamic-auth/issues/12246)) ([3d110db](https://github.com/dynamic-labs/dynamic-auth/commit/3d110db831c6e9d82d07d86841f5c7733924b17e))
|
|
23
|
+
* **bitcoin:** forward the password through the BTC importPrivateKey override ([#12278](https://github.com/dynamic-labs/dynamic-auth/issues/12278)) ([21e1df3](https://github.com/dynamic-labs/dynamic-auth/commit/21e1df3e33e96e2efdb15ffa0fd29a441056202e))
|
|
24
|
+
* **react-native-extension:** recover 4.x expo-secure-store sessions on keychain miss ([#12254](https://github.com/dynamic-labs/dynamic-auth/issues/12254)) ([217e991](https://github.com/dynamic-labs/dynamic-auth/commit/217e991838f3073c12e2d2fab7a2e12830faad9e)), closes [#12092](https://github.com/dynamic-labs/dynamic-auth/issues/12092) [#12092](https://github.com/dynamic-labs/dynamic-auth/issues/12092) [#12092](https://github.com/dynamic-labs/dynamic-auth/issues/12092) [#12092](https://github.com/dynamic-labs/dynamic-auth/issues/12092) [#12242](https://github.com/dynamic-labs/dynamic-auth/issues/12242) [#12242](https://github.com/dynamic-labs/dynamic-auth/issues/12242)
|
|
25
|
+
* **transaction-card:** use walletConnector prop for network/fee instead of primaryWallet ([#12063](https://github.com/dynamic-labs/dynamic-auth/issues/12063)) ([81314d2](https://github.com/dynamic-labs/dynamic-auth/commit/81314d25fba4b20ab89631bc2d9ceeb9e2b6b2ac))
|
|
26
|
+
* **waas-svm:** instrument sponsorship retry attempts ([#12281](https://github.com/dynamic-labs/dynamic-auth/issues/12281)) ([7273a4b](https://github.com/dynamic-labs/dynamic-auth/commit/7273a4bc456cad512c0e9fbcd2abd66532a2f7df))
|
|
27
|
+
* **webview-controller:** recover 4.x secure-storage sessions and surface init failures ([#12242](https://github.com/dynamic-labs/dynamic-auth/issues/12242)) ([b51605c](https://github.com/dynamic-labs/dynamic-auth/commit/b51605cc9bdbb5d695173192c502a58d899bbbdd)), closes [#12094](https://github.com/dynamic-labs/dynamic-auth/issues/12094) [#12095](https://github.com/dynamic-labs/dynamic-auth/issues/12095) [#12098](https://github.com/dynamic-labs/dynamic-auth/issues/12098) [dynamic-labs/flutter-sdk#256](https://github.com/dynamic-labs/flutter-sdk/issues/256)
|
|
28
|
+
|
|
2
29
|
## [5.4.0](https://github.com/dynamic-labs/dynamic-auth/compare/v5.3.2...v5.4.0) (2026-08-25)
|
|
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/waas-evm",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0",
|
|
4
4
|
"description": "A React SDK for implementing wallet web3 authentication and authorization to your website.",
|
|
5
5
|
"author": "Dynamic Labs, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,15 +18,16 @@
|
|
|
18
18
|
},
|
|
19
19
|
"homepage": "https://www.dynamic.xyz/",
|
|
20
20
|
"dependencies": {
|
|
21
|
+
"@dynamic-labs/ethereum-gasless-core": "5.5.0",
|
|
21
22
|
"@dynamic-labs/sdk-api-core": "0.12.0",
|
|
22
23
|
"viem": "^2.45.3",
|
|
23
|
-
"@dynamic-labs/assert-package-version": "5.
|
|
24
|
-
"@dynamic-labs/ethereum-core": "5.
|
|
25
|
-
"@dynamic-labs/logger": "5.
|
|
26
|
-
"@dynamic-labs/types": "5.
|
|
27
|
-
"@dynamic-labs/utils": "5.
|
|
28
|
-
"@dynamic-labs/waas": "5.
|
|
29
|
-
"@dynamic-labs/wallet-connector-core": "5.
|
|
24
|
+
"@dynamic-labs/assert-package-version": "5.5.0",
|
|
25
|
+
"@dynamic-labs/ethereum-core": "5.5.0",
|
|
26
|
+
"@dynamic-labs/logger": "5.5.0",
|
|
27
|
+
"@dynamic-labs/types": "5.5.0",
|
|
28
|
+
"@dynamic-labs/utils": "5.5.0",
|
|
29
|
+
"@dynamic-labs/waas": "5.5.0",
|
|
30
|
+
"@dynamic-labs/wallet-connector-core": "5.5.0"
|
|
30
31
|
},
|
|
31
32
|
"peerDependencies": {}
|
|
32
33
|
}
|
|
@@ -8,11 +8,14 @@ var viem = require('viem');
|
|
|
8
8
|
var accounts = require('viem/accounts');
|
|
9
9
|
var utils$1 = require('viem/utils');
|
|
10
10
|
var ethereumCore = require('@dynamic-labs/ethereum-core');
|
|
11
|
+
var ethereumGaslessCore = require('@dynamic-labs/ethereum-gasless-core');
|
|
11
12
|
var logger$1 = require('@dynamic-labs/logger');
|
|
12
13
|
var sdkApiCore = require('@dynamic-labs/sdk-api-core');
|
|
13
14
|
var utils = require('@dynamic-labs/utils');
|
|
14
15
|
var waas = require('@dynamic-labs/waas');
|
|
15
16
|
var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
|
|
17
|
+
var toSponsoredTransactionCalls = require('./gasless/toSponsoredTransactionCalls/toSponsoredTransactionCalls.cjs');
|
|
18
|
+
var withBigintSafeSignTypedData = require('./gasless/withBigintSafeSignTypedData/withBigintSafeSignTypedData.cjs');
|
|
16
19
|
|
|
17
20
|
const logger = new logger$1.Logger('DynamicWaasConnector');
|
|
18
21
|
class DynamicWaasEVMConnector extends waas.withDynamicWaas(ethereumCore.EthereumWalletConnector) {
|
|
@@ -43,6 +46,9 @@ class DynamicWaasEVMConnector extends waas.withDynamicWaas(ethereumCore.Ethereum
|
|
|
43
46
|
this.logger = logger;
|
|
44
47
|
this.overrideKey = 'dynamicwaas';
|
|
45
48
|
this.isEmbeddedWallet = true;
|
|
49
|
+
this.getEvmGasSponsorshipEnabled = () => false;
|
|
50
|
+
this.getSponsorshipSdkApi = undefined;
|
|
51
|
+
this.delegation7702Registry = ethereumGaslessCore.create7702DelegationRegistry();
|
|
46
52
|
/**
|
|
47
53
|
* Chain IDs that have dedicated connectors and should not be handled by this connector.
|
|
48
54
|
* Networks with these chain IDs are filtered from network lists and rejected during switching.
|
|
@@ -475,88 +481,162 @@ class DynamicWaasEVMConnector extends waas.withDynamicWaas(ethereumCore.Ethereum
|
|
|
475
481
|
return this.getWalletClient();
|
|
476
482
|
}
|
|
477
483
|
// Chain-specific override for exportClientKeyshares - EVM needs to set active account first
|
|
478
|
-
exportClientKeyshares(
|
|
484
|
+
exportClientKeyshares(params) {
|
|
479
485
|
const _super = Object.create(null, {
|
|
480
486
|
exportClientKeyshares: { get: () => super.exportClientKeyshares }
|
|
481
487
|
});
|
|
482
|
-
return _tslib.__awaiter(this,
|
|
483
|
-
if (!accountAddress) {
|
|
488
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
489
|
+
if (!params.accountAddress) {
|
|
484
490
|
throw new Error('Account address is required');
|
|
485
491
|
}
|
|
486
492
|
// EVM-specific: set active account before exporting
|
|
487
|
-
this.setActiveAccount(accountAddress);
|
|
488
|
-
return _super.exportClientKeyshares.call(this,
|
|
493
|
+
this.setActiveAccount(params.accountAddress);
|
|
494
|
+
return _super.exportClientKeyshares.call(this, params);
|
|
489
495
|
});
|
|
490
496
|
}
|
|
491
497
|
// Chain-specific override for backupKeySharesToGoogleDrive - EVM needs to set active account first
|
|
492
|
-
backupKeySharesToGoogleDrive(
|
|
498
|
+
backupKeySharesToGoogleDrive(params) {
|
|
493
499
|
const _super = Object.create(null, {
|
|
494
500
|
backupKeySharesToGoogleDrive: { get: () => super.backupKeySharesToGoogleDrive }
|
|
495
501
|
});
|
|
496
|
-
return _tslib.__awaiter(this,
|
|
497
|
-
if (!accountAddress) {
|
|
502
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
503
|
+
if (!params.accountAddress) {
|
|
498
504
|
throw new Error('Account address is required');
|
|
499
505
|
}
|
|
500
506
|
// EVM-specific: set active account before backing up
|
|
501
|
-
this.setActiveAccount(accountAddress);
|
|
502
|
-
return _super.backupKeySharesToGoogleDrive.call(this,
|
|
503
|
-
accountAddress,
|
|
504
|
-
googleDriveAccessToken,
|
|
505
|
-
password,
|
|
506
|
-
});
|
|
507
|
+
this.setActiveAccount(params.accountAddress);
|
|
508
|
+
return _super.backupKeySharesToGoogleDrive.call(this, params);
|
|
507
509
|
});
|
|
508
510
|
}
|
|
509
511
|
// Chain-specific override for refreshWalletAccountShares - EVM needs to set active account first
|
|
510
|
-
refreshWalletAccountShares(
|
|
512
|
+
refreshWalletAccountShares(params) {
|
|
511
513
|
const _super = Object.create(null, {
|
|
512
514
|
refreshWalletAccountShares: { get: () => super.refreshWalletAccountShares }
|
|
513
515
|
});
|
|
514
|
-
return _tslib.__awaiter(this,
|
|
515
|
-
if (!accountAddress) {
|
|
516
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
517
|
+
if (!params.accountAddress) {
|
|
516
518
|
throw new Error('Account address is required');
|
|
517
519
|
}
|
|
518
520
|
// EVM-specific: set active account before refreshing
|
|
519
|
-
this.setActiveAccount(accountAddress);
|
|
520
|
-
return _super.refreshWalletAccountShares.call(this,
|
|
521
|
+
this.setActiveAccount(params.accountAddress);
|
|
522
|
+
return _super.refreshWalletAccountShares.call(this, params);
|
|
521
523
|
});
|
|
522
524
|
}
|
|
523
525
|
// Chain-specific override for reshareWalletAccountShares - EVM needs to set active account first
|
|
524
|
-
reshareWalletAccountShares(
|
|
526
|
+
reshareWalletAccountShares(params) {
|
|
525
527
|
const _super = Object.create(null, {
|
|
526
528
|
reshareWalletAccountShares: { get: () => super.reshareWalletAccountShares }
|
|
527
529
|
});
|
|
528
|
-
return _tslib.__awaiter(this,
|
|
529
|
-
if (!accountAddress) {
|
|
530
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
531
|
+
if (!params.accountAddress) {
|
|
530
532
|
throw new Error('Account address is required');
|
|
531
533
|
}
|
|
532
|
-
this.setActiveAccount(accountAddress);
|
|
533
|
-
return _super.reshareWalletAccountShares.call(this,
|
|
534
|
-
accountAddress,
|
|
535
|
-
password,
|
|
536
|
-
thresholdSignatureScheme,
|
|
537
|
-
});
|
|
534
|
+
this.setActiveAccount(params.accountAddress);
|
|
535
|
+
return _super.reshareWalletAccountShares.call(this, params);
|
|
538
536
|
});
|
|
539
537
|
}
|
|
540
538
|
// Chain-specific override for updatePassword - EVM needs to set active account first
|
|
541
|
-
updatePassword(
|
|
539
|
+
updatePassword(params) {
|
|
542
540
|
const _super = Object.create(null, {
|
|
543
541
|
updatePassword: { get: () => super.updatePassword }
|
|
544
542
|
});
|
|
545
|
-
return _tslib.__awaiter(this,
|
|
546
|
-
if (!accountAddress) {
|
|
543
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
544
|
+
if (!params.accountAddress) {
|
|
547
545
|
throw new Error('Account address is required');
|
|
548
546
|
}
|
|
549
547
|
// EVM-specific: set active account before updating password
|
|
550
|
-
this.setActiveAccount(accountAddress);
|
|
551
|
-
return _super.updatePassword.call(this,
|
|
548
|
+
this.setActiveAccount(params.accountAddress);
|
|
549
|
+
return _super.updatePassword.call(this, params);
|
|
550
|
+
});
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Registers the project's EVM gas sponsorship configuration so the send flow
|
|
554
|
+
* can route transactions through the sponsored relay instead of paying fees
|
|
555
|
+
* from the wallet's native balance.
|
|
556
|
+
*/
|
|
557
|
+
setEvmGasSponsorshipConfig({ getEnabled, getSdkApi, }) {
|
|
558
|
+
this.getEvmGasSponsorshipEnabled = getEnabled;
|
|
559
|
+
this.getSponsorshipSdkApi = getSdkApi;
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Sponsorship requires the project setting, an SDK API client and a relayer
|
|
563
|
+
* funded for the wallet's current chain. Anything missing means the send flow
|
|
564
|
+
* pays fees from the wallet's native balance.
|
|
565
|
+
*/
|
|
566
|
+
isGasSponsorshipAvailable() {
|
|
567
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
568
|
+
var _a;
|
|
569
|
+
const { environmentId } = this;
|
|
570
|
+
if (!this.getEvmGasSponsorshipEnabled() || !environmentId) {
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
573
|
+
const sdkApi = (_a = this.getSponsorshipSdkApi) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
574
|
+
if (!sdkApi) {
|
|
575
|
+
return false;
|
|
576
|
+
}
|
|
577
|
+
const evmNetwork = this.currentEvmNetwork();
|
|
578
|
+
if (!evmNetwork) {
|
|
579
|
+
return false;
|
|
580
|
+
}
|
|
581
|
+
try {
|
|
582
|
+
yield ethereumGaslessCore.getAvailableEvmGaslessRelayer({ chainId: Number(evmNetwork.chainId) }, { environmentId, sdkApi });
|
|
583
|
+
return true;
|
|
584
|
+
}
|
|
585
|
+
catch (_b) {
|
|
586
|
+
logger.debug('No EVM gasless relayer available for chain');
|
|
587
|
+
return false;
|
|
588
|
+
}
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
sendSponsoredUiTransaction(_a) {
|
|
592
|
+
return _tslib.__awaiter(this, arguments, void 0, function* ({ accountAddress, sponsoredChainId, transaction, }) {
|
|
593
|
+
var _b, _c;
|
|
594
|
+
const sdkApi = (_b = this.getSponsorshipSdkApi) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
595
|
+
if (!sdkApi || !this.environmentId) {
|
|
596
|
+
throw new utils.DynamicError('Gas sponsorship is not configured', 'gas_sponsorship_not_configured');
|
|
597
|
+
}
|
|
598
|
+
const evmNetwork = this.currentEvmNetwork();
|
|
599
|
+
if (!evmNetwork) {
|
|
600
|
+
throw new utils.DynamicError('EVM network not found', 'evm_network_not_found');
|
|
601
|
+
}
|
|
602
|
+
if (Number(evmNetwork.chainId) !== sponsoredChainId) {
|
|
603
|
+
throw new utils.DynamicError('Gas sponsorship was not verified for the active chain', 'gas_sponsorship_chain_mismatch');
|
|
604
|
+
}
|
|
605
|
+
const publicClient = yield this.getPublicClient();
|
|
606
|
+
if (!publicClient) {
|
|
607
|
+
throw new utils.DynamicError('No public client available', 'no_public_client_available');
|
|
608
|
+
}
|
|
609
|
+
const accountSource = yield this.getViemAccountCustomSource({
|
|
552
610
|
accountAddress,
|
|
553
|
-
existingPassword,
|
|
554
|
-
newPassword,
|
|
555
611
|
});
|
|
612
|
+
const sponsorshipWalletClient = viem.createWalletClient({
|
|
613
|
+
account: accounts.toAccount(withBigintSafeSignTypedData.withBigintSafeSignTypedData(accountSource)),
|
|
614
|
+
chain: ethereumCore.getOrMapViemChain(evmNetwork),
|
|
615
|
+
transport: viem.http(this.getRpcUrl(evmNetwork), this.providersConfig.httpTransportConfig),
|
|
616
|
+
});
|
|
617
|
+
const calls = toSponsoredTransactionCalls.toSponsoredTransactionCalls({
|
|
618
|
+
nonNativeAddress: transaction.nonNativeAddress,
|
|
619
|
+
nonNativeValue: transaction.nonNativeValue,
|
|
620
|
+
to: (_c = transaction.to) !== null && _c !== void 0 ? _c : undefined,
|
|
621
|
+
value: transaction.value,
|
|
622
|
+
});
|
|
623
|
+
const { transactionHash } = yield ethereumGaslessCore.sendSponsoredTransaction({
|
|
624
|
+
autoDelegate: true,
|
|
625
|
+
calls,
|
|
626
|
+
}, {
|
|
627
|
+
chainId: Number(evmNetwork.chainId),
|
|
628
|
+
delegationRegistry: this.delegation7702Registry,
|
|
629
|
+
environmentId: this.environmentId,
|
|
630
|
+
publicClient: publicClient,
|
|
631
|
+
sdkApi,
|
|
632
|
+
walletClient: sponsorshipWalletClient,
|
|
633
|
+
});
|
|
634
|
+
return transactionHash;
|
|
556
635
|
});
|
|
557
636
|
}
|
|
558
637
|
createUiTransaction(from) {
|
|
559
638
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
639
|
+
var _a;
|
|
560
640
|
yield this.validateActiveWallet(from);
|
|
561
641
|
const walletClient = this.getWalletClient();
|
|
562
642
|
const publicClient = yield this.getPublicClient();
|
|
@@ -566,9 +646,19 @@ class DynamicWaasEVMConnector extends waas.withDynamicWaas(ethereumCore.Ethereum
|
|
|
566
646
|
if (!publicClient || !walletClient) {
|
|
567
647
|
throw new utils.DynamicError('No public client available', 'no_public_client_available');
|
|
568
648
|
}
|
|
649
|
+
const isGasSponsored = yield this.isGasSponsorshipAvailable();
|
|
650
|
+
const sponsoredChainId = Number((_a = this.currentEvmNetwork()) === null || _a === void 0 ? void 0 : _a.chainId);
|
|
569
651
|
return new ethereumCore.ViemUiTransaction({
|
|
570
652
|
account: from,
|
|
653
|
+
isGasSponsored,
|
|
571
654
|
onSubmit: (transaction) => _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
655
|
+
if (isGasSponsored) {
|
|
656
|
+
return this.sendSponsoredUiTransaction({
|
|
657
|
+
accountAddress: from,
|
|
658
|
+
sponsoredChainId,
|
|
659
|
+
transaction,
|
|
660
|
+
});
|
|
661
|
+
}
|
|
572
662
|
// Non native token
|
|
573
663
|
if (transaction.nonNativeAddress) {
|
|
574
664
|
return walletClient.writeContract({
|
|
@@ -2,10 +2,10 @@ import { Account, CustomSource, Hex, Transport, Chain as ViemChain, WalletClient
|
|
|
2
2
|
import { LocalAccount, SignAuthorizationParameters, SignAuthorizationReturnType } from 'viem/accounts';
|
|
3
3
|
import { EthereumWalletConnector, EthereumWalletConnectorOpts, SwitchNetworkOps } from '@dynamic-labs/ethereum-core';
|
|
4
4
|
import { Logger } from '@dynamic-labs/logger';
|
|
5
|
-
import { JwtVerifiedCredential, MFAAction, SignMessageContext, TokenScope } from '@dynamic-labs/sdk-api-core';
|
|
5
|
+
import { JwtVerifiedCredential, MFAAction, SDKApi, SignMessageContext, TokenScope } from '@dynamic-labs/sdk-api-core';
|
|
6
6
|
import { IUITransaction } from '@dynamic-labs/types';
|
|
7
7
|
import { WaasExportHandler } from '@dynamic-labs/waas';
|
|
8
|
-
import { IDynamicWaasConnector } from '@dynamic-labs/wallet-connector-core';
|
|
8
|
+
import { BackupKeySharesToGoogleDriveParams, ExportClientKeysharesParams, IDynamicWaasConnector, RefreshWalletAccountSharesParams, ReshareWalletAccountSharesParams, UpdatePasswordParams } from '@dynamic-labs/wallet-connector-core';
|
|
9
9
|
type EvmNetwork = EthereumWalletConnector['evmNetworks'][number];
|
|
10
10
|
interface JwtVerifiedCredentialWithSmartWalletRef extends JwtVerifiedCredential {
|
|
11
11
|
smartWalletRefId?: string;
|
|
@@ -60,6 +60,14 @@ declare const DynamicWaasEVMConnector_base: (abstract new (...args: any[]) => {
|
|
|
60
60
|
}): Promise<string | undefined>;
|
|
61
61
|
setEnvironmentId(environmentId: string): void;
|
|
62
62
|
setBaseApiUrl(baseApiUrl: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* Override getEnabledNetworks to filter out unsupported networks.
|
|
65
|
+
* This is the UI-facing method used by network pickers.
|
|
66
|
+
*
|
|
67
|
+
* Note: We override getEnabledNetworks() instead of the evmNetworks getter because
|
|
68
|
+
* evmNetworks is a class field in EthereumWalletConnector, and class fields create
|
|
69
|
+
* own properties that shadow prototype-based getters/setters.
|
|
70
|
+
*/
|
|
63
71
|
setBaseClientKeysharesRelayApiUrl(baseClientKeysharesRelayApiUrl?: string | undefined): void;
|
|
64
72
|
setRelayUrl(relayUrl: string): void;
|
|
65
73
|
setGetSignedSessionIdFunction(getSignedSessionId: () => Promise<string>): void;
|
|
@@ -76,12 +84,7 @@ declare const DynamicWaasEVMConnector_base: (abstract new (...args: any[]) => {
|
|
|
76
84
|
getWaasWalletClient(traceContext?: import("dist/packages/waas/utils/instrumentation").TraceContext | undefined, { forceRebuild }?: {
|
|
77
85
|
forceRebuild?: boolean | undefined;
|
|
78
86
|
} | undefined): Promise<import("@dynamic-labs-wallet/browser-wallet-client").DynamicWalletClient>;
|
|
79
|
-
createWalletAccount({ thresholdSignatureScheme, password, bitcoinConfig, businessAccountId, }?: {
|
|
80
|
-
thresholdSignatureScheme?: string | undefined;
|
|
81
|
-
password?: string | undefined;
|
|
82
|
-
bitcoinConfig?: import("@dynamic-labs-wallet/browser-wallet-client").BitcoinConfig | undefined;
|
|
83
|
-
businessAccountId?: string | undefined;
|
|
84
|
-
} | undefined): Promise<{
|
|
87
|
+
createWalletAccount({ thresholdSignatureScheme, password, bitcoinConfig, businessAccountId, }?: import("@dynamic-labs/wallet-connector-core").CreateWalletAccountParams | undefined): Promise<{
|
|
85
88
|
chainName: string;
|
|
86
89
|
accountAddress: string;
|
|
87
90
|
publicKeyHex: string;
|
|
@@ -101,15 +104,7 @@ declare const DynamicWaasEVMConnector_base: (abstract new (...args: any[]) => {
|
|
|
101
104
|
}): Promise<{
|
|
102
105
|
shareSetId: string;
|
|
103
106
|
}>;
|
|
104
|
-
importPrivateKey({ privateKey, thresholdSignatureScheme, publicAddressCheck, addressType, legacyWalletId, password, isRawScalarImport, }:
|
|
105
|
-
privateKey: string;
|
|
106
|
-
thresholdSignatureScheme?: string | undefined;
|
|
107
|
-
publicAddressCheck?: string | undefined;
|
|
108
|
-
addressType?: string | undefined;
|
|
109
|
-
legacyWalletId?: string | undefined;
|
|
110
|
-
password?: string | undefined;
|
|
111
|
-
isRawScalarImport?: boolean | undefined;
|
|
112
|
-
}): Promise<void>;
|
|
107
|
+
importPrivateKey({ privateKey, thresholdSignatureScheme, publicAddressCheck, addressType, legacyWalletId, password, isRawScalarImport, }: import("@dynamic-labs/wallet-connector-core").ImportPrivateKeyParams): Promise<void>;
|
|
113
108
|
migrateFromFireblocks({ deviceId, jwt, walletPassword, ncwStorage, expectedAddresses, coinTypes, password, }: {
|
|
114
109
|
deviceId: string;
|
|
115
110
|
jwt: string;
|
|
@@ -127,10 +122,7 @@ declare const DynamicWaasEVMConnector_base: (abstract new (...args: any[]) => {
|
|
|
127
122
|
getExportHandler(): {
|
|
128
123
|
clear: () => void;
|
|
129
124
|
};
|
|
130
|
-
exportClientKeyshares({ accountAddress, password, }:
|
|
131
|
-
accountAddress: string;
|
|
132
|
-
password?: string | undefined;
|
|
133
|
-
}): Promise<void>;
|
|
125
|
+
exportClientKeyshares({ accountAddress, password, }: ExportClientKeysharesParams): Promise<void>;
|
|
134
126
|
runBackupLifecycle({ provider, accountAddress, password, performBackup, }: {
|
|
135
127
|
provider: string;
|
|
136
128
|
accountAddress: string;
|
|
@@ -146,11 +138,7 @@ declare const DynamicWaasEVMConnector_base: (abstract new (...args: any[]) => {
|
|
|
146
138
|
};
|
|
147
139
|
}) => Promise<void>;
|
|
148
140
|
}): Promise<void>;
|
|
149
|
-
backupKeySharesToGoogleDrive({ accountAddress, password, googleDriveAccessToken, }:
|
|
150
|
-
accountAddress: string;
|
|
151
|
-
password?: string | undefined;
|
|
152
|
-
googleDriveAccessToken?: string | undefined;
|
|
153
|
-
}): Promise<void>;
|
|
141
|
+
backupKeySharesToGoogleDrive({ accountAddress, password, googleDriveAccessToken, }: BackupKeySharesToGoogleDriveParams): Promise<void>;
|
|
154
142
|
exportClientKeysharesFromGoogleDrive({ accountAddress, password, }: {
|
|
155
143
|
accountAddress: string;
|
|
156
144
|
password?: string | undefined;
|
|
@@ -164,24 +152,13 @@ declare const DynamicWaasEVMConnector_base: (abstract new (...args: any[]) => {
|
|
|
164
152
|
}): Promise<void>;
|
|
165
153
|
hideICloudSignIn(): Promise<void>;
|
|
166
154
|
isICloudAuthenticated(): Promise<boolean>;
|
|
167
|
-
refreshWalletAccountShares({ accountAddress, password, }:
|
|
168
|
-
|
|
169
|
-
password?: string | undefined;
|
|
170
|
-
}): Promise<void>;
|
|
171
|
-
reshareWalletAccountShares({ accountAddress, thresholdSignatureScheme, password, }: {
|
|
172
|
-
accountAddress: string;
|
|
173
|
-
thresholdSignatureScheme: string;
|
|
174
|
-
password?: string | undefined;
|
|
175
|
-
}): Promise<void>;
|
|
155
|
+
refreshWalletAccountShares({ accountAddress, password, }: RefreshWalletAccountSharesParams): Promise<void>;
|
|
156
|
+
reshareWalletAccountShares({ accountAddress, thresholdSignatureScheme, password, }: ReshareWalletAccountSharesParams): Promise<void>;
|
|
176
157
|
revokeDelegation({ accountAddress, password, }: {
|
|
177
158
|
accountAddress: string;
|
|
178
159
|
password?: string | undefined;
|
|
179
160
|
}): Promise<void>;
|
|
180
|
-
updatePassword({ accountAddress, existingPassword, newPassword, }:
|
|
181
|
-
accountAddress: string;
|
|
182
|
-
existingPassword?: string | undefined;
|
|
183
|
-
newPassword: string;
|
|
184
|
-
}): Promise<void>;
|
|
161
|
+
updatePassword({ accountAddress, existingPassword, newPassword, }: UpdatePasswordParams): Promise<void>;
|
|
185
162
|
setPassword({ accountAddress, newPassword, }: {
|
|
186
163
|
accountAddress: string;
|
|
187
164
|
newPassword: string;
|
|
@@ -241,6 +218,9 @@ export declare class DynamicWaasEVMConnector extends DynamicWaasEVMConnector_bas
|
|
|
241
218
|
logger: Logger;
|
|
242
219
|
overrideKey: string;
|
|
243
220
|
isEmbeddedWallet: boolean;
|
|
221
|
+
private getEvmGasSponsorshipEnabled;
|
|
222
|
+
private getSponsorshipSdkApi;
|
|
223
|
+
private delegation7702Registry;
|
|
244
224
|
/**
|
|
245
225
|
* Chain IDs that have dedicated connectors and should not be handled by this connector.
|
|
246
226
|
* Networks with these chain IDs are filtered from network lists and rejected during switching.
|
|
@@ -305,29 +285,27 @@ export declare class DynamicWaasEVMConnector extends DynamicWaasEVMConnector_bas
|
|
|
305
285
|
getWalletClientByAddress({ accountAddress, }: {
|
|
306
286
|
accountAddress: string;
|
|
307
287
|
}): WalletClient<Transport, ViemChain, Account> | undefined;
|
|
308
|
-
exportClientKeyshares(
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
newPassword: string;
|
|
330
|
-
}): Promise<void>;
|
|
288
|
+
exportClientKeyshares(params: ExportClientKeysharesParams): Promise<void>;
|
|
289
|
+
backupKeySharesToGoogleDrive(params: BackupKeySharesToGoogleDriveParams): Promise<void>;
|
|
290
|
+
refreshWalletAccountShares(params: RefreshWalletAccountSharesParams): Promise<void>;
|
|
291
|
+
reshareWalletAccountShares(params: ReshareWalletAccountSharesParams): Promise<void>;
|
|
292
|
+
updatePassword(params: UpdatePasswordParams): Promise<void>;
|
|
293
|
+
/**
|
|
294
|
+
* Registers the project's EVM gas sponsorship configuration so the send flow
|
|
295
|
+
* can route transactions through the sponsored relay instead of paying fees
|
|
296
|
+
* from the wallet's native balance.
|
|
297
|
+
*/
|
|
298
|
+
setEvmGasSponsorshipConfig({ getEnabled, getSdkApi, }: {
|
|
299
|
+
getEnabled: () => boolean;
|
|
300
|
+
getSdkApi: () => SDKApi;
|
|
301
|
+
}): void;
|
|
302
|
+
/**
|
|
303
|
+
* Sponsorship requires the project setting, an SDK API client and a relayer
|
|
304
|
+
* funded for the wallet's current chain. Anything missing means the send flow
|
|
305
|
+
* pays fees from the wallet's native balance.
|
|
306
|
+
*/
|
|
307
|
+
private isGasSponsorshipAvailable;
|
|
308
|
+
private sendSponsoredUiTransaction;
|
|
331
309
|
createUiTransaction(from: string): Promise<IUITransaction>;
|
|
332
310
|
getConnectedAccounts(): Promise<string[]>;
|
|
333
311
|
getAddress(): Promise<string>;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { __awaiter } from '../_virtual/_tslib.js';
|
|
3
|
-
import { http, serializeTransaction, erc20Abi, parseSignature } from 'viem';
|
|
3
|
+
import { http, serializeTransaction, createWalletClient, erc20Abi, parseSignature } from 'viem';
|
|
4
4
|
import { toAccount } from 'viem/accounts';
|
|
5
5
|
import { hashAuthorization } from 'viem/utils';
|
|
6
6
|
import { EthereumWalletConnector, createWalletClientWithUiConfirmation, getOrMapViemChain, ViemUiTransaction } from '@dynamic-labs/ethereum-core';
|
|
7
|
+
import { create7702DelegationRegistry, getAvailableEvmGaslessRelayer, sendSponsoredTransaction } from '@dynamic-labs/ethereum-gasless-core';
|
|
7
8
|
import { Logger } from '@dynamic-labs/logger';
|
|
8
9
|
import { MFAAction, TokenScope } from '@dynamic-labs/sdk-api-core';
|
|
9
10
|
import { DynamicError } from '@dynamic-labs/utils';
|
|
10
11
|
import { withDynamicWaas, WaasExportHandler } from '@dynamic-labs/waas';
|
|
11
12
|
import { isSameAddress } from '@dynamic-labs/wallet-connector-core';
|
|
13
|
+
import { toSponsoredTransactionCalls } from './gasless/toSponsoredTransactionCalls/toSponsoredTransactionCalls.js';
|
|
14
|
+
import { withBigintSafeSignTypedData } from './gasless/withBigintSafeSignTypedData/withBigintSafeSignTypedData.js';
|
|
12
15
|
|
|
13
16
|
const logger = new Logger('DynamicWaasConnector');
|
|
14
17
|
class DynamicWaasEVMConnector extends withDynamicWaas(EthereumWalletConnector) {
|
|
@@ -39,6 +42,9 @@ class DynamicWaasEVMConnector extends withDynamicWaas(EthereumWalletConnector) {
|
|
|
39
42
|
this.logger = logger;
|
|
40
43
|
this.overrideKey = 'dynamicwaas';
|
|
41
44
|
this.isEmbeddedWallet = true;
|
|
45
|
+
this.getEvmGasSponsorshipEnabled = () => false;
|
|
46
|
+
this.getSponsorshipSdkApi = undefined;
|
|
47
|
+
this.delegation7702Registry = create7702DelegationRegistry();
|
|
42
48
|
/**
|
|
43
49
|
* Chain IDs that have dedicated connectors and should not be handled by this connector.
|
|
44
50
|
* Networks with these chain IDs are filtered from network lists and rejected during switching.
|
|
@@ -471,88 +477,162 @@ class DynamicWaasEVMConnector extends withDynamicWaas(EthereumWalletConnector) {
|
|
|
471
477
|
return this.getWalletClient();
|
|
472
478
|
}
|
|
473
479
|
// Chain-specific override for exportClientKeyshares - EVM needs to set active account first
|
|
474
|
-
exportClientKeyshares(
|
|
480
|
+
exportClientKeyshares(params) {
|
|
475
481
|
const _super = Object.create(null, {
|
|
476
482
|
exportClientKeyshares: { get: () => super.exportClientKeyshares }
|
|
477
483
|
});
|
|
478
|
-
return __awaiter(this,
|
|
479
|
-
if (!accountAddress) {
|
|
484
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
485
|
+
if (!params.accountAddress) {
|
|
480
486
|
throw new Error('Account address is required');
|
|
481
487
|
}
|
|
482
488
|
// EVM-specific: set active account before exporting
|
|
483
|
-
this.setActiveAccount(accountAddress);
|
|
484
|
-
return _super.exportClientKeyshares.call(this,
|
|
489
|
+
this.setActiveAccount(params.accountAddress);
|
|
490
|
+
return _super.exportClientKeyshares.call(this, params);
|
|
485
491
|
});
|
|
486
492
|
}
|
|
487
493
|
// Chain-specific override for backupKeySharesToGoogleDrive - EVM needs to set active account first
|
|
488
|
-
backupKeySharesToGoogleDrive(
|
|
494
|
+
backupKeySharesToGoogleDrive(params) {
|
|
489
495
|
const _super = Object.create(null, {
|
|
490
496
|
backupKeySharesToGoogleDrive: { get: () => super.backupKeySharesToGoogleDrive }
|
|
491
497
|
});
|
|
492
|
-
return __awaiter(this,
|
|
493
|
-
if (!accountAddress) {
|
|
498
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
499
|
+
if (!params.accountAddress) {
|
|
494
500
|
throw new Error('Account address is required');
|
|
495
501
|
}
|
|
496
502
|
// EVM-specific: set active account before backing up
|
|
497
|
-
this.setActiveAccount(accountAddress);
|
|
498
|
-
return _super.backupKeySharesToGoogleDrive.call(this,
|
|
499
|
-
accountAddress,
|
|
500
|
-
googleDriveAccessToken,
|
|
501
|
-
password,
|
|
502
|
-
});
|
|
503
|
+
this.setActiveAccount(params.accountAddress);
|
|
504
|
+
return _super.backupKeySharesToGoogleDrive.call(this, params);
|
|
503
505
|
});
|
|
504
506
|
}
|
|
505
507
|
// Chain-specific override for refreshWalletAccountShares - EVM needs to set active account first
|
|
506
|
-
refreshWalletAccountShares(
|
|
508
|
+
refreshWalletAccountShares(params) {
|
|
507
509
|
const _super = Object.create(null, {
|
|
508
510
|
refreshWalletAccountShares: { get: () => super.refreshWalletAccountShares }
|
|
509
511
|
});
|
|
510
|
-
return __awaiter(this,
|
|
511
|
-
if (!accountAddress) {
|
|
512
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
513
|
+
if (!params.accountAddress) {
|
|
512
514
|
throw new Error('Account address is required');
|
|
513
515
|
}
|
|
514
516
|
// EVM-specific: set active account before refreshing
|
|
515
|
-
this.setActiveAccount(accountAddress);
|
|
516
|
-
return _super.refreshWalletAccountShares.call(this,
|
|
517
|
+
this.setActiveAccount(params.accountAddress);
|
|
518
|
+
return _super.refreshWalletAccountShares.call(this, params);
|
|
517
519
|
});
|
|
518
520
|
}
|
|
519
521
|
// Chain-specific override for reshareWalletAccountShares - EVM needs to set active account first
|
|
520
|
-
reshareWalletAccountShares(
|
|
522
|
+
reshareWalletAccountShares(params) {
|
|
521
523
|
const _super = Object.create(null, {
|
|
522
524
|
reshareWalletAccountShares: { get: () => super.reshareWalletAccountShares }
|
|
523
525
|
});
|
|
524
|
-
return __awaiter(this,
|
|
525
|
-
if (!accountAddress) {
|
|
526
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
527
|
+
if (!params.accountAddress) {
|
|
526
528
|
throw new Error('Account address is required');
|
|
527
529
|
}
|
|
528
|
-
this.setActiveAccount(accountAddress);
|
|
529
|
-
return _super.reshareWalletAccountShares.call(this,
|
|
530
|
-
accountAddress,
|
|
531
|
-
password,
|
|
532
|
-
thresholdSignatureScheme,
|
|
533
|
-
});
|
|
530
|
+
this.setActiveAccount(params.accountAddress);
|
|
531
|
+
return _super.reshareWalletAccountShares.call(this, params);
|
|
534
532
|
});
|
|
535
533
|
}
|
|
536
534
|
// Chain-specific override for updatePassword - EVM needs to set active account first
|
|
537
|
-
updatePassword(
|
|
535
|
+
updatePassword(params) {
|
|
538
536
|
const _super = Object.create(null, {
|
|
539
537
|
updatePassword: { get: () => super.updatePassword }
|
|
540
538
|
});
|
|
541
|
-
return __awaiter(this,
|
|
542
|
-
if (!accountAddress) {
|
|
539
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
540
|
+
if (!params.accountAddress) {
|
|
543
541
|
throw new Error('Account address is required');
|
|
544
542
|
}
|
|
545
543
|
// EVM-specific: set active account before updating password
|
|
546
|
-
this.setActiveAccount(accountAddress);
|
|
547
|
-
return _super.updatePassword.call(this,
|
|
544
|
+
this.setActiveAccount(params.accountAddress);
|
|
545
|
+
return _super.updatePassword.call(this, params);
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Registers the project's EVM gas sponsorship configuration so the send flow
|
|
550
|
+
* can route transactions through the sponsored relay instead of paying fees
|
|
551
|
+
* from the wallet's native balance.
|
|
552
|
+
*/
|
|
553
|
+
setEvmGasSponsorshipConfig({ getEnabled, getSdkApi, }) {
|
|
554
|
+
this.getEvmGasSponsorshipEnabled = getEnabled;
|
|
555
|
+
this.getSponsorshipSdkApi = getSdkApi;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Sponsorship requires the project setting, an SDK API client and a relayer
|
|
559
|
+
* funded for the wallet's current chain. Anything missing means the send flow
|
|
560
|
+
* pays fees from the wallet's native balance.
|
|
561
|
+
*/
|
|
562
|
+
isGasSponsorshipAvailable() {
|
|
563
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
564
|
+
var _a;
|
|
565
|
+
const { environmentId } = this;
|
|
566
|
+
if (!this.getEvmGasSponsorshipEnabled() || !environmentId) {
|
|
567
|
+
return false;
|
|
568
|
+
}
|
|
569
|
+
const sdkApi = (_a = this.getSponsorshipSdkApi) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
570
|
+
if (!sdkApi) {
|
|
571
|
+
return false;
|
|
572
|
+
}
|
|
573
|
+
const evmNetwork = this.currentEvmNetwork();
|
|
574
|
+
if (!evmNetwork) {
|
|
575
|
+
return false;
|
|
576
|
+
}
|
|
577
|
+
try {
|
|
578
|
+
yield getAvailableEvmGaslessRelayer({ chainId: Number(evmNetwork.chainId) }, { environmentId, sdkApi });
|
|
579
|
+
return true;
|
|
580
|
+
}
|
|
581
|
+
catch (_b) {
|
|
582
|
+
logger.debug('No EVM gasless relayer available for chain');
|
|
583
|
+
return false;
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
sendSponsoredUiTransaction(_a) {
|
|
588
|
+
return __awaiter(this, arguments, void 0, function* ({ accountAddress, sponsoredChainId, transaction, }) {
|
|
589
|
+
var _b, _c;
|
|
590
|
+
const sdkApi = (_b = this.getSponsorshipSdkApi) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
591
|
+
if (!sdkApi || !this.environmentId) {
|
|
592
|
+
throw new DynamicError('Gas sponsorship is not configured', 'gas_sponsorship_not_configured');
|
|
593
|
+
}
|
|
594
|
+
const evmNetwork = this.currentEvmNetwork();
|
|
595
|
+
if (!evmNetwork) {
|
|
596
|
+
throw new DynamicError('EVM network not found', 'evm_network_not_found');
|
|
597
|
+
}
|
|
598
|
+
if (Number(evmNetwork.chainId) !== sponsoredChainId) {
|
|
599
|
+
throw new DynamicError('Gas sponsorship was not verified for the active chain', 'gas_sponsorship_chain_mismatch');
|
|
600
|
+
}
|
|
601
|
+
const publicClient = yield this.getPublicClient();
|
|
602
|
+
if (!publicClient) {
|
|
603
|
+
throw new DynamicError('No public client available', 'no_public_client_available');
|
|
604
|
+
}
|
|
605
|
+
const accountSource = yield this.getViemAccountCustomSource({
|
|
548
606
|
accountAddress,
|
|
549
|
-
existingPassword,
|
|
550
|
-
newPassword,
|
|
551
607
|
});
|
|
608
|
+
const sponsorshipWalletClient = createWalletClient({
|
|
609
|
+
account: toAccount(withBigintSafeSignTypedData(accountSource)),
|
|
610
|
+
chain: getOrMapViemChain(evmNetwork),
|
|
611
|
+
transport: http(this.getRpcUrl(evmNetwork), this.providersConfig.httpTransportConfig),
|
|
612
|
+
});
|
|
613
|
+
const calls = toSponsoredTransactionCalls({
|
|
614
|
+
nonNativeAddress: transaction.nonNativeAddress,
|
|
615
|
+
nonNativeValue: transaction.nonNativeValue,
|
|
616
|
+
to: (_c = transaction.to) !== null && _c !== void 0 ? _c : undefined,
|
|
617
|
+
value: transaction.value,
|
|
618
|
+
});
|
|
619
|
+
const { transactionHash } = yield sendSponsoredTransaction({
|
|
620
|
+
autoDelegate: true,
|
|
621
|
+
calls,
|
|
622
|
+
}, {
|
|
623
|
+
chainId: Number(evmNetwork.chainId),
|
|
624
|
+
delegationRegistry: this.delegation7702Registry,
|
|
625
|
+
environmentId: this.environmentId,
|
|
626
|
+
publicClient: publicClient,
|
|
627
|
+
sdkApi,
|
|
628
|
+
walletClient: sponsorshipWalletClient,
|
|
629
|
+
});
|
|
630
|
+
return transactionHash;
|
|
552
631
|
});
|
|
553
632
|
}
|
|
554
633
|
createUiTransaction(from) {
|
|
555
634
|
return __awaiter(this, void 0, void 0, function* () {
|
|
635
|
+
var _a;
|
|
556
636
|
yield this.validateActiveWallet(from);
|
|
557
637
|
const walletClient = this.getWalletClient();
|
|
558
638
|
const publicClient = yield this.getPublicClient();
|
|
@@ -562,9 +642,19 @@ class DynamicWaasEVMConnector extends withDynamicWaas(EthereumWalletConnector) {
|
|
|
562
642
|
if (!publicClient || !walletClient) {
|
|
563
643
|
throw new DynamicError('No public client available', 'no_public_client_available');
|
|
564
644
|
}
|
|
645
|
+
const isGasSponsored = yield this.isGasSponsorshipAvailable();
|
|
646
|
+
const sponsoredChainId = Number((_a = this.currentEvmNetwork()) === null || _a === void 0 ? void 0 : _a.chainId);
|
|
565
647
|
return new ViemUiTransaction({
|
|
566
648
|
account: from,
|
|
649
|
+
isGasSponsored,
|
|
567
650
|
onSubmit: (transaction) => __awaiter(this, void 0, void 0, function* () {
|
|
651
|
+
if (isGasSponsored) {
|
|
652
|
+
return this.sendSponsoredUiTransaction({
|
|
653
|
+
accountAddress: from,
|
|
654
|
+
sponsoredChainId,
|
|
655
|
+
transaction,
|
|
656
|
+
});
|
|
657
|
+
}
|
|
568
658
|
// Non native token
|
|
569
659
|
if (transaction.nonNativeAddress) {
|
|
570
660
|
return walletClient.writeContract({
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var viem = require('viem');
|
|
7
|
+
var utils = require('@dynamic-labs/utils');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Maps a UI transaction to the batch of calls the sponsored-transaction
|
|
11
|
+
* delegate executes on behalf of the wallet.
|
|
12
|
+
*/
|
|
13
|
+
const toSponsoredTransactionCalls = ({ to, value, nonNativeAddress, nonNativeValue, }) => {
|
|
14
|
+
if (!to) {
|
|
15
|
+
throw new utils.DynamicError('Missing recipient, cannot sponsor transaction', 'sponsorship_missing_recipient');
|
|
16
|
+
}
|
|
17
|
+
if (nonNativeAddress) {
|
|
18
|
+
return [
|
|
19
|
+
{
|
|
20
|
+
data: viem.encodeFunctionData({
|
|
21
|
+
abi: viem.erc20Abi,
|
|
22
|
+
args: [to, nonNativeValue !== null && nonNativeValue !== void 0 ? nonNativeValue : BigInt(0)],
|
|
23
|
+
functionName: 'transfer',
|
|
24
|
+
}),
|
|
25
|
+
target: nonNativeAddress,
|
|
26
|
+
value: BigInt(0),
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
}
|
|
30
|
+
return [
|
|
31
|
+
{
|
|
32
|
+
data: '0x',
|
|
33
|
+
target: to,
|
|
34
|
+
value: value !== null && value !== void 0 ? value : BigInt(0),
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
exports.toSponsoredTransactionCalls = toSponsoredTransactionCalls;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { SponsoredTransactionCall } from '@dynamic-labs/ethereum-gasless-core';
|
|
2
|
+
type ToSponsoredTransactionCallsParams = {
|
|
3
|
+
to: string | undefined;
|
|
4
|
+
value: bigint | undefined;
|
|
5
|
+
nonNativeAddress?: string;
|
|
6
|
+
nonNativeValue?: bigint;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Maps a UI transaction to the batch of calls the sponsored-transaction
|
|
10
|
+
* delegate executes on behalf of the wallet.
|
|
11
|
+
*/
|
|
12
|
+
export declare const toSponsoredTransactionCalls: ({ to, value, nonNativeAddress, nonNativeValue, }: ToSponsoredTransactionCallsParams) => SponsoredTransactionCall[];
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { encodeFunctionData, erc20Abi } from 'viem';
|
|
3
|
+
import { DynamicError } from '@dynamic-labs/utils';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Maps a UI transaction to the batch of calls the sponsored-transaction
|
|
7
|
+
* delegate executes on behalf of the wallet.
|
|
8
|
+
*/
|
|
9
|
+
const toSponsoredTransactionCalls = ({ to, value, nonNativeAddress, nonNativeValue, }) => {
|
|
10
|
+
if (!to) {
|
|
11
|
+
throw new DynamicError('Missing recipient, cannot sponsor transaction', 'sponsorship_missing_recipient');
|
|
12
|
+
}
|
|
13
|
+
if (nonNativeAddress) {
|
|
14
|
+
return [
|
|
15
|
+
{
|
|
16
|
+
data: encodeFunctionData({
|
|
17
|
+
abi: erc20Abi,
|
|
18
|
+
args: [to, nonNativeValue !== null && nonNativeValue !== void 0 ? nonNativeValue : BigInt(0)],
|
|
19
|
+
functionName: 'transfer',
|
|
20
|
+
}),
|
|
21
|
+
target: nonNativeAddress,
|
|
22
|
+
value: BigInt(0),
|
|
23
|
+
},
|
|
24
|
+
];
|
|
25
|
+
}
|
|
26
|
+
return [
|
|
27
|
+
{
|
|
28
|
+
data: '0x',
|
|
29
|
+
target: to,
|
|
30
|
+
value: value !== null && value !== void 0 ? value : BigInt(0),
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export { toSponsoredTransactionCalls };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var utils = require('@dynamic-labs/utils');
|
|
7
|
+
|
|
8
|
+
const toJsonSafeValue = (value) => {
|
|
9
|
+
if (typeof value === 'bigint') {
|
|
10
|
+
return value.toString();
|
|
11
|
+
}
|
|
12
|
+
if (Array.isArray(value)) {
|
|
13
|
+
return value.map(toJsonSafeValue);
|
|
14
|
+
}
|
|
15
|
+
if (value !== null && typeof value === 'object') {
|
|
16
|
+
const entries = Object.entries(value).map(([key, nestedValue]) => [
|
|
17
|
+
key,
|
|
18
|
+
toJsonSafeValue(nestedValue),
|
|
19
|
+
]);
|
|
20
|
+
return Object.fromEntries(entries);
|
|
21
|
+
}
|
|
22
|
+
return value;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Wraps a viem custom source so typed-data payloads are stripped of bigints
|
|
26
|
+
* before signing. The WaaS signing transport serializes messages as JSON and
|
|
27
|
+
* rejects bigint values, which EIP-712 sponsored-transaction intents contain.
|
|
28
|
+
*/
|
|
29
|
+
const withBigintSafeSignTypedData = (source) => {
|
|
30
|
+
const { signTypedData } = source;
|
|
31
|
+
if (!signTypedData) {
|
|
32
|
+
throw new utils.DynamicError('Custom source does not support signTypedData', 'sign_typed_data_not_supported');
|
|
33
|
+
}
|
|
34
|
+
return Object.assign(Object.assign({}, source), { signTypedData: (typedData) => signTypedData(toJsonSafeValue(typedData)) });
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
exports.withBigintSafeSignTypedData = withBigintSafeSignTypedData;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CustomSource } from 'viem';
|
|
2
|
+
/**
|
|
3
|
+
* Wraps a viem custom source so typed-data payloads are stripped of bigints
|
|
4
|
+
* before signing. The WaaS signing transport serializes messages as JSON and
|
|
5
|
+
* rejects bigint values, which EIP-712 sponsored-transaction intents contain.
|
|
6
|
+
*/
|
|
7
|
+
export declare const withBigintSafeSignTypedData: (source: CustomSource) => CustomSource;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { DynamicError } from '@dynamic-labs/utils';
|
|
3
|
+
|
|
4
|
+
const toJsonSafeValue = (value) => {
|
|
5
|
+
if (typeof value === 'bigint') {
|
|
6
|
+
return value.toString();
|
|
7
|
+
}
|
|
8
|
+
if (Array.isArray(value)) {
|
|
9
|
+
return value.map(toJsonSafeValue);
|
|
10
|
+
}
|
|
11
|
+
if (value !== null && typeof value === 'object') {
|
|
12
|
+
const entries = Object.entries(value).map(([key, nestedValue]) => [
|
|
13
|
+
key,
|
|
14
|
+
toJsonSafeValue(nestedValue),
|
|
15
|
+
]);
|
|
16
|
+
return Object.fromEntries(entries);
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Wraps a viem custom source so typed-data payloads are stripped of bigints
|
|
22
|
+
* before signing. The WaaS signing transport serializes messages as JSON and
|
|
23
|
+
* rejects bigint values, which EIP-712 sponsored-transaction intents contain.
|
|
24
|
+
*/
|
|
25
|
+
const withBigintSafeSignTypedData = (source) => {
|
|
26
|
+
const { signTypedData } = source;
|
|
27
|
+
if (!signTypedData) {
|
|
28
|
+
throw new DynamicError('Custom source does not support signTypedData', 'sign_typed_data_not_supported');
|
|
29
|
+
}
|
|
30
|
+
return Object.assign(Object.assign({}, source), { signTypedData: (typedData) => signTypedData(toJsonSafeValue(typedData)) });
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export { withBigintSafeSignTypedData };
|