@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.
Files changed (67) hide show
  1. package/CHANGELOG.md +6525 -0
  2. package/LICENSE +21 -0
  3. package/README.md +7 -0
  4. package/package.cjs +8 -0
  5. package/package.js +4 -0
  6. package/package.json +23 -1
  7. package/src/index.cjs +53 -0
  8. package/src/index.d.ts +20 -0
  9. package/src/index.js +24 -0
  10. package/src/lib/activate7702Delegation/activate7702Delegation.cjs +17 -0
  11. package/src/lib/activate7702Delegation/activate7702Delegation.d.ts +18 -0
  12. package/src/lib/activate7702Delegation/activate7702Delegation.js +13 -0
  13. package/src/lib/constants.cjs +69 -0
  14. package/src/lib/constants.d.ts +76 -0
  15. package/src/lib/constants.js +60 -0
  16. package/src/lib/create7702DelegationRegistry/create7702DelegationRegistry.cjs +22 -0
  17. package/src/lib/create7702DelegationRegistry/create7702DelegationRegistry.d.ts +7 -0
  18. package/src/lib/create7702DelegationRegistry/create7702DelegationRegistry.js +18 -0
  19. package/src/lib/errors/EthereumGasSponsorshipNotEnabledError/EthereumGasSponsorshipNotEnabledError.cjs +18 -0
  20. package/src/lib/errors/EthereumGasSponsorshipNotEnabledError/EthereumGasSponsorshipNotEnabledError.d.ts +8 -0
  21. package/src/lib/errors/EthereumGasSponsorshipNotEnabledError/EthereumGasSponsorshipNotEnabledError.js +14 -0
  22. package/src/lib/errors/SponsorTransactionError/SponsorTransactionError.cjs +23 -0
  23. package/src/lib/errors/SponsorTransactionError/SponsorTransactionError.d.ts +10 -0
  24. package/src/lib/errors/SponsorTransactionError/SponsorTransactionError.js +19 -0
  25. package/src/lib/generateIntentNonce/generateIntentNonce.cjs +39 -0
  26. package/src/lib/generateIntentNonce/generateIntentNonce.d.ts +20 -0
  27. package/src/lib/generateIntentNonce/generateIntentNonce.js +35 -0
  28. package/src/lib/generateRandomNonce/generateRandomNonce.cjs +22 -0
  29. package/src/lib/generateRandomNonce/generateRandomNonce.d.ts +11 -0
  30. package/src/lib/generateRandomNonce/generateRandomNonce.js +18 -0
  31. package/src/lib/getAvailableEvmGaslessRelayer/getAvailableEvmGaslessRelayer.cjs +35 -0
  32. package/src/lib/getAvailableEvmGaslessRelayer/getAvailableEvmGaslessRelayer.d.ts +21 -0
  33. package/src/lib/getAvailableEvmGaslessRelayer/getAvailableEvmGaslessRelayer.js +31 -0
  34. package/src/lib/getEVMSponsoredTransactionStatus/getEVMSponsoredTransactionStatus.cjs +35 -0
  35. package/src/lib/getEVMSponsoredTransactionStatus/getEVMSponsoredTransactionStatus.d.ts +15 -0
  36. package/src/lib/getEVMSponsoredTransactionStatus/getEVMSponsoredTransactionStatus.js +31 -0
  37. package/src/lib/is7702DelegationActive/is7702DelegationActive.cjs +32 -0
  38. package/src/lib/is7702DelegationActive/is7702DelegationActive.d.ts +21 -0
  39. package/src/lib/is7702DelegationActive/is7702DelegationActive.js +28 -0
  40. package/src/lib/isEthereumGasSponsorshipEnabled/isEthereumGasSponsorshipEnabled.cjs +14 -0
  41. package/src/lib/isEthereumGasSponsorshipEnabled/isEthereumGasSponsorshipEnabled.d.ts +23 -0
  42. package/src/lib/isEthereumGasSponsorshipEnabled/isEthereumGasSponsorshipEnabled.js +10 -0
  43. package/src/lib/relaySponsoredTransaction/relaySponsoredTransaction.cjs +58 -0
  44. package/src/lib/relaySponsoredTransaction/relaySponsoredTransaction.d.ts +29 -0
  45. package/src/lib/relaySponsoredTransaction/relaySponsoredTransaction.js +54 -0
  46. package/src/lib/resolveAuthorization/resolveAuthorization.cjs +32 -0
  47. package/src/lib/resolveAuthorization/resolveAuthorization.d.ts +27 -0
  48. package/src/lib/resolveAuthorization/resolveAuthorization.js +28 -0
  49. package/src/lib/resolveChainId/resolveChainId.cjs +12 -0
  50. package/src/lib/resolveChainId/resolveChainId.d.ts +11 -0
  51. package/src/lib/resolveChainId/resolveChainId.js +8 -0
  52. package/src/lib/sendSponsoredTransaction/sendSponsoredTransaction.cjs +21 -0
  53. package/src/lib/sendSponsoredTransaction/sendSponsoredTransaction.d.ts +29 -0
  54. package/src/lib/sendSponsoredTransaction/sendSponsoredTransaction.js +17 -0
  55. package/src/lib/sign7702Authorization/sign7702Authorization.cjs +22 -0
  56. package/src/lib/sign7702Authorization/sign7702Authorization.d.ts +21 -0
  57. package/src/lib/sign7702Authorization/sign7702Authorization.js +18 -0
  58. package/src/lib/signSponsoredTransaction/signSponsoredTransaction.cjs +61 -0
  59. package/src/lib/signSponsoredTransaction/signSponsoredTransaction.d.ts +22 -0
  60. package/src/lib/signSponsoredTransaction/signSponsoredTransaction.js +57 -0
  61. package/src/lib/toSerializedAuthorization/toSerializedAuthorization.cjs +28 -0
  62. package/src/lib/toSerializedAuthorization/toSerializedAuthorization.d.ts +11 -0
  63. package/src/lib/toSerializedAuthorization/toSerializedAuthorization.js +24 -0
  64. package/src/lib/types.d.ts +83 -0
  65. package/src/lib/waitForSponsoredTransaction/waitForSponsoredTransaction.cjs +38 -0
  66. package/src/lib/waitForSponsoredTransaction/waitForSponsoredTransaction.d.ts +16 -0
  67. package/src/lib/waitForSponsoredTransaction/waitForSponsoredTransaction.js +34 -0
