@metamask/snaps-controllers 11.0.0 → 11.1.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 +23 -1
- package/dist/interface/SnapInterfaceController.cjs +21 -4
- package/dist/interface/SnapInterfaceController.cjs.map +1 -1
- package/dist/interface/SnapInterfaceController.d.cts +16 -3
- package/dist/interface/SnapInterfaceController.d.cts.map +1 -1
- package/dist/interface/SnapInterfaceController.d.mts +16 -3
- package/dist/interface/SnapInterfaceController.d.mts.map +1 -1
- package/dist/interface/SnapInterfaceController.mjs +23 -6
- package/dist/interface/SnapInterfaceController.mjs.map +1 -1
- package/dist/interface/utils.cjs +124 -23
- package/dist/interface/utils.cjs.map +1 -1
- package/dist/interface/utils.d.cts +82 -2
- package/dist/interface/utils.d.cts.map +1 -1
- package/dist/interface/utils.d.mts +82 -2
- package/dist/interface/utils.d.mts.map +1 -1
- package/dist/interface/utils.mjs +120 -22
- package/dist/interface/utils.mjs.map +1 -1
- package/dist/multichain/MultichainRouter.cjs +2 -2
- package/dist/multichain/MultichainRouter.cjs.map +1 -1
- package/dist/multichain/MultichainRouter.d.cts +4 -16
- package/dist/multichain/MultichainRouter.d.cts.map +1 -1
- package/dist/multichain/MultichainRouter.d.mts +4 -16
- package/dist/multichain/MultichainRouter.d.mts.map +1 -1
- package/dist/multichain/MultichainRouter.mjs +2 -2
- package/dist/multichain/MultichainRouter.mjs.map +1 -1
- package/dist/snaps/SnapController.cjs +24 -20
- package/dist/snaps/SnapController.cjs.map +1 -1
- package/dist/snaps/SnapController.d.cts +4 -0
- package/dist/snaps/SnapController.d.cts.map +1 -1
- package/dist/snaps/SnapController.d.mts +4 -0
- package/dist/snaps/SnapController.d.mts.map +1 -1
- package/dist/snaps/SnapController.mjs +24 -20
- package/dist/snaps/SnapController.mjs.map +1 -1
- package/package.json +8 -8
package/dist/interface/utils.cjs
CHANGED
|
@@ -1,9 +1,35 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.validateInterfaceContext = exports.constructState = exports.assertNameIsUnique = exports.getJsxInterface = void 0;
|
|
3
|
+
exports.validateInterfaceContext = exports.constructState = exports.getAssetSelectorStateValue = exports.getDefaultAsset = exports.assertNameIsUnique = exports.getJsxInterface = exports.isStatefulComponent = void 0;
|
|
4
4
|
const snaps_sdk_1 = require("@metamask/snaps-sdk");
|
|
5
5
|
const jsx_1 = require("@metamask/snaps-sdk/jsx");
|
|
6
6
|
const snaps_utils_1 = require("@metamask/snaps-utils");
|
|
7
|
+
const utils_1 = require("@metamask/utils");
|
|
8
|
+
/**
|
|
9
|
+
* A list of stateful component types.
|
|
10
|
+
*/
|
|
11
|
+
const STATEFUL_COMPONENT_TYPES = [
|
|
12
|
+
'Input',
|
|
13
|
+
'Dropdown',
|
|
14
|
+
'RadioGroup',
|
|
15
|
+
'FileInput',
|
|
16
|
+
'Checkbox',
|
|
17
|
+
'Selector',
|
|
18
|
+
'AssetSelector',
|
|
19
|
+
'AddressInput',
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Check if a component is a stateful component.
|
|
23
|
+
*
|
|
24
|
+
* @param component - The component to check.
|
|
25
|
+
* @param component.type - The type of the component.
|
|
26
|
+
*
|
|
27
|
+
* @returns Whether the component is a stateful component.
|
|
28
|
+
*/
|
|
29
|
+
function isStatefulComponent(component) {
|
|
30
|
+
return STATEFUL_COMPONENT_TYPES.includes(component.type);
|
|
31
|
+
}
|
|
32
|
+
exports.isStatefulComponent = isStatefulComponent;
|
|
7
33
|
/**
|
|
8
34
|
* Get a JSX element from a component or JSX element. If the component is a
|
|
9
35
|
* JSX element, it is returned as is. Otherwise, the component is converted to
|
|
@@ -29,6 +55,51 @@ function assertNameIsUnique(state, name) {
|
|
|
29
55
|
(0, snaps_sdk_1.assert)(state[name] === undefined, `Duplicate component names are not allowed, found multiple instances of: "${name}".`);
|
|
30
56
|
}
|
|
31
57
|
exports.assertNameIsUnique = assertNameIsUnique;
|
|
58
|
+
/**
|
|
59
|
+
* Get a default asset for a given address.
|
|
60
|
+
*
|
|
61
|
+
* @param addresses - The account addresses.
|
|
62
|
+
* @param chainIds - The chain IDs to filter the assets.
|
|
63
|
+
* @param elementDataGetters - Data getters for the element.
|
|
64
|
+
* @param elementDataGetters.getAccountByAddress - A function to get an account by its address.
|
|
65
|
+
* @param elementDataGetters.getAssetsState - A function to get the MultichainAssetController state.
|
|
66
|
+
*
|
|
67
|
+
* @returns The default asset for the account or undefined if not found.
|
|
68
|
+
*/
|
|
69
|
+
function getDefaultAsset(addresses, chainIds, { getAccountByAddress, getAssetsState }) {
|
|
70
|
+
const { assetsMetadata, accountsAssets } = getAssetsState();
|
|
71
|
+
const parsedAccounts = addresses.map((address) => (0, utils_1.parseCaipAccountId)(address));
|
|
72
|
+
const accountChainIds = parsedAccounts.map(({ chainId }) => chainId);
|
|
73
|
+
const filteredChainIds = chainIds && chainIds.length > 0
|
|
74
|
+
? accountChainIds.filter((accountChainId) => chainIds.includes(accountChainId))
|
|
75
|
+
: accountChainIds;
|
|
76
|
+
const accountId = getAccountByAddress(addresses[0])?.id;
|
|
77
|
+
// We should never fail on this assertion as the address is already validated.
|
|
78
|
+
(0, snaps_sdk_1.assert)(accountId, `Account not found for address: ${addresses[0]}.`);
|
|
79
|
+
const accountAssets = accountsAssets[accountId];
|
|
80
|
+
// The AssetSelector component in the UI will be disabled if there is no asset available for the account
|
|
81
|
+
// and networks provided. In this case, we return null to indicate that there is no default selected asset.
|
|
82
|
+
if (accountAssets.length === 0) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
const nativeAsset = accountAssets.find((asset) => {
|
|
86
|
+
const { chainId, assetNamespace } = (0, utils_1.parseCaipAssetType)(asset);
|
|
87
|
+
return filteredChainIds.includes(chainId) && assetNamespace === 'slip44';
|
|
88
|
+
});
|
|
89
|
+
if (nativeAsset) {
|
|
90
|
+
return {
|
|
91
|
+
asset: nativeAsset,
|
|
92
|
+
name: assetsMetadata[nativeAsset].name,
|
|
93
|
+
symbol: assetsMetadata[nativeAsset].symbol,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return {
|
|
97
|
+
asset: accountAssets[0],
|
|
98
|
+
name: assetsMetadata[accountAssets[0]].name,
|
|
99
|
+
symbol: assetsMetadata[accountAssets[0]].symbol,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
exports.getDefaultAsset = getDefaultAsset;
|
|
32
103
|
/**
|
|
33
104
|
* Construct default state for a component.
|
|
34
105
|
*
|
|
@@ -36,9 +107,11 @@ exports.assertNameIsUnique = assertNameIsUnique;
|
|
|
36
107
|
* for component specific defaults and will not override the component value or existing form state.
|
|
37
108
|
*
|
|
38
109
|
* @param element - The input element.
|
|
110
|
+
* @param elementDataGetters - Data getters for the element.
|
|
111
|
+
*
|
|
39
112
|
* @returns The default state for the specific component, if any.
|
|
40
113
|
*/
|
|
41
|
-
function constructComponentSpecificDefaultState(element) {
|
|
114
|
+
function constructComponentSpecificDefaultState(element, elementDataGetters) {
|
|
42
115
|
switch (element.type) {
|
|
43
116
|
case 'Dropdown': {
|
|
44
117
|
const children = (0, snaps_utils_1.getJsxChildren)(element);
|
|
@@ -54,10 +127,35 @@ function constructComponentSpecificDefaultState(element) {
|
|
|
54
127
|
}
|
|
55
128
|
case 'Checkbox':
|
|
56
129
|
return false;
|
|
130
|
+
case 'AssetSelector':
|
|
131
|
+
return getDefaultAsset(element.props.addresses, element.props.chainIds, elementDataGetters);
|
|
57
132
|
default:
|
|
58
133
|
return null;
|
|
59
134
|
}
|
|
60
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Get the state value for an asset selector.
|
|
138
|
+
*
|
|
139
|
+
* @param value - The asset selector value.
|
|
140
|
+
* @param getAssetState - A function to get the MultichainAssetController state.
|
|
141
|
+
* @returns The state value for the asset selector or null.
|
|
142
|
+
*/
|
|
143
|
+
function getAssetSelectorStateValue(value, getAssetState) {
|
|
144
|
+
if (!value) {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
const { assetsMetadata } = getAssetState();
|
|
148
|
+
const asset = assetsMetadata[value];
|
|
149
|
+
if (!asset) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
asset: value,
|
|
154
|
+
name: asset.name,
|
|
155
|
+
symbol: asset.symbol,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
exports.getAssetSelectorStateValue = getAssetSelectorStateValue;
|
|
61
159
|
/**
|
|
62
160
|
* Get the state value for a stateful component.
|
|
63
161
|
*
|
|
@@ -65,12 +163,24 @@ function constructComponentSpecificDefaultState(element) {
|
|
|
65
163
|
* This function exists to account for components where that isn't the case.
|
|
66
164
|
*
|
|
67
165
|
* @param element - The input element.
|
|
166
|
+
* @param elementDataGetters - Data getters for the element.
|
|
167
|
+
* @param elementDataGetters.getAssetsState - A function to get the MultichainAssetController state.
|
|
68
168
|
* @returns The state value for a given component.
|
|
69
169
|
*/
|
|
70
|
-
function getComponentStateValue(element) {
|
|
170
|
+
function getComponentStateValue(element, { getAssetsState }) {
|
|
71
171
|
switch (element.type) {
|
|
72
172
|
case 'Checkbox':
|
|
73
173
|
return element.props.checked;
|
|
174
|
+
case 'AssetSelector':
|
|
175
|
+
return getAssetSelectorStateValue(element.props.value, getAssetsState);
|
|
176
|
+
case 'AddressInput': {
|
|
177
|
+
if (!element.props.value) {
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
// Construct CAIP-10 Id
|
|
181
|
+
const { namespace, reference } = (0, utils_1.parseCaipChainId)(element.props.chainId);
|
|
182
|
+
return (0, utils_1.toCaipAccountId)(namespace, reference, element.props.value);
|
|
183
|
+
}
|
|
74
184
|
default:
|
|
75
185
|
return element.props.value;
|
|
76
186
|
}
|
|
@@ -80,18 +190,19 @@ function getComponentStateValue(element) {
|
|
|
80
190
|
*
|
|
81
191
|
* @param oldState - The previous state.
|
|
82
192
|
* @param element - The input element.
|
|
193
|
+
* @param elementDataGetters - Data getters for the element.
|
|
83
194
|
* @param form - An optional form that the input is enclosed in.
|
|
84
195
|
* @returns The input state.
|
|
85
196
|
*/
|
|
86
|
-
function constructInputState(oldState, element, form) {
|
|
197
|
+
function constructInputState(oldState, element, elementDataGetters, form) {
|
|
87
198
|
const oldStateUnwrapped = form ? oldState[form] : oldState;
|
|
88
199
|
const oldInputState = oldStateUnwrapped?.[element.props.name];
|
|
89
200
|
if (element.type === 'FileInput') {
|
|
90
201
|
return oldInputState ?? null;
|
|
91
202
|
}
|
|
92
|
-
return (getComponentStateValue(element) ??
|
|
203
|
+
return (getComponentStateValue(element, elementDataGetters) ??
|
|
93
204
|
oldInputState ??
|
|
94
|
-
constructComponentSpecificDefaultState(element) ??
|
|
205
|
+
constructComponentSpecificDefaultState(element, elementDataGetters) ??
|
|
95
206
|
null);
|
|
96
207
|
}
|
|
97
208
|
/**
|
|
@@ -99,9 +210,10 @@ function constructInputState(oldState, element, form) {
|
|
|
99
210
|
*
|
|
100
211
|
* @param oldState - The previous state.
|
|
101
212
|
* @param rootComponent - The UI component to construct state from.
|
|
213
|
+
* @param elementDataGetters - Data getters for the elements.
|
|
102
214
|
* @returns The interface state of the passed component.
|
|
103
215
|
*/
|
|
104
|
-
function constructState(oldState, rootComponent) {
|
|
216
|
+
function constructState(oldState, rootComponent, elementDataGetters) {
|
|
105
217
|
const newState = {};
|
|
106
218
|
// Stack containing the forms we have visited and at which depth
|
|
107
219
|
const formStack = [];
|
|
@@ -119,33 +231,22 @@ function constructState(oldState, rootComponent) {
|
|
|
119
231
|
return;
|
|
120
232
|
}
|
|
121
233
|
// Stateful components inside a form
|
|
122
|
-
if (currentForm &&
|
|
123
|
-
(component.type === 'Input' ||
|
|
124
|
-
component.type === 'Dropdown' ||
|
|
125
|
-
component.type === 'RadioGroup' ||
|
|
126
|
-
component.type === 'FileInput' ||
|
|
127
|
-
component.type === 'Checkbox' ||
|
|
128
|
-
component.type === 'Selector')) {
|
|
234
|
+
if (currentForm && isStatefulComponent(component)) {
|
|
129
235
|
const formState = newState[currentForm.name];
|
|
130
236
|
assertNameIsUnique(formState, component.props.name);
|
|
131
|
-
formState[component.props.name] = constructInputState(oldState, component, currentForm.name);
|
|
237
|
+
formState[component.props.name] = constructInputState(oldState, component, elementDataGetters, currentForm.name);
|
|
132
238
|
return;
|
|
133
239
|
}
|
|
134
240
|
// Stateful components outside a form
|
|
135
|
-
if (component
|
|
136
|
-
component.type === 'Dropdown' ||
|
|
137
|
-
component.type === 'RadioGroup' ||
|
|
138
|
-
component.type === 'FileInput' ||
|
|
139
|
-
component.type === 'Checkbox' ||
|
|
140
|
-
component.type === 'Selector') {
|
|
241
|
+
if (isStatefulComponent(component)) {
|
|
141
242
|
assertNameIsUnique(newState, component.props.name);
|
|
142
|
-
newState[component.props.name] = constructInputState(oldState, component);
|
|
243
|
+
newState[component.props.name] = constructInputState(oldState, component, elementDataGetters);
|
|
143
244
|
}
|
|
144
245
|
});
|
|
145
246
|
return newState;
|
|
146
247
|
}
|
|
147
248
|
exports.constructState = constructState;
|
|
148
|
-
const MAX_CONTEXT_SIZE =
|
|
249
|
+
const MAX_CONTEXT_SIZE = 5000000; // 5 mb
|
|
149
250
|
/**
|
|
150
251
|
* Validate a JSON blob to be used as the interface context.
|
|
151
252
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../src/interface/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert } from '@metamask/snaps-sdk';\nimport type {\n FormState,\n InterfaceState,\n ComponentOrElement,\n InterfaceContext,\n State,\n} from '@metamask/snaps-sdk';\nimport type {\n DropdownElement,\n InputElement,\n JSXElement,\n OptionElement,\n FileInputElement,\n CheckboxElement,\n RadioGroupElement,\n RadioElement,\n SelectorElement,\n SelectorOptionElement,\n} from '@metamask/snaps-sdk/jsx';\nimport { isJSXElementUnsafe } from '@metamask/snaps-sdk/jsx';\nimport {\n getJsonSizeUnsafe,\n getJsxChildren,\n getJsxElementFromComponent,\n walkJsx,\n} from '@metamask/snaps-utils';\n\n/**\n * Get a JSX element from a component or JSX element. If the component is a\n * JSX element, it is returned as is. Otherwise, the component is converted to\n * a JSX element.\n *\n * @param component - The component to convert.\n * @returns The JSX element.\n */\nexport function getJsxInterface(component: ComponentOrElement): JSXElement {\n if (isJSXElementUnsafe(component)) {\n return component;\n }\n\n return getJsxElementFromComponent(component);\n}\n\n/**\n * Assert that the component name is unique in state.\n *\n * @param state - The interface state to verify against.\n * @param name - The component name to verify.\n */\nexport function assertNameIsUnique(state: InterfaceState, name: string) {\n assert(\n state[name] === undefined,\n `Duplicate component names are not allowed, found multiple instances of: \"${name}\".`,\n );\n}\n\n/**\n * Construct default state for a component.\n *\n * This function is meant to be used inside constructInputState to account\n * for component specific defaults and will not override the component value or existing form state.\n *\n * @param element - The input element.\n * @returns The default state for the specific component, if any.\n */\nfunction constructComponentSpecificDefaultState(\n element:\n | InputElement\n | DropdownElement\n | RadioGroupElement\n | CheckboxElement\n | SelectorElement,\n) {\n switch (element.type) {\n case 'Dropdown': {\n const children = getJsxChildren(element) as OptionElement[];\n return children[0]?.props.value;\n }\n\n case 'RadioGroup': {\n const children = getJsxChildren(element) as RadioElement[];\n return children[0]?.props.value;\n }\n\n case 'Selector': {\n const children = getJsxChildren(element) as SelectorOptionElement[];\n return children[0]?.props.value;\n }\n\n case 'Checkbox':\n return false;\n\n default:\n return null;\n }\n}\n\n/**\n * Get the state value for a stateful component.\n *\n * Most components store the state value as a `value` prop.\n * This function exists to account for components where that isn't the case.\n *\n * @param element - The input element.\n * @returns The state value for a given component.\n */\nfunction getComponentStateValue(\n element:\n | InputElement\n | DropdownElement\n | RadioGroupElement\n | CheckboxElement\n | SelectorElement,\n) {\n switch (element.type) {\n case 'Checkbox':\n return element.props.checked;\n\n default:\n return element.props.value;\n }\n}\n\n/**\n * Construct the state for an input field.\n *\n * @param oldState - The previous state.\n * @param element - The input element.\n * @param form - An optional form that the input is enclosed in.\n * @returns The input state.\n */\nfunction constructInputState(\n oldState: InterfaceState,\n element:\n | InputElement\n | DropdownElement\n | RadioGroupElement\n | FileInputElement\n | CheckboxElement\n | SelectorElement,\n form?: string,\n) {\n const oldStateUnwrapped = form ? (oldState[form] as FormState) : oldState;\n const oldInputState = oldStateUnwrapped?.[element.props.name] as State;\n\n if (element.type === 'FileInput') {\n return oldInputState ?? null;\n }\n\n return (\n getComponentStateValue(element) ??\n oldInputState ??\n constructComponentSpecificDefaultState(element) ??\n null\n );\n}\n\n/**\n * Construct the interface state for a given component tree.\n *\n * @param oldState - The previous state.\n * @param rootComponent - The UI component to construct state from.\n * @returns The interface state of the passed component.\n */\nexport function constructState(\n oldState: InterfaceState,\n rootComponent: JSXElement,\n): InterfaceState {\n const newState: InterfaceState = {};\n\n // Stack containing the forms we have visited and at which depth\n const formStack: { name: string; depth: number }[] = [];\n\n walkJsx(rootComponent, (component, depth) => {\n let currentForm = formStack[formStack.length - 1];\n\n // Pop the current form of the stack once we leave its depth.\n if (currentForm && depth <= currentForm.depth) {\n formStack.pop();\n currentForm = formStack[formStack.length - 1];\n }\n\n if (component.type === 'Form') {\n assertNameIsUnique(newState, component.props.name);\n formStack.push({ name: component.props.name, depth });\n newState[component.props.name] = {};\n return;\n }\n\n // Stateful components inside a form\n if (\n currentForm &&\n (component.type === 'Input' ||\n component.type === 'Dropdown' ||\n component.type === 'RadioGroup' ||\n component.type === 'FileInput' ||\n component.type === 'Checkbox' ||\n component.type === 'Selector')\n ) {\n const formState = newState[currentForm.name] as FormState;\n assertNameIsUnique(formState, component.props.name);\n formState[component.props.name] = constructInputState(\n oldState,\n component,\n currentForm.name,\n );\n return;\n }\n\n // Stateful components outside a form\n if (\n component.type === 'Input' ||\n component.type === 'Dropdown' ||\n component.type === 'RadioGroup' ||\n component.type === 'FileInput' ||\n component.type === 'Checkbox' ||\n component.type === 'Selector'\n ) {\n assertNameIsUnique(newState, component.props.name);\n newState[component.props.name] = constructInputState(oldState, component);\n }\n });\n\n return newState;\n}\n\nconst MAX_CONTEXT_SIZE = 1_000_000; // 1 mb\n\n/**\n * Validate a JSON blob to be used as the interface context.\n *\n * @param context - The JSON blob.\n * @throws If the JSON blob is too large.\n */\nexport function validateInterfaceContext(context?: InterfaceContext) {\n if (!context) {\n return;\n }\n\n // We assume the validity of this JSON to be validated by the caller.\n // E.g., in the RPC method implementation.\n const size = getJsonSizeUnsafe(context);\n assert(\n size <= MAX_CONTEXT_SIZE,\n `A Snap interface context may not be larger than ${\n MAX_CONTEXT_SIZE / 1000000\n } MB.`,\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.cjs","sourceRoot":"","sources":["../../src/interface/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { assert } from '@metamask/snaps-sdk';\nimport type {\n FormState,\n InterfaceState,\n ComponentOrElement,\n InterfaceContext,\n State,\n FungibleAssetMetadata,\n AssetSelectorState,\n CaipChainId,\n} from '@metamask/snaps-sdk';\nimport type {\n DropdownElement,\n InputElement,\n JSXElement,\n OptionElement,\n FileInputElement,\n CheckboxElement,\n RadioGroupElement,\n RadioElement,\n SelectorElement,\n SelectorOptionElement,\n AssetSelectorElement,\n AddressInputElement,\n} from '@metamask/snaps-sdk/jsx';\nimport { isJSXElementUnsafe } from '@metamask/snaps-sdk/jsx';\nimport type { InternalAccount } from '@metamask/snaps-utils';\nimport {\n getJsonSizeUnsafe,\n getJsxChildren,\n getJsxElementFromComponent,\n walkJsx,\n} from '@metamask/snaps-utils';\nimport {\n type CaipAssetType,\n type CaipAccountId,\n parseCaipAccountId,\n parseCaipAssetType,\n toCaipAccountId,\n parseCaipChainId,\n} from '@metamask/utils';\n\n/**\n * A list of stateful component types.\n */\nconst STATEFUL_COMPONENT_TYPES = [\n 'Input',\n 'Dropdown',\n 'RadioGroup',\n 'FileInput',\n 'Checkbox',\n 'Selector',\n 'AssetSelector',\n 'AddressInput',\n] as const;\n\n/**\n * Type for stateful component types.\n */\ntype StatefulComponentType = (typeof STATEFUL_COMPONENT_TYPES)[number];\n\n/**\n * Check if a component is a stateful component.\n *\n * @param component - The component to check.\n * @param component.type - The type of the component.\n *\n * @returns Whether the component is a stateful component.\n */\nexport function isStatefulComponent(component: { type: string }): component is {\n type: StatefulComponentType;\n} {\n return STATEFUL_COMPONENT_TYPES.includes(\n component.type as StatefulComponentType,\n );\n}\n\n/**\n * A function to get the MultichainAssetController state.\n *\n * @returns The MultichainAssetController state.\n */\ntype GetAssetsState = () => {\n assetsMetadata: {\n [asset: CaipAssetType]: FungibleAssetMetadata;\n };\n accountsAssets: { [account: string]: CaipAssetType[] };\n};\n\n/**\n * A function to get an account by its address.\n *\n * @param address - The account address.\n * @returns The account or undefined if not found.\n */\ntype GetAccountByAddress = (\n address: CaipAccountId,\n) => InternalAccount | undefined;\n\n/**\n * Data getters for elements.\n * This is used to get data from elements that is not directly accessible from the element itself.\n *\n * @param getAssetState - A function to get the MultichainAssetController state.\n * @param getAccountByAddress - A function to get an account by its address.\n */\ntype ElementDataGetters = {\n getAssetsState: GetAssetsState;\n getAccountByAddress: GetAccountByAddress;\n};\n\n/**\n * Get a JSX element from a component or JSX element. If the component is a\n * JSX element, it is returned as is. Otherwise, the component is converted to\n * a JSX element.\n *\n * @param component - The component to convert.\n * @returns The JSX element.\n */\nexport function getJsxInterface(component: ComponentOrElement): JSXElement {\n if (isJSXElementUnsafe(component)) {\n return component;\n }\n\n return getJsxElementFromComponent(component);\n}\n\n/**\n * Assert that the component name is unique in state.\n *\n * @param state - The interface state to verify against.\n * @param name - The component name to verify.\n */\nexport function assertNameIsUnique(state: InterfaceState, name: string) {\n assert(\n state[name] === undefined,\n `Duplicate component names are not allowed, found multiple instances of: \"${name}\".`,\n );\n}\n\n/**\n * Get a default asset for a given address.\n *\n * @param addresses - The account addresses.\n * @param chainIds - The chain IDs to filter the assets.\n * @param elementDataGetters - Data getters for the element.\n * @param elementDataGetters.getAccountByAddress - A function to get an account by its address.\n * @param elementDataGetters.getAssetsState - A function to get the MultichainAssetController state.\n *\n * @returns The default asset for the account or undefined if not found.\n */\nexport function getDefaultAsset(\n addresses: CaipAccountId[],\n chainIds: CaipChainId[] | undefined,\n { getAccountByAddress, getAssetsState }: ElementDataGetters,\n) {\n const { assetsMetadata, accountsAssets } = getAssetsState();\n\n const parsedAccounts = addresses.map((address) =>\n parseCaipAccountId(address),\n );\n\n const accountChainIds = parsedAccounts.map(({ chainId }) => chainId);\n\n const filteredChainIds =\n chainIds && chainIds.length > 0\n ? accountChainIds.filter((accountChainId) =>\n chainIds.includes(accountChainId),\n )\n : accountChainIds;\n\n const accountId = getAccountByAddress(addresses[0])?.id;\n\n // We should never fail on this assertion as the address is already validated.\n assert(accountId, `Account not found for address: ${addresses[0]}.`);\n\n const accountAssets = accountsAssets[accountId];\n\n // The AssetSelector component in the UI will be disabled if there is no asset available for the account\n // and networks provided. In this case, we return null to indicate that there is no default selected asset.\n if (accountAssets.length === 0) {\n return null;\n }\n\n const nativeAsset = accountAssets.find((asset) => {\n const { chainId, assetNamespace } = parseCaipAssetType(asset);\n\n return filteredChainIds.includes(chainId) && assetNamespace === 'slip44';\n });\n\n if (nativeAsset) {\n return {\n asset: nativeAsset,\n name: assetsMetadata[nativeAsset].name,\n symbol: assetsMetadata[nativeAsset].symbol,\n };\n }\n\n return {\n asset: accountAssets[0],\n name: assetsMetadata[accountAssets[0]].name,\n symbol: assetsMetadata[accountAssets[0]].symbol,\n };\n}\n\n/**\n * Construct default state for a component.\n *\n * This function is meant to be used inside constructInputState to account\n * for component specific defaults and will not override the component value or existing form state.\n *\n * @param element - The input element.\n * @param elementDataGetters - Data getters for the element.\n *\n * @returns The default state for the specific component, if any.\n */\nfunction constructComponentSpecificDefaultState(\n element:\n | InputElement\n | DropdownElement\n | RadioGroupElement\n | CheckboxElement\n | SelectorElement\n | AssetSelectorElement\n | AddressInputElement,\n elementDataGetters: ElementDataGetters,\n) {\n switch (element.type) {\n case 'Dropdown': {\n const children = getJsxChildren(element) as OptionElement[];\n return children[0]?.props.value;\n }\n\n case 'RadioGroup': {\n const children = getJsxChildren(element) as RadioElement[];\n return children[0]?.props.value;\n }\n\n case 'Selector': {\n const children = getJsxChildren(element) as SelectorOptionElement[];\n return children[0]?.props.value;\n }\n\n case 'Checkbox':\n return false;\n\n case 'AssetSelector':\n return getDefaultAsset(\n element.props.addresses,\n element.props.chainIds,\n elementDataGetters,\n );\n\n default:\n return null;\n }\n}\n\n/**\n * Get the state value for an asset selector.\n *\n * @param value - The asset selector value.\n * @param getAssetState - A function to get the MultichainAssetController state.\n * @returns The state value for the asset selector or null.\n */\nexport function getAssetSelectorStateValue(\n value: CaipAssetType | undefined,\n getAssetState: GetAssetsState,\n): AssetSelectorState | null {\n if (!value) {\n return null;\n }\n\n const { assetsMetadata } = getAssetState();\n const asset = assetsMetadata[value];\n\n if (!asset) {\n return null;\n }\n\n return {\n asset: value,\n name: asset.name,\n symbol: asset.symbol,\n };\n}\n\n/**\n * Get the state value for a stateful component.\n *\n * Most components store the state value as a `value` prop.\n * This function exists to account for components where that isn't the case.\n *\n * @param element - The input element.\n * @param elementDataGetters - Data getters for the element.\n * @param elementDataGetters.getAssetsState - A function to get the MultichainAssetController state.\n * @returns The state value for a given component.\n */\nfunction getComponentStateValue(\n element:\n | InputElement\n | DropdownElement\n | RadioGroupElement\n | CheckboxElement\n | SelectorElement\n | AssetSelectorElement\n | AddressInputElement,\n { getAssetsState }: ElementDataGetters,\n) {\n switch (element.type) {\n case 'Checkbox':\n return element.props.checked;\n\n case 'AssetSelector':\n return getAssetSelectorStateValue(element.props.value, getAssetsState);\n\n case 'AddressInput': {\n if (!element.props.value) {\n return null;\n }\n\n // Construct CAIP-10 Id\n const { namespace, reference } = parseCaipChainId(element.props.chainId);\n return toCaipAccountId(namespace, reference, element.props.value);\n }\n default:\n return element.props.value;\n }\n}\n\n/**\n * Construct the state for an input field.\n *\n * @param oldState - The previous state.\n * @param element - The input element.\n * @param elementDataGetters - Data getters for the element.\n * @param form - An optional form that the input is enclosed in.\n * @returns The input state.\n */\nfunction constructInputState(\n oldState: InterfaceState,\n element:\n | InputElement\n | DropdownElement\n | RadioGroupElement\n | FileInputElement\n | CheckboxElement\n | SelectorElement\n | AssetSelectorElement\n | AddressInputElement,\n elementDataGetters: ElementDataGetters,\n form?: string,\n) {\n const oldStateUnwrapped = form ? (oldState[form] as FormState) : oldState;\n const oldInputState = oldStateUnwrapped?.[element.props.name] as State;\n\n if (element.type === 'FileInput') {\n return oldInputState ?? null;\n }\n\n return (\n getComponentStateValue(element, elementDataGetters) ??\n oldInputState ??\n constructComponentSpecificDefaultState(element, elementDataGetters) ??\n null\n );\n}\n\n/**\n * Construct the interface state for a given component tree.\n *\n * @param oldState - The previous state.\n * @param rootComponent - The UI component to construct state from.\n * @param elementDataGetters - Data getters for the elements.\n * @returns The interface state of the passed component.\n */\nexport function constructState(\n oldState: InterfaceState,\n rootComponent: JSXElement,\n elementDataGetters: ElementDataGetters,\n): InterfaceState {\n const newState: InterfaceState = {};\n\n // Stack containing the forms we have visited and at which depth\n const formStack: { name: string; depth: number }[] = [];\n\n walkJsx(rootComponent, (component, depth) => {\n let currentForm = formStack[formStack.length - 1];\n\n // Pop the current form of the stack once we leave its depth.\n if (currentForm && depth <= currentForm.depth) {\n formStack.pop();\n currentForm = formStack[formStack.length - 1];\n }\n\n if (component.type === 'Form') {\n assertNameIsUnique(newState, component.props.name);\n formStack.push({ name: component.props.name, depth });\n newState[component.props.name] = {};\n return;\n }\n\n // Stateful components inside a form\n if (currentForm && isStatefulComponent(component)) {\n const formState = newState[currentForm.name] as FormState;\n assertNameIsUnique(formState, component.props.name);\n formState[component.props.name] = constructInputState(\n oldState,\n component,\n elementDataGetters,\n currentForm.name,\n );\n return;\n }\n\n // Stateful components outside a form\n if (isStatefulComponent(component)) {\n assertNameIsUnique(newState, component.props.name);\n newState[component.props.name] = constructInputState(\n oldState,\n component,\n elementDataGetters,\n );\n }\n });\n\n return newState;\n}\n\nconst MAX_CONTEXT_SIZE = 5_000_000; // 5 mb\n\n/**\n * Validate a JSON blob to be used as the interface context.\n *\n * @param context - The JSON blob.\n * @throws If the JSON blob is too large.\n */\nexport function validateInterfaceContext(context?: InterfaceContext) {\n if (!context) {\n return;\n }\n\n // We assume the validity of this JSON to be validated by the caller.\n // E.g., in the RPC method implementation.\n const size = getJsonSizeUnsafe(context);\n assert(\n size <= MAX_CONTEXT_SIZE,\n `A Snap interface context may not be larger than ${\n MAX_CONTEXT_SIZE / 1000000\n } MB.`,\n );\n}\n"]}
|
|
@@ -1,5 +1,59 @@
|
|
|
1
|
-
import type { InterfaceState, ComponentOrElement, InterfaceContext } from "@metamask/snaps-sdk";
|
|
1
|
+
import type { InterfaceState, ComponentOrElement, InterfaceContext, FungibleAssetMetadata, AssetSelectorState, CaipChainId } from "@metamask/snaps-sdk";
|
|
2
2
|
import type { JSXElement } from "@metamask/snaps-sdk/jsx";
|
|
3
|
+
import type { InternalAccount } from "@metamask/snaps-utils";
|
|
4
|
+
import { type CaipAssetType, type CaipAccountId } from "@metamask/utils";
|
|
5
|
+
/**
|
|
6
|
+
* A list of stateful component types.
|
|
7
|
+
*/
|
|
8
|
+
declare const STATEFUL_COMPONENT_TYPES: readonly ["Input", "Dropdown", "RadioGroup", "FileInput", "Checkbox", "Selector", "AssetSelector", "AddressInput"];
|
|
9
|
+
/**
|
|
10
|
+
* Type for stateful component types.
|
|
11
|
+
*/
|
|
12
|
+
type StatefulComponentType = (typeof STATEFUL_COMPONENT_TYPES)[number];
|
|
13
|
+
/**
|
|
14
|
+
* Check if a component is a stateful component.
|
|
15
|
+
*
|
|
16
|
+
* @param component - The component to check.
|
|
17
|
+
* @param component.type - The type of the component.
|
|
18
|
+
*
|
|
19
|
+
* @returns Whether the component is a stateful component.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isStatefulComponent(component: {
|
|
22
|
+
type: string;
|
|
23
|
+
}): component is {
|
|
24
|
+
type: StatefulComponentType;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* A function to get the MultichainAssetController state.
|
|
28
|
+
*
|
|
29
|
+
* @returns The MultichainAssetController state.
|
|
30
|
+
*/
|
|
31
|
+
type GetAssetsState = () => {
|
|
32
|
+
assetsMetadata: {
|
|
33
|
+
[asset: CaipAssetType]: FungibleAssetMetadata;
|
|
34
|
+
};
|
|
35
|
+
accountsAssets: {
|
|
36
|
+
[account: string]: CaipAssetType[];
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* A function to get an account by its address.
|
|
41
|
+
*
|
|
42
|
+
* @param address - The account address.
|
|
43
|
+
* @returns The account or undefined if not found.
|
|
44
|
+
*/
|
|
45
|
+
type GetAccountByAddress = (address: CaipAccountId) => InternalAccount | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Data getters for elements.
|
|
48
|
+
* This is used to get data from elements that is not directly accessible from the element itself.
|
|
49
|
+
*
|
|
50
|
+
* @param getAssetState - A function to get the MultichainAssetController state.
|
|
51
|
+
* @param getAccountByAddress - A function to get an account by its address.
|
|
52
|
+
*/
|
|
53
|
+
type ElementDataGetters = {
|
|
54
|
+
getAssetsState: GetAssetsState;
|
|
55
|
+
getAccountByAddress: GetAccountByAddress;
|
|
56
|
+
};
|
|
3
57
|
/**
|
|
4
58
|
* Get a JSX element from a component or JSX element. If the component is a
|
|
5
59
|
* JSX element, it is returned as is. Otherwise, the component is converted to
|
|
@@ -16,14 +70,39 @@ export declare function getJsxInterface(component: ComponentOrElement): JSXEleme
|
|
|
16
70
|
* @param name - The component name to verify.
|
|
17
71
|
*/
|
|
18
72
|
export declare function assertNameIsUnique(state: InterfaceState, name: string): void;
|
|
73
|
+
/**
|
|
74
|
+
* Get a default asset for a given address.
|
|
75
|
+
*
|
|
76
|
+
* @param addresses - The account addresses.
|
|
77
|
+
* @param chainIds - The chain IDs to filter the assets.
|
|
78
|
+
* @param elementDataGetters - Data getters for the element.
|
|
79
|
+
* @param elementDataGetters.getAccountByAddress - A function to get an account by its address.
|
|
80
|
+
* @param elementDataGetters.getAssetsState - A function to get the MultichainAssetController state.
|
|
81
|
+
*
|
|
82
|
+
* @returns The default asset for the account or undefined if not found.
|
|
83
|
+
*/
|
|
84
|
+
export declare function getDefaultAsset(addresses: CaipAccountId[], chainIds: CaipChainId[] | undefined, { getAccountByAddress, getAssetsState }: ElementDataGetters): {
|
|
85
|
+
asset: `${string}:${string}/${string}:${string}`;
|
|
86
|
+
name: string;
|
|
87
|
+
symbol: string;
|
|
88
|
+
} | null;
|
|
89
|
+
/**
|
|
90
|
+
* Get the state value for an asset selector.
|
|
91
|
+
*
|
|
92
|
+
* @param value - The asset selector value.
|
|
93
|
+
* @param getAssetState - A function to get the MultichainAssetController state.
|
|
94
|
+
* @returns The state value for the asset selector or null.
|
|
95
|
+
*/
|
|
96
|
+
export declare function getAssetSelectorStateValue(value: CaipAssetType | undefined, getAssetState: GetAssetsState): AssetSelectorState | null;
|
|
19
97
|
/**
|
|
20
98
|
* Construct the interface state for a given component tree.
|
|
21
99
|
*
|
|
22
100
|
* @param oldState - The previous state.
|
|
23
101
|
* @param rootComponent - The UI component to construct state from.
|
|
102
|
+
* @param elementDataGetters - Data getters for the elements.
|
|
24
103
|
* @returns The interface state of the passed component.
|
|
25
104
|
*/
|
|
26
|
-
export declare function constructState(oldState: InterfaceState, rootComponent: JSXElement): InterfaceState;
|
|
105
|
+
export declare function constructState(oldState: InterfaceState, rootComponent: JSXElement, elementDataGetters: ElementDataGetters): InterfaceState;
|
|
27
106
|
/**
|
|
28
107
|
* Validate a JSON blob to be used as the interface context.
|
|
29
108
|
*
|
|
@@ -31,4 +110,5 @@ export declare function constructState(oldState: InterfaceState, rootComponent:
|
|
|
31
110
|
* @throws If the JSON blob is too large.
|
|
32
111
|
*/
|
|
33
112
|
export declare function validateInterfaceContext(context?: InterfaceContext): void;
|
|
113
|
+
export {};
|
|
34
114
|
//# sourceMappingURL=utils.d.cts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../src/interface/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,cAAc,EACd,kBAAkB,EAClB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"utils.d.cts","sourceRoot":"","sources":["../../src/interface/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAEhB,qBAAqB,EACrB,kBAAkB,EAClB,WAAW,EACZ,4BAA4B;AAC7B,OAAO,KAAK,EAGV,UAAU,EAUX,gCAAgC;AAEjC,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAO7D,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAKnB,wBAAwB;AAEzB;;GAEG;AACH,QAAA,MAAM,wBAAwB,oHASpB,CAAC;AAEX;;GAEG;AACH,KAAK,qBAAqB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,IAAI;IAC7E,IAAI,EAAE,qBAAqB,CAAC;CAC7B,CAIA;AAED;;;;GAIG;AACH,KAAK,cAAc,GAAG,MAAM;IAC1B,cAAc,EAAE;QACd,CAAC,KAAK,EAAE,aAAa,GAAG,qBAAqB,CAAC;KAC/C,CAAC;IACF,cAAc,EAAE;QAAE,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAAA;KAAE,CAAC;CACxD,CAAC;AAEF;;;;;GAKG;AACH,KAAK,mBAAmB,GAAG,CACzB,OAAO,EAAE,aAAa,KACnB,eAAe,GAAG,SAAS,CAAC;AAEjC;;;;;;GAMG;AACH,KAAK,kBAAkB,GAAG;IACxB,cAAc,EAAE,cAAc,CAAC;IAC/B,mBAAmB,EAAE,mBAAmB,CAAC;CAC1C,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,kBAAkB,GAAG,UAAU,CAMzE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,QAKrE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,aAAa,EAAE,EAC1B,QAAQ,EAAE,WAAW,EAAE,GAAG,SAAS,EACnC,EAAE,mBAAmB,EAAE,cAAc,EAAE,EAAE,kBAAkB;;;;SAiD5D;AAuDD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,aAAa,GAAG,SAAS,EAChC,aAAa,EAAE,cAAc,GAC5B,kBAAkB,GAAG,IAAI,CAiB3B;AAmFD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,cAAc,EACxB,aAAa,EAAE,UAAU,EACzB,kBAAkB,EAAE,kBAAkB,GACrC,cAAc,CA+ChB;AAID;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,CAAC,EAAE,gBAAgB,QAclE"}
|
|
@@ -1,5 +1,59 @@
|
|
|
1
|
-
import type { InterfaceState, ComponentOrElement, InterfaceContext } from "@metamask/snaps-sdk";
|
|
1
|
+
import type { InterfaceState, ComponentOrElement, InterfaceContext, FungibleAssetMetadata, AssetSelectorState, CaipChainId } from "@metamask/snaps-sdk";
|
|
2
2
|
import type { JSXElement } from "@metamask/snaps-sdk/jsx";
|
|
3
|
+
import type { InternalAccount } from "@metamask/snaps-utils";
|
|
4
|
+
import { type CaipAssetType, type CaipAccountId } from "@metamask/utils";
|
|
5
|
+
/**
|
|
6
|
+
* A list of stateful component types.
|
|
7
|
+
*/
|
|
8
|
+
declare const STATEFUL_COMPONENT_TYPES: readonly ["Input", "Dropdown", "RadioGroup", "FileInput", "Checkbox", "Selector", "AssetSelector", "AddressInput"];
|
|
9
|
+
/**
|
|
10
|
+
* Type for stateful component types.
|
|
11
|
+
*/
|
|
12
|
+
type StatefulComponentType = (typeof STATEFUL_COMPONENT_TYPES)[number];
|
|
13
|
+
/**
|
|
14
|
+
* Check if a component is a stateful component.
|
|
15
|
+
*
|
|
16
|
+
* @param component - The component to check.
|
|
17
|
+
* @param component.type - The type of the component.
|
|
18
|
+
*
|
|
19
|
+
* @returns Whether the component is a stateful component.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isStatefulComponent(component: {
|
|
22
|
+
type: string;
|
|
23
|
+
}): component is {
|
|
24
|
+
type: StatefulComponentType;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* A function to get the MultichainAssetController state.
|
|
28
|
+
*
|
|
29
|
+
* @returns The MultichainAssetController state.
|
|
30
|
+
*/
|
|
31
|
+
type GetAssetsState = () => {
|
|
32
|
+
assetsMetadata: {
|
|
33
|
+
[asset: CaipAssetType]: FungibleAssetMetadata;
|
|
34
|
+
};
|
|
35
|
+
accountsAssets: {
|
|
36
|
+
[account: string]: CaipAssetType[];
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* A function to get an account by its address.
|
|
41
|
+
*
|
|
42
|
+
* @param address - The account address.
|
|
43
|
+
* @returns The account or undefined if not found.
|
|
44
|
+
*/
|
|
45
|
+
type GetAccountByAddress = (address: CaipAccountId) => InternalAccount | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Data getters for elements.
|
|
48
|
+
* This is used to get data from elements that is not directly accessible from the element itself.
|
|
49
|
+
*
|
|
50
|
+
* @param getAssetState - A function to get the MultichainAssetController state.
|
|
51
|
+
* @param getAccountByAddress - A function to get an account by its address.
|
|
52
|
+
*/
|
|
53
|
+
type ElementDataGetters = {
|
|
54
|
+
getAssetsState: GetAssetsState;
|
|
55
|
+
getAccountByAddress: GetAccountByAddress;
|
|
56
|
+
};
|
|
3
57
|
/**
|
|
4
58
|
* Get a JSX element from a component or JSX element. If the component is a
|
|
5
59
|
* JSX element, it is returned as is. Otherwise, the component is converted to
|
|
@@ -16,14 +70,39 @@ export declare function getJsxInterface(component: ComponentOrElement): JSXEleme
|
|
|
16
70
|
* @param name - The component name to verify.
|
|
17
71
|
*/
|
|
18
72
|
export declare function assertNameIsUnique(state: InterfaceState, name: string): void;
|
|
73
|
+
/**
|
|
74
|
+
* Get a default asset for a given address.
|
|
75
|
+
*
|
|
76
|
+
* @param addresses - The account addresses.
|
|
77
|
+
* @param chainIds - The chain IDs to filter the assets.
|
|
78
|
+
* @param elementDataGetters - Data getters for the element.
|
|
79
|
+
* @param elementDataGetters.getAccountByAddress - A function to get an account by its address.
|
|
80
|
+
* @param elementDataGetters.getAssetsState - A function to get the MultichainAssetController state.
|
|
81
|
+
*
|
|
82
|
+
* @returns The default asset for the account or undefined if not found.
|
|
83
|
+
*/
|
|
84
|
+
export declare function getDefaultAsset(addresses: CaipAccountId[], chainIds: CaipChainId[] | undefined, { getAccountByAddress, getAssetsState }: ElementDataGetters): {
|
|
85
|
+
asset: `${string}:${string}/${string}:${string}`;
|
|
86
|
+
name: string;
|
|
87
|
+
symbol: string;
|
|
88
|
+
} | null;
|
|
89
|
+
/**
|
|
90
|
+
* Get the state value for an asset selector.
|
|
91
|
+
*
|
|
92
|
+
* @param value - The asset selector value.
|
|
93
|
+
* @param getAssetState - A function to get the MultichainAssetController state.
|
|
94
|
+
* @returns The state value for the asset selector or null.
|
|
95
|
+
*/
|
|
96
|
+
export declare function getAssetSelectorStateValue(value: CaipAssetType | undefined, getAssetState: GetAssetsState): AssetSelectorState | null;
|
|
19
97
|
/**
|
|
20
98
|
* Construct the interface state for a given component tree.
|
|
21
99
|
*
|
|
22
100
|
* @param oldState - The previous state.
|
|
23
101
|
* @param rootComponent - The UI component to construct state from.
|
|
102
|
+
* @param elementDataGetters - Data getters for the elements.
|
|
24
103
|
* @returns The interface state of the passed component.
|
|
25
104
|
*/
|
|
26
|
-
export declare function constructState(oldState: InterfaceState, rootComponent: JSXElement): InterfaceState;
|
|
105
|
+
export declare function constructState(oldState: InterfaceState, rootComponent: JSXElement, elementDataGetters: ElementDataGetters): InterfaceState;
|
|
27
106
|
/**
|
|
28
107
|
* Validate a JSON blob to be used as the interface context.
|
|
29
108
|
*
|
|
@@ -31,4 +110,5 @@ export declare function constructState(oldState: InterfaceState, rootComponent:
|
|
|
31
110
|
* @throws If the JSON blob is too large.
|
|
32
111
|
*/
|
|
33
112
|
export declare function validateInterfaceContext(context?: InterfaceContext): void;
|
|
113
|
+
export {};
|
|
34
114
|
//# sourceMappingURL=utils.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../src/interface/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,cAAc,EACd,kBAAkB,EAClB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"utils.d.mts","sourceRoot":"","sources":["../../src/interface/utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,cAAc,EACd,kBAAkB,EAClB,gBAAgB,EAEhB,qBAAqB,EACrB,kBAAkB,EAClB,WAAW,EACZ,4BAA4B;AAC7B,OAAO,KAAK,EAGV,UAAU,EAUX,gCAAgC;AAEjC,OAAO,KAAK,EAAE,eAAe,EAAE,8BAA8B;AAO7D,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAKnB,wBAAwB;AAEzB;;GAEG;AACH,QAAA,MAAM,wBAAwB,oHASpB,CAAC;AAEX;;GAEG;AACH,KAAK,qBAAqB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,IAAI;IAC7E,IAAI,EAAE,qBAAqB,CAAC;CAC7B,CAIA;AAED;;;;GAIG;AACH,KAAK,cAAc,GAAG,MAAM;IAC1B,cAAc,EAAE;QACd,CAAC,KAAK,EAAE,aAAa,GAAG,qBAAqB,CAAC;KAC/C,CAAC;IACF,cAAc,EAAE;QAAE,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAAA;KAAE,CAAC;CACxD,CAAC;AAEF;;;;;GAKG;AACH,KAAK,mBAAmB,GAAG,CACzB,OAAO,EAAE,aAAa,KACnB,eAAe,GAAG,SAAS,CAAC;AAEjC;;;;;;GAMG;AACH,KAAK,kBAAkB,GAAG;IACxB,cAAc,EAAE,cAAc,CAAC;IAC/B,mBAAmB,EAAE,mBAAmB,CAAC;CAC1C,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,kBAAkB,GAAG,UAAU,CAMzE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,QAKrE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,SAAS,EAAE,aAAa,EAAE,EAC1B,QAAQ,EAAE,WAAW,EAAE,GAAG,SAAS,EACnC,EAAE,mBAAmB,EAAE,cAAc,EAAE,EAAE,kBAAkB;;;;SAiD5D;AAuDD;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,aAAa,GAAG,SAAS,EAChC,aAAa,EAAE,cAAc,GAC5B,kBAAkB,GAAG,IAAI,CAiB3B;AAmFD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,cAAc,EACxB,aAAa,EAAE,UAAU,EACzB,kBAAkB,EAAE,kBAAkB,GACrC,cAAc,CA+ChB;AAID;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,CAAC,EAAE,gBAAgB,QAclE"}
|