@dynamic-labs/waas-evm 5.4.1 → 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 +15 -0
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +9 -8
- package/src/DynamicWaasEVMConnector.cjs +102 -0
- package/src/DynamicWaasEVMConnector.d.ts +28 -1
- package/src/DynamicWaasEVMConnector.js +103 -1
- 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,19 @@
|
|
|
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
|
+
|
|
2
17
|
### [5.4.1](https://github.com/dynamic-labs/dynamic-auth/compare/v5.4.0...v5.4.1) (2026-08-26)
|
|
3
18
|
|
|
4
19
|
|
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.
|
|
@@ -543,8 +549,94 @@ class DynamicWaasEVMConnector extends waas.withDynamicWaas(ethereumCore.Ethereum
|
|
|
543
549
|
return _super.updatePassword.call(this, params);
|
|
544
550
|
});
|
|
545
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({
|
|
610
|
+
accountAddress,
|
|
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;
|
|
635
|
+
});
|
|
636
|
+
}
|
|
546
637
|
createUiTransaction(from) {
|
|
547
638
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
639
|
+
var _a;
|
|
548
640
|
yield this.validateActiveWallet(from);
|
|
549
641
|
const walletClient = this.getWalletClient();
|
|
550
642
|
const publicClient = yield this.getPublicClient();
|
|
@@ -554,9 +646,19 @@ class DynamicWaasEVMConnector extends waas.withDynamicWaas(ethereumCore.Ethereum
|
|
|
554
646
|
if (!publicClient || !walletClient) {
|
|
555
647
|
throw new utils.DynamicError('No public client available', 'no_public_client_available');
|
|
556
648
|
}
|
|
649
|
+
const isGasSponsored = yield this.isGasSponsorshipAvailable();
|
|
650
|
+
const sponsoredChainId = Number((_a = this.currentEvmNetwork()) === null || _a === void 0 ? void 0 : _a.chainId);
|
|
557
651
|
return new ethereumCore.ViemUiTransaction({
|
|
558
652
|
account: from,
|
|
653
|
+
isGasSponsored,
|
|
559
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
|
+
}
|
|
560
662
|
// Non native token
|
|
561
663
|
if (transaction.nonNativeAddress) {
|
|
562
664
|
return walletClient.writeContract({
|
|
@@ -2,7 +2,7 @@ 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
8
|
import { BackupKeySharesToGoogleDriveParams, ExportClientKeysharesParams, IDynamicWaasConnector, RefreshWalletAccountSharesParams, ReshareWalletAccountSharesParams, UpdatePasswordParams } from '@dynamic-labs/wallet-connector-core';
|
|
@@ -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;
|
|
@@ -210,6 +218,9 @@ export declare class DynamicWaasEVMConnector extends DynamicWaasEVMConnector_bas
|
|
|
210
218
|
logger: Logger;
|
|
211
219
|
overrideKey: string;
|
|
212
220
|
isEmbeddedWallet: boolean;
|
|
221
|
+
private getEvmGasSponsorshipEnabled;
|
|
222
|
+
private getSponsorshipSdkApi;
|
|
223
|
+
private delegation7702Registry;
|
|
213
224
|
/**
|
|
214
225
|
* Chain IDs that have dedicated connectors and should not be handled by this connector.
|
|
215
226
|
* Networks with these chain IDs are filtered from network lists and rejected during switching.
|
|
@@ -279,6 +290,22 @@ export declare class DynamicWaasEVMConnector extends DynamicWaasEVMConnector_bas
|
|
|
279
290
|
refreshWalletAccountShares(params: RefreshWalletAccountSharesParams): Promise<void>;
|
|
280
291
|
reshareWalletAccountShares(params: ReshareWalletAccountSharesParams): Promise<void>;
|
|
281
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;
|
|
282
309
|
createUiTransaction(from: string): Promise<IUITransaction>;
|
|
283
310
|
getConnectedAccounts(): Promise<string[]>;
|
|
284
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.
|
|
@@ -539,8 +545,94 @@ class DynamicWaasEVMConnector extends withDynamicWaas(EthereumWalletConnector) {
|
|
|
539
545
|
return _super.updatePassword.call(this, params);
|
|
540
546
|
});
|
|
541
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({
|
|
606
|
+
accountAddress,
|
|
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;
|
|
631
|
+
});
|
|
632
|
+
}
|
|
542
633
|
createUiTransaction(from) {
|
|
543
634
|
return __awaiter(this, void 0, void 0, function* () {
|
|
635
|
+
var _a;
|
|
544
636
|
yield this.validateActiveWallet(from);
|
|
545
637
|
const walletClient = this.getWalletClient();
|
|
546
638
|
const publicClient = yield this.getPublicClient();
|
|
@@ -550,9 +642,19 @@ class DynamicWaasEVMConnector extends withDynamicWaas(EthereumWalletConnector) {
|
|
|
550
642
|
if (!publicClient || !walletClient) {
|
|
551
643
|
throw new DynamicError('No public client available', 'no_public_client_available');
|
|
552
644
|
}
|
|
645
|
+
const isGasSponsored = yield this.isGasSponsorshipAvailable();
|
|
646
|
+
const sponsoredChainId = Number((_a = this.currentEvmNetwork()) === null || _a === void 0 ? void 0 : _a.chainId);
|
|
553
647
|
return new ViemUiTransaction({
|
|
554
648
|
account: from,
|
|
649
|
+
isGasSponsored,
|
|
555
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
|
+
}
|
|
556
658
|
// Non native token
|
|
557
659
|
if (transaction.nonNativeAddress) {
|
|
558
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 };
|