@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.
@@ -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":"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"}
@@ -1,4 +1,4 @@
1
- import { type Method, type AxiosError, type AxiosResponse } from 'axios';
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 axiosResponse: Pick<AxiosResponse, 'data' | 'headers' | 'status'> | undefined;
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>>;
@@ -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,EAAE,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAKhF,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,aAAa,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC,GAAG,SAAS,CAAC;IACvF,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;CACT;AACD,UAAU,mBAAmB;IAC3B,OAAO,EAAE,KAAK,CAAC;IACf,SAAS,EAAE,aAAa,CAAC;IACzB,IAAI,EAAE,SAAS,CAAC;CACjB;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,CAiB1F"}
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"}
@@ -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
- axiosResponse: error.response ? (0, pick_1.default)(error.response, ['data', 'status']) : undefined,
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 { success: false, errorData: (0, exports.extractAxiosErrorData)(goAxios.error), data: undefined };
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
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":";;;;;;AAAA,uDAAyC;AACzC,kDAAgF;AAChF,uDAA+B;AAE/B,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAiB3B,MAAM,qBAAqB,GAAG,CAAC,KAAiB,EAAiB,EAAE;IACxE,2DAA2D;IAC3D,OAAO;QACL,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAA,cAAI,EAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;QACpF,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,IAAI,EAAE,KAAK,CAAC,IAAI;KACA,CAAC;AACrB,CAAC,CAAC;AAPW,QAAA,qBAAqB,yBAOhC;AAeK,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;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAA,6BAAqB,EAAC,OAAO,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAClH,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAE9B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;AACtE,CAAC;AAjBD,wCAiBC"}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@api3/commons",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "keywords": [],
5
5
  "license": "MIT",
