@dynamic-labs/ethereum-gasless-core 0.0.0 → 4.84.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 +6525 -0
- package/LICENSE +21 -0
- package/README.md +7 -0
- package/package.cjs +8 -0
- package/package.js +4 -0
- package/package.json +23 -1
- package/src/index.cjs +53 -0
- package/src/index.d.ts +20 -0
- package/src/index.js +24 -0
- package/src/lib/activate7702Delegation/activate7702Delegation.cjs +17 -0
- package/src/lib/activate7702Delegation/activate7702Delegation.d.ts +18 -0
- package/src/lib/activate7702Delegation/activate7702Delegation.js +13 -0
- package/src/lib/constants.cjs +69 -0
- package/src/lib/constants.d.ts +76 -0
- package/src/lib/constants.js +60 -0
- package/src/lib/create7702DelegationRegistry/create7702DelegationRegistry.cjs +22 -0
- package/src/lib/create7702DelegationRegistry/create7702DelegationRegistry.d.ts +7 -0
- package/src/lib/create7702DelegationRegistry/create7702DelegationRegistry.js +18 -0
- package/src/lib/errors/EthereumGasSponsorshipNotEnabledError/EthereumGasSponsorshipNotEnabledError.cjs +18 -0
- package/src/lib/errors/EthereumGasSponsorshipNotEnabledError/EthereumGasSponsorshipNotEnabledError.d.ts +8 -0
- package/src/lib/errors/EthereumGasSponsorshipNotEnabledError/EthereumGasSponsorshipNotEnabledError.js +14 -0
- package/src/lib/errors/SponsorTransactionError/SponsorTransactionError.cjs +23 -0
- package/src/lib/errors/SponsorTransactionError/SponsorTransactionError.d.ts +10 -0
- package/src/lib/errors/SponsorTransactionError/SponsorTransactionError.js +19 -0
- package/src/lib/generateIntentNonce/generateIntentNonce.cjs +39 -0
- package/src/lib/generateIntentNonce/generateIntentNonce.d.ts +20 -0
- package/src/lib/generateIntentNonce/generateIntentNonce.js +35 -0
- package/src/lib/generateRandomNonce/generateRandomNonce.cjs +22 -0
- package/src/lib/generateRandomNonce/generateRandomNonce.d.ts +11 -0
- package/src/lib/generateRandomNonce/generateRandomNonce.js +18 -0
- package/src/lib/getAvailableEvmGaslessRelayer/getAvailableEvmGaslessRelayer.cjs +35 -0
- package/src/lib/getAvailableEvmGaslessRelayer/getAvailableEvmGaslessRelayer.d.ts +21 -0
- package/src/lib/getAvailableEvmGaslessRelayer/getAvailableEvmGaslessRelayer.js +31 -0
- package/src/lib/getEVMSponsoredTransactionStatus/getEVMSponsoredTransactionStatus.cjs +35 -0
- package/src/lib/getEVMSponsoredTransactionStatus/getEVMSponsoredTransactionStatus.d.ts +15 -0
- package/src/lib/getEVMSponsoredTransactionStatus/getEVMSponsoredTransactionStatus.js +31 -0
- package/src/lib/is7702DelegationActive/is7702DelegationActive.cjs +32 -0
- package/src/lib/is7702DelegationActive/is7702DelegationActive.d.ts +21 -0
- package/src/lib/is7702DelegationActive/is7702DelegationActive.js +28 -0
- package/src/lib/isEthereumGasSponsorshipEnabled/isEthereumGasSponsorshipEnabled.cjs +14 -0
- package/src/lib/isEthereumGasSponsorshipEnabled/isEthereumGasSponsorshipEnabled.d.ts +23 -0
- package/src/lib/isEthereumGasSponsorshipEnabled/isEthereumGasSponsorshipEnabled.js +10 -0
- package/src/lib/relaySponsoredTransaction/relaySponsoredTransaction.cjs +58 -0
- package/src/lib/relaySponsoredTransaction/relaySponsoredTransaction.d.ts +29 -0
- package/src/lib/relaySponsoredTransaction/relaySponsoredTransaction.js +54 -0
- package/src/lib/resolveAuthorization/resolveAuthorization.cjs +32 -0
- package/src/lib/resolveAuthorization/resolveAuthorization.d.ts +27 -0
- package/src/lib/resolveAuthorization/resolveAuthorization.js +28 -0
- package/src/lib/resolveChainId/resolveChainId.cjs +12 -0
- package/src/lib/resolveChainId/resolveChainId.d.ts +11 -0
- package/src/lib/resolveChainId/resolveChainId.js +8 -0
- package/src/lib/sendSponsoredTransaction/sendSponsoredTransaction.cjs +21 -0
- package/src/lib/sendSponsoredTransaction/sendSponsoredTransaction.d.ts +29 -0
- package/src/lib/sendSponsoredTransaction/sendSponsoredTransaction.js +17 -0
- package/src/lib/sign7702Authorization/sign7702Authorization.cjs +22 -0
- package/src/lib/sign7702Authorization/sign7702Authorization.d.ts +21 -0
- package/src/lib/sign7702Authorization/sign7702Authorization.js +18 -0
- package/src/lib/signSponsoredTransaction/signSponsoredTransaction.cjs +61 -0
- package/src/lib/signSponsoredTransaction/signSponsoredTransaction.d.ts +22 -0
- package/src/lib/signSponsoredTransaction/signSponsoredTransaction.js +57 -0
- package/src/lib/toSerializedAuthorization/toSerializedAuthorization.cjs +28 -0
- package/src/lib/toSerializedAuthorization/toSerializedAuthorization.d.ts +11 -0
- package/src/lib/toSerializedAuthorization/toSerializedAuthorization.js +24 -0
- package/src/lib/types.d.ts +83 -0
- package/src/lib/waitForSponsoredTransaction/waitForSponsoredTransaction.cjs +38 -0
- package/src/lib/waitForSponsoredTransaction/waitForSponsoredTransaction.d.ts +16 -0
- package/src/lib/waitForSponsoredTransaction/waitForSponsoredTransaction.js +34 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var relaySponsoredTransaction = require('../relaySponsoredTransaction/relaySponsoredTransaction.cjs');
|
|
7
|
+
var waitForSponsoredTransaction = require('../waitForSponsoredTransaction/waitForSponsoredTransaction.cjs');
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Sends a sponsored EVM transaction and waits for on-chain inclusion.
|
|
11
|
+
*
|
|
12
|
+
* Composes `relaySponsoredTransaction` (signs + submits to the relay) and
|
|
13
|
+
* `waitForSponsoredTransaction` (polls relay status). Returns the on-chain
|
|
14
|
+
* transaction hash once the relay reports inclusion.
|
|
15
|
+
*/
|
|
16
|
+
const sendSponsoredTransaction = async (params, deps) => {
|
|
17
|
+
const { requestId } = await relaySponsoredTransaction.relaySponsoredTransaction(params, deps);
|
|
18
|
+
return waitForSponsoredTransaction.waitForSponsoredTransaction({ requestId }, deps);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
exports.sendSponsoredTransaction = sendSponsoredTransaction;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Hex } from 'viem';
|
|
2
|
+
import type { SignAuthorizationReturnType } from 'viem/accounts';
|
|
3
|
+
import type { EvmGaslessChainDeps, SignedSponsoredTransaction, SponsoredTransactionCall } from '../types';
|
|
4
|
+
type SendWithCallsParams = {
|
|
5
|
+
/** Pre-signed EIP-7702 authorization. Takes priority over autoDelegate. */
|
|
6
|
+
authorization?: SignAuthorizationReturnType;
|
|
7
|
+
/** Whether to automatically sign 7702 authorization if not delegated. Defaults to true. */
|
|
8
|
+
autoDelegate?: boolean;
|
|
9
|
+
/** The batch of calls to execute. */
|
|
10
|
+
calls: SponsoredTransactionCall[];
|
|
11
|
+
/** How long the signed intent remains valid, in seconds. Defaults to 600. */
|
|
12
|
+
validForSeconds?: number;
|
|
13
|
+
};
|
|
14
|
+
type SendWithSignedTxParams = {
|
|
15
|
+
/** A pre-signed sponsored transaction payload from `signSponsoredTransaction`. */
|
|
16
|
+
signedTransaction: SignedSponsoredTransaction;
|
|
17
|
+
};
|
|
18
|
+
type SendSponsoredTransactionParams = SendWithCallsParams | SendWithSignedTxParams;
|
|
19
|
+
/**
|
|
20
|
+
* Sends a sponsored EVM transaction and waits for on-chain inclusion.
|
|
21
|
+
*
|
|
22
|
+
* Composes `relaySponsoredTransaction` (signs + submits to the relay) and
|
|
23
|
+
* `waitForSponsoredTransaction` (polls relay status). Returns the on-chain
|
|
24
|
+
* transaction hash once the relay reports inclusion.
|
|
25
|
+
*/
|
|
26
|
+
export declare const sendSponsoredTransaction: (params: SendSponsoredTransactionParams, deps: EvmGaslessChainDeps) => Promise<{
|
|
27
|
+
transactionHash: Hex;
|
|
28
|
+
}>;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { relaySponsoredTransaction } from '../relaySponsoredTransaction/relaySponsoredTransaction.js';
|
|
3
|
+
import { waitForSponsoredTransaction } from '../waitForSponsoredTransaction/waitForSponsoredTransaction.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Sends a sponsored EVM transaction and waits for on-chain inclusion.
|
|
7
|
+
*
|
|
8
|
+
* Composes `relaySponsoredTransaction` (signs + submits to the relay) and
|
|
9
|
+
* `waitForSponsoredTransaction` (polls relay status). Returns the on-chain
|
|
10
|
+
* transaction hash once the relay reports inclusion.
|
|
11
|
+
*/
|
|
12
|
+
const sendSponsoredTransaction = async (params, deps) => {
|
|
13
|
+
const { requestId } = await relaySponsoredTransaction(params, deps);
|
|
14
|
+
return waitForSponsoredTransaction({ requestId }, deps);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export { sendSponsoredTransaction };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var constants = require('../constants.cjs');
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Signs an EIP-7702 authorization to delegate the user's wallet to the
|
|
10
|
+
* Dynamic gasless delegation contract.
|
|
11
|
+
*
|
|
12
|
+
* The resulting authorization can be passed to `sendSponsoredTransaction`
|
|
13
|
+
* (or any first-time sponsored call) to activate delegation as part of the
|
|
14
|
+
* sponsored intent.
|
|
15
|
+
*/
|
|
16
|
+
const sign7702Authorization = async ({ chainId }, { chainId: depsChainId, walletClient }) => walletClient.signAuthorization({
|
|
17
|
+
account: walletClient.account,
|
|
18
|
+
chainId: chainId ?? depsChainId,
|
|
19
|
+
contractAddress: constants.DELEGATION_CONTRACT_ADDRESS,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
exports.sign7702Authorization = sign7702Authorization;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Account, Chain, Transport, WalletClient } from 'viem';
|
|
2
|
+
import type { SignAuthorizationReturnType } from 'viem/accounts';
|
|
3
|
+
type Sign7702AuthorizationParams = {
|
|
4
|
+
/** Override the chain ID embedded in the signed authorization. */
|
|
5
|
+
chainId?: number;
|
|
6
|
+
};
|
|
7
|
+
type Sign7702AuthorizationDeps = {
|
|
8
|
+
/** Default chain ID used when none is supplied via `params`. */
|
|
9
|
+
chainId: number;
|
|
10
|
+
walletClient: WalletClient<Transport, Chain, Account>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Signs an EIP-7702 authorization to delegate the user's wallet to the
|
|
14
|
+
* Dynamic gasless delegation contract.
|
|
15
|
+
*
|
|
16
|
+
* The resulting authorization can be passed to `sendSponsoredTransaction`
|
|
17
|
+
* (or any first-time sponsored call) to activate delegation as part of the
|
|
18
|
+
* sponsored intent.
|
|
19
|
+
*/
|
|
20
|
+
export declare const sign7702Authorization: ({ chainId }: Sign7702AuthorizationParams, { chainId: depsChainId, walletClient }: Sign7702AuthorizationDeps) => Promise<SignAuthorizationReturnType>;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { DELEGATION_CONTRACT_ADDRESS } from '../constants.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Signs an EIP-7702 authorization to delegate the user's wallet to the
|
|
6
|
+
* Dynamic gasless delegation contract.
|
|
7
|
+
*
|
|
8
|
+
* The resulting authorization can be passed to `sendSponsoredTransaction`
|
|
9
|
+
* (or any first-time sponsored call) to activate delegation as part of the
|
|
10
|
+
* sponsored intent.
|
|
11
|
+
*/
|
|
12
|
+
const sign7702Authorization = async ({ chainId }, { chainId: depsChainId, walletClient }) => walletClient.signAuthorization({
|
|
13
|
+
account: walletClient.account,
|
|
14
|
+
chainId: chainId ?? depsChainId,
|
|
15
|
+
contractAddress: DELEGATION_CONTRACT_ADDRESS,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export { sign7702Authorization };
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var constants = require('../constants.cjs');
|
|
7
|
+
var generateIntentNonce = require('../generateIntentNonce/generateIntentNonce.cjs');
|
|
8
|
+
var getAvailableEvmGaslessRelayer = require('../getAvailableEvmGaslessRelayer/getAvailableEvmGaslessRelayer.cjs');
|
|
9
|
+
var resolveAuthorization = require('../resolveAuthorization/resolveAuthorization.cjs');
|
|
10
|
+
var toSerializedAuthorization = require('../toSerializedAuthorization/toSerializedAuthorization.cjs');
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Signs a sponsored transaction as an EIP-712 `AuthorizedExecutions` intent.
|
|
14
|
+
*
|
|
15
|
+
* Orchestrates the full signing flow: resolves the (optional) EIP-7702
|
|
16
|
+
* authorization, generates a bitmap nonce, fetches the relay address for
|
|
17
|
+
* the target chain, and signs the typed-data payload with the wallet client
|
|
18
|
+
* provided in `deps`.
|
|
19
|
+
*/
|
|
20
|
+
const signSponsoredTransaction = async ({ authorization, autoDelegate = true, calls, validForSeconds = constants.DEFAULT_VALID_FOR_SECONDS, }, deps) => {
|
|
21
|
+
const { chainId, walletClient } = deps;
|
|
22
|
+
const walletAddress = walletClient.account.address;
|
|
23
|
+
const resolvedAuthorization = await resolveAuthorization.resolveAuthorization({ authorization, autoDelegate, walletAddress }, deps);
|
|
24
|
+
const nonce = await generateIntentNonce.generateIntentNonce({ walletAddress }, deps);
|
|
25
|
+
const deadline = BigInt(Math.floor(Date.now() / 1000) + validForSeconds);
|
|
26
|
+
const { relayerAddress } = await getAvailableEvmGaslessRelayer.getAvailableEvmGaslessRelayer({ chainId }, deps);
|
|
27
|
+
const signature = await walletClient.signTypedData({
|
|
28
|
+
account: walletClient.account,
|
|
29
|
+
domain: {
|
|
30
|
+
chainId,
|
|
31
|
+
verifyingContract: constants.DELEGATION_CONTRACT_ADDRESS,
|
|
32
|
+
},
|
|
33
|
+
message: {
|
|
34
|
+
calls: calls.map((c) => ({
|
|
35
|
+
data: c.data,
|
|
36
|
+
target: c.target,
|
|
37
|
+
value: c.value,
|
|
38
|
+
})),
|
|
39
|
+
deadline,
|
|
40
|
+
mode: constants.BATCH_CALL_OPDATA_AUTH_MODE,
|
|
41
|
+
nonce,
|
|
42
|
+
relayer: relayerAddress,
|
|
43
|
+
},
|
|
44
|
+
primaryType: 'AuthorizedExecutions',
|
|
45
|
+
types: constants.AUTHORIZED_EXECUTIONS_TYPES,
|
|
46
|
+
});
|
|
47
|
+
return {
|
|
48
|
+
authorization: resolvedAuthorization
|
|
49
|
+
? toSerializedAuthorization.toSerializedAuthorization(resolvedAuthorization)
|
|
50
|
+
: undefined,
|
|
51
|
+
calls,
|
|
52
|
+
chainId,
|
|
53
|
+
deadline: deadline.toString(),
|
|
54
|
+
nonce: nonce.toString(),
|
|
55
|
+
relayer: relayerAddress,
|
|
56
|
+
signature: signature,
|
|
57
|
+
walletAddress,
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
exports.signSponsoredTransaction = signSponsoredTransaction;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { SignAuthorizationReturnType } from 'viem/accounts';
|
|
2
|
+
import type { EvmGaslessChainDeps, SignedSponsoredTransaction, SponsoredTransactionCall } from '../types';
|
|
3
|
+
type SignSponsoredTransactionParams = {
|
|
4
|
+
/** Pre-signed EIP-7702 authorization. Takes priority over autoDelegate. */
|
|
5
|
+
authorization?: SignAuthorizationReturnType;
|
|
6
|
+
/** Whether to automatically sign 7702 authorization if not delegated. Defaults to true. */
|
|
7
|
+
autoDelegate?: boolean;
|
|
8
|
+
/** The batch of calls to execute. */
|
|
9
|
+
calls: SponsoredTransactionCall[];
|
|
10
|
+
/** How long the signed intent remains valid, in seconds. Defaults to 600 (10 minutes). */
|
|
11
|
+
validForSeconds?: number;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Signs a sponsored transaction as an EIP-712 `AuthorizedExecutions` intent.
|
|
15
|
+
*
|
|
16
|
+
* Orchestrates the full signing flow: resolves the (optional) EIP-7702
|
|
17
|
+
* authorization, generates a bitmap nonce, fetches the relay address for
|
|
18
|
+
* the target chain, and signs the typed-data payload with the wallet client
|
|
19
|
+
* provided in `deps`.
|
|
20
|
+
*/
|
|
21
|
+
export declare const signSponsoredTransaction: ({ authorization, autoDelegate, calls, validForSeconds, }: SignSponsoredTransactionParams, deps: EvmGaslessChainDeps) => Promise<SignedSponsoredTransaction>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { DELEGATION_CONTRACT_ADDRESS, BATCH_CALL_OPDATA_AUTH_MODE, AUTHORIZED_EXECUTIONS_TYPES, DEFAULT_VALID_FOR_SECONDS } from '../constants.js';
|
|
3
|
+
import { generateIntentNonce } from '../generateIntentNonce/generateIntentNonce.js';
|
|
4
|
+
import { getAvailableEvmGaslessRelayer } from '../getAvailableEvmGaslessRelayer/getAvailableEvmGaslessRelayer.js';
|
|
5
|
+
import { resolveAuthorization } from '../resolveAuthorization/resolveAuthorization.js';
|
|
6
|
+
import { toSerializedAuthorization } from '../toSerializedAuthorization/toSerializedAuthorization.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Signs a sponsored transaction as an EIP-712 `AuthorizedExecutions` intent.
|
|
10
|
+
*
|
|
11
|
+
* Orchestrates the full signing flow: resolves the (optional) EIP-7702
|
|
12
|
+
* authorization, generates a bitmap nonce, fetches the relay address for
|
|
13
|
+
* the target chain, and signs the typed-data payload with the wallet client
|
|
14
|
+
* provided in `deps`.
|
|
15
|
+
*/
|
|
16
|
+
const signSponsoredTransaction = async ({ authorization, autoDelegate = true, calls, validForSeconds = DEFAULT_VALID_FOR_SECONDS, }, deps) => {
|
|
17
|
+
const { chainId, walletClient } = deps;
|
|
18
|
+
const walletAddress = walletClient.account.address;
|
|
19
|
+
const resolvedAuthorization = await resolveAuthorization({ authorization, autoDelegate, walletAddress }, deps);
|
|
20
|
+
const nonce = await generateIntentNonce({ walletAddress }, deps);
|
|
21
|
+
const deadline = BigInt(Math.floor(Date.now() / 1000) + validForSeconds);
|
|
22
|
+
const { relayerAddress } = await getAvailableEvmGaslessRelayer({ chainId }, deps);
|
|
23
|
+
const signature = await walletClient.signTypedData({
|
|
24
|
+
account: walletClient.account,
|
|
25
|
+
domain: {
|
|
26
|
+
chainId,
|
|
27
|
+
verifyingContract: DELEGATION_CONTRACT_ADDRESS,
|
|
28
|
+
},
|
|
29
|
+
message: {
|
|
30
|
+
calls: calls.map((c) => ({
|
|
31
|
+
data: c.data,
|
|
32
|
+
target: c.target,
|
|
33
|
+
value: c.value,
|
|
34
|
+
})),
|
|
35
|
+
deadline,
|
|
36
|
+
mode: BATCH_CALL_OPDATA_AUTH_MODE,
|
|
37
|
+
nonce,
|
|
38
|
+
relayer: relayerAddress,
|
|
39
|
+
},
|
|
40
|
+
primaryType: 'AuthorizedExecutions',
|
|
41
|
+
types: AUTHORIZED_EXECUTIONS_TYPES,
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
authorization: resolvedAuthorization
|
|
45
|
+
? toSerializedAuthorization(resolvedAuthorization)
|
|
46
|
+
: undefined,
|
|
47
|
+
calls,
|
|
48
|
+
chainId,
|
|
49
|
+
deadline: deadline.toString(),
|
|
50
|
+
nonce: nonce.toString(),
|
|
51
|
+
relayer: relayerAddress,
|
|
52
|
+
signature: signature,
|
|
53
|
+
walletAddress,
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export { signSponsoredTransaction };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Converts a viem `SignAuthorizationReturnType` into a plain serializable
|
|
8
|
+
* object suitable for JSON transport to the sponsorship API.
|
|
9
|
+
*
|
|
10
|
+
* viem's `Signature` type allows legacy v-only signatures without `yParity`,
|
|
11
|
+
* but our signing flow always produces one — explicitly check for `undefined`
|
|
12
|
+
* (not falsiness) so the valid `yParity: 0` recovery bit isn't rejected.
|
|
13
|
+
*/
|
|
14
|
+
const toSerializedAuthorization = (auth) => {
|
|
15
|
+
if (auth.yParity === undefined) {
|
|
16
|
+
throw new Error('Signed authorization is missing yParity');
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
address: auth.address,
|
|
20
|
+
chainId: auth.chainId,
|
|
21
|
+
nonce: auth.nonce,
|
|
22
|
+
r: auth.r,
|
|
23
|
+
s: auth.s,
|
|
24
|
+
yParity: auth.yParity,
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
exports.toSerializedAuthorization = toSerializedAuthorization;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SignAuthorizationReturnType } from 'viem/accounts';
|
|
2
|
+
import type { SerializedAuthorization } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Converts a viem `SignAuthorizationReturnType` into a plain serializable
|
|
5
|
+
* object suitable for JSON transport to the sponsorship API.
|
|
6
|
+
*
|
|
7
|
+
* viem's `Signature` type allows legacy v-only signatures without `yParity`,
|
|
8
|
+
* but our signing flow always produces one — explicitly check for `undefined`
|
|
9
|
+
* (not falsiness) so the valid `yParity: 0` recovery bit isn't rejected.
|
|
10
|
+
*/
|
|
11
|
+
export declare const toSerializedAuthorization: (auth: SignAuthorizationReturnType) => SerializedAuthorization;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
/**
|
|
3
|
+
* Converts a viem `SignAuthorizationReturnType` into a plain serializable
|
|
4
|
+
* object suitable for JSON transport to the sponsorship API.
|
|
5
|
+
*
|
|
6
|
+
* viem's `Signature` type allows legacy v-only signatures without `yParity`,
|
|
7
|
+
* but our signing flow always produces one — explicitly check for `undefined`
|
|
8
|
+
* (not falsiness) so the valid `yParity: 0` recovery bit isn't rejected.
|
|
9
|
+
*/
|
|
10
|
+
const toSerializedAuthorization = (auth) => {
|
|
11
|
+
if (auth.yParity === undefined) {
|
|
12
|
+
throw new Error('Signed authorization is missing yParity');
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
address: auth.address,
|
|
16
|
+
chainId: auth.chainId,
|
|
17
|
+
nonce: auth.nonce,
|
|
18
|
+
r: auth.r,
|
|
19
|
+
s: auth.s,
|
|
20
|
+
yParity: auth.yParity,
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export { toSerializedAuthorization };
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Account, Chain, Hex, PublicClient, Transport, WalletClient } from 'viem';
|
|
2
|
+
import type { SDKApi } from '@dynamic-labs/sdk-api-core';
|
|
3
|
+
/**
|
|
4
|
+
* An EIP-712 sponsored-transaction call: a single (target, value, data) tuple
|
|
5
|
+
* batched together with other calls inside one sponsored intent.
|
|
6
|
+
*/
|
|
7
|
+
export type SponsoredTransactionCall = {
|
|
8
|
+
data: Hex;
|
|
9
|
+
target: Hex;
|
|
10
|
+
value: bigint;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Plain-object form of a viem signed EIP-7702 authorization, suitable for
|
|
14
|
+
* JSON transport to the sponsorship API.
|
|
15
|
+
*/
|
|
16
|
+
export type SerializedAuthorization = {
|
|
17
|
+
address: Hex;
|
|
18
|
+
chainId: number;
|
|
19
|
+
nonce: number;
|
|
20
|
+
r: Hex;
|
|
21
|
+
s: Hex;
|
|
22
|
+
yParity: number;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Lifecycle states reported by the relay for a sponsored transaction.
|
|
26
|
+
*/
|
|
27
|
+
export type SponsoredTransactionStatus = 'failure' | 'pending' | 'submitted' | 'success';
|
|
28
|
+
/**
|
|
29
|
+
* Full status payload returned by `getEVMSponsoredTransactionStatus`.
|
|
30
|
+
*/
|
|
31
|
+
export type SponsoredTransactionStatusResult = {
|
|
32
|
+
errorMessage?: string;
|
|
33
|
+
status: SponsoredTransactionStatus;
|
|
34
|
+
transactionHash?: Hex;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* A signed sponsored-transaction payload ready to be relayed.
|
|
38
|
+
*/
|
|
39
|
+
export type SignedSponsoredTransaction = {
|
|
40
|
+
authorization?: SerializedAuthorization;
|
|
41
|
+
calls: SponsoredTransactionCall[];
|
|
42
|
+
chainId: number;
|
|
43
|
+
deadline: string;
|
|
44
|
+
nonce: string;
|
|
45
|
+
relayer: Hex;
|
|
46
|
+
signature: Hex;
|
|
47
|
+
walletAddress: Hex;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* In-memory cache of "this wallet on this chain has active 7702 delegation",
|
|
51
|
+
* scoped to the host (controller / extension) instance. Only positive
|
|
52
|
+
* delegations are cached — a missing entry means the status is unknown and
|
|
53
|
+
* should be resolved via RPC.
|
|
54
|
+
*/
|
|
55
|
+
export type Delegation7702Registry = {
|
|
56
|
+
isDelegated: (params: {
|
|
57
|
+
chainId: number;
|
|
58
|
+
walletAddress: string;
|
|
59
|
+
}) => boolean;
|
|
60
|
+
markDelegated: (params: {
|
|
61
|
+
chainId: number;
|
|
62
|
+
walletAddress: string;
|
|
63
|
+
}) => void;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Dependencies needed by gasless API-only functions (relay, status, relayer
|
|
67
|
+
* lookup, sponsorship-enabled).
|
|
68
|
+
*/
|
|
69
|
+
export type EvmGaslessApiDeps = {
|
|
70
|
+
environmentId: string;
|
|
71
|
+
sdkApi: SDKApi;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Dependencies needed by gasless signing flows. Includes the API deps plus a
|
|
75
|
+
* viem `WalletClient` for signing, a viem `PublicClient` for read RPC, the
|
|
76
|
+
* chain ID being signed against, and the host-wide delegation registry.
|
|
77
|
+
*/
|
|
78
|
+
export type EvmGaslessChainDeps = EvmGaslessApiDeps & {
|
|
79
|
+
chainId: number;
|
|
80
|
+
delegationRegistry: Delegation7702Registry;
|
|
81
|
+
publicClient: PublicClient<Transport, Chain>;
|
|
82
|
+
walletClient: WalletClient<Transport, Chain, Account>;
|
|
83
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
5
|
+
|
|
6
|
+
var SponsorTransactionError = require('../errors/SponsorTransactionError/SponsorTransactionError.cjs');
|
|
7
|
+
var getEVMSponsoredTransactionStatus = require('../getEVMSponsoredTransactionStatus/getEVMSponsoredTransactionStatus.cjs');
|
|
8
|
+
|
|
9
|
+
const POLL_INTERVAL_MS = 2000;
|
|
10
|
+
const TIMEOUT_MS = 60000;
|
|
11
|
+
const MAX_POLLING_ATTEMPTS = TIMEOUT_MS / POLL_INTERVAL_MS;
|
|
12
|
+
const TERMINAL_FAILURE_STATUSES = new Set([
|
|
13
|
+
'failure',
|
|
14
|
+
]);
|
|
15
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
16
|
+
/**
|
|
17
|
+
* Polls `getEVMSponsoredTransactionStatus` until the relay reports the
|
|
18
|
+
* transaction has been included on-chain, then returns the transaction hash.
|
|
19
|
+
*
|
|
20
|
+
* Throws if the relay returns a terminal failure or if polling times out.
|
|
21
|
+
*/
|
|
22
|
+
const waitForSponsoredTransaction = async ({ requestId }, deps) => {
|
|
23
|
+
for (let attempt = 0; attempt < MAX_POLLING_ATTEMPTS; attempt++) {
|
|
24
|
+
const result = await getEVMSponsoredTransactionStatus.getEVMSponsoredTransactionStatus({ requestId }, deps);
|
|
25
|
+
if (TERMINAL_FAILURE_STATUSES.has(result.status)) {
|
|
26
|
+
throw new SponsorTransactionError.SponsorTransactionError(null, result.errorMessage);
|
|
27
|
+
}
|
|
28
|
+
if (result.transactionHash) {
|
|
29
|
+
return { transactionHash: result.transactionHash };
|
|
30
|
+
}
|
|
31
|
+
if (attempt < MAX_POLLING_ATTEMPTS - 1) {
|
|
32
|
+
await sleep(POLL_INTERVAL_MS);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
throw new SponsorTransactionError.SponsorTransactionError(null, `Timed out waiting for sponsored transaction ${requestId}`);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
exports.waitForSponsoredTransaction = waitForSponsoredTransaction;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Hex } from 'viem';
|
|
2
|
+
import type { EvmGaslessApiDeps } from '../types';
|
|
3
|
+
type WaitForSponsoredTransactionParams = {
|
|
4
|
+
/** The request ID returned by `relaySponsoredTransaction` / `sendSponsoredTransaction`. */
|
|
5
|
+
requestId: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Polls `getEVMSponsoredTransactionStatus` until the relay reports the
|
|
9
|
+
* transaction has been included on-chain, then returns the transaction hash.
|
|
10
|
+
*
|
|
11
|
+
* Throws if the relay returns a terminal failure or if polling times out.
|
|
12
|
+
*/
|
|
13
|
+
export declare const waitForSponsoredTransaction: ({ requestId }: WaitForSponsoredTransactionParams, deps: EvmGaslessApiDeps) => Promise<{
|
|
14
|
+
transactionHash: Hex;
|
|
15
|
+
}>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
import { SponsorTransactionError } from '../errors/SponsorTransactionError/SponsorTransactionError.js';
|
|
3
|
+
import { getEVMSponsoredTransactionStatus } from '../getEVMSponsoredTransactionStatus/getEVMSponsoredTransactionStatus.js';
|
|
4
|
+
|
|
5
|
+
const POLL_INTERVAL_MS = 2000;
|
|
6
|
+
const TIMEOUT_MS = 60000;
|
|
7
|
+
const MAX_POLLING_ATTEMPTS = TIMEOUT_MS / POLL_INTERVAL_MS;
|
|
8
|
+
const TERMINAL_FAILURE_STATUSES = new Set([
|
|
9
|
+
'failure',
|
|
10
|
+
]);
|
|
11
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
12
|
+
/**
|
|
13
|
+
* Polls `getEVMSponsoredTransactionStatus` until the relay reports the
|
|
14
|
+
* transaction has been included on-chain, then returns the transaction hash.
|
|
15
|
+
*
|
|
16
|
+
* Throws if the relay returns a terminal failure or if polling times out.
|
|
17
|
+
*/
|
|
18
|
+
const waitForSponsoredTransaction = async ({ requestId }, deps) => {
|
|
19
|
+
for (let attempt = 0; attempt < MAX_POLLING_ATTEMPTS; attempt++) {
|
|
20
|
+
const result = await getEVMSponsoredTransactionStatus({ requestId }, deps);
|
|
21
|
+
if (TERMINAL_FAILURE_STATUSES.has(result.status)) {
|
|
22
|
+
throw new SponsorTransactionError(null, result.errorMessage);
|
|
23
|
+
}
|
|
24
|
+
if (result.transactionHash) {
|
|
25
|
+
return { transactionHash: result.transactionHash };
|
|
26
|
+
}
|
|
27
|
+
if (attempt < MAX_POLLING_ATTEMPTS - 1) {
|
|
28
|
+
await sleep(POLL_INTERVAL_MS);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
throw new SponsorTransactionError(null, `Timed out waiting for sponsored transaction ${requestId}`);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export { waitForSponsoredTransaction };
|