@metamask-previews/bridge-status-controller 1.0.0-preview-dbdf1da

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 (52) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +20 -0
  3. package/README.md +15 -0
  4. package/dist/bridge-status-controller.cjs +247 -0
  5. package/dist/bridge-status-controller.cjs.map +1 -0
  6. package/dist/bridge-status-controller.d.cts +44 -0
  7. package/dist/bridge-status-controller.d.cts.map +1 -0
  8. package/dist/bridge-status-controller.d.mts +44 -0
  9. package/dist/bridge-status-controller.d.mts.map +1 -0
  10. package/dist/bridge-status-controller.mjs +243 -0
  11. package/dist/bridge-status-controller.mjs.map +1 -0
  12. package/dist/constants.cjs +12 -0
  13. package/dist/constants.cjs.map +1 -0
  14. package/dist/constants.d.cts +10 -0
  15. package/dist/constants.d.cts.map +1 -0
  16. package/dist/constants.d.mts +10 -0
  17. package/dist/constants.d.mts.map +1 -0
  18. package/dist/constants.mjs +9 -0
  19. package/dist/constants.mjs.map +1 -0
  20. package/dist/index.cjs +17 -0
  21. package/dist/index.cjs.map +1 -0
  22. package/dist/index.d.cts +5 -0
  23. package/dist/index.d.cts.map +1 -0
  24. package/dist/index.d.mts +5 -0
  25. package/dist/index.d.mts.map +1 -0
  26. package/dist/index.mjs +5 -0
  27. package/dist/index.mjs.map +1 -0
  28. package/dist/types.cjs +42 -0
  29. package/dist/types.cjs.map +1 -0
  30. package/dist/types.d.cts +240 -0
  31. package/dist/types.d.cts.map +1 -0
  32. package/dist/types.d.mts +240 -0
  33. package/dist/types.d.mts.map +1 -0
  34. package/dist/types.mjs +39 -0
  35. package/dist/types.mjs.map +1 -0
  36. package/dist/utils/bridge-status.cjs +53 -0
  37. package/dist/utils/bridge-status.cjs.map +1 -0
  38. package/dist/utils/bridge-status.d.cts +10 -0
  39. package/dist/utils/bridge-status.d.cts.map +1 -0
  40. package/dist/utils/bridge-status.d.mts +10 -0
  41. package/dist/utils/bridge-status.d.mts.map +1 -0
  42. package/dist/utils/bridge-status.mjs +46 -0
  43. package/dist/utils/bridge-status.mjs.map +1 -0
  44. package/dist/utils/validators.cjs +161 -0
  45. package/dist/utils/validators.cjs.map +1 -0
  46. package/dist/utils/validators.d.cts +15 -0
  47. package/dist/utils/validators.d.cts.map +1 -0
  48. package/dist/utils/validators.d.mts +15 -0
  49. package/dist/utils/validators.d.mts.map +1 -0
  50. package/dist/utils/validators.mjs +155 -0
  51. package/dist/utils/validators.mjs.map +1 -0
  52. package/package.json +85 -0