6
6
  "engines": {
@@ -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('deriveWalletPathFromSponsorAddress', () => {
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
- describe('blockchain utilities', () => {
57
- it('derives a sponsor wallet', () => {
58
- const dapiName = ethers.utils.formatBytes32String('BTC/ETH');
59
- const sponsorWallet = deriveSponsorWallet(
60
- 'test test test test test test test test test test test junk',
61
- dapiName,
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
- expect(sponsorWallet.address).toBe('0x4f86228e0Bc58829Cd77547224291bb8d212174D');
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
- it('throws deriving a sponsor wallet due to an invalid DApi name', () => {
69
- const dapiName = 'invalid dapi name';
70
- const throwingFn = () =>
71
- deriveSponsorWallet('test test test test test test test test test test test junk', dapiName, '5');
93
+ expect(actualSponsorWallet.address).toBe(expectedSponsorWallet.address);
94
+ expect(actualSponsorWallet.address).toBe('0x228A54F33E46fbb32a62ca650Fcc9eD3C730511d');
95
+ });
96
+ });
72
97
 
73
- expect(throwingFn).toThrow(expect.objectContaining({ name: expect.stringContaining('Error') }));
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
- it('derives the same sponsor wallet as Airnode', () => {
77
- function deriveSponsorWalletAirnode(masterHDNode: ethers.utils.HDNode, sponsorAddress: Address): ethers.Wallet {
78
- const sponsorWalletHdNode = masterHDNode.derivePath(
79
- `m/44'/60'/0'/${deriveWalletPathFromSponsorAddress(sponsorAddress, '1')}`
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
- // https://github.com/api3dao/airnode/blob/a4c17c28c8b31c9fb13d2828764b89f1063b702f/packages/airnode-node/src/evm/wallet.test.ts#L25
87
- const expectedSponsorWallet = deriveSponsorWalletAirnode(hdNode, '0x06f509f73eefba36352bc8228f9112c3786100da');
88
- const actualSponsorWallet = deriveSponsorWallet(mnemonic, '0x06f509f73eefba36352bc8228f9112c3786100da', '1');
108
+ describe(deriveEndpointId.name, () => {
109
+ it(`derives an endpoint ID`, () => {
110
+ const endpointId = deriveEndpointId('weather', 'temperature');
89
111
 
90
- expect(actualSponsorWallet.address).toBe(expectedSponsorWallet.address);
91
- expect(actualSponsorWallet.address).toBe('0x228A54F33E46fbb32a62ca650Fcc9eD3C730511d');
92
- });
112
+ expect(endpointId).toBe('0x5a82d40e44ecd3ef0906e9e82c1a20f2f4ffe4f613ac70f999047496a9cd4635');
113
+ });
114
+ });
93
115
 
94
- it(`derives an airnode's xpub from a mnemonic`, () => {
95
- const xpub = deriveAirnodeXpub('test test test test test test test test test test test junk');
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
- expect(xpub).toBe(
98
- 'xpub6Ce9NcJvTk36xtLSrJLZqE7wtgA5deCeYs7rSQtreh4cj6ByPtrg9sD7V2FNFLPnf8heNP3FGkeV9qwfzvZNSd54JoNXVsXFYSYwHsnJxqP'
99
- );
100
- });
124
+ expect(templateId).toBe('0x25ea8b12135e4b8d49960ef9e0f967b7c0ccad136b955fbb7fbeb76da27d60b0');
125
+ });
126
+ });
101
127
 
102
- it(`derives an endpoint ID`, () => {
103
- const endpointId = deriveEndpointId('weather', 'temperature');
128
+ describe(deriveTemplateIdV1.name, () => {
129
+ it('derives templateId for V1', () => {
130
+ const expectedTemplateIdV1 = deriveTemplateIdV1(
131
+ '0x2f3a3adf6daf5a3bb00ab83aa82262a6a84b59b0a89222386135330a1819ab48',
132
+ '0x6466726f6d63455448'
133
+ );
104
134
 
105
- expect(endpointId).toBe('0x5a82d40e44ecd3ef0906e9e82c1a20f2f4ffe4f613ac70f999047496a9cd4635');
106
- });
135
+ expect(expectedTemplateIdV1).toBe('0xe5d99287b5a870c3453bc0b42769c6f37cf4a3143890e9c34753181171fac842');
136
+ });
137
+ });
107
138
 
108
- it(`it derives a template ID V0`, () => {
109
- const templateId = deriveTemplateIdV0(
110
- '0x4E95C31894a89CdC4288669A6F294836948c862b',
111
- '0x5a82d40e44ecd3ef0906e9e82c1a20f2f4ffe4f613ac70f999047496a9cd4635',
112
- '0x6466726f6d63455448'
113
- );
139
+ describe(deriveBeaconId.name, () => {
140
+ it('derives a beacon ID', () => {
141
+ const beaconId = deriveBeaconId(
142
+ '0xc52EeA00154B4fF1EbbF8Ba39FDe37F1AC3B9Fd4',
143
+ '0x457a3b3da67e394a895ea49e534a4d91b2d009477bef15eab8cbed313925b010'
144
+ );
114
145
 
115
- expect(templateId).toBe('0x25ea8b12135e4b8d49960ef9e0f967b7c0ccad136b955fbb7fbeb76da27d60b0');
116
- });
146
+ expect(beaconId).toBe('0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc6');
147
+ });
148
+ });
117
149
 
118
- it('derives templateId for V1', () => {
119
- const expectedTemplateIdV1 = deriveTemplateIdV1(
120
- '0x2f3a3adf6daf5a3bb00ab83aa82262a6a84b59b0a89222386135330a1819ab48',
121
- '0x6466726f6d63455448'
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
- expect(expectedTemplateIdV1).toBe('0xe5d99287b5a870c3453bc0b42769c6f37cf4a3143890e9c34753181171fac842');
125
- });
164
+ describe(toBytes32String.name, () => {
165
+ it('encodes a string as a bytes32 string', () => {
166
+ const formattedString = toBytes32String('test string');
126
167
 
127
- it('derives a beacon ID', () => {
128
- const beaconId = deriveBeaconId(
129
- '0xc52EeA00154B4fF1EbbF8Ba39FDe37F1AC3B9Fd4',
130
- '0x457a3b3da67e394a895ea49e534a4d91b2d009477bef15eab8cbed313925b010'
131
- );
168
+ expect(formattedString).toBe('0x7465737420737472696e67000000000000000000000000000000000000000000');
169
+ });
170
+ });
132
171
 
133
- expect(beaconId).toBe('0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc6');
134
- });
172
+ describe(fromBytes32String.name, () => {
173
+ it('decodes a bytes32 string to a normal string', () => {
174
+ const formattedString = fromBytes32String('0x7465737420737472696e67000000000000000000000000000000000000000000');
135
175
 
136
- it(`derives a beacon set ID`, () => {
137
- const beaconSetId = deriveBeaconSetId([
138
- '0x0e30ed302a3c8eeaa0053caf5fbd0825c86ce1767584d12c69c310f0068b1176',
139
- '0x496092597aef79595df1567412c6ddefd037f63a5a1572702dd469f62f31f469',
140
- '0x84c1da28b2f29f0a2b0ff360d537d405d1cd69249fcf5f32ae9c2298cee6da12',
141
- '0xe8655dc68f2b765c5e6d4a042ba7ba8606cf37e1c8c96676f85364ec5bfe9163',
142
- '0xf5c140bcb4814dfec311d38f6293e86c02d32ba1b7da027fe5b5202cae35dbc6',
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
- expect(beaconSetId).toBe('0x33bf380fd5b06a317a905b23eaf5c61ef0a9b4a20589a1bf1d13133daca34b0e');
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
- it('encodes a string as a bytes32 string', () => {
149
- const formattedString = toBytes32String('test string');
209
+ expect(sponsorWalletAddress).toBe('0xDdfd47366cA427e75C26c9F3364EE37b33e1DD38');
210
+ });
150
211
 
151
- expect(formattedString).toBe('0x7465737420737472696e67000000000000000000000000000000000000000000');
152
- });
212
+ it('derives the sponsor wallet without xpub verifification', () => {
213
+ const sponsorWalletAddress = deriveSponsorWalletAddress(
214
+ 'xpub6CvZvZuFtPUtNirE36eMqYu8pRa1CEQuDon9tT4G8fisU3jj38Sn53TxdHb1SUvWiwVjJ68ytPZf45gnPM7Kg4g4CNTdyjJMevDQ1wk4tYD',
215
+ '0xE9232cde1f37B029dfbB403f79429f912D7405F3',
216
+ '1'
217
+ );
153
218
 
154
- it('decodes a bytes32 string to a normal string', () => {
155
- const formattedString = fromBytes32String('0x7465737420737472696e67000000000000000000000000000000000000000000');
219
+ expect(sponsorWalletAddress).toBe('0xDdfd47366cA427e75C26c9F3364EE37b33e1DD38');
220
+ });
156
221
 
157
- expect(formattedString).toBe('test string');
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
+ }
@@ -11,12 +11,9 @@ describe(extractAxiosErrorData.name, () => {
11
11
  } as any as AxiosResponse);
12
12
 
13
13
  expect(extractAxiosErrorData(axiosError)).toStrictEqual({
14
- axiosResponse: {
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
- axiosResponse: undefined,
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 axiosResponse: Pick<AxiosResponse, 'data' | 'headers' | 'status'> | undefined;
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
- axiosResponse: error.response ? pick(error.response, ['data', 'status']) : undefined,
24
+ response: error.response?.data,
26
25
  message: error.message,
27
26
  code: error.code,
28
- } as ErrorResponse;
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) return { success: false, errorData: extractAxiosErrorData(goAxios.error), data: undefined };
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
  }