@api3/commons 0.8.0 → 0.9.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/dist/blockchain-utilities/derivation.d.ts +3 -0
- package/dist/blockchain-utilities/derivation.d.ts.map +1 -1
- package/dist/blockchain-utilities/derivation.js +19 -1
- package/dist/blockchain-utilities/derivation.js.map +1 -1
- package/dist/http/index.d.ts +4 -2
- package/dist/http/index.d.ts.map +1 -1
- package/dist/http/index.js +10 -5
- package/dist/http/index.js.map +1 -1
- package/package.json +1 -1
- package/src/blockchain-utilities/derivation.test.ts +153 -81
- package/src/blockchain-utilities/derivation.ts +23 -0
- package/src/http/index.test.ts +4 -6
- package/src/http/index.ts +14 -6
|
@@ -18,4 +18,7 @@ export declare const fromBytes32String: (input: Hex) => string;
|
|
|
18
18
|
export declare const deriveSponsorWallet: (airnodeMnemonic: Mnemonic, dapiName: string, protocolId: ProtocolId) => ethers.Wallet;
|
|
19
19
|
export declare const deriveBeaconId: (airnodeAddress: Address, templateId: Hex) => string;
|
|
20
20
|
export declare const deriveBeaconSetId: (beaconIds: Hex[]) => string;
|
|
21
|
+
export declare const deriveHdNodeFromXpub: (xpub: string) => ethers.utils.HDNode;
|
|
22
|
+
export declare const verifyAirnodeXpub: (airnodeXpub: string, airnodeAddress: Address) => ethers.utils.HDNode;
|
|
23
|
+
export declare function deriveSponsorWalletAddress(airnodeXpub: string, sponsorAddress: Address, protocolId: ProtocolId, airnodeAddress?: Address): string;
|
|
21
24
|
//# sourceMappingURL=derivation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derivation.d.ts","sourceRoot":"","sources":["../../src/blockchain-utilities/derivation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEvD,eAAO,MAAM,YAAY;;;;;;CAMf,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE1E,eAAO,MAAM,kBAAkB,YAAa,OAAO,cAAc,GAAG,qBAAqB,GAAG,WACe,CAAC;AAE5G,eAAO,MAAM,kBAAkB,eAAgB,GAAG,qBAAqB,GAAG,WACa,CAAC;AAExF,eAAO,MAAM,gBAAgB,aAAc,MAAM,gBAAgB,MAAM,WACsC,CAAC;AAE9G,eAAO,MAAM,iBAAiB,oBAAqB,QAAQ,WACwC,CAAC;AAEpG,wBAAgB,kCAAkC,CAAC,cAAc,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,UAQjG;AAED,eAAO,MAAM,eAAe,UAAW,MAAM,WAA4C,CAAC;AAE1F,eAAO,MAAM,iBAAiB,UAAW,GAAG,WAA2C,CAAC;AAExF,eAAO,MAAM,mBAAmB,oBAAqB,QAAQ,YAAY,MAAM,cAAc,UAAU,kBAStG,CAAC;AAEF,eAAO,MAAM,cAAc,mBAAoB,OAAO,cAAc,GAAG,WACe,CAAC;AAEvF,eAAO,MAAM,iBAAiB,cAAe,GAAG,EAAE,WAEuC,CAAC"}
|
|
1
|
+
{"version":3,"file":"derivation.d.ts","sourceRoot":"","sources":["../../src/blockchain-utilities/derivation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,OAAO,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEvD,eAAO,MAAM,YAAY;;;;;;CAMf,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE1E,eAAO,MAAM,kBAAkB,YAAa,OAAO,cAAc,GAAG,qBAAqB,GAAG,WACe,CAAC;AAE5G,eAAO,MAAM,kBAAkB,eAAgB,GAAG,qBAAqB,GAAG,WACa,CAAC;AAExF,eAAO,MAAM,gBAAgB,aAAc,MAAM,gBAAgB,MAAM,WACsC,CAAC;AAE9G,eAAO,MAAM,iBAAiB,oBAAqB,QAAQ,WACwC,CAAC;AAEpG,wBAAgB,kCAAkC,CAAC,cAAc,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,UAQjG;AAED,eAAO,MAAM,eAAe,UAAW,MAAM,WAA4C,CAAC;AAE1F,eAAO,MAAM,iBAAiB,UAAW,GAAG,WAA2C,CAAC;AAExF,eAAO,MAAM,mBAAmB,oBAAqB,QAAQ,YAAY,MAAM,cAAc,UAAU,kBAStG,CAAC;AAEF,eAAO,MAAM,cAAc,mBAAoB,OAAO,cAAc,GAAG,WACe,CAAC;AAEvF,eAAO,MAAM,iBAAiB,cAAe,GAAG,EAAE,WAEuC,CAAC;AAE1F,eAAO,MAAM,oBAAoB,SAAU,MAAM,wBAA8C,CAAC;AAEhG,eAAO,MAAM,iBAAiB,gBAAiB,MAAM,kBAAkB,OAAO,KAAG,OAAO,KAAK,CAAC,MAQ7F,CAAC;AAEF,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,OAAO,EACvB,UAAU,EAAE,UAAU,EACtB,cAAc,CAAC,EAAE,OAAO,UAKzB"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deriveBeaconSetId = exports.deriveBeaconId = exports.deriveSponsorWallet = exports.fromBytes32String = exports.toBytes32String = exports.deriveWalletPathFromSponsorAddress = exports.deriveAirnodeXpub = exports.deriveEndpointId = exports.deriveTemplateIdV1 = exports.deriveTemplateIdV0 = exports.PROTOCOL_IDS = void 0;
|
|
3
|
+
exports.deriveSponsorWalletAddress = exports.verifyAirnodeXpub = exports.deriveHdNodeFromXpub = exports.deriveBeaconSetId = exports.deriveBeaconId = exports.deriveSponsorWallet = exports.fromBytes32String = exports.toBytes32String = exports.deriveWalletPathFromSponsorAddress = exports.deriveAirnodeXpub = exports.deriveEndpointId = exports.deriveTemplateIdV1 = exports.deriveTemplateIdV0 = exports.PROTOCOL_IDS = void 0;
|
|
4
4
|
const ethers_1 = require("ethers");
|
|
5
5
|
exports.PROTOCOL_IDS = {
|
|
6
6
|
RRP: '1',
|
|
@@ -44,4 +44,22 @@ const deriveBeaconSetId = (beaconIds) =>
|
|
|
44
44
|
// By convention beacon IDs are sorted alphabetically - the ordering impacts the resulting hash.
|
|
45
45
|
ethers_1.ethers.utils.keccak256(ethers_1.ethers.utils.defaultAbiCoder.encode(['bytes32[]'], [beaconIds]));
|
|
46
46
|
exports.deriveBeaconSetId = deriveBeaconSetId;
|
|
47
|
+
const deriveHdNodeFromXpub = (xpub) => ethers_1.ethers.utils.HDNode.fromExtendedKey(xpub);
|
|
48
|
+
exports.deriveHdNodeFromXpub = deriveHdNodeFromXpub;
|
|
49
|
+
const verifyAirnodeXpub = (airnodeXpub, airnodeAddress) => {
|
|
50
|
+
// The xpub is expected to belong to the hardened path m/44'/60'/0' so we must derive the child default derivation
|
|
51
|
+
// path m/44'/60'/0'/0/0 to compare it and check if xpub belongs to the Airnode wallet.
|
|
52
|
+
const hdNode = (0, exports.deriveHdNodeFromXpub)(airnodeXpub);
|
|
53
|
+
if (airnodeAddress !== hdNode.derivePath('0/0').address) {
|
|
54
|
+
throw new Error(`xpub does not belong to Airnode: ${airnodeAddress}`);
|
|
55
|
+
}
|
|
56
|
+
return hdNode;
|
|
57
|
+
};
|
|
58
|
+
exports.verifyAirnodeXpub = verifyAirnodeXpub;
|
|
59
|
+
function deriveSponsorWalletAddress(airnodeXpub, sponsorAddress, protocolId, airnodeAddress) {
|
|
60
|
+
const hdNode = airnodeAddress ? (0, exports.verifyAirnodeXpub)(airnodeXpub, airnodeAddress) : (0, exports.deriveHdNodeFromXpub)(airnodeXpub);
|
|
61
|
+
const derivationPath = deriveWalletPathFromSponsorAddress(sponsorAddress, protocolId);
|
|
62
|
+
return hdNode.derivePath(derivationPath).address;
|
|
63
|
+
}
|
|
64
|
+
exports.deriveSponsorWalletAddress = deriveSponsorWalletAddress;
|
|
47
65
|
//# sourceMappingURL=derivation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"derivation.js","sourceRoot":"","sources":["../../src/blockchain-utilities/derivation.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"derivation.js","sourceRoot":"","sources":["../../src/blockchain-utilities/derivation.ts"],"names":[],"mappings":";;;AAAA,mCAAgC;AAInB,QAAA,YAAY,GAAG;IAC1B,GAAG,EAAE,GAAG;IACR,GAAG,EAAE,GAAG;IACR,WAAW,EAAE,GAAG;IAChB,WAAW,EAAE,GAAG;IAChB,SAAS,EAAE,GAAG;CACN,CAAC;AAIJ,MAAM,kBAAkB,GAAG,CAAC,OAAgB,EAAE,UAAe,EAAE,iBAAsB,EAAE,EAAE,CAC9F,eAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAD/F,QAAA,kBAAkB,sBAC6E;AAErG,MAAM,kBAAkB,GAAG,CAAC,UAAe,EAAE,iBAAsB,EAAE,EAAE,CAC5E,eAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC;AAD3E,QAAA,kBAAkB,sBACyD;AAEjF,MAAM,gBAAgB,GAAG,CAAC,QAAgB,EAAE,YAAoB,EAAE,EAAE,CACzE,eAAM,CAAC,KAAK,CAAC,SAAS,CAAC,eAAM,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;AADjG,QAAA,gBAAgB,oBACiF;AAEvG,MAAM,iBAAiB,GAAG,CAAC,eAAyB,EAAE,EAAE,CAC7D,eAAM,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC;AADvF,QAAA,iBAAiB,qBACsE;AAEpG,SAAgB,kCAAkC,CAAC,cAAuB,EAAE,UAAsB;IAChG,MAAM,gBAAgB,GAAG,eAAM,CAAC,SAAS,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IAC/D,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;QAC1B,MAAM,uBAAuB,GAAG,gBAAgB,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QAC7D,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;KACzD;IACD,OAAO,GAAG,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AAC5C,CAAC;AARD,gFAQC;AAEM,MAAM,eAAe,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,eAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;AAA7E,QAAA,eAAe,mBAA8D;AAEnF,MAAM,iBAAiB,GAAG,CAAC,KAAU,EAAE,EAAE,CAAC,eAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC;AAA3E,QAAA,iBAAiB,qBAA0D;AAEjF,MAAM,mBAAmB,GAAG,CAAC,eAAyB,EAAE,QAAgB,EAAE,UAAsB,EAAE,EAAE;IACzG,oFAAoF;IACpF,MAAM,cAAc,GAAG,eAAM,CAAC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAY,CAAC;IACjF,MAAM,aAAa,GAAG,eAAM,CAAC,MAAM,CAAC,YAAY,CAC9C,eAAe,EACf,gBAAgB,kCAAkC,CAAC,cAAc,EAAE,UAAU,CAAC,EAAE,CACjF,CAAC;IAEF,OAAO,aAAa,CAAC;AACvB,CAAC,CAAC;AATW,QAAA,mBAAmB,uBAS9B;AAEK,MAAM,cAAc,GAAG,CAAC,cAAuB,EAAE,UAAe,EAAE,EAAE,CACzE,eAAM,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,EAAE,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC;AAD1E,QAAA,cAAc,kBAC4D;AAEhF,MAAM,iBAAiB,GAAG,CAAC,SAAgB,EAAE,EAAE;AACpD,gGAAgG;AAChG,eAAM,CAAC,KAAK,CAAC,SAAS,CAAC,eAAM,CAAC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAF7E,QAAA,iBAAiB,qBAE4D;AAEnF,MAAM,oBAAoB,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,eAAM,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;AAAnF,QAAA,oBAAoB,wBAA+D;AAEzF,MAAM,iBAAiB,GAAG,CAAC,WAAmB,EAAE,cAAuB,EAAuB,EAAE;IACrG,kHAAkH;IAClH,uFAAuF;IACvF,MAAM,MAAM,GAAG,IAAA,4BAAoB,EAAC,WAAW,CAAC,CAAC;IACjD,IAAI,cAAc,KAAK,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE;QACvD,MAAM,IAAI,KAAK,CAAC,oCAAoC,cAAc,EAAE,CAAC,CAAC;KACvE;IACD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AARW,QAAA,iBAAiB,qBAQ5B;AAEF,SAAgB,0BAA0B,CACxC,WAAmB,EACnB,cAAuB,EACvB,UAAsB,EACtB,cAAwB;IAExB,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,IAAA,yBAAiB,EAAC,WAAW,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,IAAA,4BAAoB,EAAC,WAAW,CAAC,CAAC;IACnH,MAAM,cAAc,GAAG,kCAAkC,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;IACtF,OAAO,MAAM,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC;AACnD,CAAC;AATD,gEASC"}
|
package/dist/http/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Method, type AxiosError
|
|
1
|
+
import { type Method, type AxiosError } from 'axios';
|
|
2
2
|
export interface Request {
|
|
3
3
|
readonly method: Method;
|
|
4
4
|
readonly url: string;
|
|
@@ -8,7 +8,7 @@ export interface Request {
|
|
|
8
8
|
readonly body?: unknown;
|
|
9
9
|
}
|
|
10
10
|
export interface ErrorResponse {
|
|
11
|
-
readonly
|
|
11
|
+
readonly response: unknown;
|
|
12
12
|
readonly message: string;
|
|
13
13
|
readonly code: string | undefined;
|
|
14
14
|
}
|
|
@@ -17,11 +17,13 @@ interface ExecuteRequestSuccess<T> {
|
|
|
17
17
|
success: true;
|
|
18
18
|
errorData: undefined;
|
|
19
19
|
data: T;
|
|
20
|
+
statusCode: number;
|
|
20
21
|
}
|
|
21
22
|
interface ExecuteRequestError {
|
|
22
23
|
success: false;
|
|
23
24
|
errorData: ErrorResponse;
|
|
24
25
|
data: undefined;
|
|
26
|
+
statusCode: number | undefined;
|
|
25
27
|
}
|
|
26
28
|
export type ExecuteRequestResult<T> = ExecuteRequestError | ExecuteRequestSuccess<T>;
|
|
27
29
|
export declare function executeRequest<T>(request: Request): Promise<ExecuteRequestResult<T>>;
|
package/dist/http/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AACA,OAAc,EAAE,KAAK,MAAM,EAAE,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AACA,OAAc,EAAE,KAAK,MAAM,EAAE,KAAK,UAAU,EAAsB,MAAM,OAAO,CAAC;AAIhF,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC3C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,eAAO,MAAM,qBAAqB,UAAW,UAAU,KAAG,aAOzD,CAAC;AAEF,UAAU,qBAAqB,CAAC,CAAC;IAC/B,OAAO,EAAE,IAAI,CAAC;IACd,SAAS,EAAE,SAAS,CAAC;IACrB,IAAI,EAAE,CAAC,CAAC;IACR,UAAU,EAAE,MAAM,CAAC;CACpB;AACD,UAAU,mBAAmB;IAC3B,OAAO,EAAE,KAAK,CAAC;IACf,SAAS,EAAE,aAAa,CAAC;IACzB,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,MAAM,oBAAoB,CAAC,CAAC,IAAI,mBAAmB,GAAG,qBAAqB,CAAC,CAAC,CAAC,CAAC;AAErF,wBAAsB,cAAc,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAwB1F"}
|
package/dist/http/index.js
CHANGED
|
@@ -6,12 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.executeRequest = exports.extractAxiosErrorData = void 0;
|
|
7
7
|
const promise_utils_1 = require("@api3/promise-utils");
|
|
8
8
|
const axios_1 = __importDefault(require("axios"));
|
|
9
|
-
const pick_1 = __importDefault(require("lodash/pick"));
|
|
10
9
|
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
11
10
|
const extractAxiosErrorData = (error) => {
|
|
12
11
|
// Inspired by: https://axios-http.com/docs/handling_errors
|
|
13
12
|
return {
|
|
14
|
-
|
|
13
|
+
response: error.response?.data,
|
|
15
14
|
message: error.message,
|
|
16
15
|
code: error.code,
|
|
17
16
|
};
|
|
@@ -27,10 +26,16 @@ async function executeRequest(request) {
|
|
|
27
26
|
params: queryParams,
|
|
28
27
|
timeout,
|
|
29
28
|
}));
|
|
30
|
-
if (!goAxios.success)
|
|
31
|
-
return {
|
|
29
|
+
if (!goAxios.success) {
|
|
30
|
+
return {
|
|
31
|
+
success: false,
|
|
32
|
+
errorData: (0, exports.extractAxiosErrorData)(goAxios.error),
|
|
33
|
+
data: undefined,
|
|
34
|
+
statusCode: goAxios.error.status,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
32
37
|
const response = goAxios.data;
|
|
33
|
-
return { success: true, errorData: undefined, data: response.data };
|
|
38
|
+
return { success: true, errorData: undefined, data: response.data, statusCode: response.status };
|
|
34
39
|
}
|
|
35
40
|
exports.executeRequest = executeRequest;
|
|
36
41
|
//# sourceMappingURL=index.js.map
|
package/dist/http/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":";;;;;;AAAA,uDAAyC;AACzC,kDAAgF;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":";;;;;;AAAA,uDAAyC;AACzC,kDAAgF;AAEhF,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAiB3B,MAAM,qBAAqB,GAAG,CAAC,KAAiB,EAAiB,EAAE;IACxE,2DAA2D;IAC3D,OAAO;QACL,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI;QAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,IAAI,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC;AACJ,CAAC,CAAC;AAPW,QAAA,qBAAqB,yBAOhC;AAiBK,KAAK,UAAU,cAAc,CAAI,OAAgB;IACtD,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,EAAE,EAAE,WAAW,GAAG,EAAE,EAAE,OAAO,GAAG,kBAAkB,EAAE,GAAG,OAAO,CAAC;IAEpG,MAAM,OAAO,GAAG,MAAM,IAAA,kBAAE,EAAwC,KAAK,IAAI,EAAE,CACzE,IAAA,eAAK,EAAC;QACJ,GAAG;QACH,MAAM;QACN,OAAO;QACP,IAAI,EAAE,IAAI;QACV,MAAM,EAAE,WAAW;QACnB,OAAO;KACR,CAAC,CACH,CAAC;IACF,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE;QACpB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,SAAS,EAAE,IAAA,6BAAqB,EAAC,OAAO,CAAC,KAAK,CAAC;YAC/C,IAAI,EAAE,SAAS;YACf,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM;SACjC,CAAC;KACH;IACD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAE9B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC;AACnG,CAAC;AAxBD,wCAwBC"}
|
package/package.json
CHANGED
|
@@ -6,16 +6,18 @@ import {
|
|
|
6
6
|
deriveBeaconSetId,
|
|
7
7
|
deriveEndpointId,
|
|
8
8
|
deriveSponsorWallet,
|
|
9
|
+
deriveSponsorWalletAddress,
|
|
9
10
|
deriveTemplateIdV0,
|
|
10
11
|
deriveTemplateIdV1,
|
|
11
12
|
deriveWalletPathFromSponsorAddress,
|
|
12
13
|
fromBytes32String,
|
|
13
14
|
PROTOCOL_IDS,
|
|
14
15
|
toBytes32String,
|
|
16
|
+
verifyAirnodeXpub,
|
|
15
17
|
} from './derivation';
|
|
16
18
|
import type { Address } from './schema';
|
|
17
19
|
|
|
18
|
-
describe(
|
|
20
|
+
describe(deriveWalletPathFromSponsorAddress.name, () => {
|
|
19
21
|
it('converts address to derivation path', () => {
|
|
20
22
|
const sponsorAddress = '0x8A45eac0267dD0803Fd957723EdE10693A076698';
|
|
21
23
|
const res = deriveWalletPathFromSponsorAddress(sponsorAddress, PROTOCOL_IDS.AIRSEEKER);
|
|
@@ -52,109 +54,179 @@ describe('deriveWalletPathFromSponsorAddress', () => {
|
|
|
52
54
|
expect.objectContaining({ name: expect.stringContaining('Error') })
|
|
53
55
|
);
|
|
54
56
|
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe(deriveSponsorWallet.name, () => {
|
|
60
|
+
it('derives a sponsor wallet', () => {
|
|
61
|
+
const dapiName = ethers.utils.formatBytes32String('BTC/ETH');
|
|
62
|
+
const sponsorWallet = deriveSponsorWallet(
|
|
63
|
+
'test test test test test test test test test test test junk',
|
|
64
|
+
dapiName,
|
|
65
|
+
'1'
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
expect(sponsorWallet.address).toBe('0x4f86228e0Bc58829Cd77547224291bb8d212174D');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('throws deriving a sponsor wallet due to an invalid DApi name', () => {
|
|
72
|
+
const dapiName = 'invalid dapi name';
|
|
73
|
+
const throwingFn = () =>
|
|
74
|
+
deriveSponsorWallet('test test test test test test test test test test test junk', dapiName, '5');
|
|
55
75
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
'1'
|
|
76
|
+
expect(throwingFn).toThrow(expect.objectContaining({ name: expect.stringContaining('Error') }));
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('derives the same sponsor wallet as Airnode', () => {
|
|
80
|
+
function deriveSponsorWalletAirnode(masterHDNode: ethers.utils.HDNode, sponsorAddress: Address): ethers.Wallet {
|
|
81
|
+
const sponsorWalletHdNode = masterHDNode.derivePath(
|
|
82
|
+
`m/44'/60'/0'/${deriveWalletPathFromSponsorAddress(sponsorAddress, '1')}`
|
|
63
83
|
);
|
|
84
|
+
return new ethers.Wallet(sponsorWalletHdNode.privateKey);
|
|
85
|
+
}
|
|
86
|
+
const mnemonic = 'achieve climb couple wait accident symbol spy blouse reduce foil echo label';
|
|
87
|
+
const hdNode = ethers.utils.HDNode.fromMnemonic(mnemonic);
|
|
64
88
|
|
|
65
|
-
|
|
66
|
-
|
|
89
|
+
// https://github.com/api3dao/airnode/blob/a4c17c28c8b31c9fb13d2828764b89f1063b702f/packages/airnode-node/src/evm/wallet.test.ts#L25
|
|
90
|
+
const expectedSponsorWallet = deriveSponsorWalletAirnode(hdNode, '0x06f509f73eefba36352bc8228f9112c3786100da');
|
|
91
|
+
const actualSponsorWallet = deriveSponsorWallet(mnemonic, '0x06f509f73eefba36352bc8228f9112c3786100da', '1');
|
|
67
92
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
93
|
+
expect(actualSponsorWallet.address).toBe(expectedSponsorWallet.address);
|
|
94
|
+
expect(actualSponsorWallet.address).toBe('0x228A54F33E46fbb32a62ca650Fcc9eD3C730511d');
|
|
95
|
+
});
|
|
96
|
+
});
|
|
72
97
|
|
|
73
|
-
|
|
74
|
-
|
|
98
|
+
describe(deriveAirnodeXpub.name, () => {
|
|
99
|
+
it(`derives an airnode's xpub from a mnemonic`, () => {
|
|
100
|
+
const xpub = deriveAirnodeXpub('test test test test test test test test test test test junk');
|
|
75
101
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return new ethers.Wallet(sponsorWalletHdNode.privateKey);
|
|
82
|
-
}
|
|
83
|
-
const mnemonic = 'achieve climb couple wait accident symbol spy blouse reduce foil echo label';
|
|
84
|
-
const hdNode = ethers.utils.HDNode.fromMnemonic(mnemonic);
|
|
102
|
+
expect(xpub).toBe(
|
|
103
|
+
'xpub6Ce9NcJvTk36xtLSrJLZqE7wtgA5deCeYs7rSQtreh4cj6ByPtrg9sD7V2FNFLPnf8heNP3FGkeV9qwfzvZNSd54JoNXVsXFYSYwHsnJxqP'
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
});
|
|
85
107
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
108
|
+
describe(deriveEndpointId.name, () => {
|
|
109
|
+
it(`derives an endpoint ID`, () => {
|
|
110
|
+
const endpointId = deriveEndpointId('weather', 'temperature');
|
|
89
111
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
112
|
+
expect(endpointId).toBe('0x5a82d40e44ecd3ef0906e9e82c1a20f2f4ffe4f613ac70f999047496a9cd4635');
|
|
113
|
+
});
|
|
114
|
+
});
|
|
93
115
|
|
|
94
|
-
|
|
95
|
-
|
|
116
|
+
describe(deriveTemplateIdV0.name, () => {
|
|
117
|
+
it(`it derives a template ID V0`, () => {
|
|
118
|
+
const templateId = deriveTemplateIdV0(
|
|
119
|
+
'0x4E95C31894a89CdC4288669A6F294836948c862b',
|
|
120
|
+
'0x5a82d40e44ecd3ef0906e9e82c1a20f2f4ffe4f613ac70f999047496a9cd4635',
|
|
121
|
+
'0x6466726f6d63455448'
|
|
122
|
+
);
|
|
96
123
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
});
|
|
124
|
+
expect(templateId).toBe('0x25ea8b12135e4b8d49960ef9e0f967b7c0ccad136b955fbb7fbeb76da27d60b0');
|
|
125
|
+
});
|
|
126
|
+
});
|
|
101
127
|
|
|
102
|
-
|
|
103
|
-
|
|
128
|
+
describe(deriveTemplateIdV1.name, () => {
|
|
129
|
+
it('derives templateId for V1', () => {
|
|
130
|
+
const expectedTemplateIdV1 = deriveTemplateIdV1(
|
|
131
|
+
'0x2f3a3adf6daf5a3bb00ab83aa82262a6a84b59b0a89222386135330a1819ab48',
|
|
132
|
+
'0x6466726f6d63455448'
|
|
133
|
+
);
|
|
104
134
|
|
|
105
|
-
|
|
106
|
-
|
|
135
|
+
expect(expectedTemplateIdV1).toBe('0xe5d99287b5a870c3453bc0b42769c6f37cf4a3143890e9c34753181171fac842');
|
|
136
|
+
});
|
|
137
|
+
});
|
|
107
138
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
139
|
+
describe(deriveBeaconId.name, () => {
|
|
140
|
+
it('derives a beacon ID', () => {
|
|
141
|
+
const beaconId = deriveBeaconId(
|
|
142
|
+
'0xc52EeA00154B4fF1EbbF8Ba39FDe37F1AC3B9Fd4',
|
|
143
|
+
'0x457a3b3da67e394a895ea49e534a4d91b2d009477bef15eab8cbed313925b010'
|
|
144
|
+
);
|
|
114
145
|
|
|
115
|
-
|
|
116
|
-
|
|
146
|
+
expect(beaconId).toBe('0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc6');
|
|
147
|
+
});
|
|
148
|
+
});
|
|
117
149
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
150
|
+
describe(deriveBeaconSetId.name, () => {
|
|
151
|
+
it(`derives a beacon set ID`, () => {
|
|
152
|
+
const beaconSetId = deriveBeaconSetId([
|
|
153
|
+
'0x0e30ed302a3c8eeaa0053caf5fbd0825c86ce1767584d12c69c310f0068b1176',
|
|
154
|
+
'0x496092597aef79595df1567412c6ddefd037f63a5a1572702dd469f62f31f469',
|
|
155
|
+
'0x84c1da28b2f29f0a2b0ff360d537d405d1cd69249fcf5f32ae9c2298cee6da12',
|
|
156
|
+
'0xe8655dc68f2b765c5e6d4a042ba7ba8606cf37e1c8c96676f85364ec5bfe9163',
|
|
157
|
+
'0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc6',
|
|
158
|
+
]);
|
|
159
|
+
|
|
160
|
+
expect(beaconSetId).toBe('0x33bf380fd5b06a317a905b23eaf5c61ef0a9b4a20589a1bf1d13133daca34b0e');
|
|
161
|
+
});
|
|
162
|
+
});
|
|
123
163
|
|
|
124
|
-
|
|
125
|
-
|
|
164
|
+
describe(toBytes32String.name, () => {
|
|
165
|
+
it('encodes a string as a bytes32 string', () => {
|
|
166
|
+
const formattedString = toBytes32String('test string');
|
|
126
167
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
'0x457a3b3da67e394a895ea49e534a4d91b2d009477bef15eab8cbed313925b010'
|
|
131
|
-
);
|
|
168
|
+
expect(formattedString).toBe('0x7465737420737472696e67000000000000000000000000000000000000000000');
|
|
169
|
+
});
|
|
170
|
+
});
|
|
132
171
|
|
|
133
|
-
|
|
134
|
-
|
|
172
|
+
describe(fromBytes32String.name, () => {
|
|
173
|
+
it('decodes a bytes32 string to a normal string', () => {
|
|
174
|
+
const formattedString = fromBytes32String('0x7465737420737472696e67000000000000000000000000000000000000000000');
|
|
135
175
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
176
|
+
expect(formattedString).toBe('test string');
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
describe(verifyAirnodeXpub.name, () => {
|
|
181
|
+
it('does not throw for valid xpub/airnode combination', () => {
|
|
182
|
+
expect(() =>
|
|
183
|
+
verifyAirnodeXpub(
|
|
184
|
+
'xpub6CvZvZuFtPUtNirE36eMqYu8pRa1CEQuDon9tT4G8fisU3jj38Sn53TxdHb1SUvWiwVjJ68ytPZf45gnPM7Kg4g4CNTdyjJMevDQ1wk4tYD',
|
|
185
|
+
'0x02F5BD238B866c36f7d7b144D2889fB5e594474e'
|
|
186
|
+
)
|
|
187
|
+
).not.toThrow();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('throws when the xpub is invalid', () => {
|
|
191
|
+
expect(() =>
|
|
192
|
+
verifyAirnodeXpub(
|
|
193
|
+
'xpub6CvZvZuFtPUtNirE36eMqYu8pRa1CEQuDon9tT4G8fisU3jj38Sn53TxdHb1SUvWiwVjJ68ytPZf45gnPM7Kg4g4CNTdyjJMevDQ1wk4tYD',
|
|
194
|
+
'0xDdfd47366cA427e75C26c9F3364EE37b33e1DD38'
|
|
195
|
+
)
|
|
196
|
+
).toThrow('xpub does not belong to Airnode: 0xDdfd47366cA427e75C26c9F3364EE37b33e1DD38');
|
|
197
|
+
});
|
|
198
|
+
});
|
|
144
199
|
|
|
145
|
-
|
|
146
|
-
|
|
200
|
+
describe(deriveSponsorWalletAddress, () => {
|
|
201
|
+
it('derives the sponsor wallet address and verifies airnode address', () => {
|
|
202
|
+
const sponsorWalletAddress = deriveSponsorWalletAddress(
|
|
203
|
+
'xpub6CvZvZuFtPUtNirE36eMqYu8pRa1CEQuDon9tT4G8fisU3jj38Sn53TxdHb1SUvWiwVjJ68ytPZf45gnPM7Kg4g4CNTdyjJMevDQ1wk4tYD',
|
|
204
|
+
'0xE9232cde1f37B029dfbB403f79429f912D7405F3',
|
|
205
|
+
'1',
|
|
206
|
+
'0x02F5BD238B866c36f7d7b144D2889fB5e594474e'
|
|
207
|
+
);
|
|
147
208
|
|
|
148
|
-
|
|
149
|
-
|
|
209
|
+
expect(sponsorWalletAddress).toBe('0xDdfd47366cA427e75C26c9F3364EE37b33e1DD38');
|
|
210
|
+
});
|
|
150
211
|
|
|
151
|
-
|
|
152
|
-
|
|
212
|
+
it('derives the sponsor wallet without xpub verifification', () => {
|
|
213
|
+
const sponsorWalletAddress = deriveSponsorWalletAddress(
|
|
214
|
+
'xpub6CvZvZuFtPUtNirE36eMqYu8pRa1CEQuDon9tT4G8fisU3jj38Sn53TxdHb1SUvWiwVjJ68ytPZf45gnPM7Kg4g4CNTdyjJMevDQ1wk4tYD',
|
|
215
|
+
'0xE9232cde1f37B029dfbB403f79429f912D7405F3',
|
|
216
|
+
'1'
|
|
217
|
+
);
|
|
153
218
|
|
|
154
|
-
|
|
155
|
-
|
|
219
|
+
expect(sponsorWalletAddress).toBe('0xDdfd47366cA427e75C26c9F3364EE37b33e1DD38');
|
|
220
|
+
});
|
|
156
221
|
|
|
157
|
-
|
|
158
|
-
|
|
222
|
+
it('verifies that xpub is valid when airnode address is provided', () => {
|
|
223
|
+
expect(() =>
|
|
224
|
+
deriveSponsorWalletAddress(
|
|
225
|
+
'xpub6CvZvZuFtPUtNirE36eMqYu8pRa1CEQuDon9tT4G8fisU3jj38Sn53TxdHb1SUvWiwVjJ68ytPZf45gnPM7Kg4g4CNTdyjJMevDQ1wk4tYD',
|
|
226
|
+
'0xE9232cde1f37B029dfbB403f79429f912D7405F3',
|
|
227
|
+
'1',
|
|
228
|
+
'0xA143283e75c8e0a3174d51e6ccA38B334E1D6b12'
|
|
229
|
+
)
|
|
230
|
+
).toThrow('xpub does not belong to Airnode: 0xA143283e75c8e0a3174d51e6ccA38B334E1D6b12');
|
|
159
231
|
});
|
|
160
232
|
});
|
|
@@ -55,3 +55,26 @@ export const deriveBeaconId = (airnodeAddress: Address, templateId: Hex) =>
|
|
|
55
55
|
export const deriveBeaconSetId = (beaconIds: Hex[]) =>
|
|
56
56
|
// By convention beacon IDs are sorted alphabetically - the ordering impacts the resulting hash.
|
|
57
57
|
ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(['bytes32[]'], [beaconIds]));
|
|
58
|
+
|
|
59
|
+
export const deriveHdNodeFromXpub = (xpub: string) => ethers.utils.HDNode.fromExtendedKey(xpub);
|
|
60
|
+
|
|
61
|
+
export const verifyAirnodeXpub = (airnodeXpub: string, airnodeAddress: Address): ethers.utils.HDNode => {
|
|
62
|
+
// The xpub is expected to belong to the hardened path m/44'/60'/0' so we must derive the child default derivation
|
|
63
|
+
// path m/44'/60'/0'/0/0 to compare it and check if xpub belongs to the Airnode wallet.
|
|
64
|
+
const hdNode = deriveHdNodeFromXpub(airnodeXpub);
|
|
65
|
+
if (airnodeAddress !== hdNode.derivePath('0/0').address) {
|
|
66
|
+
throw new Error(`xpub does not belong to Airnode: ${airnodeAddress}`);
|
|
67
|
+
}
|
|
68
|
+
return hdNode;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export function deriveSponsorWalletAddress(
|
|
72
|
+
airnodeXpub: string,
|
|
73
|
+
sponsorAddress: Address,
|
|
74
|
+
protocolId: ProtocolId,
|
|
75
|
+
airnodeAddress?: Address
|
|
76
|
+
) {
|
|
77
|
+
const hdNode = airnodeAddress ? verifyAirnodeXpub(airnodeXpub, airnodeAddress) : deriveHdNodeFromXpub(airnodeXpub);
|
|
78
|
+
const derivationPath = deriveWalletPathFromSponsorAddress(sponsorAddress, protocolId);
|
|
79
|
+
return hdNode.derivePath(derivationPath).address;
|
|
80
|
+
}
|
package/src/http/index.test.ts
CHANGED
|
@@ -11,12 +11,9 @@ describe(extractAxiosErrorData.name, () => {
|
|
|
11
11
|
} as any as AxiosResponse);
|
|
12
12
|
|
|
13
13
|
expect(extractAxiosErrorData(axiosError)).toStrictEqual({
|
|
14
|
-
|
|
15
|
-
data: 'error data',
|
|
16
|
-
status: 500,
|
|
17
|
-
},
|
|
18
|
-
code: '500',
|
|
14
|
+
response: 'error data',
|
|
19
15
|
message: 'error message',
|
|
16
|
+
code: '500',
|
|
20
17
|
});
|
|
21
18
|
});
|
|
22
19
|
});
|
|
@@ -33,10 +30,11 @@ describe(executeRequest.name, () => {
|
|
|
33
30
|
expect(response).toStrictEqual({
|
|
34
31
|
data: undefined,
|
|
35
32
|
errorData: {
|
|
36
|
-
|
|
33
|
+
response: undefined,
|
|
37
34
|
code: 'ECONNREFUSED',
|
|
38
35
|
message: expect.any(String), // The message is empty in node@20, but "connect ECONNREFUSED ::1:9999" on node@18
|
|
39
36
|
},
|
|
37
|
+
statusCode: undefined,
|
|
40
38
|
success: false,
|
|
41
39
|
});
|
|
42
40
|
});
|
package/src/http/index.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { go } from '@api3/promise-utils';
|
|
2
2
|
import axios, { type Method, type AxiosError, type AxiosResponse } from 'axios';
|
|
3
|
-
import pick from 'lodash/pick';
|
|
4
3
|
|
|
5
4
|
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
6
5
|
|
|
@@ -14,7 +13,7 @@ export interface Request {
|
|
|
14
13
|
}
|
|
15
14
|
|
|
16
15
|
export interface ErrorResponse {
|
|
17
|
-
readonly
|
|
16
|
+
readonly response: unknown;
|
|
18
17
|
readonly message: string;
|
|
19
18
|
readonly code: string | undefined;
|
|
20
19
|
}
|
|
@@ -22,21 +21,23 @@ export interface ErrorResponse {
|
|
|
22
21
|
export const extractAxiosErrorData = (error: AxiosError): ErrorResponse => {
|
|
23
22
|
// Inspired by: https://axios-http.com/docs/handling_errors
|
|
24
23
|
return {
|
|
25
|
-
|
|
24
|
+
response: error.response?.data,
|
|
26
25
|
message: error.message,
|
|
27
26
|
code: error.code,
|
|
28
|
-
}
|
|
27
|
+
};
|
|
29
28
|
};
|
|
30
29
|
|
|
31
30
|
interface ExecuteRequestSuccess<T> {
|
|
32
31
|
success: true;
|
|
33
32
|
errorData: undefined;
|
|
34
33
|
data: T;
|
|
34
|
+
statusCode: number;
|
|
35
35
|
}
|
|
36
36
|
interface ExecuteRequestError {
|
|
37
37
|
success: false;
|
|
38
38
|
errorData: ErrorResponse;
|
|
39
39
|
data: undefined;
|
|
40
|
+
statusCode: number | undefined;
|
|
40
41
|
}
|
|
41
42
|
|
|
42
43
|
export type ExecuteRequestResult<T> = ExecuteRequestError | ExecuteRequestSuccess<T>;
|
|
@@ -54,8 +55,15 @@ export async function executeRequest<T>(request: Request): Promise<ExecuteReques
|
|
|
54
55
|
timeout,
|
|
55
56
|
})
|
|
56
57
|
);
|
|
57
|
-
if (!goAxios.success)
|
|
58
|
+
if (!goAxios.success) {
|
|
59
|
+
return {
|
|
60
|
+
success: false,
|
|
61
|
+
errorData: extractAxiosErrorData(goAxios.error),
|
|
62
|
+
data: undefined,
|
|
63
|
+
statusCode: goAxios.error.status,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
58
66
|
const response = goAxios.data;
|
|
59
67
|
|
|
60
|
-
return { success: true, errorData: undefined, data: response.data };
|
|
68
|
+
return { success: true, errorData: undefined, data: response.data, statusCode: response.status };
|
|
61
69
|
}
|