Skip to content

Commit 6af673b

Browse files
authored
feat: add auxiliaryFunds + requiredAssets support to eip5792-middleware (#6623)
## Explanation This PR integrates the `auxiliaryFunds` and `requiredAssets` capabilities defined under [ERC-7682](https://eips.ethereum.org/EIPS/eip-7682) to enable auxiliary funds flows and improve capability consistency across clients. <!-- Thanks for your contribution! Take a moment to answer these questions so that reviewers have the information they need to properly understand your changes: * What is the current state of things and why does it need to change? * What is the solution your changes offer and how does it work? * Are there any changes whose purpose might not obvious to those unfamiliar with the domain? * If your primary goal was to update one package but you found you had to update another one along the way, why did you do so? * If you had to upgrade a dependency, why did you do so? --> ## References <!-- Are there any issues that this pull request is tied to? Are there other links that reviewers should consult to understand these changes better? Are there client or consumer pull requests to adopt any breaking changes? For example: * Fixes #12345 * Related to #67890 --> * Fixes https://consensyssoftware.atlassian.net/browse/WAPI-409 ## Checklist - [x] I've updated the test suite for new or updated code as appropriate - [x] I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate - [x] I've communicated my changes to consumers by [updating changelogs for packages I've changed](https://github.com/MetaMask/core/tree/main/docs/contributing.md#updating-changelogs), highlighting breaking changes as necessary - [x] I've prepared draft pull requests for clients and consumer packages to resolve any breaking changes
1 parent 024efbe commit 6af673b

File tree

9 files changed

+519
-13
lines changed

9 files changed

+519
-13
lines changed

packages/eip-5792-middleware/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Changed
1111

12+
- Add `auxiliaryFunds` + `requiredAssets` support defined under [ERC-7682](https://eips.ethereum.org/EIPS/eip-7682) ([#6623](https://github.com/MetaMask/core/pull/6623))
1213
- Bump `@metamask/transaction-controller` from `^60.2.0` to `^60.4.0` ([#6561](https://github.com/MetaMask/core/pull/6561), [#6641](https://github.com/MetaMask/core/pull/6641))
1314
- Bump `@metamask/utils` from `^11.4.2` to `^11.8.0` ([#6588](https://github.com/MetaMask/core/pull/6588))
1415

packages/eip-5792-middleware/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"@metamask/superstruct": "^3.1.0",
5252
"@metamask/transaction-controller": "^60.4.0",
5353
"@metamask/utils": "^11.8.0",
54+
"lodash": "^4.17.21",
5455
"uuid": "^8.3.2"
5556
},
5657
"devDependencies": {

packages/eip-5792-middleware/src/constants.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ export enum MessageType {
1111
SendTransaction = 'eth_sendTransaction',
1212
}
1313

14+
export enum SupportedCapabilities {
15+
AuxiliaryFunds = 'auxiliaryFunds',
16+
}
17+
1418
// To be moved to @metamask/rpc-errors in future.
1519
export enum EIP5792ErrorCode {
1620
UnsupportedNonOptionalCapability = 5700,
@@ -19,6 +23,13 @@ export enum EIP5792ErrorCode {
1923
RejectedUpgrade = 5750,
2024
}
2125

26+
// To be moved to @metamask/rpc-errors in future.
27+
export enum EIP7682ErrorCode {
28+
UnsupportedAsset = 5771,
29+
UnsupportedChain = 5772,
30+
MalformedRequiredAssets = 5773,
31+
}
32+
2233
// wallet_getCallStatus
2334
export enum GetCallsStatusCode {
2435
PENDING = 100,

packages/eip-5792-middleware/src/hooks/getCapabilities.test.ts

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ describe('EIP-5792', () => {
4444
PreferencesControllerGetStateAction['handler']
4545
> = jest.fn();
4646

47+
const isAuxiliaryFundsSupportedMock: jest.Mock = jest.fn();
48+
4749
let messenger: EIP5792Messenger;
4850

4951
const getCapabilitiesHooks = {
@@ -53,6 +55,7 @@ describe('EIP-5792', () => {
5355
getIsSmartTransaction: getIsSmartTransactionMock,
5456
isRelaySupported: isRelaySupportedMock,
5557
getSendBundleSupportedChains: getSendBundleSupportedChainsMock,
58+
isAuxiliaryFundsSupported: isAuxiliaryFundsSupportedMock,
5659
};
5760

5861
beforeEach(() => {
@@ -425,5 +428,119 @@ describe('EIP-5792', () => {
425428
},
426429
});
427430
});
431+
432+
it('fetches all network configurations when chainIds is undefined', async () => {
433+
const networkConfigurationsMock = {
434+
'0x1': { chainId: '0x1' },
435+
'0x89': { chainId: '0x89' },
436+
};
437+
438+
messenger.registerActionHandler(
439+
'NetworkController:getState',
440+
jest.fn().mockReturnValue({
441+
networkConfigurationsByChainId: networkConfigurationsMock,
442+
}),
443+
);
444+
445+
isAtomicBatchSupportedMock.mockResolvedValueOnce([
446+
{
447+
chainId: '0x1',
448+
delegationAddress: DELEGATION_ADDRESS_MOCK,
449+
isSupported: true,
450+
},
451+
{
452+
chainId: '0x89',
453+
delegationAddress: undefined,
454+
isSupported: false,
455+
upgradeContractAddress: DELEGATION_ADDRESS_MOCK,
456+
},
457+
]);
458+
459+
const capabilities = await getCapabilities(
460+
getCapabilitiesHooks,
461+
messenger,
462+
FROM_MOCK,
463+
undefined,
464+
);
465+
466+
expect(capabilities).toStrictEqual({
467+
'0x1': {
468+
atomic: {
469+
status: 'supported',
470+
},
471+
alternateGasFees: {
472+
supported: true,
473+
},
474+
},
475+
'0x89': {
476+
atomic: {
477+
status: 'ready',
478+
},
479+
},
480+
});
481+
});
482+
483+
it('includes auxiliary funds capability when supported', async () => {
484+
isAtomicBatchSupportedMock.mockResolvedValueOnce([
485+
{
486+
chainId: CHAIN_ID_MOCK,
487+
delegationAddress: DELEGATION_ADDRESS_MOCK,
488+
isSupported: true,
489+
},
490+
]);
491+
492+
isAuxiliaryFundsSupportedMock.mockReturnValue(true);
493+
494+
const capabilities = await getCapabilities(
495+
getCapabilitiesHooks,
496+
messenger,
497+
FROM_MOCK,
498+
[CHAIN_ID_MOCK],
499+
);
500+
501+
expect(capabilities).toStrictEqual({
502+
[CHAIN_ID_MOCK]: {
503+
atomic: {
504+
status: 'supported',
505+
},
506+
alternateGasFees: {
507+
supported: true,
508+
},
509+
auxiliaryFunds: {
510+
supported: true,
511+
},
512+
},
513+
});
514+
});
515+
516+
it('does not include auxiliary funds capability when not supported', async () => {
517+
isAtomicBatchSupportedMock.mockResolvedValueOnce([
518+
{
519+
chainId: CHAIN_ID_MOCK,
520+
delegationAddress: DELEGATION_ADDRESS_MOCK,
521+
isSupported: true,
522+
},
523+
]);
524+
525+
isAuxiliaryFundsSupportedMock.mockReturnValue(false);
526+
527+
const capabilities = await getCapabilities(
528+
getCapabilitiesHooks,
529+
messenger,
530+
FROM_MOCK,
531+
[CHAIN_ID_MOCK],
532+
);
533+
534+
expect(capabilities).toStrictEqual({
535+
[CHAIN_ID_MOCK]: {
536+
atomic: {
537+
status: 'supported',
538+
},
539+
alternateGasFees: {
540+
supported: true,
541+
},
542+
},
543+
});
544+
});
428545
});
429546
});

packages/eip-5792-middleware/src/hooks/getCapabilities.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ export type GetCapabilitiesHooks = {
2525
getSendBundleSupportedChains: (
2626
chainIds: Hex[],
2727
) => Promise<Record<string, boolean>>;
28+
/** Function to validate if auxiliary funds capability is supported. */
29+
isAuxiliaryFundsSupported: (chainId: Hex) => boolean;
2830
};
2931

3032
/**
@@ -48,6 +50,7 @@ export async function getCapabilities(
4850
isAtomicBatchSupported,
4951
isRelaySupported,
5052
getSendBundleSupportedChains,
53+
isAuxiliaryFundsSupported,
5154
} = hooks;
5255

5356
let chainIdsNormalized = chainIds?.map(
@@ -106,15 +109,22 @@ export async function getCapabilities(
106109
}
107110

108111
const status = isSupported ? 'supported' : 'ready';
112+
const hexChainId = chainId as Hex;
109113

110-
if (acc[chainId as Hex] === undefined) {
111-
acc[chainId as Hex] = {};
114+
if (acc[hexChainId] === undefined) {
115+
acc[hexChainId] = {};
112116
}
113117

114-
acc[chainId as Hex].atomic = {
118+
acc[hexChainId].atomic = {
115119
status,
116120
};
117121

122+
if (isSupportedAccount && isAuxiliaryFundsSupported(chainId)) {
123+
acc[hexChainId].auxiliaryFunds = {
124+
supported: true,
125+
};
126+
}
127+
118128
return acc;
119129
}, alternateGasFeesAcc);
120130
}

0 commit comments

Comments
 (0)