@dynamic-labs-wallet/node-evm 1.0.49 → 1.0.51
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/index.cjs +355 -6
- package/index.esm.js +343 -8
- package/package.json +3 -3
- package/src/client/client.d.ts +24 -1
- package/src/client/client.d.ts.map +1 -1
- package/src/client/gasless.client.d.ts +25 -0
- package/src/client/gasless.client.d.ts.map +1 -0
- package/src/client/gasless.constants.d.ts +63 -0
- package/src/client/gasless.constants.d.ts.map +1 -0
- package/src/client/gasless.types.d.ts +120 -0
- package/src/client/gasless.types.d.ts.map +1 -0
- package/src/client/index.d.ts +2 -0
- package/src/client/index.d.ts.map +1 -1
package/index.cjs
CHANGED
|
@@ -5,6 +5,7 @@ var node = require('@dynamic-labs-wallet/node');
|
|
|
5
5
|
var viem = require('viem');
|
|
6
6
|
var utils = require('viem/utils');
|
|
7
7
|
var chains = require('viem/chains');
|
|
8
|
+
var node_crypto = require('node:crypto');
|
|
8
9
|
var client = require('@dynamic-labs-sdk/client');
|
|
9
10
|
var core = require('@dynamic-labs-sdk/client/core');
|
|
10
11
|
var viem$1 = require('@dynamic-labs-sdk/evm/viem');
|
|
@@ -95,7 +96,7 @@ const deriveAccountAddress = ({ rawPublicKey })=>{
|
|
|
95
96
|
};
|
|
96
97
|
};
|
|
97
98
|
|
|
98
|
-
const logError$
|
|
99
|
+
const logError$2 = node.createLogError('node-evm');
|
|
99
100
|
/**
|
|
100
101
|
* Creates a delegated EVM wallet client for functional operations
|
|
101
102
|
*/ const createDelegatedEvmWalletClient = ({ environmentId, baseApiUrl, baseMPCRelayApiUrl, apiKey, debug = false })=>{
|
|
@@ -134,7 +135,7 @@ const logError$1 = node.createLogError('node-evm');
|
|
|
134
135
|
});
|
|
135
136
|
return serializeECDSASignature(signatureEcdsa);
|
|
136
137
|
} catch (error) {
|
|
137
|
-
logError$
|
|
138
|
+
logError$2({
|
|
138
139
|
message: 'Error in delegatedSignMessage',
|
|
139
140
|
error: error,
|
|
140
141
|
context: {
|
|
@@ -180,7 +181,7 @@ const logError$1 = node.createLogError('node-evm');
|
|
|
180
181
|
});
|
|
181
182
|
return viem.serializeTransaction(signedTx);
|
|
182
183
|
} catch (error) {
|
|
183
|
-
logError$
|
|
184
|
+
logError$2({
|
|
184
185
|
message: 'Error in delegatedSignTransaction',
|
|
185
186
|
error: error,
|
|
186
187
|
context: {
|
|
@@ -213,7 +214,7 @@ const logError$1 = node.createLogError('node-evm');
|
|
|
213
214
|
});
|
|
214
215
|
return serializeECDSASignature(signatureEcdsa);
|
|
215
216
|
} catch (error) {
|
|
216
|
-
logError$
|
|
217
|
+
logError$2({
|
|
217
218
|
message: 'Error in delegatedSignTypedData',
|
|
218
219
|
error: error,
|
|
219
220
|
context: {
|
|
@@ -248,7 +249,7 @@ const logError$1 = node.createLogError('node-evm');
|
|
|
248
249
|
const serializedSignature = serializeECDSASignature(signatureEcdsa);
|
|
249
250
|
return viem.parseSignature(serializedSignature);
|
|
250
251
|
} catch (error) {
|
|
251
|
-
logError$
|
|
252
|
+
logError$2({
|
|
252
253
|
message: 'Error in delegatedSignAuthorization',
|
|
253
254
|
error: error,
|
|
254
255
|
context: {
|
|
@@ -281,7 +282,7 @@ const logError$1 = node.createLogError('node-evm');
|
|
|
281
282
|
});
|
|
282
283
|
return serializeECDSASignature(signatureEcdsa);
|
|
283
284
|
} catch (error) {
|
|
284
|
-
logError$
|
|
285
|
+
logError$2({
|
|
285
286
|
message: 'Error in delegatedSignRawMessage',
|
|
286
287
|
error: error,
|
|
287
288
|
context: {
|
|
@@ -397,6 +398,306 @@ const createAccountAdapter = ({ evmClient, walletMetadata, password, externalSer
|
|
|
397
398
|
});
|
|
398
399
|
};
|
|
399
400
|
|
|
401
|
+
/** The Fireblocks Universal Gasless Delegate (UGD) contract address used for EIP-7702 delegation. */ const DELEGATION_CONTRACT_ADDRESS = '0x0000Fb7702036ff9f76044a501ac1aA74cbab16b';
|
|
402
|
+
/** Default sponsored transaction validity duration in seconds (10 minutes). */ const DEFAULT_VALID_FOR_SECONDS = 600;
|
|
403
|
+
/** EIP-7702 delegation code prefix used to identify delegated accounts. */ const DELEGATION_CODE_PREFIX = '0xef0100';
|
|
404
|
+
/** ERC-7579 batch call with opData and auth mode identifier. */ const BATCH_CALL_OPDATA_AUTH_MODE = '0x0100000000007821000100000000000000000000000000000000000000000000';
|
|
405
|
+
/** EIP-712 typed data types for UGD AuthorizedExecutions signing. */ const AUTHORIZED_EXECUTIONS_TYPES = {
|
|
406
|
+
AuthorizedExecutions: [
|
|
407
|
+
{
|
|
408
|
+
name: 'calls',
|
|
409
|
+
type: 'Execution[]'
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
name: 'deadline',
|
|
413
|
+
type: 'uint256'
|
|
414
|
+
},
|
|
415
|
+
{
|
|
416
|
+
name: 'mode',
|
|
417
|
+
type: 'bytes32'
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
name: 'nonce',
|
|
421
|
+
type: 'uint256'
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
name: 'relayer',
|
|
425
|
+
type: 'address'
|
|
426
|
+
}
|
|
427
|
+
],
|
|
428
|
+
Execution: [
|
|
429
|
+
{
|
|
430
|
+
name: 'target',
|
|
431
|
+
type: 'address'
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
name: 'value',
|
|
435
|
+
type: 'uint256'
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
name: 'data',
|
|
439
|
+
type: 'bytes'
|
|
440
|
+
}
|
|
441
|
+
]
|
|
442
|
+
};
|
|
443
|
+
/** Minimal ABI for the UGD contract's nonce validation function. */ const UGD_ABI = [
|
|
444
|
+
{
|
|
445
|
+
inputs: [
|
|
446
|
+
{
|
|
447
|
+
name: 'nonce',
|
|
448
|
+
type: 'uint256'
|
|
449
|
+
}
|
|
450
|
+
],
|
|
451
|
+
name: 'isNonceUsed',
|
|
452
|
+
outputs: [
|
|
453
|
+
{
|
|
454
|
+
name: '',
|
|
455
|
+
type: 'bool'
|
|
456
|
+
}
|
|
457
|
+
],
|
|
458
|
+
stateMutability: 'view',
|
|
459
|
+
type: 'function'
|
|
460
|
+
}
|
|
461
|
+
];
|
|
462
|
+
/** Default polling interval for sponsored transaction status checks (milliseconds). */ const EVM_GASLESS_DEFAULT_POLL_INTERVAL_MS = 2000;
|
|
463
|
+
/** Default timeout for sponsored transaction polling (milliseconds). */ const EVM_GASLESS_DEFAULT_TIMEOUT_MS = 60000;
|
|
464
|
+
// Error messages
|
|
465
|
+
const ERROR_GASLESS_RPC_REQUIRED_FOR_AUTO_DELEGATE = 'rpcUrl is required when autoDelegate is true and no explicit authorization is provided. ' + 'Pass rpcUrl, pass an explicit authorization, or set autoDelegate: false.';
|
|
466
|
+
const ERROR_GASLESS_RELAY_FAILED = 'EVM sponsored transaction relay failed';
|
|
467
|
+
const ERROR_GASLESS_TIMEOUT = 'EVM sponsored transaction timed out waiting for terminal status';
|
|
468
|
+
const ERROR_GASLESS_MISSING_REQUEST_ID = 'Relay response did not include a requestId';
|
|
469
|
+
const ERROR_GASLESS_MISSING_YPARITY = 'Signed authorization is missing yParity';
|
|
470
|
+
const ERROR_GASLESS_RPC_REQUIRED = 'rpcUrl is required for this operation';
|
|
471
|
+
|
|
472
|
+
const logError$1 = node.createLogError('node-evm');
|
|
473
|
+
/**
|
|
474
|
+
* Builds a stateless gasless client for EVM sponsored transactions (Fireblocks-relayer
|
|
475
|
+
* native gasless via EIP-7702 / AuthorizedExecutions). It holds no wallet state — the
|
|
476
|
+
* signing primitives and API client are injected by the owning `DynamicEvmWalletClient`.
|
|
477
|
+
*/ const createEvmGaslessClient = ({ apiClient, createViemPublicClient, signAuthorization, signTypedData })=>{
|
|
478
|
+
const viemPublicClientForChain = (chainId, rpcUrl)=>{
|
|
479
|
+
if (!rpcUrl) {
|
|
480
|
+
throw new Error(ERROR_GASLESS_RPC_REQUIRED);
|
|
481
|
+
}
|
|
482
|
+
const chain = viem.defineChain({
|
|
483
|
+
id: chainId,
|
|
484
|
+
name: `Chain ${chainId}`,
|
|
485
|
+
nativeCurrency: {
|
|
486
|
+
name: 'Ether',
|
|
487
|
+
symbol: 'ETH',
|
|
488
|
+
decimals: 18
|
|
489
|
+
},
|
|
490
|
+
rpcUrls: {
|
|
491
|
+
default: {
|
|
492
|
+
http: [
|
|
493
|
+
rpcUrl
|
|
494
|
+
]
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
return createViemPublicClient({
|
|
499
|
+
chain,
|
|
500
|
+
rpcUrl
|
|
501
|
+
});
|
|
502
|
+
};
|
|
503
|
+
const generateRandomNonce = ()=>BigInt('0x' + node_crypto.randomBytes(32).toString('hex'));
|
|
504
|
+
const generateIntentNonce = async ({ walletAddress, chainId, rpcUrl })=>{
|
|
505
|
+
let nonce = generateRandomNonce();
|
|
506
|
+
if (rpcUrl) {
|
|
507
|
+
try {
|
|
508
|
+
const publicClient = viemPublicClientForChain(chainId, rpcUrl);
|
|
509
|
+
// On a brand-new (undelegated) wallet the address has no UGD code yet,
|
|
510
|
+
// so isNonceUsed reverts — the random value is safe regardless.
|
|
511
|
+
const isUsed = await publicClient.readContract({
|
|
512
|
+
address: walletAddress,
|
|
513
|
+
abi: UGD_ABI,
|
|
514
|
+
functionName: 'isNonceUsed',
|
|
515
|
+
args: [
|
|
516
|
+
nonce
|
|
517
|
+
]
|
|
518
|
+
});
|
|
519
|
+
if (isUsed) {
|
|
520
|
+
nonce = generateRandomNonce();
|
|
521
|
+
}
|
|
522
|
+
} catch (e) {
|
|
523
|
+
// RPC failure is tolerable — 256-bit random collision is negligible
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
return nonce;
|
|
527
|
+
};
|
|
528
|
+
const is7702DelegationActive = async ({ walletAddress, chainId, rpcUrl })=>{
|
|
529
|
+
const publicClient = viemPublicClientForChain(chainId, rpcUrl);
|
|
530
|
+
const code = await publicClient.getCode({
|
|
531
|
+
address: walletAddress
|
|
532
|
+
});
|
|
533
|
+
if (!code) return false;
|
|
534
|
+
const expectedPrefix = DELEGATION_CODE_PREFIX + DELEGATION_CONTRACT_ADDRESS.slice(2).toLowerCase();
|
|
535
|
+
return code.toLowerCase().startsWith(expectedPrefix);
|
|
536
|
+
};
|
|
537
|
+
const sign7702Authorization = async ({ walletMetadata, chainId, rpcUrl, nonce, password, externalServerKeyShares })=>{
|
|
538
|
+
const address = walletMetadata.accountAddress;
|
|
539
|
+
try {
|
|
540
|
+
let eoaNonce;
|
|
541
|
+
if (nonce === undefined) {
|
|
542
|
+
if (!rpcUrl) {
|
|
543
|
+
throw new Error(ERROR_GASLESS_RPC_REQUIRED);
|
|
544
|
+
}
|
|
545
|
+
const publicClient = viemPublicClientForChain(chainId, rpcUrl);
|
|
546
|
+
eoaNonce = Number(await publicClient.getTransactionCount({
|
|
547
|
+
address
|
|
548
|
+
}));
|
|
549
|
+
} else {
|
|
550
|
+
eoaNonce = nonce;
|
|
551
|
+
}
|
|
552
|
+
const authorization = {
|
|
553
|
+
address: DELEGATION_CONTRACT_ADDRESS,
|
|
554
|
+
chainId,
|
|
555
|
+
nonce: eoaNonce
|
|
556
|
+
};
|
|
557
|
+
const sig = await signAuthorization({
|
|
558
|
+
authorization,
|
|
559
|
+
walletMetadata,
|
|
560
|
+
password,
|
|
561
|
+
externalServerKeyShares
|
|
562
|
+
});
|
|
563
|
+
if (sig.yParity === undefined) {
|
|
564
|
+
throw new Error(ERROR_GASLESS_MISSING_YPARITY);
|
|
565
|
+
}
|
|
566
|
+
return {
|
|
567
|
+
address: DELEGATION_CONTRACT_ADDRESS,
|
|
568
|
+
chainId,
|
|
569
|
+
nonce: eoaNonce,
|
|
570
|
+
r: sig.r,
|
|
571
|
+
s: sig.s,
|
|
572
|
+
yParity: sig.yParity
|
|
573
|
+
};
|
|
574
|
+
} catch (error) {
|
|
575
|
+
logError$1({
|
|
576
|
+
message: 'Error signing 7702 authorization',
|
|
577
|
+
error: error,
|
|
578
|
+
context: {
|
|
579
|
+
accountAddress: address,
|
|
580
|
+
chainId
|
|
581
|
+
}
|
|
582
|
+
});
|
|
583
|
+
throw error;
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
const getAvailableEvmGaslessRelayer = async ({ chainId, traceContext })=>{
|
|
587
|
+
const result = await apiClient.getAvailableEVMGaslessRelayer({
|
|
588
|
+
chainId,
|
|
589
|
+
traceContext
|
|
590
|
+
});
|
|
591
|
+
return {
|
|
592
|
+
relayerAddress: result.relayerAddress
|
|
593
|
+
};
|
|
594
|
+
};
|
|
595
|
+
const resolveSponsoredAuthorization = async ({ authorization, autoDelegate, walletMetadata, chainId, rpcUrl, password, externalServerKeyShares })=>{
|
|
596
|
+
if (authorization) {
|
|
597
|
+
return authorization;
|
|
598
|
+
}
|
|
599
|
+
if (!autoDelegate) {
|
|
600
|
+
return undefined;
|
|
601
|
+
}
|
|
602
|
+
// The EOA nonce and delegation status are only knowable on-chain; without
|
|
603
|
+
// an RPC we can't safely auto-sign a 7702 authorization, so fail loud
|
|
604
|
+
// instead of relaying an intent that would revert.
|
|
605
|
+
if (!rpcUrl) {
|
|
606
|
+
throw new Error(ERROR_GASLESS_RPC_REQUIRED_FOR_AUTO_DELEGATE);
|
|
607
|
+
}
|
|
608
|
+
const walletAddress = walletMetadata.accountAddress;
|
|
609
|
+
const isDelegated = await is7702DelegationActive({
|
|
610
|
+
walletAddress,
|
|
611
|
+
chainId,
|
|
612
|
+
rpcUrl
|
|
613
|
+
});
|
|
614
|
+
if (isDelegated) {
|
|
615
|
+
return undefined;
|
|
616
|
+
}
|
|
617
|
+
return sign7702Authorization({
|
|
618
|
+
walletMetadata,
|
|
619
|
+
chainId,
|
|
620
|
+
rpcUrl,
|
|
621
|
+
password,
|
|
622
|
+
externalServerKeyShares
|
|
623
|
+
});
|
|
624
|
+
};
|
|
625
|
+
const signSponsoredTransaction = async ({ walletMetadata, calls, chainId, rpcUrl, authorization, autoDelegate = true, nonce: providedNonce, validForSeconds = DEFAULT_VALID_FOR_SECONDS, password, externalServerKeyShares, traceContext })=>{
|
|
626
|
+
const walletAddress = walletMetadata.accountAddress;
|
|
627
|
+
try {
|
|
628
|
+
const resolvedAuth = await resolveSponsoredAuthorization({
|
|
629
|
+
authorization,
|
|
630
|
+
autoDelegate,
|
|
631
|
+
walletMetadata,
|
|
632
|
+
chainId,
|
|
633
|
+
rpcUrl,
|
|
634
|
+
password,
|
|
635
|
+
externalServerKeyShares
|
|
636
|
+
});
|
|
637
|
+
const nonce = providedNonce != null ? providedNonce : await generateIntentNonce({
|
|
638
|
+
walletAddress,
|
|
639
|
+
chainId,
|
|
640
|
+
rpcUrl
|
|
641
|
+
});
|
|
642
|
+
const deadline = BigInt(Math.floor(Date.now() / 1000) + validForSeconds);
|
|
643
|
+
const { relayerAddress } = await getAvailableEvmGaslessRelayer({
|
|
644
|
+
chainId,
|
|
645
|
+
traceContext
|
|
646
|
+
});
|
|
647
|
+
const signature = await signTypedData({
|
|
648
|
+
walletMetadata,
|
|
649
|
+
password,
|
|
650
|
+
externalServerKeyShares,
|
|
651
|
+
typedData: {
|
|
652
|
+
domain: {
|
|
653
|
+
chainId,
|
|
654
|
+
verifyingContract: DELEGATION_CONTRACT_ADDRESS
|
|
655
|
+
},
|
|
656
|
+
message: {
|
|
657
|
+
calls: calls.map((c)=>({
|
|
658
|
+
data: c.data,
|
|
659
|
+
target: c.target,
|
|
660
|
+
value: c.value
|
|
661
|
+
})),
|
|
662
|
+
deadline,
|
|
663
|
+
mode: BATCH_CALL_OPDATA_AUTH_MODE,
|
|
664
|
+
nonce,
|
|
665
|
+
relayer: relayerAddress
|
|
666
|
+
},
|
|
667
|
+
primaryType: 'AuthorizedExecutions',
|
|
668
|
+
types: AUTHORIZED_EXECUTIONS_TYPES
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
return {
|
|
672
|
+
authorization: resolvedAuth,
|
|
673
|
+
calls,
|
|
674
|
+
chainId,
|
|
675
|
+
deadline: deadline.toString(),
|
|
676
|
+
nonce: nonce.toString(),
|
|
677
|
+
relayer: relayerAddress,
|
|
678
|
+
signature,
|
|
679
|
+
walletAddress
|
|
680
|
+
};
|
|
681
|
+
} catch (error) {
|
|
682
|
+
logError$1({
|
|
683
|
+
message: 'Error signing sponsored transaction',
|
|
684
|
+
error: error,
|
|
685
|
+
context: {
|
|
686
|
+
accountAddress: walletAddress,
|
|
687
|
+
chainId
|
|
688
|
+
}
|
|
689
|
+
});
|
|
690
|
+
throw error;
|
|
691
|
+
}
|
|
692
|
+
};
|
|
693
|
+
return {
|
|
694
|
+
getAvailableEvmGaslessRelayer,
|
|
695
|
+
is7702DelegationActive,
|
|
696
|
+
sign7702Authorization,
|
|
697
|
+
signSponsoredTransaction
|
|
698
|
+
};
|
|
699
|
+
};
|
|
700
|
+
|
|
400
701
|
const logError = node.createLogError('node-evm');
|
|
401
702
|
class DynamicEvmWalletClient extends node.DynamicWalletClient {
|
|
402
703
|
get jwtAuthToken() {
|
|
@@ -829,6 +1130,40 @@ class DynamicEvmWalletClient extends node.DynamicWalletClient {
|
|
|
829
1130
|
const evmWallets = wallets.filter((wallet)=>wallet.chainName === 'EVM');
|
|
830
1131
|
return evmWallets;
|
|
831
1132
|
}
|
|
1133
|
+
// ---------------------------------------------------------------------------
|
|
1134
|
+
// EVM gasless (Fireblocks-relayer native gasless via EIP-7702 / AuthorizedExecutions)
|
|
1135
|
+
// ---------------------------------------------------------------------------
|
|
1136
|
+
get evmGasless() {
|
|
1137
|
+
return createEvmGaslessClient({
|
|
1138
|
+
apiClient: this.apiClient,
|
|
1139
|
+
createViemPublicClient: (args)=>this.createViemPublicClient(args),
|
|
1140
|
+
signAuthorization: (args)=>this.signAuthorization(args),
|
|
1141
|
+
signTypedData: (args)=>this.signTypedData(args)
|
|
1142
|
+
});
|
|
1143
|
+
}
|
|
1144
|
+
/**
|
|
1145
|
+
* Checks whether the given wallet address has an active EIP-7702 delegation
|
|
1146
|
+
* to the Universal Gasless Delegate (UGD) contract.
|
|
1147
|
+
*/ async is7702DelegationActive(params) {
|
|
1148
|
+
return this.evmGasless.is7702DelegationActive(params);
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Signs an EIP-7702 authorization that delegates the EOA to the UGD contract.
|
|
1152
|
+
* The EOA nonce is fetched from the chain unless explicitly provided.
|
|
1153
|
+
*/ async sign7702Authorization(params) {
|
|
1154
|
+
return this.evmGasless.sign7702Authorization(params);
|
|
1155
|
+
}
|
|
1156
|
+
/**
|
|
1157
|
+
* Fetches the available gasless relayer address for a given chain.
|
|
1158
|
+
*/ async getAvailableEvmGaslessRelayer(params) {
|
|
1159
|
+
return this.evmGasless.getAvailableEvmGaslessRelayer(params);
|
|
1160
|
+
}
|
|
1161
|
+
/**
|
|
1162
|
+
* Signs a sponsored transaction intent: resolves 7702 authorization, generates
|
|
1163
|
+
* a bitmap nonce, fetches the relayer, and MPC-signs the EIP-712 typed data.
|
|
1164
|
+
*/ async signSponsoredTransaction(params) {
|
|
1165
|
+
return this.evmGasless.signSponsoredTransaction(params);
|
|
1166
|
+
}
|
|
832
1167
|
constructor({ environmentId, baseApiUrl, baseMPCRelayApiUrl, debug, enableMPCAccelerator, logger }){
|
|
833
1168
|
super({
|
|
834
1169
|
environmentId,
|
|
@@ -1024,15 +1359,29 @@ const createZerodevClient = async (evmClient)=>{
|
|
|
1024
1359
|
return client;
|
|
1025
1360
|
};
|
|
1026
1361
|
|
|
1362
|
+
exports.AUTHORIZED_EXECUTIONS_TYPES = AUTHORIZED_EXECUTIONS_TYPES;
|
|
1363
|
+
exports.BATCH_CALL_OPDATA_AUTH_MODE = BATCH_CALL_OPDATA_AUTH_MODE;
|
|
1364
|
+
exports.DEFAULT_VALID_FOR_SECONDS = DEFAULT_VALID_FOR_SECONDS;
|
|
1365
|
+
exports.DELEGATION_CODE_PREFIX = DELEGATION_CODE_PREFIX;
|
|
1366
|
+
exports.DELEGATION_CONTRACT_ADDRESS = DELEGATION_CONTRACT_ADDRESS;
|
|
1027
1367
|
exports.DynamicEvmWalletClient = DynamicEvmWalletClient;
|
|
1028
1368
|
exports.ERROR_ACCOUNT_ADDRESS_REQUIRED = ERROR_ACCOUNT_ADDRESS_REQUIRED;
|
|
1029
1369
|
exports.ERROR_CREATE_WALLET_ACCOUNT = ERROR_CREATE_WALLET_ACCOUNT;
|
|
1370
|
+
exports.ERROR_GASLESS_MISSING_REQUEST_ID = ERROR_GASLESS_MISSING_REQUEST_ID;
|
|
1371
|
+
exports.ERROR_GASLESS_MISSING_YPARITY = ERROR_GASLESS_MISSING_YPARITY;
|
|
1372
|
+
exports.ERROR_GASLESS_RELAY_FAILED = ERROR_GASLESS_RELAY_FAILED;
|
|
1373
|
+
exports.ERROR_GASLESS_RPC_REQUIRED = ERROR_GASLESS_RPC_REQUIRED;
|
|
1374
|
+
exports.ERROR_GASLESS_RPC_REQUIRED_FOR_AUTO_DELEGATE = ERROR_GASLESS_RPC_REQUIRED_FOR_AUTO_DELEGATE;
|
|
1375
|
+
exports.ERROR_GASLESS_TIMEOUT = ERROR_GASLESS_TIMEOUT;
|
|
1030
1376
|
exports.ERROR_KEYGEN_FAILED = ERROR_KEYGEN_FAILED;
|
|
1031
1377
|
exports.ERROR_SIGN_MESSAGE = ERROR_SIGN_MESSAGE;
|
|
1032
1378
|
exports.ERROR_SIGN_RAW_MESSAGE = ERROR_SIGN_RAW_MESSAGE;
|
|
1033
1379
|
exports.ERROR_SIGN_TYPED_DATA = ERROR_SIGN_TYPED_DATA;
|
|
1034
1380
|
exports.ERROR_VERIFY_MESSAGE_SIGNATURE = ERROR_VERIFY_MESSAGE_SIGNATURE;
|
|
1381
|
+
exports.EVM_GASLESS_DEFAULT_POLL_INTERVAL_MS = EVM_GASLESS_DEFAULT_POLL_INTERVAL_MS;
|
|
1382
|
+
exports.EVM_GASLESS_DEFAULT_TIMEOUT_MS = EVM_GASLESS_DEFAULT_TIMEOUT_MS;
|
|
1035
1383
|
exports.EVM_SIGN_MESSAGE_PREFIX = EVM_SIGN_MESSAGE_PREFIX;
|
|
1384
|
+
exports.UGD_ABI = UGD_ABI;
|
|
1036
1385
|
exports.createAccountAdapter = createAccountAdapter;
|
|
1037
1386
|
exports.createDelegatedEvmWalletClient = createDelegatedEvmWalletClient;
|
|
1038
1387
|
exports.createZerodevClient = createZerodevClient;
|
package/index.esm.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { toAccount } from 'viem/accounts';
|
|
2
2
|
import { MessageHash, createLogError, createDelegatedWalletClient, delegatedSignMessage as delegatedSignMessage$1, stripHexPrefix, revokeDelegation as revokeDelegation$1, DynamicWalletClient, getMPCChainConfig, WalletOperation } from '@dynamic-labs-wallet/node';
|
|
3
|
-
import { getAddress, stringToHex, bytesToHex, size, concat, hashTypedData, validateTypedData, serializeSignature, parseSignature, serializeTransaction, createPublicClient, http,
|
|
3
|
+
import { getAddress, stringToHex, bytesToHex, size, concat, hashTypedData, validateTypedData, serializeSignature, parseSignature, serializeTransaction, defineChain, createPublicClient, http, createWalletClient } from 'viem';
|
|
4
4
|
import { hashAuthorization } from 'viem/utils';
|
|
5
5
|
import { mainnet } from 'viem/chains';
|
|
6
|
+
import { randomBytes } from 'node:crypto';
|
|
6
7
|
import { initializeClient, refreshUser, getNetworksData, createDynamicClient } from '@dynamic-labs-sdk/client';
|
|
7
8
|
import { assertDefined } from '@dynamic-labs-sdk/client/core';
|
|
8
9
|
import { mapNetworkDataToViemChain } from '@dynamic-labs-sdk/evm/viem';
|
|
@@ -93,7 +94,7 @@ const deriveAccountAddress = ({ rawPublicKey })=>{
|
|
|
93
94
|
};
|
|
94
95
|
};
|
|
95
96
|
|
|
96
|
-
const logError$
|
|
97
|
+
const logError$2 = createLogError('node-evm');
|
|
97
98
|
/**
|
|
98
99
|
* Creates a delegated EVM wallet client for functional operations
|
|
99
100
|
*/ const createDelegatedEvmWalletClient = ({ environmentId, baseApiUrl, baseMPCRelayApiUrl, apiKey, debug = false })=>{
|
|
@@ -132,7 +133,7 @@ const logError$1 = createLogError('node-evm');
|
|
|
132
133
|
});
|
|
133
134
|
return serializeECDSASignature(signatureEcdsa);
|
|
134
135
|
} catch (error) {
|
|
135
|
-
logError$
|
|
136
|
+
logError$2({
|
|
136
137
|
message: 'Error in delegatedSignMessage',
|
|
137
138
|
error: error,
|
|
138
139
|
context: {
|
|
@@ -178,7 +179,7 @@ const logError$1 = createLogError('node-evm');
|
|
|
178
179
|
});
|
|
179
180
|
return serializeTransaction(signedTx);
|
|
180
181
|
} catch (error) {
|
|
181
|
-
logError$
|
|
182
|
+
logError$2({
|
|
182
183
|
message: 'Error in delegatedSignTransaction',
|
|
183
184
|
error: error,
|
|
184
185
|
context: {
|
|
@@ -211,7 +212,7 @@ const logError$1 = createLogError('node-evm');
|
|
|
211
212
|
});
|
|
212
213
|
return serializeECDSASignature(signatureEcdsa);
|
|
213
214
|
} catch (error) {
|
|
214
|
-
logError$
|
|
215
|
+
logError$2({
|
|
215
216
|
message: 'Error in delegatedSignTypedData',
|
|
216
217
|
error: error,
|
|
217
218
|
context: {
|
|
@@ -246,7 +247,7 @@ const logError$1 = createLogError('node-evm');
|
|
|
246
247
|
const serializedSignature = serializeECDSASignature(signatureEcdsa);
|
|
247
248
|
return parseSignature(serializedSignature);
|
|
248
249
|
} catch (error) {
|
|
249
|
-
logError$
|
|
250
|
+
logError$2({
|
|
250
251
|
message: 'Error in delegatedSignAuthorization',
|
|
251
252
|
error: error,
|
|
252
253
|
context: {
|
|
@@ -279,7 +280,7 @@ const logError$1 = createLogError('node-evm');
|
|
|
279
280
|
});
|
|
280
281
|
return serializeECDSASignature(signatureEcdsa);
|
|
281
282
|
} catch (error) {
|
|
282
|
-
logError$
|
|
283
|
+
logError$2({
|
|
283
284
|
message: 'Error in delegatedSignRawMessage',
|
|
284
285
|
error: error,
|
|
285
286
|
context: {
|
|
@@ -395,6 +396,306 @@ const createAccountAdapter = ({ evmClient, walletMetadata, password, externalSer
|
|
|
395
396
|
});
|
|
396
397
|
};
|
|
397
398
|
|
|
399
|
+
/** The Fireblocks Universal Gasless Delegate (UGD) contract address used for EIP-7702 delegation. */ const DELEGATION_CONTRACT_ADDRESS = '0x0000Fb7702036ff9f76044a501ac1aA74cbab16b';
|
|
400
|
+
/** Default sponsored transaction validity duration in seconds (10 minutes). */ const DEFAULT_VALID_FOR_SECONDS = 600;
|
|
401
|
+
/** EIP-7702 delegation code prefix used to identify delegated accounts. */ const DELEGATION_CODE_PREFIX = '0xef0100';
|
|
402
|
+
/** ERC-7579 batch call with opData and auth mode identifier. */ const BATCH_CALL_OPDATA_AUTH_MODE = '0x0100000000007821000100000000000000000000000000000000000000000000';
|
|
403
|
+
/** EIP-712 typed data types for UGD AuthorizedExecutions signing. */ const AUTHORIZED_EXECUTIONS_TYPES = {
|
|
404
|
+
AuthorizedExecutions: [
|
|
405
|
+
{
|
|
406
|
+
name: 'calls',
|
|
407
|
+
type: 'Execution[]'
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
name: 'deadline',
|
|
411
|
+
type: 'uint256'
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
name: 'mode',
|
|
415
|
+
type: 'bytes32'
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
name: 'nonce',
|
|
419
|
+
type: 'uint256'
|
|
420
|
+
},
|
|
421
|
+
{
|
|
422
|
+
name: 'relayer',
|
|
423
|
+
type: 'address'
|
|
424
|
+
}
|
|
425
|
+
],
|
|
426
|
+
Execution: [
|
|
427
|
+
{
|
|
428
|
+
name: 'target',
|
|
429
|
+
type: 'address'
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
name: 'value',
|
|
433
|
+
type: 'uint256'
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
name: 'data',
|
|
437
|
+
type: 'bytes'
|
|
438
|
+
}
|
|
439
|
+
]
|
|
440
|
+
};
|
|
441
|
+
/** Minimal ABI for the UGD contract's nonce validation function. */ const UGD_ABI = [
|
|
442
|
+
{
|
|
443
|
+
inputs: [
|
|
444
|
+
{
|
|
445
|
+
name: 'nonce',
|
|
446
|
+
type: 'uint256'
|
|
447
|
+
}
|
|
448
|
+
],
|
|
449
|
+
name: 'isNonceUsed',
|
|
450
|
+
outputs: [
|
|
451
|
+
{
|
|
452
|
+
name: '',
|
|
453
|
+
type: 'bool'
|
|
454
|
+
}
|
|
455
|
+
],
|
|
456
|
+
stateMutability: 'view',
|
|
457
|
+
type: 'function'
|
|
458
|
+
}
|
|
459
|
+
];
|
|
460
|
+
/** Default polling interval for sponsored transaction status checks (milliseconds). */ const EVM_GASLESS_DEFAULT_POLL_INTERVAL_MS = 2000;
|
|
461
|
+
/** Default timeout for sponsored transaction polling (milliseconds). */ const EVM_GASLESS_DEFAULT_TIMEOUT_MS = 60000;
|
|
462
|
+
// Error messages
|
|
463
|
+
const ERROR_GASLESS_RPC_REQUIRED_FOR_AUTO_DELEGATE = 'rpcUrl is required when autoDelegate is true and no explicit authorization is provided. ' + 'Pass rpcUrl, pass an explicit authorization, or set autoDelegate: false.';
|
|
464
|
+
const ERROR_GASLESS_RELAY_FAILED = 'EVM sponsored transaction relay failed';
|
|
465
|
+
const ERROR_GASLESS_TIMEOUT = 'EVM sponsored transaction timed out waiting for terminal status';
|
|
466
|
+
const ERROR_GASLESS_MISSING_REQUEST_ID = 'Relay response did not include a requestId';
|
|
467
|
+
const ERROR_GASLESS_MISSING_YPARITY = 'Signed authorization is missing yParity';
|
|
468
|
+
const ERROR_GASLESS_RPC_REQUIRED = 'rpcUrl is required for this operation';
|
|
469
|
+
|
|
470
|
+
const logError$1 = createLogError('node-evm');
|
|
471
|
+
/**
|
|
472
|
+
* Builds a stateless gasless client for EVM sponsored transactions (Fireblocks-relayer
|
|
473
|
+
* native gasless via EIP-7702 / AuthorizedExecutions). It holds no wallet state — the
|
|
474
|
+
* signing primitives and API client are injected by the owning `DynamicEvmWalletClient`.
|
|
475
|
+
*/ const createEvmGaslessClient = ({ apiClient, createViemPublicClient, signAuthorization, signTypedData })=>{
|
|
476
|
+
const viemPublicClientForChain = (chainId, rpcUrl)=>{
|
|
477
|
+
if (!rpcUrl) {
|
|
478
|
+
throw new Error(ERROR_GASLESS_RPC_REQUIRED);
|
|
479
|
+
}
|
|
480
|
+
const chain = defineChain({
|
|
481
|
+
id: chainId,
|
|
482
|
+
name: `Chain ${chainId}`,
|
|
483
|
+
nativeCurrency: {
|
|
484
|
+
name: 'Ether',
|
|
485
|
+
symbol: 'ETH',
|
|
486
|
+
decimals: 18
|
|
487
|
+
},
|
|
488
|
+
rpcUrls: {
|
|
489
|
+
default: {
|
|
490
|
+
http: [
|
|
491
|
+
rpcUrl
|
|
492
|
+
]
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
return createViemPublicClient({
|
|
497
|
+
chain,
|
|
498
|
+
rpcUrl
|
|
499
|
+
});
|
|
500
|
+
};
|
|
501
|
+
const generateRandomNonce = ()=>BigInt('0x' + randomBytes(32).toString('hex'));
|
|
502
|
+
const generateIntentNonce = async ({ walletAddress, chainId, rpcUrl })=>{
|
|
503
|
+
let nonce = generateRandomNonce();
|
|
504
|
+
if (rpcUrl) {
|
|
505
|
+
try {
|
|
506
|
+
const publicClient = viemPublicClientForChain(chainId, rpcUrl);
|
|
507
|
+
// On a brand-new (undelegated) wallet the address has no UGD code yet,
|
|
508
|
+
// so isNonceUsed reverts — the random value is safe regardless.
|
|
509
|
+
const isUsed = await publicClient.readContract({
|
|
510
|
+
address: walletAddress,
|
|
511
|
+
abi: UGD_ABI,
|
|
512
|
+
functionName: 'isNonceUsed',
|
|
513
|
+
args: [
|
|
514
|
+
nonce
|
|
515
|
+
]
|
|
516
|
+
});
|
|
517
|
+
if (isUsed) {
|
|
518
|
+
nonce = generateRandomNonce();
|
|
519
|
+
}
|
|
520
|
+
} catch (e) {
|
|
521
|
+
// RPC failure is tolerable — 256-bit random collision is negligible
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
return nonce;
|
|
525
|
+
};
|
|
526
|
+
const is7702DelegationActive = async ({ walletAddress, chainId, rpcUrl })=>{
|
|
527
|
+
const publicClient = viemPublicClientForChain(chainId, rpcUrl);
|
|
528
|
+
const code = await publicClient.getCode({
|
|
529
|
+
address: walletAddress
|
|
530
|
+
});
|
|
531
|
+
if (!code) return false;
|
|
532
|
+
const expectedPrefix = DELEGATION_CODE_PREFIX + DELEGATION_CONTRACT_ADDRESS.slice(2).toLowerCase();
|
|
533
|
+
return code.toLowerCase().startsWith(expectedPrefix);
|
|
534
|
+
};
|
|
535
|
+
const sign7702Authorization = async ({ walletMetadata, chainId, rpcUrl, nonce, password, externalServerKeyShares })=>{
|
|
536
|
+
const address = walletMetadata.accountAddress;
|
|
537
|
+
try {
|
|
538
|
+
let eoaNonce;
|
|
539
|
+
if (nonce === undefined) {
|
|
540
|
+
if (!rpcUrl) {
|
|
541
|
+
throw new Error(ERROR_GASLESS_RPC_REQUIRED);
|
|
542
|
+
}
|
|
543
|
+
const publicClient = viemPublicClientForChain(chainId, rpcUrl);
|
|
544
|
+
eoaNonce = Number(await publicClient.getTransactionCount({
|
|
545
|
+
address
|
|
546
|
+
}));
|
|
547
|
+
} else {
|
|
548
|
+
eoaNonce = nonce;
|
|
549
|
+
}
|
|
550
|
+
const authorization = {
|
|
551
|
+
address: DELEGATION_CONTRACT_ADDRESS,
|
|
552
|
+
chainId,
|
|
553
|
+
nonce: eoaNonce
|
|
554
|
+
};
|
|
555
|
+
const sig = await signAuthorization({
|
|
556
|
+
authorization,
|
|
557
|
+
walletMetadata,
|
|
558
|
+
password,
|
|
559
|
+
externalServerKeyShares
|
|
560
|
+
});
|
|
561
|
+
if (sig.yParity === undefined) {
|
|
562
|
+
throw new Error(ERROR_GASLESS_MISSING_YPARITY);
|
|
563
|
+
}
|
|
564
|
+
return {
|
|
565
|
+
address: DELEGATION_CONTRACT_ADDRESS,
|
|
566
|
+
chainId,
|
|
567
|
+
nonce: eoaNonce,
|
|
568
|
+
r: sig.r,
|
|
569
|
+
s: sig.s,
|
|
570
|
+
yParity: sig.yParity
|
|
571
|
+
};
|
|
572
|
+
} catch (error) {
|
|
573
|
+
logError$1({
|
|
574
|
+
message: 'Error signing 7702 authorization',
|
|
575
|
+
error: error,
|
|
576
|
+
context: {
|
|
577
|
+
accountAddress: address,
|
|
578
|
+
chainId
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
throw error;
|
|
582
|
+
}
|
|
583
|
+
};
|
|
584
|
+
const getAvailableEvmGaslessRelayer = async ({ chainId, traceContext })=>{
|
|
585
|
+
const result = await apiClient.getAvailableEVMGaslessRelayer({
|
|
586
|
+
chainId,
|
|
587
|
+
traceContext
|
|
588
|
+
});
|
|
589
|
+
return {
|
|
590
|
+
relayerAddress: result.relayerAddress
|
|
591
|
+
};
|
|
592
|
+
};
|
|
593
|
+
const resolveSponsoredAuthorization = async ({ authorization, autoDelegate, walletMetadata, chainId, rpcUrl, password, externalServerKeyShares })=>{
|
|
594
|
+
if (authorization) {
|
|
595
|
+
return authorization;
|
|
596
|
+
}
|
|
597
|
+
if (!autoDelegate) {
|
|
598
|
+
return undefined;
|
|
599
|
+
}
|
|
600
|
+
// The EOA nonce and delegation status are only knowable on-chain; without
|
|
601
|
+
// an RPC we can't safely auto-sign a 7702 authorization, so fail loud
|
|
602
|
+
// instead of relaying an intent that would revert.
|
|
603
|
+
if (!rpcUrl) {
|
|
604
|
+
throw new Error(ERROR_GASLESS_RPC_REQUIRED_FOR_AUTO_DELEGATE);
|
|
605
|
+
}
|
|
606
|
+
const walletAddress = walletMetadata.accountAddress;
|
|
607
|
+
const isDelegated = await is7702DelegationActive({
|
|
608
|
+
walletAddress,
|
|
609
|
+
chainId,
|
|
610
|
+
rpcUrl
|
|
611
|
+
});
|
|
612
|
+
if (isDelegated) {
|
|
613
|
+
return undefined;
|
|
614
|
+
}
|
|
615
|
+
return sign7702Authorization({
|
|
616
|
+
walletMetadata,
|
|
617
|
+
chainId,
|
|
618
|
+
rpcUrl,
|
|
619
|
+
password,
|
|
620
|
+
externalServerKeyShares
|
|
621
|
+
});
|
|
622
|
+
};
|
|
623
|
+
const signSponsoredTransaction = async ({ walletMetadata, calls, chainId, rpcUrl, authorization, autoDelegate = true, nonce: providedNonce, validForSeconds = DEFAULT_VALID_FOR_SECONDS, password, externalServerKeyShares, traceContext })=>{
|
|
624
|
+
const walletAddress = walletMetadata.accountAddress;
|
|
625
|
+
try {
|
|
626
|
+
const resolvedAuth = await resolveSponsoredAuthorization({
|
|
627
|
+
authorization,
|
|
628
|
+
autoDelegate,
|
|
629
|
+
walletMetadata,
|
|
630
|
+
chainId,
|
|
631
|
+
rpcUrl,
|
|
632
|
+
password,
|
|
633
|
+
externalServerKeyShares
|
|
634
|
+
});
|
|
635
|
+
const nonce = providedNonce != null ? providedNonce : await generateIntentNonce({
|
|
636
|
+
walletAddress,
|
|
637
|
+
chainId,
|
|
638
|
+
rpcUrl
|
|
639
|
+
});
|
|
640
|
+
const deadline = BigInt(Math.floor(Date.now() / 1000) + validForSeconds);
|
|
641
|
+
const { relayerAddress } = await getAvailableEvmGaslessRelayer({
|
|
642
|
+
chainId,
|
|
643
|
+
traceContext
|
|
644
|
+
});
|
|
645
|
+
const signature = await signTypedData({
|
|
646
|
+
walletMetadata,
|
|
647
|
+
password,
|
|
648
|
+
externalServerKeyShares,
|
|
649
|
+
typedData: {
|
|
650
|
+
domain: {
|
|
651
|
+
chainId,
|
|
652
|
+
verifyingContract: DELEGATION_CONTRACT_ADDRESS
|
|
653
|
+
},
|
|
654
|
+
message: {
|
|
655
|
+
calls: calls.map((c)=>({
|
|
656
|
+
data: c.data,
|
|
657
|
+
target: c.target,
|
|
658
|
+
value: c.value
|
|
659
|
+
})),
|
|
660
|
+
deadline,
|
|
661
|
+
mode: BATCH_CALL_OPDATA_AUTH_MODE,
|
|
662
|
+
nonce,
|
|
663
|
+
relayer: relayerAddress
|
|
664
|
+
},
|
|
665
|
+
primaryType: 'AuthorizedExecutions',
|
|
666
|
+
types: AUTHORIZED_EXECUTIONS_TYPES
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
return {
|
|
670
|
+
authorization: resolvedAuth,
|
|
671
|
+
calls,
|
|
672
|
+
chainId,
|
|
673
|
+
deadline: deadline.toString(),
|
|
674
|
+
nonce: nonce.toString(),
|
|
675
|
+
relayer: relayerAddress,
|
|
676
|
+
signature,
|
|
677
|
+
walletAddress
|
|
678
|
+
};
|
|
679
|
+
} catch (error) {
|
|
680
|
+
logError$1({
|
|
681
|
+
message: 'Error signing sponsored transaction',
|
|
682
|
+
error: error,
|
|
683
|
+
context: {
|
|
684
|
+
accountAddress: walletAddress,
|
|
685
|
+
chainId
|
|
686
|
+
}
|
|
687
|
+
});
|
|
688
|
+
throw error;
|
|
689
|
+
}
|
|
690
|
+
};
|
|
691
|
+
return {
|
|
692
|
+
getAvailableEvmGaslessRelayer,
|
|
693
|
+
is7702DelegationActive,
|
|
694
|
+
sign7702Authorization,
|
|
695
|
+
signSponsoredTransaction
|
|
696
|
+
};
|
|
697
|
+
};
|
|
698
|
+
|
|
398
699
|
const logError = createLogError('node-evm');
|
|
399
700
|
class DynamicEvmWalletClient extends DynamicWalletClient {
|
|
400
701
|
get jwtAuthToken() {
|
|
@@ -827,6 +1128,40 @@ class DynamicEvmWalletClient extends DynamicWalletClient {
|
|
|
827
1128
|
const evmWallets = wallets.filter((wallet)=>wallet.chainName === 'EVM');
|
|
828
1129
|
return evmWallets;
|
|
829
1130
|
}
|
|
1131
|
+
// ---------------------------------------------------------------------------
|
|
1132
|
+
// EVM gasless (Fireblocks-relayer native gasless via EIP-7702 / AuthorizedExecutions)
|
|
1133
|
+
// ---------------------------------------------------------------------------
|
|
1134
|
+
get evmGasless() {
|
|
1135
|
+
return createEvmGaslessClient({
|
|
1136
|
+
apiClient: this.apiClient,
|
|
1137
|
+
createViemPublicClient: (args)=>this.createViemPublicClient(args),
|
|
1138
|
+
signAuthorization: (args)=>this.signAuthorization(args),
|
|
1139
|
+
signTypedData: (args)=>this.signTypedData(args)
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1142
|
+
/**
|
|
1143
|
+
* Checks whether the given wallet address has an active EIP-7702 delegation
|
|
1144
|
+
* to the Universal Gasless Delegate (UGD) contract.
|
|
1145
|
+
*/ async is7702DelegationActive(params) {
|
|
1146
|
+
return this.evmGasless.is7702DelegationActive(params);
|
|
1147
|
+
}
|
|
1148
|
+
/**
|
|
1149
|
+
* Signs an EIP-7702 authorization that delegates the EOA to the UGD contract.
|
|
1150
|
+
* The EOA nonce is fetched from the chain unless explicitly provided.
|
|
1151
|
+
*/ async sign7702Authorization(params) {
|
|
1152
|
+
return this.evmGasless.sign7702Authorization(params);
|
|
1153
|
+
}
|
|
1154
|
+
/**
|
|
1155
|
+
* Fetches the available gasless relayer address for a given chain.
|
|
1156
|
+
*/ async getAvailableEvmGaslessRelayer(params) {
|
|
1157
|
+
return this.evmGasless.getAvailableEvmGaslessRelayer(params);
|
|
1158
|
+
}
|
|
1159
|
+
/**
|
|
1160
|
+
* Signs a sponsored transaction intent: resolves 7702 authorization, generates
|
|
1161
|
+
* a bitmap nonce, fetches the relayer, and MPC-signs the EIP-712 typed data.
|
|
1162
|
+
*/ async signSponsoredTransaction(params) {
|
|
1163
|
+
return this.evmGasless.signSponsoredTransaction(params);
|
|
1164
|
+
}
|
|
830
1165
|
constructor({ environmentId, baseApiUrl, baseMPCRelayApiUrl, debug, enableMPCAccelerator, logger }){
|
|
831
1166
|
super({
|
|
832
1167
|
environmentId,
|
|
@@ -1022,4 +1357,4 @@ const createZerodevClient = async (evmClient)=>{
|
|
|
1022
1357
|
return client;
|
|
1023
1358
|
};
|
|
1024
1359
|
|
|
1025
|
-
export { DynamicEvmWalletClient, ERROR_ACCOUNT_ADDRESS_REQUIRED, ERROR_CREATE_WALLET_ACCOUNT, ERROR_KEYGEN_FAILED, ERROR_SIGN_MESSAGE, ERROR_SIGN_RAW_MESSAGE, ERROR_SIGN_TYPED_DATA, ERROR_VERIFY_MESSAGE_SIGNATURE, EVM_SIGN_MESSAGE_PREFIX, createAccountAdapter, createDelegatedEvmWalletClient, createZerodevClient, delegatedSignAuthorization, delegatedSignMessage, delegatedSignRawMessage, delegatedSignTransaction, delegatedSignTypedData, deriveAccountAddress, formatEVMMessage, formatTypedData, revokeDelegation, serializeECDSASignature };
|
|
1360
|
+
export { AUTHORIZED_EXECUTIONS_TYPES, BATCH_CALL_OPDATA_AUTH_MODE, DEFAULT_VALID_FOR_SECONDS, DELEGATION_CODE_PREFIX, DELEGATION_CONTRACT_ADDRESS, DynamicEvmWalletClient, ERROR_ACCOUNT_ADDRESS_REQUIRED, ERROR_CREATE_WALLET_ACCOUNT, ERROR_GASLESS_MISSING_REQUEST_ID, ERROR_GASLESS_MISSING_YPARITY, ERROR_GASLESS_RELAY_FAILED, ERROR_GASLESS_RPC_REQUIRED, ERROR_GASLESS_RPC_REQUIRED_FOR_AUTO_DELEGATE, ERROR_GASLESS_TIMEOUT, ERROR_KEYGEN_FAILED, ERROR_SIGN_MESSAGE, ERROR_SIGN_RAW_MESSAGE, ERROR_SIGN_TYPED_DATA, ERROR_VERIFY_MESSAGE_SIGNATURE, EVM_GASLESS_DEFAULT_POLL_INTERVAL_MS, EVM_GASLESS_DEFAULT_TIMEOUT_MS, EVM_SIGN_MESSAGE_PREFIX, UGD_ABI, createAccountAdapter, createDelegatedEvmWalletClient, createZerodevClient, delegatedSignAuthorization, delegatedSignMessage, delegatedSignRawMessage, delegatedSignTransaction, delegatedSignTypedData, deriveAccountAddress, formatEVMMessage, formatTypedData, revokeDelegation, serializeECDSASignature };
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs-wallet/node-evm",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.51",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@dynamic-labs-wallet/node": "1.0.
|
|
7
|
+
"@dynamic-labs-wallet/node": "1.0.51",
|
|
8
8
|
"@dynamic-labs/sdk-api-core": "^0.0.984",
|
|
9
9
|
"@dynamic-labs-sdk/client": "0.3.0",
|
|
10
10
|
"@dynamic-labs-sdk/zerodev": "0.3.0",
|
|
11
11
|
"@dynamic-labs-sdk/evm": "0.3.0",
|
|
12
12
|
"@zerodev/ecdsa-validator": "5.4.9",
|
|
13
13
|
"@zerodev/sdk": "5.4.36",
|
|
14
|
-
"@dynamic-labs-wallet/core": "1.0.
|
|
14
|
+
"@dynamic-labs-wallet/core": "1.0.51"
|
|
15
15
|
},
|
|
16
16
|
"publishConfig": {
|
|
17
17
|
"access": "public"
|
package/src/client/client.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DynamicWalletClient, type DynamicWalletClientProps, type EcdsaKeygenResult, type EcdsaPublicKey, type Ed25519KeygenResult, type ServerKeyShare, type ThresholdSignatureScheme, type WalletMetadata } from '@dynamic-labs-wallet/node';
|
|
2
2
|
import type { SignMessageContext } from '@dynamic-labs/sdk-api-core';
|
|
3
|
-
import { type Account, type Chain, type PublicClient, type SignableMessage, type TransactionSerializable, type Transport, type TypedData, type WalletClient } from 'viem';
|
|
3
|
+
import { type Account, type Chain, type Hex, type PublicClient, type SignableMessage, type TransactionSerializable, type Transport, type TypedData, type WalletClient } from 'viem';
|
|
4
|
+
import type { GetAvailableEvmGaslessRelayerParams, Is7702DelegationActiveParams, SerializedAuthorization, Sign7702AuthorizationParams, SignedSponsoredTransaction, SignSponsoredTransactionParams } from './gasless.types.js';
|
|
4
5
|
export declare class DynamicEvmWalletClient extends DynamicWalletClient {
|
|
5
6
|
readonly chainName = "EVM";
|
|
6
7
|
constructor({ environmentId, baseApiUrl, baseMPCRelayApiUrl, debug, enableMPCAccelerator, logger, }: DynamicWalletClientProps);
|
|
@@ -143,5 +144,27 @@ export declare class DynamicEvmWalletClient extends DynamicWalletClient {
|
|
|
143
144
|
derivationPath: string | undefined;
|
|
144
145
|
thresholdSignatureScheme: ThresholdSignatureScheme;
|
|
145
146
|
}[]>;
|
|
147
|
+
private get evmGasless();
|
|
148
|
+
/**
|
|
149
|
+
* Checks whether the given wallet address has an active EIP-7702 delegation
|
|
150
|
+
* to the Universal Gasless Delegate (UGD) contract.
|
|
151
|
+
*/
|
|
152
|
+
is7702DelegationActive(params: Is7702DelegationActiveParams): Promise<boolean>;
|
|
153
|
+
/**
|
|
154
|
+
* Signs an EIP-7702 authorization that delegates the EOA to the UGD contract.
|
|
155
|
+
* The EOA nonce is fetched from the chain unless explicitly provided.
|
|
156
|
+
*/
|
|
157
|
+
sign7702Authorization(params: Sign7702AuthorizationParams): Promise<SerializedAuthorization>;
|
|
158
|
+
/**
|
|
159
|
+
* Fetches the available gasless relayer address for a given chain.
|
|
160
|
+
*/
|
|
161
|
+
getAvailableEvmGaslessRelayer(params: GetAvailableEvmGaslessRelayerParams): Promise<{
|
|
162
|
+
relayerAddress: Hex;
|
|
163
|
+
}>;
|
|
164
|
+
/**
|
|
165
|
+
* Signs a sponsored transaction intent: resolves 7702 authorization, generates
|
|
166
|
+
* a bitmap nonce, fetches the relayer, and MPC-signs the EIP-712 typed data.
|
|
167
|
+
*/
|
|
168
|
+
signSponsoredTransaction(params: SignSponsoredTransactionParams): Promise<SignedSponsoredTransaction>;
|
|
146
169
|
}
|
|
147
170
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,KAAK,iBAAiB,EACtB,KAAK,cAAc,EAEnB,KAAK,mBAAmB,EAExB,KAAK,cAAc,EAEnB,KAAK,wBAAwB,EAC7B,KAAK,cAAc,EAEpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,KAAK,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DynamicApiClient } from '@dynamic-labs-wallet/core';
|
|
2
|
+
import { type Hex } from 'viem';
|
|
3
|
+
import type { DynamicEvmWalletClient } from './client.js';
|
|
4
|
+
import type { GetAvailableEvmGaslessRelayerParams, Is7702DelegationActiveParams, SerializedAuthorization, Sign7702AuthorizationParams, SignedSponsoredTransaction, SignSponsoredTransactionParams } from './gasless.types.js';
|
|
5
|
+
/** Primitives the gasless client borrows from the EVM wallet client it belongs to. */
|
|
6
|
+
export type EvmGaslessClientDeps = {
|
|
7
|
+
apiClient: DynamicApiClient;
|
|
8
|
+
createViemPublicClient: DynamicEvmWalletClient['createViemPublicClient'];
|
|
9
|
+
signAuthorization: DynamicEvmWalletClient['signAuthorization'];
|
|
10
|
+
signTypedData: DynamicEvmWalletClient['signTypedData'];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Builds a stateless gasless client for EVM sponsored transactions (Fireblocks-relayer
|
|
14
|
+
* native gasless via EIP-7702 / AuthorizedExecutions). It holds no wallet state — the
|
|
15
|
+
* signing primitives and API client are injected by the owning `DynamicEvmWalletClient`.
|
|
16
|
+
*/
|
|
17
|
+
export declare const createEvmGaslessClient: ({ apiClient, createViemPublicClient, signAuthorization, signTypedData, }: EvmGaslessClientDeps) => {
|
|
18
|
+
getAvailableEvmGaslessRelayer: ({ chainId, traceContext, }: GetAvailableEvmGaslessRelayerParams) => Promise<{
|
|
19
|
+
relayerAddress: Hex;
|
|
20
|
+
}>;
|
|
21
|
+
is7702DelegationActive: ({ walletAddress, chainId, rpcUrl, }: Is7702DelegationActiveParams) => Promise<boolean>;
|
|
22
|
+
sign7702Authorization: ({ walletMetadata, chainId, rpcUrl, nonce, password, externalServerKeyShares, }: Sign7702AuthorizationParams) => Promise<SerializedAuthorization>;
|
|
23
|
+
signSponsoredTransaction: ({ walletMetadata, calls, chainId, rpcUrl, authorization, autoDelegate, nonce: providedNonce, validForSeconds, password, externalServerKeyShares, traceContext, }: SignSponsoredTransactionParams) => Promise<SignedSponsoredTransaction>;
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=gasless.client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gasless.client.d.ts","sourceRoot":"","sources":["../../src/client/gasless.client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAe,KAAK,GAAG,EAAqC,MAAM,MAAM,CAAC;AAChF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAY1D,OAAO,KAAK,EACV,mCAAmC,EACnC,4BAA4B,EAC5B,uBAAuB,EACvB,2BAA2B,EAC3B,0BAA0B,EAC1B,8BAA8B,EAC/B,MAAM,oBAAoB,CAAC;AAI5B,sFAAsF;AACtF,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,gBAAgB,CAAC;IAC5B,sBAAsB,EAAE,sBAAsB,CAAC,wBAAwB,CAAC,CAAC;IACzE,iBAAiB,EAAE,sBAAsB,CAAC,mBAAmB,CAAC,CAAC;IAC/D,aAAa,EAAE,sBAAsB,CAAC,eAAe,CAAC,CAAC;CACxD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,6EAKhC,oBAAoB;gEAgIlB,mCAAmC,KAAG,OAAO,CAAC;QAAE,cAAc,EAAE,GAAG,CAAA;KAAE,CAAC;kEAxEtE,4BAA4B,KAAG,OAAO,CAAC,OAAO,CAAC;4GAkB/C,2BAA2B,KAAG,OAAO,CAAC,uBAAuB,CAAC;iMA+H9D,8BAA8B,KAAG,OAAO,CAAC,0BAA0B,CAAC;CAmExE,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { Hex } from 'viem';
|
|
2
|
+
/** The Fireblocks Universal Gasless Delegate (UGD) contract address used for EIP-7702 delegation. */
|
|
3
|
+
export declare const DELEGATION_CONTRACT_ADDRESS: Hex;
|
|
4
|
+
/** Default sponsored transaction validity duration in seconds (10 minutes). */
|
|
5
|
+
export declare const DEFAULT_VALID_FOR_SECONDS = 600;
|
|
6
|
+
/** EIP-7702 delegation code prefix used to identify delegated accounts. */
|
|
7
|
+
export declare const DELEGATION_CODE_PREFIX = "0xef0100";
|
|
8
|
+
/** ERC-7579 batch call with opData and auth mode identifier. */
|
|
9
|
+
export declare const BATCH_CALL_OPDATA_AUTH_MODE: Hex;
|
|
10
|
+
/** EIP-712 typed data types for UGD AuthorizedExecutions signing. */
|
|
11
|
+
export declare const AUTHORIZED_EXECUTIONS_TYPES: {
|
|
12
|
+
readonly AuthorizedExecutions: readonly [{
|
|
13
|
+
readonly name: "calls";
|
|
14
|
+
readonly type: "Execution[]";
|
|
15
|
+
}, {
|
|
16
|
+
readonly name: "deadline";
|
|
17
|
+
readonly type: "uint256";
|
|
18
|
+
}, {
|
|
19
|
+
readonly name: "mode";
|
|
20
|
+
readonly type: "bytes32";
|
|
21
|
+
}, {
|
|
22
|
+
readonly name: "nonce";
|
|
23
|
+
readonly type: "uint256";
|
|
24
|
+
}, {
|
|
25
|
+
readonly name: "relayer";
|
|
26
|
+
readonly type: "address";
|
|
27
|
+
}];
|
|
28
|
+
readonly Execution: readonly [{
|
|
29
|
+
readonly name: "target";
|
|
30
|
+
readonly type: "address";
|
|
31
|
+
}, {
|
|
32
|
+
readonly name: "value";
|
|
33
|
+
readonly type: "uint256";
|
|
34
|
+
}, {
|
|
35
|
+
readonly name: "data";
|
|
36
|
+
readonly type: "bytes";
|
|
37
|
+
}];
|
|
38
|
+
};
|
|
39
|
+
/** Minimal ABI for the UGD contract's nonce validation function. */
|
|
40
|
+
export declare const UGD_ABI: readonly [{
|
|
41
|
+
readonly inputs: readonly [{
|
|
42
|
+
readonly name: "nonce";
|
|
43
|
+
readonly type: "uint256";
|
|
44
|
+
}];
|
|
45
|
+
readonly name: "isNonceUsed";
|
|
46
|
+
readonly outputs: readonly [{
|
|
47
|
+
readonly name: "";
|
|
48
|
+
readonly type: "bool";
|
|
49
|
+
}];
|
|
50
|
+
readonly stateMutability: "view";
|
|
51
|
+
readonly type: "function";
|
|
52
|
+
}];
|
|
53
|
+
/** Default polling interval for sponsored transaction status checks (milliseconds). */
|
|
54
|
+
export declare const EVM_GASLESS_DEFAULT_POLL_INTERVAL_MS = 2000;
|
|
55
|
+
/** Default timeout for sponsored transaction polling (milliseconds). */
|
|
56
|
+
export declare const EVM_GASLESS_DEFAULT_TIMEOUT_MS = 60000;
|
|
57
|
+
export declare const ERROR_GASLESS_RPC_REQUIRED_FOR_AUTO_DELEGATE: string;
|
|
58
|
+
export declare const ERROR_GASLESS_RELAY_FAILED = "EVM sponsored transaction relay failed";
|
|
59
|
+
export declare const ERROR_GASLESS_TIMEOUT = "EVM sponsored transaction timed out waiting for terminal status";
|
|
60
|
+
export declare const ERROR_GASLESS_MISSING_REQUEST_ID = "Relay response did not include a requestId";
|
|
61
|
+
export declare const ERROR_GASLESS_MISSING_YPARITY = "Signed authorization is missing yParity";
|
|
62
|
+
export declare const ERROR_GASLESS_RPC_REQUIRED = "rpcUrl is required for this operation";
|
|
63
|
+
//# sourceMappingURL=gasless.constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gasless.constants.d.ts","sourceRoot":"","sources":["../../src/client/gasless.constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEhC,qGAAqG;AACrG,eAAO,MAAM,2BAA2B,EAAE,GAAkD,CAAC;AAE7F,+EAA+E;AAC/E,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C,2EAA2E;AAC3E,eAAO,MAAM,sBAAsB,aAAa,CAAC;AAEjD,gEAAgE;AAChE,eAAO,MAAM,2BAA2B,EAAE,GAA0E,CAAC;AAErH,qEAAqE;AACrE,eAAO,MAAM,2BAA2B;;;;;;;;;;;;;;;;;;;;;;;;;;;CAa9B,CAAC;AAEX,oEAAoE;AACpE,eAAO,MAAM,OAAO;;;;;;;;;;;;EAQV,CAAC;AAEX,uFAAuF;AACvF,eAAO,MAAM,oCAAoC,OAAO,CAAC;AAEzD,wEAAwE;AACxE,eAAO,MAAM,8BAA8B,QAAQ,CAAC;AAGpD,eAAO,MAAM,4CAA4C,QAEmB,CAAC;AAE7E,eAAO,MAAM,0BAA0B,2CAA2C,CAAC;AAEnF,eAAO,MAAM,qBAAqB,oEAAoE,CAAC;AAEvG,eAAO,MAAM,gCAAgC,+CAA+C,CAAC;AAE7F,eAAO,MAAM,6BAA6B,4CAA4C,CAAC;AAEvF,eAAO,MAAM,0BAA0B,0CAA0C,CAAC"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { ServerKeyShare, TraceContext, WalletMetadata } from '@dynamic-labs-wallet/node';
|
|
2
|
+
import type { Hex } from 'viem';
|
|
3
|
+
/** A single call within a sponsored transaction batch. */
|
|
4
|
+
export type SponsoredTransactionCall = {
|
|
5
|
+
/** Hex-encoded calldata to execute on the target. */
|
|
6
|
+
data: Hex;
|
|
7
|
+
/** Target contract address. */
|
|
8
|
+
target: Hex;
|
|
9
|
+
/** Amount of native token (in wei) to send with the call. */
|
|
10
|
+
value: bigint;
|
|
11
|
+
};
|
|
12
|
+
/** Serialized EIP-7702 authorization for JSON transport. */
|
|
13
|
+
export type SerializedAuthorization = {
|
|
14
|
+
/** Contract address to delegate to. */
|
|
15
|
+
address: Hex;
|
|
16
|
+
/** Chain ID the authorization is valid for. */
|
|
17
|
+
chainId: number;
|
|
18
|
+
/** EOA transaction nonce at signing time. */
|
|
19
|
+
nonce: number;
|
|
20
|
+
/** ECDSA signature r component. */
|
|
21
|
+
r: Hex;
|
|
22
|
+
/** ECDSA signature s component. */
|
|
23
|
+
s: Hex;
|
|
24
|
+
/** ECDSA signature y-parity. */
|
|
25
|
+
yParity: number;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Lifecycle status of a sponsored transaction relay request.
|
|
29
|
+
*
|
|
30
|
+
* - `pending`: accepted by the relayer, not yet broadcast to the chain.
|
|
31
|
+
* - `submitted`: broadcasted to the chain, waiting for confirmation.
|
|
32
|
+
* - `success`: finalized successfully on-chain.
|
|
33
|
+
* - `failure`: terminal failure.
|
|
34
|
+
*/
|
|
35
|
+
export type SponsoredTransactionStatus = 'failure' | 'pending' | 'submitted' | 'success';
|
|
36
|
+
/** Result of a `getEVMSponsoredTransactionStatus` lookup. */
|
|
37
|
+
export type SponsoredTransactionStatusResult = {
|
|
38
|
+
/** Error message when the status is a terminal failure. */
|
|
39
|
+
errorMessage?: string;
|
|
40
|
+
/** Current relay state for the request. */
|
|
41
|
+
status: SponsoredTransactionStatus;
|
|
42
|
+
/** On-chain transaction hash once the relay has broadcast / confirmed it. */
|
|
43
|
+
transactionHash?: Hex;
|
|
44
|
+
};
|
|
45
|
+
/** The signed payload ready to be sent to the sponsorship API. */
|
|
46
|
+
export type SignedSponsoredTransaction = {
|
|
47
|
+
/** EIP-7702 authorization for delegation, if needed. */
|
|
48
|
+
authorization?: SerializedAuthorization;
|
|
49
|
+
/** The batch of calls to execute. */
|
|
50
|
+
calls: SponsoredTransactionCall[];
|
|
51
|
+
/** Target chain ID. */
|
|
52
|
+
chainId: number;
|
|
53
|
+
/** Intent expiration as a unix timestamp string. */
|
|
54
|
+
deadline: string;
|
|
55
|
+
/** Bitmap nonce as a string (uint256). */
|
|
56
|
+
nonce: string;
|
|
57
|
+
/** The relayer address signed in the EIP-712 intent. */
|
|
58
|
+
relayer: Hex;
|
|
59
|
+
/** EIP-712 signature over the AuthorizedExecutions typed data. */
|
|
60
|
+
signature: Hex;
|
|
61
|
+
/** The user's wallet address. */
|
|
62
|
+
walletAddress: Hex;
|
|
63
|
+
};
|
|
64
|
+
/** Parameters for `is7702DelegationActive`. */
|
|
65
|
+
export type Is7702DelegationActiveParams = {
|
|
66
|
+
/** Target chain ID. */
|
|
67
|
+
chainId: number;
|
|
68
|
+
/** RPC URL used to read the wallet's on-chain code. */
|
|
69
|
+
rpcUrl: string;
|
|
70
|
+
/** The wallet address to check delegation for. */
|
|
71
|
+
walletAddress: Hex;
|
|
72
|
+
};
|
|
73
|
+
/** Parameters for `sign7702Authorization`. */
|
|
74
|
+
export type Sign7702AuthorizationParams = {
|
|
75
|
+
/** Target chain ID. */
|
|
76
|
+
chainId: number;
|
|
77
|
+
/** Optional externally supplied server key shares. */
|
|
78
|
+
externalServerKeyShares?: ServerKeyShare[];
|
|
79
|
+
/** EOA nonce; fetched from the chain via `rpcUrl` when omitted. */
|
|
80
|
+
nonce?: number;
|
|
81
|
+
/** Optional password protecting the key. */
|
|
82
|
+
password?: string;
|
|
83
|
+
/** RPC URL used to fetch the EOA nonce when `nonce` is omitted. */
|
|
84
|
+
rpcUrl?: string;
|
|
85
|
+
/** Metadata for the wallet signing the authorization. */
|
|
86
|
+
walletMetadata: WalletMetadata;
|
|
87
|
+
};
|
|
88
|
+
/** Parameters for `getAvailableEvmGaslessRelayer`. */
|
|
89
|
+
export type GetAvailableEvmGaslessRelayerParams = {
|
|
90
|
+
/** Target chain ID. */
|
|
91
|
+
chainId: number;
|
|
92
|
+
/** Optional trace context for request correlation. */
|
|
93
|
+
traceContext?: TraceContext;
|
|
94
|
+
};
|
|
95
|
+
/** Parameters for `signSponsoredTransaction`. */
|
|
96
|
+
export type SignSponsoredTransactionParams = {
|
|
97
|
+
/** Pre-signed EIP-7702 authorization; resolved automatically when omitted. */
|
|
98
|
+
authorization?: SerializedAuthorization;
|
|
99
|
+
/** When true, auto-sign a 7702 authorization if the wallet is not yet delegated. */
|
|
100
|
+
autoDelegate?: boolean;
|
|
101
|
+
/** The batch of calls to execute. */
|
|
102
|
+
calls: SponsoredTransactionCall[];
|
|
103
|
+
/** Target chain ID. */
|
|
104
|
+
chainId: number;
|
|
105
|
+
/** Optional externally supplied server key shares. */
|
|
106
|
+
externalServerKeyShares?: ServerKeyShare[];
|
|
107
|
+
/** Explicit bitmap nonce; a random unused one is generated when omitted. */
|
|
108
|
+
nonce?: bigint;
|
|
109
|
+
/** Optional password protecting the key. */
|
|
110
|
+
password?: string;
|
|
111
|
+
/** RPC URL used for delegation checks and nonce validation. */
|
|
112
|
+
rpcUrl?: string;
|
|
113
|
+
/** Optional trace context for request correlation. */
|
|
114
|
+
traceContext?: TraceContext;
|
|
115
|
+
/** Intent validity window in seconds. */
|
|
116
|
+
validForSeconds?: number;
|
|
117
|
+
/** Metadata for the wallet signing the transaction. */
|
|
118
|
+
walletMetadata: WalletMetadata;
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=gasless.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gasless.types.d.ts","sourceRoot":"","sources":["../../src/client/gasless.types.ts"],"names":[],"mappings":"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"}
|
package/src/client/index.d.ts
CHANGED
|
@@ -2,4 +2,6 @@ export * from './accountAdapter.js';
|
|
|
2
2
|
export * from './client.js';
|
|
3
3
|
export * from './constants.js';
|
|
4
4
|
export * from '../utils.js';
|
|
5
|
+
export type { SerializedAuthorization, SignedSponsoredTransaction, SponsoredTransactionCall, SponsoredTransactionStatus, SponsoredTransactionStatusResult, } from './gasless.types.js';
|
|
6
|
+
export { AUTHORIZED_EXECUTIONS_TYPES, BATCH_CALL_OPDATA_AUTH_MODE, DEFAULT_VALID_FOR_SECONDS, DELEGATION_CODE_PREFIX, DELEGATION_CONTRACT_ADDRESS, ERROR_GASLESS_MISSING_REQUEST_ID, ERROR_GASLESS_MISSING_YPARITY, ERROR_GASLESS_RELAY_FAILED, ERROR_GASLESS_RPC_REQUIRED, ERROR_GASLESS_RPC_REQUIRED_FOR_AUTO_DELEGATE, ERROR_GASLESS_TIMEOUT, EVM_GASLESS_DEFAULT_POLL_INTERVAL_MS, EVM_GASLESS_DEFAULT_TIMEOUT_MS, UGD_ABI, } from './gasless.constants.js';
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,YAAY,EACV,uBAAuB,EACvB,0BAA0B,EAC1B,wBAAwB,EACxB,0BAA0B,EAC1B,gCAAgC,GACjC,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,2BAA2B,EAC3B,2BAA2B,EAC3B,yBAAyB,EACzB,sBAAsB,EACtB,2BAA2B,EAC3B,gCAAgC,EAChC,6BAA6B,EAC7B,0BAA0B,EAC1B,0BAA0B,EAC1B,4CAA4C,EAC5C,qBAAqB,EACrB,oCAAoC,EACpC,8BAA8B,EAC9B,OAAO,GACR,MAAM,wBAAwB,CAAC"}
|