@@ -0,0 +1,35 @@
1
+ 'use client'
2
+ import { UGD_ABI } from '../constants.js';
3
+ import { generateRandomNonce } from '../generateRandomNonce/generateRandomNonce.js';
4
+
5
+ /**
6
+ * Generates a random 256-bit bitmap nonce for UGD `AuthorizedExecutions`
7
+ * signing.
8
+ *
9
+ * Uses `crypto.getRandomValues` for entropy; collisions are essentially
10
+ * impossible at 256 bits. As a safety check the freshly-generated nonce is
11
+ * validated against the on-chain `isNonceUsed` view — if the contract call
12
+ * fails (e.g. delegation not yet active), the random nonce is still safe to
13
+ * use because it was generated locally with 256 bits of entropy.
14
+ */
15
+ const generateIntentNonce = async ({ walletAddress }, { publicClient }) => {
16
+ const nonce = generateRandomNonce();
17
+ try {
18
+ const isUsed = await publicClient.readContract({
19
+ abi: UGD_ABI,
20
+ address: walletAddress,
21
+ args: [nonce],
22
+ functionName: 'isNonceUsed',
23
+ });
24
+ if (isUsed) {
25
+ return generateRandomNonce();
26
+ }
27
+ }
28
+ catch {
29
+ // Contract call may fail if delegation is not yet active — the nonce is
30
+ // still safe to use since it was randomly generated.
31
+ }
32
+ return nonce;
33
+ };
34
+
35
+ export { generateIntentNonce };
@@ -0,0 +1,22 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ /**
7
+ * Generates a cryptographically random 256-bit nonce for the UGD
8
+ * AuthorizedExecutions bitmap.
9
+ *
10
+ * Uses `crypto.getRandomValues` for 256 bits of entropy. Collisions against
11
+ * the on-chain bitmap are effectively impossible at this width but callers
12
+ * may still validate via `isNonceUsed` as a safety net.
13
+ *
14
+ * @returns A random bigint nonce.
15
+ */
16
+ const generateRandomNonce = () => {
17
+ const bytes = new Uint8Array(32);
18
+ crypto.getRandomValues(bytes);
19
+ return bytes.reduce((acc, byte) => (acc << BigInt(8)) | BigInt(byte), BigInt(0));
20
+ };
21
+
22
+ exports.generateRandomNonce = generateRandomNonce;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Generates a cryptographically random 256-bit nonce for the UGD
3
+ * AuthorizedExecutions bitmap.
4
+ *
5
+ * Uses `crypto.getRandomValues` for 256 bits of entropy. Collisions against
6
+ * the on-chain bitmap are effectively impossible at this width but callers
7
+ * may still validate via `isNonceUsed` as a safety net.
8
+ *
9
+ * @returns A random bigint nonce.
10
+ */
11
+ export declare const generateRandomNonce: () => bigint;
@@ -0,0 +1,18 @@
1
+ 'use client'
2
+ /**
3
+ * Generates a cryptographically random 256-bit nonce for the UGD
4
+ * AuthorizedExecutions bitmap.
5
+ *
6
+ * Uses `crypto.getRandomValues` for 256 bits of entropy. Collisions against
7
+ * the on-chain bitmap are effectively impossible at this width but callers
8
+ * may still validate via `isNonceUsed` as a safety net.
9
+ *
10
+ * @returns A random bigint nonce.
11
+ */
12
+ const generateRandomNonce = () => {
13
+ const bytes = new Uint8Array(32);
14
+ crypto.getRandomValues(bytes);
15
+ return bytes.reduce((acc, byte) => (acc << BigInt(8)) | BigInt(byte), BigInt(0));
16
+ };
17
+
18
+ export { generateRandomNonce };
@@ -0,0 +1,35 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var SponsorTransactionError = require('../errors/SponsorTransactionError/SponsorTransactionError.cjs');
7
+
8
+ /**
9
+ * Fetches the relayer address to embed in the EIP-712 sponsored-transaction
10
+ * intent for the given chain.
11
+ *
12
+ * The returned address is owned by the project's relay backend and is the
13
+ * eventual `from` of the on-chain broadcast. It must be set as the `relayer`
14
+ * field of the EIP-712 intent before signing — the on-chain delegate
15
+ * validates the signature against this address.
16
+ */
17
+ const getAvailableEvmGaslessRelayer = async ({ chainId }, { sdkApi, environmentId }) => {
18
+ let data;
19
+ try {
20
+ data = await sdkApi.getAvailableEVMGaslessRelayer({
21
+ chainId,
22
+ environmentId,
23
+ });
24
+ }
25
+ catch (error) {
26
+ const cause = error instanceof Error ? error : null;
27
+ throw new SponsorTransactionError.SponsorTransactionError(cause);
28
+ }
29
+ if (!data.relayerAddress) {
30
+ throw new SponsorTransactionError.SponsorTransactionError();
31
+ }
32
+ return { relayerAddress: data.relayerAddress };
33
+ };
34
+
35
+ exports.getAvailableEvmGaslessRelayer = getAvailableEvmGaslessRelayer;
@@ -0,0 +1,21 @@
1
+ import type { Hex } from 'viem';
2
+ import type { EvmGaslessApiDeps } from '../types';
3
+ type GetAvailableEvmGaslessRelayerParams = {
4
+ /** The EVM chain ID the sponsored transaction will target. */
5
+ chainId: number;
6
+ };
7
+ type GetAvailableEvmGaslessRelayerResult = {
8
+ /** Relayer EOA that will broadcast the sponsored transaction on-chain. */
9
+ relayerAddress: Hex;
10
+ };
11
+ /**
12
+ * Fetches the relayer address to embed in the EIP-712 sponsored-transaction
13
+ * intent for the given chain.
14
+ *
15
+ * The returned address is owned by the project's relay backend and is the
16
+ * eventual `from` of the on-chain broadcast. It must be set as the `relayer`
17
+ * field of the EIP-712 intent before signing — the on-chain delegate
18
+ * validates the signature against this address.
19
+ */
20
+ export declare const getAvailableEvmGaslessRelayer: ({ chainId }: GetAvailableEvmGaslessRelayerParams, { sdkApi, environmentId }: EvmGaslessApiDeps) => Promise<GetAvailableEvmGaslessRelayerResult>;
21
+ export {};
@@ -0,0 +1,31 @@
1
+ 'use client'
2
+ import { SponsorTransactionError } from '../errors/SponsorTransactionError/SponsorTransactionError.js';
3
+
4
+ /**
5
+ * Fetches the relayer address to embed in the EIP-712 sponsored-transaction
6
+ * intent for the given chain.
7
+ *
8
+ * The returned address is owned by the project's relay backend and is the
9
+ * eventual `from` of the on-chain broadcast. It must be set as the `relayer`
10
+ * field of the EIP-712 intent before signing — the on-chain delegate
11
+ * validates the signature against this address.
12
+ */
13
+ const getAvailableEvmGaslessRelayer = async ({ chainId }, { sdkApi, environmentId }) => {
14
+ let data;
15
+ try {
16
+ data = await sdkApi.getAvailableEVMGaslessRelayer({
17
+ chainId,
18
+ environmentId,
19
+ });
20
+ }
21
+ catch (error) {
22
+ const cause = error instanceof Error ? error : null;
23
+ throw new SponsorTransactionError(cause);
24
+ }
25
+ if (!data.relayerAddress) {
26
+ throw new SponsorTransactionError();
27
+ }
28
+ return { relayerAddress: data.relayerAddress };
29
+ };
30
+
31
+ export { getAvailableEvmGaslessRelayer };
@@ -0,0 +1,35 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var SponsorTransactionError = require('../errors/SponsorTransactionError/SponsorTransactionError.cjs');
7
+
8
+ /**
9
+ * Fetches the current relay state for a sponsored EVM transaction.
10
+ *
11
+ * Returns the lifecycle status, the on-chain transaction hash (when the
12
+ * relay has broadcast it), and any terminal-failure error message. Use this
13
+ * as the building block for custom polling flows; for the common "wait until
14
+ * done" case prefer `waitForSponsoredTransaction`.
15
+ */
16
+ const getEVMSponsoredTransactionStatus = async ({ requestId }, { sdkApi, environmentId }) => {
17
+ let data;
18
+ try {
19
+ data = await sdkApi.getEVMSponsoredTransactionStatus({
20
+ environmentId,
21
+ requestId,
22
+ });
23
+ }
24
+ catch (error) {
25
+ const cause = error instanceof Error ? error : null;
26
+ throw new SponsorTransactionError.SponsorTransactionError(cause);
27
+ }
28
+ return {
29
+ errorMessage: data.errorMessage,
30
+ status: data.status,
31
+ transactionHash: data.transactionHash,
32
+ };
33
+ };
34
+
35
+ exports.getEVMSponsoredTransactionStatus = getEVMSponsoredTransactionStatus;
@@ -0,0 +1,15 @@
1
+ import type { EvmGaslessApiDeps, SponsoredTransactionStatusResult } from '../types';
2
+ type GetEVMSponsoredTransactionStatusParams = {
3
+ /** The request ID returned by `relaySponsoredTransaction` / `sendSponsoredTransaction`. */
4
+ requestId: string;
5
+ };
6
+ /**
7
+ * Fetches the current relay state for a sponsored EVM transaction.
8
+ *
9
+ * Returns the lifecycle status, the on-chain transaction hash (when the
10
+ * relay has broadcast it), and any terminal-failure error message. Use this
11
+ * as the building block for custom polling flows; for the common "wait until
12
+ * done" case prefer `waitForSponsoredTransaction`.
13
+ */
14
+ export declare const getEVMSponsoredTransactionStatus: ({ requestId }: GetEVMSponsoredTransactionStatusParams, { sdkApi, environmentId }: EvmGaslessApiDeps) => Promise<SponsoredTransactionStatusResult>;
15
+ export {};
@@ -0,0 +1,31 @@
1
+ 'use client'
2
+ import { SponsorTransactionError } from '../errors/SponsorTransactionError/SponsorTransactionError.js';
3
+
4
+ /**
5
+ * Fetches the current relay state for a sponsored EVM transaction.
6
+ *
7
+ * Returns the lifecycle status, the on-chain transaction hash (when the
8
+ * relay has broadcast it), and any terminal-failure error message. Use this
9
+ * as the building block for custom polling flows; for the common "wait until
10
+ * done" case prefer `waitForSponsoredTransaction`.
11
+ */
12
+ const getEVMSponsoredTransactionStatus = async ({ requestId }, { sdkApi, environmentId }) => {
13
+ let data;
14
+ try {
15
+ data = await sdkApi.getEVMSponsoredTransactionStatus({
16
+ environmentId,
17
+ requestId,
18
+ });
19
+ }
20
+ catch (error) {
21
+ const cause = error instanceof Error ? error : null;
22
+ throw new SponsorTransactionError(cause);
23
+ }
24
+ return {
25
+ errorMessage: data.errorMessage,
26
+ status: data.status,
27
+ transactionHash: data.transactionHash,
28
+ };
29
+ };
30
+
31
+ export { getEVMSponsoredTransactionStatus };
@@ -0,0 +1,32 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var constants = require('../constants.cjs');
7
+
8
+ /**
9
+ * Checks whether EIP-7702 delegation to the Dynamic gasless contract is
10
+ * active for the given wallet on the given chain.
11
+ *
12
+ * Positive results are cached in the in-memory registry; missing entries
13
+ * fall back to an on-chain bytecode check (`eth_getCode`). The on-chain
14
+ * delegation marker is `DELEGATION_CODE_PREFIX + DELEGATION_CONTRACT_ADDRESS`.
15
+ */
16
+ const is7702DelegationActive = async ({ walletAddress }, { chainId, delegationRegistry, publicClient }) => {
17
+ if (delegationRegistry.isDelegated({ chainId, walletAddress })) {
18
+ return true;
19
+ }
20
+ const bytecode = await publicClient.getCode({ address: walletAddress });
21
+ if (!bytecode) {
22
+ return false;
23
+ }
24
+ const expectedPrefix = constants.DELEGATION_CODE_PREFIX + constants.DELEGATION_CONTRACT_ADDRESS.slice(2).toLowerCase();
25
+ const isActive = bytecode.toLowerCase().startsWith(expectedPrefix);
26
+ if (isActive) {
27
+ delegationRegistry.markDelegated({ chainId, walletAddress });
28
+ }
29
+ return isActive;
30
+ };
31
+
32
+ exports.is7702DelegationActive = is7702DelegationActive;
@@ -0,0 +1,21 @@
1
+ import type { Chain, Hex, PublicClient, Transport } from 'viem';
2
+ import type { Delegation7702Registry } from '../types';
3
+ type Is7702DelegationActiveParams = {
4
+ /** The wallet address to check delegation status for. */
5
+ walletAddress: Hex;
6
+ };
7
+ type Is7702DelegationActiveDeps = {
8
+ chainId: number;
9
+ delegationRegistry: Delegation7702Registry;
10
+ publicClient: PublicClient<Transport, Chain>;
11
+ };
12
+ /**
13
+ * Checks whether EIP-7702 delegation to the Dynamic gasless contract is
14
+ * active for the given wallet on the given chain.
15
+ *
16
+ * Positive results are cached in the in-memory registry; missing entries
17
+ * fall back to an on-chain bytecode check (`eth_getCode`). The on-chain
18
+ * delegation marker is `DELEGATION_CODE_PREFIX + DELEGATION_CONTRACT_ADDRESS`.
19
+ */
20
+ export declare const is7702DelegationActive: ({ walletAddress }: Is7702DelegationActiveParams, { chainId, delegationRegistry, publicClient }: Is7702DelegationActiveDeps) => Promise<boolean>;
21
+ export {};
@@ -0,0 +1,28 @@
1
+ 'use client'
2
+ import { DELEGATION_CODE_PREFIX, DELEGATION_CONTRACT_ADDRESS } from '../constants.js';
3
+
4
+ /**
5
+ * Checks whether EIP-7702 delegation to the Dynamic gasless contract is
6
+ * active for the given wallet on the given chain.
7
+ *
8
+ * Positive results are cached in the in-memory registry; missing entries
9
+ * fall back to an on-chain bytecode check (`eth_getCode`). The on-chain
10
+ * delegation marker is `DELEGATION_CODE_PREFIX + DELEGATION_CONTRACT_ADDRESS`.
11
+ */
12
+ const is7702DelegationActive = async ({ walletAddress }, { chainId, delegationRegistry, publicClient }) => {
13
+ if (delegationRegistry.isDelegated({ chainId, walletAddress })) {
14
+ return true;
15
+ }
16
+ const bytecode = await publicClient.getCode({ address: walletAddress });
17
+ if (!bytecode) {
18
+ return false;
19
+ }
20
+ const expectedPrefix = DELEGATION_CODE_PREFIX + DELEGATION_CONTRACT_ADDRESS.slice(2).toLowerCase();
21
+ const isActive = bytecode.toLowerCase().startsWith(expectedPrefix);
22
+ if (isActive) {
23
+ delegationRegistry.markDelegated({ chainId, walletAddress });
24
+ }
25
+ return isActive;
26
+ };
27
+
28
+ export { is7702DelegationActive };
@@ -0,0 +1,14 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ /**
7
+ * Checks whether EVM gas sponsorship is enabled for the current project.
8
+ *
9
+ * Returns `false` when no project settings are available — callers can
10
+ * always treat the return value as a definitive boolean.
11
+ */
12
+ const isEthereumGasSponsorshipEnabled = ({ projectSettings, }) => projectSettings?.sdk.embeddedWallets?.evmGasSponsorshipEnabled ?? false;
13
+
14
+ exports.isEthereumGasSponsorshipEnabled = isEthereumGasSponsorshipEnabled;
@@ -0,0 +1,23 @@
1
+ type ProjectSettingsLike = {
2
+ sdk: {
3
+ embeddedWallets?: {
4
+ evmGasSponsorshipEnabled?: boolean;
5
+ };
6
+ };
7
+ };
8
+ type IsEthereumGasSponsorshipEnabledDeps = {
9
+ /**
10
+ * The project settings object resolved by the host (e.g. from the webview
11
+ * manifest or the React SDK's project store). When the settings object is
12
+ * unavailable, returns `false`.
13
+ */
14
+ projectSettings: ProjectSettingsLike | null | undefined;
15
+ };
16
+ /**
17
+ * Checks whether EVM gas sponsorship is enabled for the current project.
18
+ *
19
+ * Returns `false` when no project settings are available — callers can
20
+ * always treat the return value as a definitive boolean.
21
+ */
22
+ export declare const isEthereumGasSponsorshipEnabled: ({ projectSettings, }: IsEthereumGasSponsorshipEnabledDeps) => boolean;
23
+ export {};
@@ -0,0 +1,10 @@
1
+ 'use client'
2
+ /**
3
+ * Checks whether EVM gas sponsorship is enabled for the current project.
4
+ *
5
+ * Returns `false` when no project settings are available — callers can
6
+ * always treat the return value as a definitive boolean.
7
+ */
8
+ const isEthereumGasSponsorshipEnabled = ({ projectSettings, }) => projectSettings?.sdk.embeddedWallets?.evmGasSponsorshipEnabled ?? false;
9
+
10
+ export { isEthereumGasSponsorshipEnabled };
@@ -0,0 +1,58 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var constants = require('../constants.cjs');
7
+ var SponsorTransactionError = require('../errors/SponsorTransactionError/SponsorTransactionError.cjs');
8
+ var signSponsoredTransaction = require('../signSponsoredTransaction/signSponsoredTransaction.cjs');
9
+
10
+ const isSignedTransactionParams = (params) => 'signedTransaction' in params;
11
+ /**
12
+ * Relays a signed sponsored transaction to the Dynamic backend.
13
+ *
14
+ * Accepts either an already-signed payload from `signSponsoredTransaction`
15
+ * or unsigned calls (in which case signing is performed first). Returns the
16
+ * `requestId` the relay backend uses to identify the broadcast attempt — use
17
+ * this with `waitForSponsoredTransaction` to await on-chain inclusion.
18
+ */
19
+ const relaySponsoredTransaction = async (params, deps) => {
20
+ const signedTransaction = isSignedTransactionParams(params)
21
+ ? params.signedTransaction
22
+ : await signSponsoredTransaction.signSponsoredTransaction({
23
+ authorization: params.authorization,
24
+ autoDelegate: params.autoDelegate,
25
+ calls: params.calls,
26
+ validForSeconds: params.validForSeconds ?? constants.DEFAULT_VALID_FOR_SECONDS,
27
+ }, deps);
28
+ let data;
29
+ try {
30
+ data = await deps.sdkApi.sponsorEVMTransaction({
31
+ environmentId: deps.environmentId,
32
+ sponsorEVMTransactionRequest: {
33
+ authorization: signedTransaction.authorization,
34
+ calls: signedTransaction.calls.map((c) => ({
35
+ data: c.data,
36
+ target: c.target,
37
+ value: c.value.toString(),
38
+ })),
39
+ chainId: signedTransaction.chainId,
40
+ deadline: signedTransaction.deadline,
41
+ nonce: signedTransaction.nonce,
42
+ relayer: signedTransaction.relayer,
43
+ signature: signedTransaction.signature,
44
+ walletAddress: signedTransaction.walletAddress,
45
+ },
46
+ });
47
+ }
48
+ catch (error) {
49
+ const cause = error instanceof Error ? error : null;
50
+ throw new SponsorTransactionError.SponsorTransactionError(cause);
51
+ }
52
+ if (!data.requestId) {
53
+ throw new SponsorTransactionError.SponsorTransactionError();
54
+ }
55
+ return { requestId: data.requestId };
56
+ };
57
+
58
+ exports.relaySponsoredTransaction = relaySponsoredTransaction;
@@ -0,0 +1,29 @@
1
+ import type { SignAuthorizationReturnType } from 'viem/accounts';
2
+ import type { EvmGaslessChainDeps, SignedSponsoredTransaction, SponsoredTransactionCall } from '../types';
3
+ type RelayWithCallsParams = {
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. */
11
+ validForSeconds?: number;
12
+ };
13
+ type RelayWithSignedTxParams = {
14
+ /** A pre-signed sponsored transaction payload from `signSponsoredTransaction`. */
15
+ signedTransaction: SignedSponsoredTransaction;
16
+ };
17
+ type RelaySponsoredTransactionParams = RelayWithCallsParams | RelayWithSignedTxParams;
18
+ /**
19
+ * Relays a signed sponsored transaction to the Dynamic backend.
20
+ *
21
+ * Accepts either an already-signed payload from `signSponsoredTransaction`
22
+ * or unsigned calls (in which case signing is performed first). Returns the
23
+ * `requestId` the relay backend uses to identify the broadcast attempt — use
24
+ * this with `waitForSponsoredTransaction` to await on-chain inclusion.
25
+ */
26
+ export declare const relaySponsoredTransaction: (params: RelaySponsoredTransactionParams, deps: EvmGaslessChainDeps) => Promise<{
27
+ requestId: string;
28
+ }>;
29
+ export {};
@@ -0,0 +1,54 @@
1
+ 'use client'
2
+ import { DEFAULT_VALID_FOR_SECONDS } from '../constants.js';
3
+ import { SponsorTransactionError } from '../errors/SponsorTransactionError/SponsorTransactionError.js';
4
+ import { signSponsoredTransaction } from '../signSponsoredTransaction/signSponsoredTransaction.js';
5
+
6
+ const isSignedTransactionParams = (params) => 'signedTransaction' in params;
7
+ /**
8
+ * Relays a signed sponsored transaction to the Dynamic backend.
9
+ *
10
+ * Accepts either an already-signed payload from `signSponsoredTransaction`
11
+ * or unsigned calls (in which case signing is performed first). Returns the
12
+ * `requestId` the relay backend uses to identify the broadcast attempt — use
13
+ * this with `waitForSponsoredTransaction` to await on-chain inclusion.
14
+ */
15
+ const relaySponsoredTransaction = async (params, deps) => {
16
+ const signedTransaction = isSignedTransactionParams(params)
17
+ ? params.signedTransaction
18
+ : await signSponsoredTransaction({
19
+ authorization: params.authorization,
20
+ autoDelegate: params.autoDelegate,
21
+ calls: params.calls,
22
+ validForSeconds: params.validForSeconds ?? DEFAULT_VALID_FOR_SECONDS,
23
+ }, deps);
24
+ let data;
25
+ try {
26
+ data = await deps.sdkApi.sponsorEVMTransaction({
27
+ environmentId: deps.environmentId,
28
+ sponsorEVMTransactionRequest: {
29
+ authorization: signedTransaction.authorization,
30
+ calls: signedTransaction.calls.map((c) => ({
31
+ data: c.data,
32
+ target: c.target,
33
+ value: c.value.toString(),
34
+ })),
35
+ chainId: signedTransaction.chainId,
36
+ deadline: signedTransaction.deadline,
37
+ nonce: signedTransaction.nonce,
38
+ relayer: signedTransaction.relayer,
39
+ signature: signedTransaction.signature,
40
+ walletAddress: signedTransaction.walletAddress,
41
+ },
42
+ });
43
+ }
44
+ catch (error) {
45
+ const cause = error instanceof Error ? error : null;
46
+ throw new SponsorTransactionError(cause);
47
+ }
48
+ if (!data.requestId) {
49
+ throw new SponsorTransactionError();
50
+ }
51
+ return { requestId: data.requestId };
52
+ };
53
+
54
+ export { relaySponsoredTransaction };
@@ -0,0 +1,32 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var is7702DelegationActive = require('../is7702DelegationActive/is7702DelegationActive.cjs');
7
+ var sign7702Authorization = require('../sign7702Authorization/sign7702Authorization.cjs');
8
+
9
+ /**
10
+ * Resolves which EIP-7702 authorization (if any) to attach to a sponsored
11
+ * transaction.
12
+ *
13
+ * - If the caller pre-signed an authorization, it is returned as-is.
14
+ * - If `autoDelegate` is false, no authorization is attached.
15
+ * - Otherwise, queries the on-chain delegation state. If delegation is
16
+ * already active, no authorization is needed; if not, signs one.
17
+ */
18
+ const resolveAuthorization = async ({ authorization, autoDelegate, walletAddress }, deps) => {
19
+ if (authorization) {
20
+ return authorization;
21
+ }
22
+ if (!autoDelegate) {
23
+ return undefined;
24
+ }
25
+ const isDelegated = await is7702DelegationActive.is7702DelegationActive({ walletAddress }, deps);
26
+ if (isDelegated) {
27
+ return undefined;
28
+ }
29
+ return sign7702Authorization.sign7702Authorization({}, deps);
30
+ };
31
+
32
+ exports.resolveAuthorization = resolveAuthorization;
@@ -0,0 +1,27 @@
1
+ import type { Account, Chain, Hex, PublicClient, Transport, WalletClient } from 'viem';
2
+ import type { SignAuthorizationReturnType } from 'viem/accounts';
3
+ import type { Delegation7702Registry } from '../types';
4
+ type ResolveAuthorizationParams = {
5
+ /** Pre-signed authorization; when provided it is returned as-is. */
6
+ authorization?: SignAuthorizationReturnType;
7
+ /** When true and no authorization is provided, sign one if delegation is inactive. */
8
+ autoDelegate: boolean;
9
+ walletAddress: Hex;
10
+ };
11
+ type ResolveAuthorizationDeps = {
12
+ chainId: number;
13
+ delegationRegistry: Delegation7702Registry;
14
+ publicClient: PublicClient<Transport, Chain>;
15
+ walletClient: WalletClient<Transport, Chain, Account>;
16
+ };
17
+ /**
18
+ * Resolves which EIP-7702 authorization (if any) to attach to a sponsored
19
+ * transaction.
20
+ *
21
+ * - If the caller pre-signed an authorization, it is returned as-is.
22
+ * - If `autoDelegate` is false, no authorization is attached.
23
+ * - Otherwise, queries the on-chain delegation state. If delegation is
24
+ * already active, no authorization is needed; if not, signs one.
25
+ */
26
+ export declare const resolveAuthorization: ({ authorization, autoDelegate, walletAddress }: ResolveAuthorizationParams, deps: ResolveAuthorizationDeps) => Promise<SignAuthorizationReturnType | undefined>;
27
+ export {};
@@ -0,0 +1,28 @@
1
+ 'use client'
2
+ import { is7702DelegationActive } from '../is7702DelegationActive/is7702DelegationActive.js';
3
+ import { sign7702Authorization } from '../sign7702Authorization/sign7702Authorization.js';
4
+
5
+ /**
6
+ * Resolves which EIP-7702 authorization (if any) to attach to a sponsored
7
+ * transaction.
8
+ *
9
+ * - If the caller pre-signed an authorization, it is returned as-is.
10
+ * - If `autoDelegate` is false, no authorization is attached.
11
+ * - Otherwise, queries the on-chain delegation state. If delegation is
12
+ * already active, no authorization is needed; if not, signs one.
13
+ */
14
+ const resolveAuthorization = async ({ authorization, autoDelegate, walletAddress }, deps) => {
15
+ if (authorization) {
16
+ return authorization;
17
+ }
18
+ if (!autoDelegate) {
19
+ return undefined;
20
+ }
21
+ const isDelegated = await is7702DelegationActive({ walletAddress }, deps);
22
+ if (isDelegated) {
23
+ return undefined;
24
+ }
25
+ return sign7702Authorization({}, deps);
26
+ };
27
+
28
+ export { resolveAuthorization };
@@ -0,0 +1,12 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ /**
7
+ * Resolves a chain ID from either an explicit override or the chain ID
8
+ * configured in the gasless chain deps.
9
+ */
10
+ const resolveChainId = ({ chainId }, { chainId: depsChainId }) => chainId ?? depsChainId;
11
+
12
+ exports.resolveChainId = resolveChainId;
@@ -0,0 +1,11 @@
1
+ import type { EvmGaslessChainDeps } from '../types';
2
+ type ResolveChainIdParams = {
3
+ /** Optional override; when set the deps' chainId is ignored. */
4
+ chainId?: number;
5
+ };
6
+ /**
7
+ * Resolves a chain ID from either an explicit override or the chain ID
8
+ * configured in the gasless chain deps.
9
+ */
10
+ export declare const resolveChainId: ({ chainId }: ResolveChainIdParams, { chainId: depsChainId }: Pick<EvmGaslessChainDeps, 'chainId'>) => number;
11
+ export {};