diff --git a/packages/thirdweb/scripts/generate/abis/erc7702/MinimalAccount.json b/packages/thirdweb/scripts/generate/abis/erc7702/MinimalAccount.json index fceb4dc2d0b..7065f761222 100644 --- a/packages/thirdweb/scripts/generate/abis/erc7702/MinimalAccount.json +++ b/packages/thirdweb/scripts/generate/abis/erc7702/MinimalAccount.json @@ -1,7 +1,6 @@ [ "error AllowanceExceeded(uint256 allowanceUsage, uint256 limit, uint64 period)", "error CallPolicyViolated(address target, bytes4 selector)", - "error CallReverted()", "error ConditionFailed(bytes32 param, bytes32 refValue, uint8 condition)", "error InvalidDataLength(uint256 actualLength, uint256 expectedLength)", "error InvalidSignature(address msgSender, address thisAddress)", @@ -13,8 +12,9 @@ "error SessionZeroSigner()", "error TransferPolicyViolated(address target)", "error UIDAlreadyProcessed()", - "event Executed(address indexed to, uint256 value, bytes data)", - "event SessionCreated(address indexed signer, (address signer, bool isWildcard, uint256 expiresAt, (address target, bytes4 selector, uint256 maxValuePerUse, (uint8 limitType, uint256 limit, uint256 period) valueLimit, (uint8 condition, uint64 index, bytes32 refValue, (uint8 limitType, uint256 limit, uint256 period) limit)[] constraints)[] callPolicies, (address target, uint256 maxValuePerUse, (uint8 limitType, uint256 limit, uint256 period) valueLimit)[] transferPolicies, bytes32 uid) sessionSpec)", + "event Executed(address indexed user, address indexed signer, address indexed executor, uint256 batchSize)", + "event SessionCreated(address indexed user, address indexed newSigner, (address signer, bool isWildcard, uint256 expiresAt, (address target, bytes4 selector, uint256 maxValuePerUse, (uint8 limitType, uint256 limit, uint256 period) valueLimit, (uint8 condition, uint64 index, bytes32 refValue, (uint8 limitType, uint256 limit, uint256 period) limit)[] constraints)[] callPolicies, (address target, uint256 maxValuePerUse, (uint8 limitType, uint256 limit, uint256 period) valueLimit)[] transferPolicies, bytes32 uid) sessionSpec)", + "event ValueReceived(address indexed user, address indexed from, uint256 value)", "function createSessionWithSig((address signer, bool isWildcard, uint256 expiresAt, (address target, bytes4 selector, uint256 maxValuePerUse, (uint8 limitType, uint256 limit, uint256 period) valueLimit, (uint8 condition, uint64 index, bytes32 refValue, (uint8 limitType, uint256 limit, uint256 period) limit)[] constraints)[] callPolicies, (address target, uint256 maxValuePerUse, (uint8 limitType, uint256 limit, uint256 period) valueLimit)[] transferPolicies, bytes32 uid) sessionSpec, bytes signature)", "function eip712Domain() view returns (bytes1 fields, string name, string version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] extensions)", "function execute((address target, uint256 value, bytes data)[] calls) payable", @@ -23,5 +23,10 @@ "function getSessionExpirationForSigner(address signer) view returns (uint256)", "function getSessionStateForSigner(address signer) view returns (((uint256 remaining, address target, bytes4 selector, uint256 index)[] transferValue, (uint256 remaining, address target, bytes4 selector, uint256 index)[] callValue, (uint256 remaining, address target, bytes4 selector, uint256 index)[] callParams))", "function getTransferPoliciesForSigner(address signer) view returns ((address target, uint256 maxValuePerUse, (uint8 limitType, uint256 limit, uint256 period) valueLimit)[])", - "function isWildcardSigner(address signer) view returns (bool)" + "function isWildcardSigner(address signer) view returns (bool)", + "function onERC1155BatchReceived(address, address, uint256[], uint256[], bytes) returns (bytes4)", + "function onERC1155Received(address, address, uint256, uint256, bytes) returns (bytes4)", + "function onERC721Received(address, address, uint256, bytes) returns (bytes4)", + "function supportsInterface(bytes4 interfaceId) view returns (bool)", + "receive() external payable" ] \ No newline at end of file diff --git a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/events/Executed.ts b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/events/Executed.ts index de30c93be7e..69308a02535 100644 --- a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/events/Executed.ts +++ b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/events/Executed.ts @@ -5,9 +5,19 @@ import { prepareEvent } from "../../../../../event/prepare-event.js"; * Represents the filters for the "Executed" event. */ export type ExecutedEventFilters = Partial<{ - to: AbiParameterToPrimitiveType<{ + user: AbiParameterToPrimitiveType<{ type: "address"; - name: "to"; + name: "user"; + indexed: true; + }>; + signer: AbiParameterToPrimitiveType<{ + type: "address"; + name: "signer"; + indexed: true; + }>; + executor: AbiParameterToPrimitiveType<{ + type: "address"; + name: "executor"; indexed: true; }>; }>; @@ -26,7 +36,9 @@ export type ExecutedEventFilters = Partial<{ * contract, * events: [ * executedEvent({ - * to: ..., + * user: ..., + * signer: ..., + * executor: ..., * }) * ], * }); @@ -34,7 +46,8 @@ export type ExecutedEventFilters = Partial<{ */ export function executedEvent(filters: ExecutedEventFilters = {}) { return prepareEvent({ + signature: + "event Executed(address indexed user, address indexed signer, address indexed executor, uint256 batchSize)", filters, - signature: "event Executed(address indexed to, uint256 value, bytes data)", }); } diff --git a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/events/SessionCreated.ts b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/events/SessionCreated.ts index 6851748f9d1..f03fedded14 100644 --- a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/events/SessionCreated.ts +++ b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/events/SessionCreated.ts @@ -5,9 +5,14 @@ import { prepareEvent } from "../../../../../event/prepare-event.js"; * Represents the filters for the "SessionCreated" event. */ export type SessionCreatedEventFilters = Partial<{ - signer: AbiParameterToPrimitiveType<{ + user: AbiParameterToPrimitiveType<{ type: "address"; - name: "signer"; + name: "user"; + indexed: true; + }>; + newSigner: AbiParameterToPrimitiveType<{ + type: "address"; + name: "newSigner"; indexed: true; }>; }>; @@ -26,7 +31,8 @@ export type SessionCreatedEventFilters = Partial<{ * contract, * events: [ * sessionCreatedEvent({ - * signer: ..., + * user: ..., + * newSigner: ..., * }) * ], * }); @@ -34,8 +40,8 @@ export type SessionCreatedEventFilters = Partial<{ */ export function sessionCreatedEvent(filters: SessionCreatedEventFilters = {}) { return prepareEvent({ - filters, signature: - "event SessionCreated(address indexed signer, (address signer, bool isWildcard, uint256 expiresAt, (address target, bytes4 selector, uint256 maxValuePerUse, (uint8 limitType, uint256 limit, uint256 period) valueLimit, (uint8 condition, uint64 index, bytes32 refValue, (uint8 limitType, uint256 limit, uint256 period) limit)[] constraints)[] callPolicies, (address target, uint256 maxValuePerUse, (uint8 limitType, uint256 limit, uint256 period) valueLimit)[] transferPolicies, bytes32 uid) sessionSpec)", + "event SessionCreated(address indexed user, address indexed newSigner, (address signer, bool isWildcard, uint256 expiresAt, (address target, bytes4 selector, uint256 maxValuePerUse, (uint8 limitType, uint256 limit, uint256 period) valueLimit, (uint8 condition, uint64 index, bytes32 refValue, (uint8 limitType, uint256 limit, uint256 period) limit)[] constraints)[] callPolicies, (address target, uint256 maxValuePerUse, (uint8 limitType, uint256 limit, uint256 period) valueLimit)[] transferPolicies, bytes32 uid) sessionSpec)", + filters, }); } diff --git a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/events/ValueReceived.ts b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/events/ValueReceived.ts new file mode 100644 index 00000000000..4c1e85c80b9 --- /dev/null +++ b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/events/ValueReceived.ts @@ -0,0 +1,47 @@ +import type { AbiParameterToPrimitiveType } from "abitype"; +import { prepareEvent } from "../../../../../event/prepare-event.js"; + +/** + * Represents the filters for the "ValueReceived" event. + */ +export type ValueReceivedEventFilters = Partial<{ + user: AbiParameterToPrimitiveType<{ + type: "address"; + name: "user"; + indexed: true; + }>; + from: AbiParameterToPrimitiveType<{ + type: "address"; + name: "from"; + indexed: true; + }>; +}>; + +/** + * Creates an event object for the ValueReceived event. + * @param filters - Optional filters to apply to the event. + * @returns The prepared event object. + * @extension ERC7702 + * @example + * ```ts + * import { getContractEvents } from "thirdweb"; + * import { valueReceivedEvent } from "thirdweb/extensions/erc7702"; + * + * const events = await getContractEvents({ + * contract, + * events: [ + * valueReceivedEvent({ + * user: ..., + * from: ..., + * }) + * ], + * }); + * ``` + */ +export function valueReceivedEvent(filters: ValueReceivedEventFilters = {}) { + return prepareEvent({ + signature: + "event ValueReceived(address indexed user, address indexed from, uint256 value)", + filters, + }); +} diff --git a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/eip712Domain.ts b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/eip712Domain.ts index 95be7b27e5a..9ed2c26e1bf 100644 --- a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/eip712Domain.ts +++ b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/eip712Domain.ts @@ -8,32 +8,32 @@ export const FN_SELECTOR = "0x84b0196e" as const; const FN_INPUTS = [] as const; const FN_OUTPUTS = [ { - name: "fields", type: "bytes1", + name: "fields", }, { - name: "name", type: "string", + name: "name", }, { - name: "version", type: "string", + name: "version", }, { - name: "chainId", type: "uint256", + name: "chainId", }, { - name: "verifyingContract", type: "address", + name: "verifyingContract", }, { - name: "salt", type: "bytes32", + name: "salt", }, { - name: "extensions", type: "uint256[]", + name: "extensions", }, ] as const; diff --git a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getCallPoliciesForSigner.ts b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getCallPoliciesForSigner.ts index e5680d5fe09..4a44f5a3fd1 100644 --- a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getCallPoliciesForSigner.ts +++ b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getCallPoliciesForSigner.ts @@ -16,81 +16,81 @@ export type GetCallPoliciesForSignerParams = { export const FN_SELECTOR = "0x7103acbb" as const; const FN_INPUTS = [ { - name: "signer", type: "address", + name: "signer", }, ] as const; const FN_OUTPUTS = [ { + type: "tuple[]", components: [ { - name: "target", type: "address", + name: "target", }, { - name: "selector", type: "bytes4", + name: "selector", }, { - name: "maxValuePerUse", type: "uint256", + name: "maxValuePerUse", }, { + type: "tuple", + name: "valueLimit", components: [ { - name: "limitType", type: "uint8", + name: "limitType", }, { - name: "limit", type: "uint256", + name: "limit", }, { - name: "period", type: "uint256", + name: "period", }, ], - name: "valueLimit", - type: "tuple", }, { + type: "tuple[]", + name: "constraints", components: [ { - name: "condition", type: "uint8", + name: "condition", }, { - name: "index", type: "uint64", + name: "index", }, { - name: "refValue", type: "bytes32", + name: "refValue", }, { + type: "tuple", + name: "limit", components: [ { - name: "limitType", type: "uint8", + name: "limitType", }, { - name: "limit", type: "uint256", + name: "limit", }, { - name: "period", type: "uint256", + name: "period", }, ], - name: "limit", - type: "tuple", }, ], - name: "constraints", - type: "tuple[]", }, ], - type: "tuple[]", }, ] as const; diff --git a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getSessionExpirationForSigner.ts b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getSessionExpirationForSigner.ts index de9198c6317..a5a81370ba3 100644 --- a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getSessionExpirationForSigner.ts +++ b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getSessionExpirationForSigner.ts @@ -16,8 +16,8 @@ export type GetSessionExpirationForSignerParams = { export const FN_SELECTOR = "0xf0a83adf" as const; const FN_INPUTS = [ { - name: "signer", type: "address", + name: "signer", }, ] as const; const FN_OUTPUTS = [ diff --git a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getSessionStateForSigner.ts b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getSessionStateForSigner.ts index 190f7ace4ba..3e948ef623e 100644 --- a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getSessionStateForSigner.ts +++ b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getSessionStateForSigner.ts @@ -16,81 +16,81 @@ export type GetSessionStateForSignerParams = { export const FN_SELECTOR = "0x74e25eb2" as const; const FN_INPUTS = [ { - name: "signer", type: "address", + name: "signer", }, ] as const; const FN_OUTPUTS = [ { + type: "tuple", components: [ { + type: "tuple[]", + name: "transferValue", components: [ { - name: "remaining", type: "uint256", + name: "remaining", }, { - name: "target", type: "address", + name: "target", }, { - name: "selector", type: "bytes4", + name: "selector", }, { - name: "index", type: "uint256", + name: "index", }, ], - name: "transferValue", - type: "tuple[]", }, { + type: "tuple[]", + name: "callValue", components: [ { - name: "remaining", type: "uint256", + name: "remaining", }, { - name: "target", type: "address", + name: "target", }, { - name: "selector", type: "bytes4", + name: "selector", }, { - name: "index", type: "uint256", + name: "index", }, ], - name: "callValue", - type: "tuple[]", }, { + type: "tuple[]", + name: "callParams", components: [ { - name: "remaining", type: "uint256", + name: "remaining", }, { - name: "target", type: "address", + name: "target", }, { - name: "selector", type: "bytes4", + name: "selector", }, { - name: "index", type: "uint256", + name: "index", }, ], - name: "callParams", - type: "tuple[]", }, ], - type: "tuple", }, ] as const; diff --git a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getTransferPoliciesForSigner.ts b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getTransferPoliciesForSigner.ts index e08786479ca..a97dfb80636 100644 --- a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getTransferPoliciesForSigner.ts +++ b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/getTransferPoliciesForSigner.ts @@ -16,41 +16,41 @@ export type GetTransferPoliciesForSignerParams = { export const FN_SELECTOR = "0xed6ed279" as const; const FN_INPUTS = [ { - name: "signer", type: "address", + name: "signer", }, ] as const; const FN_OUTPUTS = [ { + type: "tuple[]", components: [ { - name: "target", type: "address", + name: "target", }, { - name: "maxValuePerUse", type: "uint256", + name: "maxValuePerUse", }, { + type: "tuple", + name: "valueLimit", components: [ { - name: "limitType", type: "uint8", + name: "limitType", }, { - name: "limit", type: "uint256", + name: "limit", }, { - name: "period", type: "uint256", + name: "period", }, ], - name: "valueLimit", - type: "tuple", }, ], - type: "tuple[]", }, ] as const; diff --git a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/isWildcardSigner.ts b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/isWildcardSigner.ts index 880b985ffdd..f653921de04 100644 --- a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/isWildcardSigner.ts +++ b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/read/isWildcardSigner.ts @@ -16,8 +16,8 @@ export type IsWildcardSignerParams = { export const FN_SELECTOR = "0x16c258a7" as const; const FN_INPUTS = [ { - name: "signer", type: "address", + name: "signer", }, ] as const; const FN_OUTPUTS = [ diff --git a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/write/createSessionWithSig.ts b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/write/createSessionWithSig.ts index e4b50d9a004..fc57af91cb6 100644 --- a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/write/createSessionWithSig.ts +++ b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/write/createSessionWithSig.ts @@ -81,134 +81,134 @@ export type CreateSessionWithSigParams = WithOverrides<{ export const FN_SELECTOR = "0xb5051648" as const; const FN_INPUTS = [ { + type: "tuple", + name: "sessionSpec", components: [ { - name: "signer", type: "address", + name: "signer", }, { - name: "isWildcard", type: "bool", + name: "isWildcard", }, { - name: "expiresAt", type: "uint256", + name: "expiresAt", }, { + type: "tuple[]", + name: "callPolicies", components: [ { - name: "target", type: "address", + name: "target", }, { - name: "selector", type: "bytes4", + name: "selector", }, { - name: "maxValuePerUse", type: "uint256", + name: "maxValuePerUse", }, { + type: "tuple", + name: "valueLimit", components: [ { - name: "limitType", type: "uint8", + name: "limitType", }, { - name: "limit", type: "uint256", + name: "limit", }, { - name: "period", type: "uint256", + name: "period", }, ], - name: "valueLimit", - type: "tuple", }, { + type: "tuple[]", + name: "constraints", components: [ { - name: "condition", type: "uint8", + name: "condition", }, { - name: "index", type: "uint64", + name: "index", }, { - name: "refValue", type: "bytes32", + name: "refValue", }, { + type: "tuple", + name: "limit", components: [ { - name: "limitType", type: "uint8", + name: "limitType", }, { - name: "limit", type: "uint256", + name: "limit", }, { - name: "period", type: "uint256", + name: "period", }, ], - name: "limit", - type: "tuple", }, ], - name: "constraints", - type: "tuple[]", }, ], - name: "callPolicies", - type: "tuple[]", }, { + type: "tuple[]", + name: "transferPolicies", components: [ { - name: "target", type: "address", + name: "target", }, { - name: "maxValuePerUse", type: "uint256", + name: "maxValuePerUse", }, { + type: "tuple", + name: "valueLimit", components: [ { - name: "limitType", type: "uint8", + name: "limitType", }, { - name: "limit", type: "uint256", + name: "limit", }, { - name: "period", type: "uint256", + name: "period", }, ], - name: "valueLimit", - type: "tuple", }, ], - name: "transferPolicies", - type: "tuple[]", }, { - name: "uid", type: "bytes32", + name: "uid", }, ], - name: "sessionSpec", - type: "tuple", }, { - name: "signature", type: "bytes", + name: "signature", }, ] as const; const FN_OUTPUTS = [] as const; @@ -316,23 +316,23 @@ export function createSessionWithSig( }); return prepareContractCall({ - accessList: async () => (await asyncOptions()).overrides?.accessList, - authorizationList: async () => - (await asyncOptions()).overrides?.authorizationList, contract: options.contract, - erc20Value: async () => (await asyncOptions()).overrides?.erc20Value, - extraGas: async () => (await asyncOptions()).overrides?.extraGas, - gas: async () => (await asyncOptions()).overrides?.gas, - gasPrice: async () => (await asyncOptions()).overrides?.gasPrice, - maxFeePerGas: async () => (await asyncOptions()).overrides?.maxFeePerGas, - maxPriorityFeePerGas: async () => - (await asyncOptions()).overrides?.maxPriorityFeePerGas, method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const, - nonce: async () => (await asyncOptions()).overrides?.nonce, params: async () => { const resolvedOptions = await asyncOptions(); return [resolvedOptions.sessionSpec, resolvedOptions.signature] as const; }, value: async () => (await asyncOptions()).overrides?.value, + accessList: async () => (await asyncOptions()).overrides?.accessList, + gas: async () => (await asyncOptions()).overrides?.gas, + gasPrice: async () => (await asyncOptions()).overrides?.gasPrice, + maxFeePerGas: async () => (await asyncOptions()).overrides?.maxFeePerGas, + maxPriorityFeePerGas: async () => + (await asyncOptions()).overrides?.maxPriorityFeePerGas, + nonce: async () => (await asyncOptions()).overrides?.nonce, + extraGas: async () => (await asyncOptions()).overrides?.extraGas, + erc20Value: async () => (await asyncOptions()).overrides?.erc20Value, + authorizationList: async () => + (await asyncOptions()).overrides?.authorizationList, }); } diff --git a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/write/execute.ts b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/write/execute.ts index e3e0a0ad402..98988776faa 100644 --- a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/write/execute.ts +++ b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/write/execute.ts @@ -26,22 +26,22 @@ export type ExecuteParams = WithOverrides<{ export const FN_SELECTOR = "0x3f707e6b" as const; const FN_INPUTS = [ { + type: "tuple[]", + name: "calls", components: [ { - name: "target", type: "address", + name: "target", }, { - name: "value", type: "uint256", + name: "value", }, { - name: "data", type: "bytes", + name: "data", }, ], - name: "calls", - type: "tuple[]", }, ] as const; const FN_OUTPUTS = [] as const; @@ -137,23 +137,23 @@ export function execute( }); return prepareContractCall({ - accessList: async () => (await asyncOptions()).overrides?.accessList, - authorizationList: async () => - (await asyncOptions()).overrides?.authorizationList, contract: options.contract, - erc20Value: async () => (await asyncOptions()).overrides?.erc20Value, - extraGas: async () => (await asyncOptions()).overrides?.extraGas, - gas: async () => (await asyncOptions()).overrides?.gas, - gasPrice: async () => (await asyncOptions()).overrides?.gasPrice, - maxFeePerGas: async () => (await asyncOptions()).overrides?.maxFeePerGas, - maxPriorityFeePerGas: async () => - (await asyncOptions()).overrides?.maxPriorityFeePerGas, method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const, - nonce: async () => (await asyncOptions()).overrides?.nonce, params: async () => { const resolvedOptions = await asyncOptions(); return [resolvedOptions.calls] as const; }, value: async () => (await asyncOptions()).overrides?.value, + accessList: async () => (await asyncOptions()).overrides?.accessList, + gas: async () => (await asyncOptions()).overrides?.gas, + gasPrice: async () => (await asyncOptions()).overrides?.gasPrice, + maxFeePerGas: async () => (await asyncOptions()).overrides?.maxFeePerGas, + maxPriorityFeePerGas: async () => + (await asyncOptions()).overrides?.maxPriorityFeePerGas, + nonce: async () => (await asyncOptions()).overrides?.nonce, + extraGas: async () => (await asyncOptions()).overrides?.extraGas, + erc20Value: async () => (await asyncOptions()).overrides?.erc20Value, + authorizationList: async () => + (await asyncOptions()).overrides?.authorizationList, }); } diff --git a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/write/executeWithSig.ts b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/write/executeWithSig.ts index b70e69ad6cd..92ecb549276 100644 --- a/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/write/executeWithSig.ts +++ b/packages/thirdweb/src/extensions/erc7702/__generated__/MinimalAccount/write/executeWithSig.ts @@ -34,36 +34,36 @@ export type ExecuteWithSigParams = WithOverrides<{ export const FN_SELECTOR = "0xba61557d" as const; const FN_INPUTS = [ { + type: "tuple", + name: "wrappedCalls", components: [ { + type: "tuple[]", + name: "calls", components: [ { - name: "target", type: "address", + name: "target", }, { - name: "value", type: "uint256", + name: "value", }, { - name: "data", type: "bytes", + name: "data", }, ], - name: "calls", - type: "tuple[]", }, { - name: "uid", type: "bytes32", + name: "uid", }, ], - name: "wrappedCalls", - type: "tuple", }, { - name: "signature", type: "bytes", + name: "signature", }, ] as const; const FN_OUTPUTS = [] as const; @@ -167,23 +167,23 @@ export function executeWithSig( }); return prepareContractCall({ - accessList: async () => (await asyncOptions()).overrides?.accessList, - authorizationList: async () => - (await asyncOptions()).overrides?.authorizationList, contract: options.contract, - erc20Value: async () => (await asyncOptions()).overrides?.erc20Value, - extraGas: async () => (await asyncOptions()).overrides?.extraGas, - gas: async () => (await asyncOptions()).overrides?.gas, - gasPrice: async () => (await asyncOptions()).overrides?.gasPrice, - maxFeePerGas: async () => (await asyncOptions()).overrides?.maxFeePerGas, - maxPriorityFeePerGas: async () => - (await asyncOptions()).overrides?.maxPriorityFeePerGas, method: [FN_SELECTOR, FN_INPUTS, FN_OUTPUTS] as const, - nonce: async () => (await asyncOptions()).overrides?.nonce, params: async () => { const resolvedOptions = await asyncOptions(); return [resolvedOptions.wrappedCalls, resolvedOptions.signature] as const; }, value: async () => (await asyncOptions()).overrides?.value, + accessList: async () => (await asyncOptions()).overrides?.accessList, + gas: async () => (await asyncOptions()).overrides?.gas, + gasPrice: async () => (await asyncOptions()).overrides?.gasPrice, + maxFeePerGas: async () => (await asyncOptions()).overrides?.maxFeePerGas, + maxPriorityFeePerGas: async () => + (await asyncOptions()).overrides?.maxPriorityFeePerGas, + nonce: async () => (await asyncOptions()).overrides?.nonce, + extraGas: async () => (await asyncOptions()).overrides?.extraGas, + erc20Value: async () => (await asyncOptions()).overrides?.erc20Value, + authorizationList: async () => + (await asyncOptions()).overrides?.authorizationList, }); } diff --git a/packages/thirdweb/src/extensions/erc7702/account/sessionkey.test.ts b/packages/thirdweb/src/extensions/erc7702/account/sessionkey.test.ts index 156fcc8ee6c..bd3ced88c2f 100644 --- a/packages/thirdweb/src/extensions/erc7702/account/sessionkey.test.ts +++ b/packages/thirdweb/src/extensions/erc7702/account/sessionkey.test.ts @@ -75,7 +75,7 @@ describe.runIf(process.env.TW_SECRET_KEY)( events: [sessionCreatedEvent()], logs: receipt.logs, }); - expect(logs[0]?.args.signer).toBe(TEST_ACCOUNT_A.address); + expect(logs[0]?.args.newSigner).toBe(TEST_ACCOUNT_A.address); }); it("should allow adding granular session keys", async () => { @@ -124,9 +124,7 @@ describe.runIf(process.env.TW_SECRET_KEY)( events: [sessionCreatedEvent()], logs: receipt.logs, }); - expect(logs[0]?.args.signer).toBe(TEST_ACCOUNT_A.address); - expect(logs[0]?.args.sessionSpec.callPolicies).toHaveLength(1); - expect(logs[0]?.args.sessionSpec.transferPolicies).toHaveLength(1); + expect(logs[0]?.args.newSigner).toBe(TEST_ACCOUNT_A.address); }); }, ); diff --git a/packages/thirdweb/src/wallets/in-app/core/eip7702/minimal-account.ts b/packages/thirdweb/src/wallets/in-app/core/eip7702/minimal-account.ts index 4cbabd58815..ca62053497e 100644 --- a/packages/thirdweb/src/wallets/in-app/core/eip7702/minimal-account.ts +++ b/packages/thirdweb/src/wallets/in-app/core/eip7702/minimal-account.ts @@ -14,6 +14,9 @@ import type { SignedAuthorization } from "../../../../transaction/actions/eip770 import { toSerializableTransaction } from "../../../../transaction/actions/to-serializable-transaction.js"; import type { SendTransactionResult } from "../../../../transaction/types.js"; import { getAddress } from "../../../../utils/address.js"; +import { getClientFetch } from "../../../../utils/fetch.js"; +import { stringify } from "../../../../utils/json.js"; +import { withCache } from "../../../../utils/promise/withCache.js"; import { randomBytesHex } from "../../../../utils/random.js"; import type { Account, @@ -23,10 +26,75 @@ import { executeWithSignature, getQueuedTransactionHash, } from "../../../smart/lib/bundler.js"; +import { getDefaultBundlerUrl } from "../../../smart/lib/constants.js"; import type { BundlerOptions } from "../../../smart/types.js"; -const MINIMAL_ACCOUNT_IMPLEMENTATION_ADDRESS = - "0xD6999651Fc0964B9c6B444307a0ab20534a66560"; +interface DelegationContractResponse { + id: string; + jsonrpc: string; + result: { + delegationContract: string; + }; +} + +/** + * Fetches the delegation contract address from the bundler using the tw_getDelegationContract RPC method + * @internal + */ +async function getDelegationContractAddress(args: { + client: ThirdwebClient; + chain: Chain; + bundlerUrl?: string; +}): Promise { + const { client, chain, bundlerUrl } = args; + const url = bundlerUrl ?? getDefaultBundlerUrl(chain); + + // Create a cache key based on the bundler URL to ensure we cache per chain/bundler + const cacheKey = `delegation-contract:${url}`; + + return withCache( + async () => { + const fetchWithHeaders = getClientFetch(client); + + const response = await fetchWithHeaders(url, { + useAuthToken: true, + body: stringify({ + id: 1, + jsonrpc: "2.0", + method: "tw_getDelegationContract", + params: [], + }), + headers: { + "Content-Type": "application/json", + }, + method: "POST", + }); + + if (!response.ok) { + throw new Error( + `Failed to fetch delegation contract: ${response.status} ${response.statusText}`, + ); + } + + const result: DelegationContractResponse = await response.json(); + + if ((result as any).error) { + throw new Error( + `Delegation contract RPC error: ${JSON.stringify((result as any).error)}`, + ); + } + + if (!result.result?.delegationContract) { + throw new Error( + "Invalid response: missing delegationContract in result", + ); + } + + return result.result.delegationContract; + }, + { cacheKey, cacheTime: 24 * 60 * 60 * 1000 }, // cache for 24 hours + ); +} export const create7702MinimalAccount = (args: { client: ThirdwebClient; @@ -49,7 +117,14 @@ export const create7702MinimalAccount = (args: { }); // check if account has been delegated already let authorization: SignedAuthorization | undefined; - const isMinimalAccount = await is7702MinimalAccount(eoaContract); + const delegationContractAddress = await getDelegationContractAddress({ + client, + chain, + }); + const isMinimalAccount = await is7702MinimalAccount( + eoaContract, + delegationContractAddress, + ); if (!isMinimalAccount) { // if not, sign authorization let nonce = firstTx.nonce @@ -58,12 +133,12 @@ export const create7702MinimalAccount = (args: { await getNonce({ client, address: adminAccount.address, - chain: getCachedChain(firstTx.chainId), + chain, }), ); nonce += sponsorGas ? 0n : 1n; const auth = await adminAccount.signAuthorization?.({ - address: MINIMAL_ACCOUNT_IMPLEMENTATION_ADDRESS, + address: getAddress(delegationContractAddress), chainId: firstTx.chainId, nonce, }); @@ -76,7 +151,7 @@ export const create7702MinimalAccount = (args: { // send transaction from executor, needs signature const wrappedCalls = { calls: txs.map((tx) => ({ - data: tx.data ?? "0x", // will throw if undefined address + data: tx.data ?? "0x", target: getAddress(tx.to ?? ""), value: tx.value ?? 0n, })), @@ -131,7 +206,7 @@ export const create7702MinimalAccount = (args: { const executeTx = execute({ calls: txs.map((tx) => ({ data: tx.data ?? "0x", - target: tx.to ?? "", + target: getAddress(tx.to ?? ""), value: tx.value ?? 0n, })), contract: eoaContract, @@ -228,7 +303,7 @@ async function getNonce(args: { "../../../../rpc/actions/eth_getTransactionCount.js" ).then(({ eth_getTransactionCount }) => eth_getTransactionCount(rpcRequest, { - address, + address: getAddress(address), blockTag: "pending", }), ); @@ -238,14 +313,14 @@ async function getNonce(args: { async function is7702MinimalAccount( // biome-ignore lint/suspicious/noExplicitAny: TODO properly type tw contract eoaContract: ThirdwebContract, + delegationContractAddress: string, ): Promise { const code = await getBytecode(eoaContract); const isDelegated = code.length > 0 && code.startsWith("0xef0100"); const target = `0x${code.slice(8, 48)}`; return ( isDelegated && - target.toLowerCase() === - MINIMAL_ACCOUNT_IMPLEMENTATION_ADDRESS.toLowerCase() + target.toLowerCase() === delegationContractAddress.toLowerCase() ); } diff --git a/packages/thirdweb/src/wallets/in-app/web/lib/in-app-integration.test.ts b/packages/thirdweb/src/wallets/in-app/web/lib/in-app-integration.test.ts index 7a80eab6507..5112e9741ca 100644 --- a/packages/thirdweb/src/wallets/in-app/web/lib/in-app-integration.test.ts +++ b/packages/thirdweb/src/wallets/in-app/web/lib/in-app-integration.test.ts @@ -73,8 +73,7 @@ describe.runIf(process.env.TW_SECRET_KEY)( if (!executedLog) { throw new Error("No executed log found"); } - expect(executedLog.args.to).toBe(account.address); - expect(executedLog.args.value).toBe(0n); + expect(executedLog.args.user).toBe(account.address); }); it("should sponsor gas for a 4337 smart account", async () => {