@@ -0,0 +1,10 @@
1
+ import type { Quote } from "@metamask/bridge-controller";
2
+ import type { StatusResponse, StatusRequestWithSrcTxHash, StatusRequestDto, FetchFunction } from "../types.mjs";
3
+ export declare const getClientIdHeader: (clientId: string) => {
4
+ 'X-Client-Id': string;
5
+ };
6
+ export declare const BRIDGE_STATUS_BASE_URL: string;
7
+ export declare const getStatusRequestDto: (statusRequest: StatusRequestWithSrcTxHash) => StatusRequestDto;
8
+ export declare const fetchBridgeTxStatus: (statusRequest: StatusRequestWithSrcTxHash, clientId: string, fetchFn: FetchFunction) => Promise<StatusResponse>;
9
+ export declare const getStatusRequestWithSrcTxHash: (quote: Quote, srcTxHash: string) => StatusRequestWithSrcTxHash;
10
+ //# sourceMappingURL=bridge-status.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-status.d.mts","sourceRoot":"","sources":["../../src/utils/bridge-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,oCAAoC;AAIzD,OAAO,KAAK,EACV,cAAc,EACd,0BAA0B,EAC1B,gBAAgB,EAChB,aAAa,EACd,qBAAiB;AAElB,eAAO,MAAM,iBAAiB,aAAc,MAAM;;CAEhD,CAAC;AAEH,eAAO,MAAM,sBAAsB,QAAyC,CAAC;AAE7E,eAAO,MAAM,mBAAmB,kBACf,0BAA0B,KACxC,gBAiBF,CAAC;AAEF,eAAO,MAAM,mBAAmB,kBACf,0BAA0B,YAC/B,MAAM,WACP,aAAa,4BAwBvB,CAAC;AAEF,eAAO,MAAM,6BAA6B,UACjC,KAAK,aACD,MAAM,KAChB,0BAUF,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { getBridgeApiBaseUrl } from "@metamask/bridge-controller";
2
+ import { validateResponse, validators } from "./validators.mjs";
3
+ export const getClientIdHeader = (clientId) => ({
4
+ 'X-Client-Id': clientId,
5
+ });
6
+ export const BRIDGE_STATUS_BASE_URL = `${getBridgeApiBaseUrl()}/getTxStatus`;
7
+ export const getStatusRequestDto = (statusRequest) => {
8
+ const { quote, ...statusRequestNoQuote } = statusRequest;
9
+ const statusRequestNoQuoteFormatted = Object.fromEntries(Object.entries(statusRequestNoQuote).map(([key, value]) => [
10
+ key,
11
+ value.toString(),
12
+ ]));
13
+ const requestId = quote?.requestId ? { requestId: quote.requestId } : {};
14
+ return {
15
+ ...statusRequestNoQuoteFormatted,
16
+ ...requestId,
17
+ };
18
+ };
19
+ export const fetchBridgeTxStatus = async (statusRequest, clientId, fetchFn) => {
20
+ const statusRequestDto = getStatusRequestDto(statusRequest);
21
+ const params = new URLSearchParams(statusRequestDto);
22
+ // Fetch
23
+ const url = `${BRIDGE_STATUS_BASE_URL}?${params.toString()}`;
24
+ const rawTxStatus = await fetchFn(url, {
25
+ headers: getClientIdHeader(clientId),
26
+ });
27
+ // Validate
28
+ const isValid = validateResponse(validators, rawTxStatus, BRIDGE_STATUS_BASE_URL);
29
+ if (!isValid) {
30
+ throw new Error('Invalid response from bridge');
31
+ }
32
+ // Return
33
+ return rawTxStatus;
34
+ };
35
+ export const getStatusRequestWithSrcTxHash = (quote, srcTxHash) => {
36
+ return {
37
+ bridgeId: quote.bridgeId,
38
+ srcTxHash,
39
+ bridge: quote.bridges[0],
40
+ srcChainId: quote.srcChainId,
41
+ destChainId: quote.destChainId,
42
+ quote,
43
+ refuel: Boolean(quote.refuel),
44
+ };
45
+ };
46
+ //# sourceMappingURL=bridge-status.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-status.mjs","sourceRoot":"","sources":["../../src/utils/bridge-status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,oCAAoC;AAElE,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,yBAAqB;AAQ5D,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAE,EAAE,CAAC,CAAC;IACtD,aAAa,EAAE,QAAQ;CACxB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,mBAAmB,EAAE,cAAc,CAAC;AAE7E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,aAAyC,EACvB,EAAE;IACpB,MAAM,EAAE,KAAK,EAAE,GAAG,oBAAoB,EAAE,GAAG,aAAa,CAAC;IAEzD,MAAM,6BAA6B,GAAG,MAAM,CAAC,WAAW,CACtD,MAAM,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;QACzD,GAAG;QACH,KAAK,CAAC,QAAQ,EAAE;KACjB,CAAC,CAC+C,CAAC;IAEpD,MAAM,SAAS,GACb,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAEzD,OAAO;QACL,GAAG,6BAA6B;QAChC,GAAG,SAAS;KACb,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,EACtC,aAAyC,EACzC,QAAgB,EAChB,OAAsB,EACtB,EAAE;IACF,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,aAAa,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,gBAAgB,CAAC,CAAC;IAErD,QAAQ;IACR,MAAM,GAAG,GAAG,GAAG,sBAAsB,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,CAAC;IAE7D,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE;QACrC,OAAO,EAAE,iBAAiB,CAAC,QAAQ,CAAC;KACrC,CAAC,CAAC;IAEH,WAAW;IACX,MAAM,OAAO,GAAG,gBAAgB,CAC9B,UAAU,EACV,WAAW,EACX,sBAAsB,CACvB,CAAC;IACF,IAAI,CAAC,OAAO,EAAE;QACZ,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;KACjD;IAED,SAAS;IACT,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,KAAY,EACZ,SAAiB,EACW,EAAE;IAC9B,OAAO;QACL,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,SAAS;QACT,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACxB,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,KAAK;QACL,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;KAC9B,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import type { Quote } from '@metamask/bridge-controller';\nimport { getBridgeApiBaseUrl } from '@metamask/bridge-controller';\n\nimport { validateResponse, validators } from './validators';\nimport type {\n StatusResponse,\n StatusRequestWithSrcTxHash,\n StatusRequestDto,\n FetchFunction,\n} from '../types';\n\nexport const getClientIdHeader = (clientId: string) => ({\n 'X-Client-Id': clientId,\n});\n\nexport const BRIDGE_STATUS_BASE_URL = `${getBridgeApiBaseUrl()}/getTxStatus`;\n\nexport const getStatusRequestDto = (\n statusRequest: StatusRequestWithSrcTxHash,\n): StatusRequestDto => {\n const { quote, ...statusRequestNoQuote } = statusRequest;\n\n const statusRequestNoQuoteFormatted = Object.fromEntries(\n Object.entries(statusRequestNoQuote).map(([key, value]) => [\n key,\n value.toString(),\n ]),\n ) as unknown as Omit<StatusRequestDto, 'requestId'>;\n\n const requestId: { requestId: string } | Record<string, never> =\n quote?.requestId ? { requestId: quote.requestId } : {};\n\n return {\n ...statusRequestNoQuoteFormatted,\n ...requestId,\n };\n};\n\nexport const fetchBridgeTxStatus = async (\n statusRequest: StatusRequestWithSrcTxHash,\n clientId: string,\n fetchFn: FetchFunction,\n) => {\n const statusRequestDto = getStatusRequestDto(statusRequest);\n const params = new URLSearchParams(statusRequestDto);\n\n // Fetch\n const url = `${BRIDGE_STATUS_BASE_URL}?${params.toString()}`;\n\n const rawTxStatus = await fetchFn(url, {\n headers: getClientIdHeader(clientId),\n });\n\n // Validate\n const isValid = validateResponse<StatusResponse, unknown>(\n validators,\n rawTxStatus,\n BRIDGE_STATUS_BASE_URL,\n );\n if (!isValid) {\n throw new Error('Invalid response from bridge');\n }\n\n // Return\n return rawTxStatus;\n};\n\nexport const getStatusRequestWithSrcTxHash = (\n quote: Quote,\n srcTxHash: string,\n): StatusRequestWithSrcTxHash => {\n return {\n bridgeId: quote.bridgeId,\n srcTxHash,\n bridge: quote.bridges[0],\n srcChainId: quote.srcChainId,\n destChainId: quote.destChainId,\n quote,\n refuel: Boolean(quote.refuel),\n };\n};\n"]}
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validators = exports.validateResponse = exports.validateData = exports.validHex = void 0;
4
+ const controller_utils_1 = require("@metamask/controller-utils");
5
+ const bridge_status_1 = require("./bridge-status.cjs");
6
+ const types_1 = require("../types.cjs");
7
+ const validHex = (value) => typeof value === 'string' && Boolean(value.match(/^0x[a-f0-9]+$/u));
8
+ exports.validHex = validHex;
9
+ const isValidObject = (v) => typeof v === 'object' && v !== null;
10
+ const validateData = (validators, object, urlUsed, logError = true) => {
11
+ return validators.every(({ property, type, validator }) => {
12
+ const types = type.split('|');
13
+ const propertyString = String(property);
14
+ const valid = isValidObject(object) &&
15
+ types.some((_type) => typeof object[propertyString] === _type) &&
16
+ (!validator || validator(object[propertyString]));
17
+ if (!valid && logError) {
18
+ const value = isValidObject(object)
19
+ ? object[propertyString]
20
+ : undefined;
21
+ const typeString = isValidObject(object)
22
+ ? typeof object[propertyString]
23
+ : 'undefined';
24
+ console.error(`response to GET ${urlUsed} invalid for property ${String(property)}; value was:`, value, '| type was: ', typeString);
25
+ }
26
+ return valid;
27
+ });
28
+ };
29
+ exports.validateData = validateData;
30
+ const validateResponse = (validators, data, urlUsed) => {
31
+ if (data === null || data === undefined) {
32
+ return false;
33
+ }
34
+ return (0, exports.validateData)(validators, data, urlUsed);
35
+ };
36
+ exports.validateResponse = validateResponse;
37
+ const assetValidators = [
38
+ {
39
+ property: 'chainId',
40
+ type: 'number',
41
+ validator: (v) => typeof v === 'number',
42
+ },
43
+ {
44
+ property: 'address',
45
+ type: 'string',
46
+ validator: (v) => (0, controller_utils_1.isValidHexAddress)(v),
47
+ },
48
+ {
49
+ property: 'symbol',
50
+ type: 'string',
51
+ validator: (v) => typeof v === 'string',
52
+ },
53
+ {
54
+ property: 'name',
55
+ type: 'string',
56
+ validator: (v) => typeof v === 'string',
57
+ },
58
+ {
59
+ property: 'decimals',
60
+ type: 'number',
61
+ validator: (v) => typeof v === 'number',
62
+ },
63
+ {
64
+ property: 'icon',
65
+ // typeof null === 'object'
66
+ type: 'string|undefined|object',
67
+ validator: (v) => v === undefined || v === null || typeof v === 'string',
68
+ },
69
+ ];
70
+ const assetValidator = (v) => (0, exports.validateResponse)(assetValidators, v, bridge_status_1.BRIDGE_STATUS_BASE_URL);
71
+ const srcChainStatusValidators = [
72
+ {
73
+ property: 'chainId',
74
+ // For some reason, API returns destChain.chainId as a string, it's a number everywhere else
75
+ type: 'number|string',
76
+ validator: (v) => typeof v === 'number' || typeof v === 'string',
77
+ },
78
+ {
79
+ property: 'txHash',
80
+ type: 'string',
81
+ validator: exports.validHex,
82
+ },
83
+ {
84
+ property: 'amount',
85
+ type: 'string|undefined',
86
+ validator: (v) => v === undefined || typeof v === 'string',
87
+ },
88
+ {
89
+ property: 'token',
90
+ type: 'object|undefined',
91
+ validator: (v) => v === undefined ||
92
+ (v && typeof v === 'object' && Object.keys(v).length === 0) ||
93
+ assetValidator(v),
94
+ },
95
+ ];
96
+ const srcChainStatusValidator = (v) => (0, exports.validateResponse)(srcChainStatusValidators, v, bridge_status_1.BRIDGE_STATUS_BASE_URL);
97
+ const destChainStatusValidators = [
98
+ {
99
+ property: 'chainId',
100
+ // For some reason, API returns destChain.chainId as a string, it's a number everywhere else
101
+ type: 'number|string',
102
+ validator: (v) => typeof v === 'number' || typeof v === 'string',
103
+ },
104
+ {
105
+ property: 'amount',
106
+ type: 'string|undefined',
107
+ validator: (v) => v === undefined || typeof v === 'string',
108
+ },
109
+ {
110
+ property: 'txHash',
111
+ type: 'string|undefined',
112
+ validator: (v) => v === undefined || typeof v === 'string',
113
+ },
114
+ {
115
+ property: 'token',
116
+ type: 'object|undefined',
117
+ validator: (v) => v === undefined ||
118
+ (v && typeof v === 'object' && Object.keys(v).length === 0) ||
119
+ assetValidator(v),
120
+ },
121
+ ];
122
+ const destChainStatusValidator = (v) => (0, exports.validateResponse)(destChainStatusValidators, v, bridge_status_1.BRIDGE_STATUS_BASE_URL);
123
+ exports.validators = [
124
+ {
125
+ property: 'status',
126
+ type: 'string',
127
+ validator: (v) => Object.values(types_1.StatusTypes).includes(v),
128
+ },
129
+ {
130
+ property: 'srcChain',
131
+ type: 'object',
132
+ validator: srcChainStatusValidator,
133
+ },
134
+ {
135
+ property: 'destChain',
136
+ type: 'object|undefined',
137
+ validator: (v) => v === undefined || destChainStatusValidator(v),
138
+ },
139
+ {
140
+ property: 'bridge',
141
+ type: 'string|undefined',
142
+ validator: (v) => v === undefined || Object.values(types_1.BridgeId).includes(v),
143
+ },
144
+ {
145
+ property: 'isExpectedToken',
146
+ type: 'boolean|undefined',
147
+ validator: (v) => v === undefined || typeof v === 'boolean',
148
+ },
149
+ {
150
+ property: 'isUnrecognizedRouterAddress',
151
+ type: 'boolean|undefined',
152
+ validator: (v) => v === undefined || typeof v === 'boolean',
153
+ },
154
+ // TODO: add refuel validator
155
+ // {
156
+ // property: 'refuel',
157
+ // type: 'object',
158
+ // validator: (v: unknown) => Object.values(RefuelStatusResponse).includes(v),
159
+ // },
160
+ ];
161
+ //# sourceMappingURL=validators.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.cjs","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"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","sourcesContent":["import { isValidHexAddress } from '@metamask/controller-utils';\n\nimport { BRIDGE_STATUS_BASE_URL } from './bridge-status';\nimport type { DestChainStatus, SrcChainStatus, Asset } from '../types';\nimport { BridgeId, StatusTypes } from '../types';\n\ntype Validator<ExpectedResponse, DataToValidate> = {\n property: keyof ExpectedResponse | string;\n type: string;\n validator: (value: DataToValidate) => boolean;\n};\n\nexport const validHex = (value: unknown) =>\n typeof value === 'string' && Boolean(value.match(/^0x[a-f0-9]+$/u));\nconst isValidObject = (v: unknown): v is object =>\n typeof v === 'object' && v !== null;\n\nexport const validateData = <ExpectedResponse, DataToValidate>(\n validators: Validator<ExpectedResponse, DataToValidate>[],\n object: unknown,\n urlUsed: string,\n logError = true,\n): object is ExpectedResponse => {\n return validators.every(({ property, type, validator }) => {\n const types = type.split('|');\n const propertyString = String(property);\n\n const valid =\n isValidObject(object) &&\n types.some(\n (_type) =>\n typeof object[propertyString as keyof typeof object] === _type,\n ) &&\n (!validator || validator(object[propertyString as keyof typeof object]));\n\n if (!valid && logError) {\n const value = isValidObject(object)\n ? object[propertyString as keyof typeof object]\n : undefined;\n const typeString = isValidObject(object)\n ? typeof object[propertyString as keyof typeof object]\n : 'undefined';\n\n console.error(\n `response to GET ${urlUsed} invalid for property ${String(property)}; value was:`,\n value,\n '| type was: ',\n typeString,\n );\n }\n return valid;\n });\n};\n\nexport const validateResponse = <ExpectedResponse, DataToValidate>(\n validators: Validator<ExpectedResponse, DataToValidate>[],\n data: unknown,\n urlUsed: string,\n): data is ExpectedResponse => {\n if (data === null || data === undefined) {\n return false;\n }\n return validateData(validators, data, urlUsed);\n};\n\nconst assetValidators = [\n {\n property: 'chainId',\n type: 'number',\n validator: (v: unknown): v is number => typeof v === 'number',\n },\n {\n property: 'address',\n type: 'string',\n validator: (v: unknown): v is string => isValidHexAddress(v as string),\n },\n {\n property: 'symbol',\n type: 'string',\n validator: (v: unknown): v is string => typeof v === 'string',\n },\n {\n property: 'name',\n type: 'string',\n validator: (v: unknown): v is string => typeof v === 'string',\n },\n {\n property: 'decimals',\n type: 'number',\n validator: (v: unknown): v is number => typeof v === 'number',\n },\n {\n property: 'icon',\n // typeof null === 'object'\n type: 'string|undefined|object',\n validator: (v: unknown): v is string | undefined | object =>\n v === undefined || v === null || typeof v === 'string',\n },\n];\n\nconst assetValidator = (v: unknown): v is Asset =>\n validateResponse<Asset, unknown>(assetValidators, v, BRIDGE_STATUS_BASE_URL);\n\nconst srcChainStatusValidators = [\n {\n property: 'chainId',\n // For some reason, API returns destChain.chainId as a string, it's a number everywhere else\n type: 'number|string',\n validator: (v: unknown): v is number | string =>\n typeof v === 'number' || typeof v === 'string',\n },\n {\n property: 'txHash',\n type: 'string',\n validator: validHex,\n },\n {\n property: 'amount',\n type: 'string|undefined',\n validator: (v: unknown): v is string | undefined =>\n v === undefined || typeof v === 'string',\n },\n {\n property: 'token',\n type: 'object|undefined',\n validator: (v: unknown): v is object | undefined =>\n v === undefined ||\n (v && typeof v === 'object' && Object.keys(v).length === 0) ||\n assetValidator(v),\n },\n];\n\nconst srcChainStatusValidator = (v: unknown): v is SrcChainStatus =>\n validateResponse<SrcChainStatus, unknown>(\n srcChainStatusValidators,\n v,\n BRIDGE_STATUS_BASE_URL,\n );\n\nconst destChainStatusValidators = [\n {\n property: 'chainId',\n // For some reason, API returns destChain.chainId as a string, it's a number everywhere else\n type: 'number|string',\n validator: (v: unknown): v is number | string =>\n typeof v === 'number' || typeof v === 'string',\n },\n {\n property: 'amount',\n type: 'string|undefined',\n validator: (v: unknown): v is string | undefined =>\n v === undefined || typeof v === 'string',\n },\n {\n property: 'txHash',\n type: 'string|undefined',\n validator: (v: unknown): v is string | undefined =>\n v === undefined || typeof v === 'string',\n },\n {\n property: 'token',\n type: 'object|undefined',\n validator: (v: unknown): v is Asset | undefined =>\n v === undefined ||\n (v && typeof v === 'object' && Object.keys(v).length === 0) ||\n assetValidator(v),\n },\n];\n\nconst destChainStatusValidator = (v: unknown): v is DestChainStatus =>\n validateResponse<DestChainStatus, unknown>(\n destChainStatusValidators,\n v,\n BRIDGE_STATUS_BASE_URL,\n );\n\nexport const validators = [\n {\n property: 'status',\n type: 'string',\n validator: (v: unknown): v is StatusTypes =>\n Object.values(StatusTypes).includes(v as StatusTypes),\n },\n {\n property: 'srcChain',\n type: 'object',\n validator: srcChainStatusValidator,\n },\n {\n property: 'destChain',\n type: 'object|undefined',\n validator: (v: unknown): v is object | unknown =>\n v === undefined || destChainStatusValidator(v),\n },\n {\n property: 'bridge',\n type: 'string|undefined',\n validator: (v: unknown): v is BridgeId | undefined =>\n v === undefined || Object.values(BridgeId).includes(v as BridgeId),\n },\n {\n property: 'isExpectedToken',\n type: 'boolean|undefined',\n validator: (v: unknown): v is boolean | undefined =>\n v === undefined || typeof v === 'boolean',\n },\n {\n property: 'isUnrecognizedRouterAddress',\n type: 'boolean|undefined',\n validator: (v: unknown): v is boolean | undefined =>\n v === undefined || typeof v === 'boolean',\n },\n // TODO: add refuel validator\n // {\n // property: 'refuel',\n // type: 'object',\n // validator: (v: unknown) => Object.values(RefuelStatusResponse).includes(v),\n // },\n];\n"]}
@@ -0,0 +1,15 @@
1
+ type Validator<ExpectedResponse, DataToValidate> = {
2
+ property: keyof ExpectedResponse | string;
3
+ type: string;
4
+ validator: (value: DataToValidate) => boolean;
5
+ };
6
+ export declare const validHex: (value: unknown) => boolean;
7
+ export declare const validateData: <ExpectedResponse, DataToValidate>(validators: Validator<ExpectedResponse, DataToValidate>[], object: unknown, urlUsed: string, logError?: boolean) => object is ExpectedResponse;
8
+ export declare const validateResponse: <ExpectedResponse, DataToValidate>(validators: Validator<ExpectedResponse, DataToValidate>[], data: unknown, urlUsed: string) => data is ExpectedResponse;
9
+ export declare const validators: {
10
+ property: string;
11
+ type: string;
12
+ validator: (v: unknown) => v is unknown;
13
+ }[];
14
+ export {};
15
+ //# sourceMappingURL=validators.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.cts","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"AAMA,KAAK,SAAS,CAAC,gBAAgB,EAAE,cAAc,IAAI;IACjD,QAAQ,EAAE,MAAM,gBAAgB,GAAG,MAAM,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC;CAC/C,CAAC;AAEF,eAAO,MAAM,QAAQ,UAAW,OAAO,YAC8B,CAAC;AAItE,eAAO,MAAM,YAAY,wGAEf,OAAO,WACN,MAAM,mDAgChB,CAAC;AAEF,eAAO,MAAM,gBAAgB,sGAErB,OAAO,WACJ,MAAM,6BAMhB,CAAC;AAiHF,eAAO,MAAM,UAAU;;;mBAeJ,OAAO;GA2BzB,CAAC"}
@@ -0,0 +1,15 @@
1
+ type Validator<ExpectedResponse, DataToValidate> = {
2
+ property: keyof ExpectedResponse | string;
3
+ type: string;
4
+ validator: (value: DataToValidate) => boolean;
5
+ };
6
+ export declare const validHex: (value: unknown) => boolean;
7
+ export declare const validateData: <ExpectedResponse, DataToValidate>(validators: Validator<ExpectedResponse, DataToValidate>[], object: unknown, urlUsed: string, logError?: boolean) => object is ExpectedResponse;
8
+ export declare const validateResponse: <ExpectedResponse, DataToValidate>(validators: Validator<ExpectedResponse, DataToValidate>[], data: unknown, urlUsed: string) => data is ExpectedResponse;
9
+ export declare const validators: {
10
+ property: string;
11
+ type: string;
12
+ validator: (v: unknown) => v is unknown;
13
+ }[];
14
+ export {};
15
+ //# sourceMappingURL=validators.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.d.mts","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"AAMA,KAAK,SAAS,CAAC,gBAAgB,EAAE,cAAc,IAAI;IACjD,QAAQ,EAAE,MAAM,gBAAgB,GAAG,MAAM,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC;CAC/C,CAAC;AAEF,eAAO,MAAM,QAAQ,UAAW,OAAO,YAC8B,CAAC;AAItE,eAAO,MAAM,YAAY,wGAEf,OAAO,WACN,MAAM,mDAgChB,CAAC;AAEF,eAAO,MAAM,gBAAgB,sGAErB,OAAO,WACJ,MAAM,6BAMhB,CAAC;AAiHF,eAAO,MAAM,UAAU;;;mBAeJ,OAAO;GA2BzB,CAAC"}
@@ -0,0 +1,155 @@
1
+ import { isValidHexAddress } from "@metamask/controller-utils";
2
+ import { BRIDGE_STATUS_BASE_URL } from "./bridge-status.mjs";
3
+ import { BridgeId, StatusTypes } from "../types.mjs";
4
+ export const validHex = (value) => typeof value === 'string' && Boolean(value.match(/^0x[a-f0-9]+$/u));
5
+ const isValidObject = (v) => typeof v === 'object' && v !== null;
6
+ export const validateData = (validators, object, urlUsed, logError = true) => {
7
+ return validators.every(({ property, type, validator }) => {
8
+ const types = type.split('|');
9
+ const propertyString = String(property);
10
+ const valid = isValidObject(object) &&
11
+ types.some((_type) => typeof object[propertyString] === _type) &&
12
+ (!validator || validator(object[propertyString]));
13
+ if (!valid && logError) {
14
+ const value = isValidObject(object)
15
+ ? object[propertyString]
16
+ : undefined;
17
+ const typeString = isValidObject(object)
18
+ ? typeof object[propertyString]
19
+ : 'undefined';
20
+ console.error(`response to GET ${urlUsed} invalid for property ${String(property)}; value was:`, value, '| type was: ', typeString);
21
+ }
22
+ return valid;
23
+ });
24
+ };
25
+ export const validateResponse = (validators, data, urlUsed) => {
26
+ if (data === null || data === undefined) {
27
+ return false;
28
+ }
29
+ return validateData(validators, data, urlUsed);
30
+ };
31
+ const assetValidators = [
32
+ {
33
+ property: 'chainId',
34
+ type: 'number',
35
+ validator: (v) => typeof v === 'number',
36
+ },
37
+ {
38
+ property: 'address',
39
+ type: 'string',
40
+ validator: (v) => isValidHexAddress(v),
41
+ },
42
+ {
43
+ property: 'symbol',
44
+ type: 'string',
45
+ validator: (v) => typeof v === 'string',
46
+ },
47
+ {
48
+ property: 'name',
49
+ type: 'string',
50
+ validator: (v) => typeof v === 'string',
51
+ },
52
+ {
53
+ property: 'decimals',
54
+ type: 'number',
55
+ validator: (v) => typeof v === 'number',
56
+ },
57
+ {
58
+ property: 'icon',
59
+ // typeof null === 'object'
60
+ type: 'string|undefined|object',
61
+ validator: (v) => v === undefined || v === null || typeof v === 'string',
62
+ },
63
+ ];
64
+ const assetValidator = (v) => validateResponse(assetValidators, v, BRIDGE_STATUS_BASE_URL);
65
+ const srcChainStatusValidators = [
66
+ {
67
+ property: 'chainId',
68
+ // For some reason, API returns destChain.chainId as a string, it's a number everywhere else
69
+ type: 'number|string',
70
+ validator: (v) => typeof v === 'number' || typeof v === 'string',
71
+ },
72
+ {
73
+ property: 'txHash',
74
+ type: 'string',
75
+ validator: validHex,
76
+ },
77
+ {
78
+ property: 'amount',
79
+ type: 'string|undefined',
80
+ validator: (v) => v === undefined || typeof v === 'string',
81
+ },
82
+ {
83
+ property: 'token',
84
+ type: 'object|undefined',
85
+ validator: (v) => v === undefined ||
86
+ (v && typeof v === 'object' && Object.keys(v).length === 0) ||
87
+ assetValidator(v),
88
+ },
89
+ ];
90
+ const srcChainStatusValidator = (v) => validateResponse(srcChainStatusValidators, v, BRIDGE_STATUS_BASE_URL);
91
+ const destChainStatusValidators = [
92
+ {
93
+ property: 'chainId',
94
+ // For some reason, API returns destChain.chainId as a string, it's a number everywhere else
95
+ type: 'number|string',
96
+ validator: (v) => typeof v === 'number' || typeof v === 'string',
97
+ },
98
+ {
99
+ property: 'amount',
100
+ type: 'string|undefined',
101
+ validator: (v) => v === undefined || typeof v === 'string',
102
+ },
103
+ {
104
+ property: 'txHash',
105
+ type: 'string|undefined',
106
+ validator: (v) => v === undefined || typeof v === 'string',
107
+ },
108
+ {
109
+ property: 'token',
110
+ type: 'object|undefined',
111
+ validator: (v) => v === undefined ||
112
+ (v && typeof v === 'object' && Object.keys(v).length === 0) ||
113
+ assetValidator(v),
114
+ },
115
+ ];
116
+ const destChainStatusValidator = (v) => validateResponse(destChainStatusValidators, v, BRIDGE_STATUS_BASE_URL);
117
+ export const validators = [
118
+ {
119
+ property: 'status',
120
+ type: 'string',
121
+ validator: (v) => Object.values(StatusTypes).includes(v),
122
+ },
123
+ {
124
+ property: 'srcChain',
125
+ type: 'object',
126
+ validator: srcChainStatusValidator,
127
+ },
128
+ {
129
+ property: 'destChain',
130
+ type: 'object|undefined',
131
+ validator: (v) => v === undefined || destChainStatusValidator(v),
132
+ },
133
+ {
134
+ property: 'bridge',
135
+ type: 'string|undefined',
136
+ validator: (v) => v === undefined || Object.values(BridgeId).includes(v),
137
+ },
138
+ {
139
+ property: 'isExpectedToken',
140
+ type: 'boolean|undefined',
141
+ validator: (v) => v === undefined || typeof v === 'boolean',
142
+ },
143
+ {
144
+ property: 'isUnrecognizedRouterAddress',
145
+ type: 'boolean|undefined',
146
+ validator: (v) => v === undefined || typeof v === 'boolean',
147
+ },
148
+ // TODO: add refuel validator
149
+ // {
150
+ // property: 'refuel',
151
+ // type: 'object',
152
+ // validator: (v: unknown) => Object.values(RefuelStatusResponse).includes(v),
153
+ // },
154
+ ];
155
+ //# sourceMappingURL=validators.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validators.mjs","sourceRoot":"","sources":["../../src/utils/validators.ts"],"names":[],"mappings":"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","sourcesContent":["import { isValidHexAddress } from '@metamask/controller-utils';\n\nimport { BRIDGE_STATUS_BASE_URL } from './bridge-status';\nimport type { DestChainStatus, SrcChainStatus, Asset } from '../types';\nimport { BridgeId, StatusTypes } from '../types';\n\ntype Validator<ExpectedResponse, DataToValidate> = {\n property: keyof ExpectedResponse | string;\n type: string;\n validator: (value: DataToValidate) => boolean;\n};\n\nexport const validHex = (value: unknown) =>\n typeof value === 'string' && Boolean(value.match(/^0x[a-f0-9]+$/u));\nconst isValidObject = (v: unknown): v is object =>\n typeof v === 'object' && v !== null;\n\nexport const validateData = <ExpectedResponse, DataToValidate>(\n validators: Validator<ExpectedResponse, DataToValidate>[],\n object: unknown,\n urlUsed: string,\n logError = true,\n): object is ExpectedResponse => {\n return validators.every(({ property, type, validator }) => {\n const types = type.split('|');\n const propertyString = String(property);\n\n const valid =\n isValidObject(object) &&\n types.some(\n (_type) =>\n typeof object[propertyString as keyof typeof object] === _type,\n ) &&\n (!validator || validator(object[propertyString as keyof typeof object]));\n\n if (!valid && logError) {\n const value = isValidObject(object)\n ? object[propertyString as keyof typeof object]\n : undefined;\n const typeString = isValidObject(object)\n ? typeof object[propertyString as keyof typeof object]\n : 'undefined';\n\n console.error(\n `response to GET ${urlUsed} invalid for property ${String(property)}; value was:`,\n value,\n '| type was: ',\n typeString,\n );\n }\n return valid;\n });\n};\n\nexport const validateResponse = <ExpectedResponse, DataToValidate>(\n validators: Validator<ExpectedResponse, DataToValidate>[],\n data: unknown,\n urlUsed: string,\n): data is ExpectedResponse => {\n if (data === null || data === undefined) {\n return false;\n }\n return validateData(validators, data, urlUsed);\n};\n\nconst assetValidators = [\n {\n property: 'chainId',\n type: 'number',\n validator: (v: unknown): v is number => typeof v === 'number',\n },\n {\n property: 'address',\n type: 'string',\n validator: (v: unknown): v is string => isValidHexAddress(v as string),\n },\n {\n property: 'symbol',\n type: 'string',\n validator: (v: unknown): v is string => typeof v === 'string',\n },\n {\n property: 'name',\n type: 'string',\n validator: (v: unknown): v is string => typeof v === 'string',\n },\n {\n property: 'decimals',\n type: 'number',\n validator: (v: unknown): v is number => typeof v === 'number',\n },\n {\n property: 'icon',\n // typeof null === 'object'\n type: 'string|undefined|object',\n validator: (v: unknown): v is string | undefined | object =>\n v === undefined || v === null || typeof v === 'string',\n },\n];\n\nconst assetValidator = (v: unknown): v is Asset =>\n validateResponse<Asset, unknown>(assetValidators, v, BRIDGE_STATUS_BASE_URL);\n\nconst srcChainStatusValidators = [\n {\n property: 'chainId',\n // For some reason, API returns destChain.chainId as a string, it's a number everywhere else\n type: 'number|string',\n validator: (v: unknown): v is number | string =>\n typeof v === 'number' || typeof v === 'string',\n },\n {\n property: 'txHash',\n type: 'string',\n validator: validHex,\n },\n {\n property: 'amount',\n type: 'string|undefined',\n validator: (v: unknown): v is string | undefined =>\n v === undefined || typeof v === 'string',\n },\n {\n property: 'token',\n type: 'object|undefined',\n validator: (v: unknown): v is object | undefined =>\n v === undefined ||\n (v && typeof v === 'object' && Object.keys(v).length === 0) ||\n assetValidator(v),\n },\n];\n\nconst srcChainStatusValidator = (v: unknown): v is SrcChainStatus =>\n validateResponse<SrcChainStatus, unknown>(\n srcChainStatusValidators,\n v,\n BRIDGE_STATUS_BASE_URL,\n );\n\nconst destChainStatusValidators = [\n {\n property: 'chainId',\n // For some reason, API returns destChain.chainId as a string, it's a number everywhere else\n type: 'number|string',\n validator: (v: unknown): v is number | string =>\n typeof v === 'number' || typeof v === 'string',\n },\n {\n property: 'amount',\n type: 'string|undefined',\n validator: (v: unknown): v is string | undefined =>\n v === undefined || typeof v === 'string',\n },\n {\n property: 'txHash',\n type: 'string|undefined',\n validator: (v: unknown): v is string | undefined =>\n v === undefined || typeof v === 'string',\n },\n {\n property: 'token',\n type: 'object|undefined',\n validator: (v: unknown): v is Asset | undefined =>\n v === undefined ||\n (v && typeof v === 'object' && Object.keys(v).length === 0) ||\n assetValidator(v),\n },\n];\n\nconst destChainStatusValidator = (v: unknown): v is DestChainStatus =>\n validateResponse<DestChainStatus, unknown>(\n destChainStatusValidators,\n v,\n BRIDGE_STATUS_BASE_URL,\n );\n\nexport const validators = [\n {\n property: 'status',\n type: 'string',\n validator: (v: unknown): v is StatusTypes =>\n Object.values(StatusTypes).includes(v as StatusTypes),\n },\n {\n property: 'srcChain',\n type: 'object',\n validator: srcChainStatusValidator,\n },\n {\n property: 'destChain',\n type: 'object|undefined',\n validator: (v: unknown): v is object | unknown =>\n v === undefined || destChainStatusValidator(v),\n },\n {\n property: 'bridge',\n type: 'string|undefined',\n validator: (v: unknown): v is BridgeId | undefined =>\n v === undefined || Object.values(BridgeId).includes(v as BridgeId),\n },\n {\n property: 'isExpectedToken',\n type: 'boolean|undefined',\n validator: (v: unknown): v is boolean | undefined =>\n v === undefined || typeof v === 'boolean',\n },\n {\n property: 'isUnrecognizedRouterAddress',\n type: 'boolean|undefined',\n validator: (v: unknown): v is boolean | undefined =>\n v === undefined || typeof v === 'boolean',\n },\n // TODO: add refuel validator\n // {\n // property: 'refuel',\n // type: 'object',\n // validator: (v: unknown) => Object.values(RefuelStatusResponse).includes(v),\n // },\n];\n"]}
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@metamask-previews/bridge-status-controller",
3
+ "version": "1.0.0-preview-dbdf1da",
4
+ "description": "Manages bridge-related status fetching functionality for MetaMask",
5
+ "keywords": [
6
+ "MetaMask",
7
+ "Ethereum"
8
+ ],
9
+ "homepage": "https://github.com/MetaMask/core/tree/main/packages/bridge-status-controller#readme",
10
+ "bugs": {
11
+ "url": "https://github.com/MetaMask/core/issues"
12
+ },
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/MetaMask/core.git"
16
+ },
17
+ "license": "MIT",
18
+ "sideEffects": false,
19
+ "exports": {
20
+ ".": {
21
+ "import": {
22
+ "types": "./dist/index.d.mts",
23
+ "default": "./dist/index.mjs"
24
+ },
25
+ "require": {
26
+ "types": "./dist/index.d.cts",
27
+ "default": "./dist/index.cjs"
28
+ }
29
+ },
30
+ "./package.json": "./package.json"
31
+ },
32
+ "main": "./dist/index.cjs",
33
+ "types": "./dist/index.d.cts",
34
+ "files": [
35
+ "dist/"
36
+ ],
37
+ "scripts": {
38
+ "build": "ts-bridge --project tsconfig.build.json --verbose --clean --no-references",
39
+ "build:docs": "typedoc",
40
+ "changelog:update": "../../scripts/update-changelog.sh @metamask/bridge-status-controller",
41
+ "changelog:validate": "../../scripts/validate-changelog.sh @metamask/bridge-status-controller",
42
+ "publish:preview": "yarn npm publish --tag preview",
43
+ "since-latest-release": "../../scripts/since-latest-release.sh",
44
+ "test": "NODE_OPTIONS=--experimental-vm-modules jest --reporters=jest-silent-reporter",
45
+ "test:clean": "NODE_OPTIONS=--experimental-vm-modules jest --clearCache",
46
+ "test:verbose": "NODE_OPTIONS=--experimental-vm-modules jest --verbose",
47
+ "test:watch": "NODE_OPTIONS=--experimental-vm-modules jest --watch"
48
+ },
49
+ "dependencies": {
50
+ "@metamask/base-controller": "^8.0.0",
51
+ "@metamask/bridge-controller": "^1.0.0",
52
+ "@metamask/controller-utils": "^11.5.0",
53
+ "@metamask/polling-controller": "^12.0.3",
54
+ "@metamask/utils": "^11.2.0"
55
+ },
56
+ "devDependencies": {
57
+ "@metamask/accounts-controller": "^24.0.0",
58
+ "@metamask/auto-changelog": "^3.4.4",
59
+ "@metamask/network-controller": "^22.2.1",
60
+ "@metamask/transaction-controller": "^46.0.0",
61
+ "@types/jest": "^27.4.1",
62
+ "deepmerge": "^4.2.2",
63
+ "jest": "^27.5.1",
64
+ "jest-environment-jsdom": "^27.5.1",
65
+ "lodash": "^4.17.21",
66
+ "nock": "^13.3.1",
67
+ "ts-jest": "^27.1.4",
68
+ "typedoc": "^0.24.8",
69
+ "typedoc-plugin-missing-exports": "^2.0.0",
70
+ "typescript": "~5.2.2"
71
+ },
72
+ "peerDependencies": {
73
+ "@metamask/accounts-controller": "^24.0.0",
74
+ "@metamask/bridge-controller": "^1.0.0",
75
+ "@metamask/network-controller": "^22.0.0",
76
+ "@metamask/transaction-controller": "^46.0.0"
77
+ },
78
+ "engines": {
79
+ "node": "^18.18 || >=20"
80
+ },
81
+ "publishConfig": {
82
+ "access": "public",
83
+ "registry": "https://registry.npmjs.org/"
84
+ }
85
+ }