zapo-js 1.4.0 → 1.5.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.
Files changed (94) hide show
  1. package/dist/appstate/types.d.ts +1 -2
  2. package/dist/auth/WaAuthClient.d.ts +10 -0
  3. package/dist/auth/WaAuthClient.js +17 -8
  4. package/dist/auth/credentials-flow.d.ts +8 -0
  5. package/dist/auth/credentials-flow.js +35 -2
  6. package/dist/auth/pairing/companion-host.d.ts +105 -0
  7. package/dist/auth/pairing/companion-host.js +148 -0
  8. package/dist/auth/types.d.ts +20 -9
  9. package/dist/client/WaClient.d.ts +15 -5
  10. package/dist/client/WaClient.js +46 -12
  11. package/dist/client/WaClientFactory.d.ts +3 -0
  12. package/dist/client/WaClientFactory.js +24 -6
  13. package/dist/client/coordinators/WaAppStateMutationCoordinator.d.ts +8 -0
  14. package/dist/client/coordinators/WaAppStateMutationCoordinator.js +37 -1
  15. package/dist/client/coordinators/WaGroupCoordinator.js +6 -1
  16. package/dist/client/coordinators/WaMessageDispatchCoordinator.d.ts +3 -1
  17. package/dist/client/coordinators/WaMessageDispatchCoordinator.js +13 -3
  18. package/dist/client/coordinators/WaMobileCoordinator.d.ts +192 -0
  19. package/dist/client/coordinators/WaMobileCoordinator.js +645 -0
  20. package/dist/client/messaging/companion-host.d.ts +43 -0
  21. package/dist/client/messaging/companion-host.js +61 -0
  22. package/dist/client/messaging/key-protocol.js +25 -1
  23. package/dist/client/persistence/companion-host.d.ts +36 -0
  24. package/dist/client/persistence/companion-host.js +57 -0
  25. package/dist/client/plugins/install.d.ts +2 -1
  26. package/dist/client/plugins/install.js +44 -11
  27. package/dist/client/types.d.ts +71 -7
  28. package/dist/esm/auth/WaAuthClient.js +18 -9
  29. package/dist/esm/auth/credentials-flow.js +36 -3
  30. package/dist/esm/auth/pairing/companion-host.js +140 -0
  31. package/dist/esm/client/WaClient.js +46 -12
  32. package/dist/esm/client/WaClientFactory.js +25 -7
  33. package/dist/esm/client/coordinators/WaAppStateMutationCoordinator.js +37 -1
  34. package/dist/esm/client/coordinators/WaGroupCoordinator.js +6 -1
  35. package/dist/esm/client/coordinators/WaMessageDispatchCoordinator.js +14 -4
  36. package/dist/esm/client/coordinators/WaMobileCoordinator.js +641 -0
  37. package/dist/esm/client/messaging/companion-host.js +56 -0
  38. package/dist/esm/client/messaging/key-protocol.js +25 -1
  39. package/dist/esm/client/persistence/companion-host.js +54 -0
  40. package/dist/esm/client/plugins/install.js +44 -11
  41. package/dist/esm/index.js +5 -2
  42. package/dist/esm/message/WaMessageClient.js +3 -2
  43. package/dist/esm/message/context-info.js +4 -0
  44. package/dist/esm/protocol/constants.js +4 -3
  45. package/dist/esm/protocol/device-identity.js +18 -0
  46. package/dist/esm/protocol/group.js +6 -0
  47. package/dist/esm/protocol/message.js +12 -0
  48. package/dist/esm/protocol/nodes.js +15 -1
  49. package/dist/esm/retry/replay.js +3 -3
  50. package/dist/esm/signal/attestation/WaAdvSignature.js +67 -2
  51. package/dist/esm/signal/attestation/constants.js +2 -0
  52. package/dist/esm/signal/index.js +1 -0
  53. package/dist/esm/transport/index.js +1 -1
  54. package/dist/esm/transport/node/builders/group.js +4 -3
  55. package/dist/esm/transport/node/builders/mobile.js +113 -0
  56. package/dist/esm/transport/noise/WaClientPayload.js +16 -7
  57. package/dist/esm/transport/wa-version-fetcher.js +152 -0
  58. package/dist/esm/util/index.js +1 -0
  59. package/dist/index.d.ts +10 -4
  60. package/dist/index.js +13 -4
  61. package/dist/message/WaMessageClient.js +2 -1
  62. package/dist/message/context-info.d.ts +2 -0
  63. package/dist/message/context-info.js +5 -0
  64. package/dist/protocol/constants.d.ts +6 -4
  65. package/dist/protocol/constants.js +8 -2
  66. package/dist/protocol/device-identity.d.ts +25 -0
  67. package/dist/protocol/device-identity.js +21 -0
  68. package/dist/protocol/group.d.ts +6 -0
  69. package/dist/protocol/group.js +7 -1
  70. package/dist/protocol/message.d.ts +14 -0
  71. package/dist/protocol/message.js +13 -1
  72. package/dist/protocol/nodes.d.ts +14 -0
  73. package/dist/protocol/nodes.js +15 -1
  74. package/dist/retry/replay.js +2 -2
  75. package/dist/signal/attestation/WaAdvSignature.d.ts +50 -1
  76. package/dist/signal/attestation/WaAdvSignature.js +71 -1
  77. package/dist/signal/attestation/constants.d.ts +2 -0
  78. package/dist/signal/attestation/constants.js +3 -1
  79. package/dist/signal/index.d.ts +1 -0
  80. package/dist/signal/index.js +13 -1
  81. package/dist/transport/index.d.ts +2 -2
  82. package/dist/transport/index.js +4 -3
  83. package/dist/transport/node/builders/group.js +4 -3
  84. package/dist/transport/node/builders/mobile.d.ts +68 -0
  85. package/dist/transport/node/builders/mobile.js +120 -0
  86. package/dist/transport/noise/WaClientPayload.js +16 -7
  87. package/dist/transport/wa-version-fetcher.d.ts +92 -0
  88. package/dist/transport/wa-version-fetcher.js +156 -0
  89. package/dist/util/index.d.ts +1 -0
  90. package/dist/util/index.js +3 -1
  91. package/package.json +1 -1
  92. package/dist/esm/transport/wa-web-version-fetcher.js +0 -91
  93. package/dist/transport/wa-web-version-fetcher.d.ts +0 -44
  94. package/dist/transport/wa-web-version-fetcher.js +0 -94
@@ -1,8 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WA_GROUP_PARTICIPANT_TYPES = void 0;
3
+ exports.WA_GROUP_MEMBERSHIP_ACTION_TAGS = exports.WA_GROUP_PARTICIPANT_TYPES = void 0;
4
4
  exports.WA_GROUP_PARTICIPANT_TYPES = Object.freeze({
5
5
  SUPERADMIN: 'superadmin',
6
6
  ADMIN: 'admin',
7
7
  REGULAR: 'participant'
8
8
  });
9
+ /** `<membership_requests_action>` child tags for approving/rejecting group join requests. */
10
+ exports.WA_GROUP_MEMBERSHIP_ACTION_TAGS = Object.freeze({
11
+ REQUESTS_ACTION: 'membership_requests_action',
12
+ APPROVE: 'approve',
13
+ REJECT: 'reject'
14
+ });
@@ -5,6 +5,20 @@ export declare const WA_MESSAGE_TAGS: Readonly<{
5
5
  readonly ACK: "ack";
6
6
  readonly ERROR: "error";
7
7
  }>;
8
+ /** `<enc type>` ciphertext kinds (Signal `msg`/`pkmsg`, group `skmsg`, message-secret `msmsg`). */
9
+ export declare const WA_ENC_CIPHERTEXT_TYPES: Readonly<{
10
+ readonly MESSAGE: "msg";
11
+ readonly PREKEY: "pkmsg";
12
+ readonly SENDER_KEY: "skmsg";
13
+ readonly MESSAGE_SECRET: "msmsg";
14
+ }>;
15
+ export type WaEncCiphertextType = (typeof WA_ENC_CIPHERTEXT_TYPES)[keyof typeof WA_ENC_CIPHERTEXT_TYPES];
16
+ /** `addressing_mode` stanza attr: phone-number vs LID addressing. */
17
+ export declare const WA_ADDRESSING_MODES: Readonly<{
18
+ readonly PN: "pn";
19
+ readonly LID: "lid";
20
+ }>;
21
+ export type WaAddressingMode = (typeof WA_ADDRESSING_MODES)[keyof typeof WA_ADDRESSING_MODES];
8
22
  export declare const WA_MESSAGE_TYPES: Readonly<{
9
23
  readonly ENC_VERSION: "2";
10
24
  readonly MEDIA_NOTIFY: "medianotify";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WA_ENC_MEDIA_TYPES = exports.WA_EVENT_META_TYPES = exports.WA_POLL_META_TYPES = exports.WA_EDIT_ATTRS = exports.WA_STANZA_MSG_TYPES = exports.WA_NACK_REASONS = exports.WA_RETRYABLE_ACK_CODES = exports.WA_MESSAGE_TYPES = exports.WA_MESSAGE_TAGS = void 0;
3
+ exports.WA_ENC_MEDIA_TYPES = exports.WA_EVENT_META_TYPES = exports.WA_POLL_META_TYPES = exports.WA_EDIT_ATTRS = exports.WA_STANZA_MSG_TYPES = exports.WA_NACK_REASONS = exports.WA_RETRYABLE_ACK_CODES = exports.WA_MESSAGE_TYPES = exports.WA_ADDRESSING_MODES = exports.WA_ENC_CIPHERTEXT_TYPES = exports.WA_MESSAGE_TAGS = void 0;
4
4
  exports.WA_MESSAGE_TAGS = Object.freeze({
5
5
  MESSAGE: 'message',
6
6
  ENC: 'enc',
@@ -8,6 +8,18 @@ exports.WA_MESSAGE_TAGS = Object.freeze({
8
8
  ACK: 'ack',
9
9
  ERROR: 'error'
10
10
  });
11
+ /** `<enc type>` ciphertext kinds (Signal `msg`/`pkmsg`, group `skmsg`, message-secret `msmsg`). */
12
+ exports.WA_ENC_CIPHERTEXT_TYPES = Object.freeze({
13
+ MESSAGE: 'msg',
14
+ PREKEY: 'pkmsg',
15
+ SENDER_KEY: 'skmsg',
16
+ MESSAGE_SECRET: 'msmsg'
17
+ });
18
+ /** `addressing_mode` stanza attr: phone-number vs LID addressing. */
19
+ exports.WA_ADDRESSING_MODES = Object.freeze({
20
+ PN: 'pn',
21
+ LID: 'lid'
22
+ });
11
23
  exports.WA_MESSAGE_TYPES = Object.freeze({
12
24
  ENC_VERSION: '2',
13
25
  MEDIA_NOTIFY: 'medianotify',
@@ -10,6 +10,7 @@ export declare const WA_NODE_TAGS: Readonly<{
10
10
  readonly NOTIFICATION: "notification";
11
11
  readonly SUCCESS: "success";
12
12
  readonly INFO_BULLETIN: "ib";
13
+ readonly OFFLINE: "offline";
13
14
  readonly DIRTY: "dirty";
14
15
  readonly EDGE_ROUTING: "edge_routing";
15
16
  readonly ROUTING_INFO: "routing_info";
@@ -81,6 +82,19 @@ export declare const WA_NODE_TAGS: Readonly<{
81
82
  readonly TEXT_STATUS: "text_status";
82
83
  readonly DISAPPEARING_MODE: "disappearing_mode";
83
84
  readonly BUSINESS: "business";
85
+ readonly PUB_KEY: "pub-key";
86
+ readonly KEY_INDEX_LIST: "key-index-list";
87
+ readonly CLIENT_PROPS: "client-props";
88
+ readonly PEM: "pem";
89
+ readonly TTL: "ttl";
90
+ readonly KEY_ID: "key_id";
91
+ readonly REMOVE_COMPANION_DEVICE: "remove-companion-device";
92
+ readonly PRIMARY_IDENTITY_PUB: "primary_identity_pub";
93
+ readonly COMPANION_IDENTITY_PUBLIC: "companion_identity_public";
94
+ readonly COMPANION_SERVER_AUTH_KEY_PUB: "companion_server_auth_key_pub";
95
+ readonly LINK_CODE_PAIRING_WRAPPED_PRIMARY_EPHEMERAL_PUB: "link_code_pairing_wrapped_primary_ephemeral_pub";
96
+ readonly LINK_CODE_PAIRING_WRAPPED_COMPANION_EPHEMERAL_PUB: "link_code_pairing_wrapped_companion_ephemeral_pub";
97
+ readonly LINK_CODE_PAIRING_WRAPPED_KEY_BUNDLE: "link_code_pairing_wrapped_key_bundle";
84
98
  }>;
85
99
  export declare const WA_IQ_TYPES: Readonly<{
86
100
  readonly GET: "get";
@@ -13,6 +13,7 @@ exports.WA_NODE_TAGS = Object.freeze({
13
13
  NOTIFICATION: 'notification',
14
14
  SUCCESS: 'success',
15
15
  INFO_BULLETIN: 'ib',
16
+ OFFLINE: 'offline',
16
17
  DIRTY: 'dirty',
17
18
  EDGE_ROUTING: 'edge_routing',
18
19
  ROUTING_INFO: 'routing_info',
@@ -83,7 +84,20 @@ exports.WA_NODE_TAGS = Object.freeze({
83
84
  USERNAME: 'username',
84
85
  TEXT_STATUS: 'text_status',
85
86
  DISAPPEARING_MODE: 'disappearing_mode',
86
- BUSINESS: 'business'
87
+ BUSINESS: 'business',
88
+ PUB_KEY: 'pub-key',
89
+ KEY_INDEX_LIST: 'key-index-list',
90
+ CLIENT_PROPS: 'client-props',
91
+ PEM: 'pem',
92
+ TTL: 'ttl',
93
+ KEY_ID: 'key_id',
94
+ REMOVE_COMPANION_DEVICE: 'remove-companion-device',
95
+ PRIMARY_IDENTITY_PUB: 'primary_identity_pub',
96
+ COMPANION_IDENTITY_PUBLIC: 'companion_identity_public',
97
+ COMPANION_SERVER_AUTH_KEY_PUB: 'companion_server_auth_key_pub',
98
+ LINK_CODE_PAIRING_WRAPPED_PRIMARY_EPHEMERAL_PUB: 'link_code_pairing_wrapped_primary_ephemeral_pub',
99
+ LINK_CODE_PAIRING_WRAPPED_COMPANION_EPHEMERAL_PUB: 'link_code_pairing_wrapped_companion_ephemeral_pub',
100
+ LINK_CODE_PAIRING_WRAPPED_KEY_BUNDLE: 'link_code_pairing_wrapped_key_bundle'
87
101
  });
88
102
  exports.WA_IQ_TYPES = Object.freeze({
89
103
  GET: 'get',
@@ -200,8 +200,8 @@ class WaRetryReplayService {
200
200
  addressingMode: isStatus
201
201
  ? undefined
202
202
  : requesterAddress.server === constants_1.WA_DEFAULTS.LID_SERVER
203
- ? 'lid'
204
- : 'pn',
203
+ ? constants_1.WA_ADDRESSING_MODES.LID
204
+ : constants_1.WA_ADDRESSING_MODES.PN,
205
205
  encType: encrypted.type,
206
206
  ciphertext: encrypted.ciphertext,
207
207
  retryCount,
@@ -1,5 +1,54 @@
1
1
  import type { SignalKeyPair } from '../../crypto/curves/types';
2
- export { ADV_PREFIX_ACCOUNT_SIGNATURE, ADV_PREFIX_DEVICE_SIGNATURE, ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE } from '../attestation/constants';
2
+ export { ADV_PREFIX_ACCOUNT_KEY_INDEX, ADV_PREFIX_ACCOUNT_SIGNATURE, ADV_PREFIX_DEVICE_SIGNATURE, ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE } from '../attestation/constants';
3
+ /**
4
+ * Companion-side check that the primary's account key signed a device identity.
5
+ * Verifies `accountSignature` over `prefix || details || identityPublicKey`
6
+ * against the account signature public key. Inverse of
7
+ * {@link generateDeviceIdentityAccountSignature}.
8
+ */
3
9
  export declare function verifyDeviceIdentityAccountSignature(details: Uint8Array, accountSignature: Uint8Array, identityPublicKey: Uint8Array, accountSignatureKey: Uint8Array, isHosted?: boolean): Promise<boolean>;
10
+ /**
11
+ * Companion-side signature proving possession of the identity private key after
12
+ * adopting a primary-signed identity. Signs
13
+ * `prefix || details || identityKeyPair.pubKey || accountSignatureKey`, and is
14
+ * verified by the primary via {@link verifyDeviceSignature}.
15
+ */
4
16
  export declare function generateDeviceSignature(details: Uint8Array, identityKeyPair: SignalKeyPair, accountSignatureKey: Uint8Array, isHosted?: boolean): Promise<Uint8Array>;
17
+ /**
18
+ * HMAC-SHA256 over an `ADVSignedDeviceIdentity` (or hosted-prefixed variant)
19
+ * keyed by the shared ADV secret, binding the signed identity to the pairing
20
+ * secret inside `ADVSignedDeviceIdentityHMAC`.
21
+ */
5
22
  export declare function computeAdvIdentityHmac(secretKey: Uint8Array, details: Uint8Array): Uint8Array;
23
+ /**
24
+ * Primary-side counterpart to {@link verifyDeviceIdentityAccountSignature}.
25
+ * Signs a companion's `ADVDeviceIdentity` details with the account (primary)
26
+ * identity key so a linking companion can prove the primary authorized this
27
+ * device. The signed message is `prefix || details || companionIdentityPublicKey`.
28
+ *
29
+ * `accountIdentityKeyPair` is the primary's own Signal identity key pair; its
30
+ * public half is what ships as `ADVSignedDeviceIdentity.accountSignatureKey`.
31
+ * Pass `companionIdentityPublicKey` in the exact byte form the companion will
32
+ * present at verification (the value carried in its pairing QR / key bundle).
33
+ */
34
+ export declare function generateDeviceIdentityAccountSignature(details: Uint8Array, companionIdentityPublicKey: Uint8Array, accountIdentityKeyPair: SignalKeyPair, isHosted?: boolean): Promise<Uint8Array>;
35
+ /**
36
+ * Primary-side counterpart to {@link generateDeviceSignature}. Verifies the
37
+ * device signature a companion returns after adopting a signed identity, which
38
+ * proves the companion holds the identity private key it registered. The signed
39
+ * message is `prefix || details || companionIdentityPublicKey || accountSignatureKey`.
40
+ */
41
+ export declare function verifyDeviceSignature(details: Uint8Array, deviceSignature: Uint8Array, companionIdentityPublicKey: Uint8Array, accountSignatureKey: Uint8Array, isHosted?: boolean): Promise<boolean>;
42
+ /**
43
+ * Signs an `ADVKeyIndexList` details blob with the account (primary) identity
44
+ * key. A primary republishes this list whenever its companion set changes so
45
+ * every device can validate the current set of key indexes. The signed message
46
+ * is `prefix || keyIndexListDetails`.
47
+ */
48
+ export declare function signKeyIndexList(keyIndexListDetails: Uint8Array, accountIdentityKeyPair: SignalKeyPair, isHosted?: boolean): Promise<Uint8Array>;
49
+ /**
50
+ * Verifies an `ADVSignedKeyIndexList` account signature against the primary's
51
+ * account signature key. Inverse of {@link signKeyIndexList}; used by a device
52
+ * to validate a key-index list published by the primary.
53
+ */
54
+ export declare function verifyKeyIndexListSignature(keyIndexListDetails: Uint8Array, accountSignature: Uint8Array, accountSignatureKey: Uint8Array, isHosted?: boolean): Promise<boolean>;
@@ -1,26 +1,96 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE = exports.ADV_PREFIX_DEVICE_SIGNATURE = exports.ADV_PREFIX_ACCOUNT_SIGNATURE = void 0;
3
+ exports.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE = exports.ADV_PREFIX_DEVICE_SIGNATURE = exports.ADV_PREFIX_ACCOUNT_SIGNATURE = exports.ADV_PREFIX_ACCOUNT_KEY_INDEX = void 0;
4
4
  exports.verifyDeviceIdentityAccountSignature = verifyDeviceIdentityAccountSignature;
5
5
  exports.generateDeviceSignature = generateDeviceSignature;
6
6
  exports.computeAdvIdentityHmac = computeAdvIdentityHmac;
7
+ exports.generateDeviceIdentityAccountSignature = generateDeviceIdentityAccountSignature;
8
+ exports.verifyDeviceSignature = verifyDeviceSignature;
9
+ exports.signKeyIndexList = signKeyIndexList;
10
+ exports.verifyKeyIndexListSignature = verifyKeyIndexListSignature;
7
11
  const _crypto_1 = require("../../crypto");
8
12
  const constants_1 = require("../attestation/constants");
9
13
  const bytes_1 = require("../../util/bytes");
10
14
  var constants_2 = require("../attestation/constants");
15
+ Object.defineProperty(exports, "ADV_PREFIX_ACCOUNT_KEY_INDEX", { enumerable: true, get: function () { return constants_2.ADV_PREFIX_ACCOUNT_KEY_INDEX; } });
11
16
  Object.defineProperty(exports, "ADV_PREFIX_ACCOUNT_SIGNATURE", { enumerable: true, get: function () { return constants_2.ADV_PREFIX_ACCOUNT_SIGNATURE; } });
12
17
  Object.defineProperty(exports, "ADV_PREFIX_DEVICE_SIGNATURE", { enumerable: true, get: function () { return constants_2.ADV_PREFIX_DEVICE_SIGNATURE; } });
13
18
  Object.defineProperty(exports, "ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE", { enumerable: true, get: function () { return constants_2.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE; } });
19
+ /**
20
+ * Companion-side check that the primary's account key signed a device identity.
21
+ * Verifies `accountSignature` over `prefix || details || identityPublicKey`
22
+ * against the account signature public key. Inverse of
23
+ * {@link generateDeviceIdentityAccountSignature}.
24
+ */
14
25
  async function verifyDeviceIdentityAccountSignature(details, accountSignature, identityPublicKey, accountSignatureKey, isHosted = false) {
15
26
  const prefix = isHosted ? constants_1.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE : constants_1.ADV_PREFIX_ACCOUNT_SIGNATURE;
16
27
  const message = (0, bytes_1.concatBytes)([prefix, details, identityPublicKey]);
17
28
  return (0, _crypto_1.xeddsaVerify)((0, _crypto_1.toRawPubKey)(accountSignatureKey), message, accountSignature);
18
29
  }
30
+ /**
31
+ * Companion-side signature proving possession of the identity private key after
32
+ * adopting a primary-signed identity. Signs
33
+ * `prefix || details || identityKeyPair.pubKey || accountSignatureKey`, and is
34
+ * verified by the primary via {@link verifyDeviceSignature}.
35
+ */
19
36
  async function generateDeviceSignature(details, identityKeyPair, accountSignatureKey, isHosted = false) {
20
37
  const prefix = isHosted ? constants_1.ADV_PREFIX_HOSTED_DEVICE_SIGNATURE : constants_1.ADV_PREFIX_DEVICE_SIGNATURE;
21
38
  const message = (0, bytes_1.concatBytes)([prefix, details, identityKeyPair.pubKey, accountSignatureKey]);
22
39
  return (0, _crypto_1.xeddsaSign)(identityKeyPair.privKey, message);
23
40
  }
41
+ /**
42
+ * HMAC-SHA256 over an `ADVSignedDeviceIdentity` (or hosted-prefixed variant)
43
+ * keyed by the shared ADV secret, binding the signed identity to the pairing
44
+ * secret inside `ADVSignedDeviceIdentityHMAC`.
45
+ */
24
46
  function computeAdvIdentityHmac(secretKey, details) {
25
47
  return (0, _crypto_1.hmacSha256Sign)(secretKey, details);
26
48
  }
49
+ /**
50
+ * Primary-side counterpart to {@link verifyDeviceIdentityAccountSignature}.
51
+ * Signs a companion's `ADVDeviceIdentity` details with the account (primary)
52
+ * identity key so a linking companion can prove the primary authorized this
53
+ * device. The signed message is `prefix || details || companionIdentityPublicKey`.
54
+ *
55
+ * `accountIdentityKeyPair` is the primary's own Signal identity key pair; its
56
+ * public half is what ships as `ADVSignedDeviceIdentity.accountSignatureKey`.
57
+ * Pass `companionIdentityPublicKey` in the exact byte form the companion will
58
+ * present at verification (the value carried in its pairing QR / key bundle).
59
+ */
60
+ async function generateDeviceIdentityAccountSignature(details, companionIdentityPublicKey, accountIdentityKeyPair, isHosted = false) {
61
+ const prefix = isHosted ? constants_1.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE : constants_1.ADV_PREFIX_ACCOUNT_SIGNATURE;
62
+ const message = (0, bytes_1.concatBytes)([prefix, details, companionIdentityPublicKey]);
63
+ return (0, _crypto_1.xeddsaSign)(accountIdentityKeyPair.privKey, message);
64
+ }
65
+ /**
66
+ * Primary-side counterpart to {@link generateDeviceSignature}. Verifies the
67
+ * device signature a companion returns after adopting a signed identity, which
68
+ * proves the companion holds the identity private key it registered. The signed
69
+ * message is `prefix || details || companionIdentityPublicKey || accountSignatureKey`.
70
+ */
71
+ async function verifyDeviceSignature(details, deviceSignature, companionIdentityPublicKey, accountSignatureKey, isHosted = false) {
72
+ const prefix = isHosted ? constants_1.ADV_PREFIX_HOSTED_DEVICE_SIGNATURE : constants_1.ADV_PREFIX_DEVICE_SIGNATURE;
73
+ const message = (0, bytes_1.concatBytes)([prefix, details, companionIdentityPublicKey, accountSignatureKey]);
74
+ return (0, _crypto_1.xeddsaVerify)((0, _crypto_1.toRawPubKey)(companionIdentityPublicKey), message, deviceSignature);
75
+ }
76
+ /**
77
+ * Signs an `ADVKeyIndexList` details blob with the account (primary) identity
78
+ * key. A primary republishes this list whenever its companion set changes so
79
+ * every device can validate the current set of key indexes. The signed message
80
+ * is `prefix || keyIndexListDetails`.
81
+ */
82
+ async function signKeyIndexList(keyIndexListDetails, accountIdentityKeyPair, isHosted = false) {
83
+ const prefix = isHosted ? constants_1.ADV_PREFIX_HOSTED_ACCOUNT_KEY_INDEX : constants_1.ADV_PREFIX_ACCOUNT_KEY_INDEX;
84
+ const message = (0, bytes_1.concatBytes)([prefix, keyIndexListDetails]);
85
+ return (0, _crypto_1.xeddsaSign)(accountIdentityKeyPair.privKey, message);
86
+ }
87
+ /**
88
+ * Verifies an `ADVSignedKeyIndexList` account signature against the primary's
89
+ * account signature key. Inverse of {@link signKeyIndexList}; used by a device
90
+ * to validate a key-index list published by the primary.
91
+ */
92
+ async function verifyKeyIndexListSignature(keyIndexListDetails, accountSignature, accountSignatureKey, isHosted = false) {
93
+ const prefix = isHosted ? constants_1.ADV_PREFIX_HOSTED_ACCOUNT_KEY_INDEX : constants_1.ADV_PREFIX_ACCOUNT_KEY_INDEX;
94
+ const message = (0, bytes_1.concatBytes)([prefix, keyIndexListDetails]);
95
+ return (0, _crypto_1.xeddsaVerify)((0, _crypto_1.toRawPubKey)(accountSignatureKey), message, accountSignature);
96
+ }
@@ -1,4 +1,6 @@
1
1
  export declare const ADV_PREFIX_ACCOUNT_SIGNATURE: Readonly<Uint8Array>;
2
2
  export declare const ADV_PREFIX_DEVICE_SIGNATURE: Readonly<Uint8Array>;
3
+ export declare const ADV_PREFIX_ACCOUNT_KEY_INDEX: Readonly<Uint8Array>;
3
4
  export declare const ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE: Readonly<Uint8Array>;
4
5
  export declare const ADV_PREFIX_HOSTED_DEVICE_SIGNATURE: Readonly<Uint8Array>;
6
+ export declare const ADV_PREFIX_HOSTED_ACCOUNT_KEY_INDEX: Readonly<Uint8Array>;
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ADV_PREFIX_HOSTED_DEVICE_SIGNATURE = exports.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE = exports.ADV_PREFIX_DEVICE_SIGNATURE = exports.ADV_PREFIX_ACCOUNT_SIGNATURE = void 0;
3
+ exports.ADV_PREFIX_HOSTED_ACCOUNT_KEY_INDEX = exports.ADV_PREFIX_HOSTED_DEVICE_SIGNATURE = exports.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE = exports.ADV_PREFIX_ACCOUNT_KEY_INDEX = exports.ADV_PREFIX_DEVICE_SIGNATURE = exports.ADV_PREFIX_ACCOUNT_SIGNATURE = void 0;
4
4
  exports.ADV_PREFIX_ACCOUNT_SIGNATURE = new Uint8Array([6, 0]);
5
5
  exports.ADV_PREFIX_DEVICE_SIGNATURE = new Uint8Array([6, 1]);
6
+ exports.ADV_PREFIX_ACCOUNT_KEY_INDEX = new Uint8Array([6, 2]);
6
7
  exports.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE = new Uint8Array([6, 5]);
7
8
  exports.ADV_PREFIX_HOSTED_DEVICE_SIGNATURE = new Uint8Array([6, 6]);
9
+ exports.ADV_PREFIX_HOSTED_ACCOUNT_KEY_INDEX = new Uint8Array([6, 7]);
@@ -16,3 +16,4 @@ export { SenderKeyManager } from './group/SenderKeyManager';
16
16
  export { createAndStoreInitialKeys } from './registration/utils';
17
17
  export { SignalProtocol } from './session/SignalProtocol';
18
18
  export { createSignalSessionResolver, type SignalSessionResolver } from './session/resolver';
19
+ export { ADV_PREFIX_ACCOUNT_KEY_INDEX, ADV_PREFIX_ACCOUNT_SIGNATURE, ADV_PREFIX_DEVICE_SIGNATURE, ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE, computeAdvIdentityHmac, generateDeviceIdentityAccountSignature, generateDeviceSignature, signKeyIndexList, verifyDeviceIdentityAccountSignature, verifyDeviceSignature, verifyKeyIndexListSignature } from './attestation/WaAdvSignature';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createSignalSessionResolver = exports.SignalProtocol = exports.createAndStoreInitialKeys = exports.SenderKeyManager = exports.SignalSessionSyncApi = exports.SignalRotateKeyApi = exports.SignalMissingPreKeysSyncApi = exports.SignalIdentitySyncApi = exports.SignalDeviceSyncApi = exports.SignalDigestSyncApi = exports.parsePreKeyUploadFailure = exports.buildPreKeyUploadIq = exports.generateSignedPreKey = exports.generateRegistrationInfo = exports.generateRegistrationId = exports.generatePreKeyPair = exports.encodeSenderKeyRecord = exports.decodeSenderKeyRecord = exports.decodeSenderKeyDistributionRow = exports.decodeSignalSignedPreKeyRow = exports.decodeSignalRegistrationRow = exports.decodeSignalPreKeyRow = exports.encodeSignalSessionRecord = exports.decodeSignalSessionRecord = exports.decodeSignalRemoteIdentity = exports.toSignalAddressParts = exports.decodeStoreCount = void 0;
3
+ exports.verifyKeyIndexListSignature = exports.verifyDeviceSignature = exports.verifyDeviceIdentityAccountSignature = exports.signKeyIndexList = exports.generateDeviceSignature = exports.generateDeviceIdentityAccountSignature = exports.computeAdvIdentityHmac = exports.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE = exports.ADV_PREFIX_DEVICE_SIGNATURE = exports.ADV_PREFIX_ACCOUNT_SIGNATURE = exports.ADV_PREFIX_ACCOUNT_KEY_INDEX = exports.createSignalSessionResolver = exports.SignalProtocol = exports.createAndStoreInitialKeys = exports.SenderKeyManager = exports.SignalSessionSyncApi = exports.SignalRotateKeyApi = exports.SignalMissingPreKeysSyncApi = exports.SignalIdentitySyncApi = exports.SignalDeviceSyncApi = exports.SignalDigestSyncApi = exports.parsePreKeyUploadFailure = exports.buildPreKeyUploadIq = exports.generateSignedPreKey = exports.generateRegistrationInfo = exports.generateRegistrationId = exports.generatePreKeyPair = exports.encodeSenderKeyRecord = exports.decodeSenderKeyRecord = exports.decodeSenderKeyDistributionRow = exports.decodeSignalSignedPreKeyRow = exports.decodeSignalRegistrationRow = exports.decodeSignalPreKeyRow = exports.encodeSignalSessionRecord = exports.decodeSignalSessionRecord = exports.decodeSignalRemoteIdentity = exports.toSignalAddressParts = exports.decodeStoreCount = void 0;
4
4
  var encoding_1 = require("./encoding");
5
5
  Object.defineProperty(exports, "decodeStoreCount", { enumerable: true, get: function () { return encoding_1.decodeStoreCount; } });
6
6
  Object.defineProperty(exports, "toSignalAddressParts", { enumerable: true, get: function () { return encoding_1.toSignalAddressParts; } });
@@ -44,3 +44,15 @@ var SignalProtocol_1 = require("./session/SignalProtocol");
44
44
  Object.defineProperty(exports, "SignalProtocol", { enumerable: true, get: function () { return SignalProtocol_1.SignalProtocol; } });
45
45
  var resolver_1 = require("./session/resolver");
46
46
  Object.defineProperty(exports, "createSignalSessionResolver", { enumerable: true, get: function () { return resolver_1.createSignalSessionResolver; } });
47
+ var WaAdvSignature_1 = require("./attestation/WaAdvSignature");
48
+ Object.defineProperty(exports, "ADV_PREFIX_ACCOUNT_KEY_INDEX", { enumerable: true, get: function () { return WaAdvSignature_1.ADV_PREFIX_ACCOUNT_KEY_INDEX; } });
49
+ Object.defineProperty(exports, "ADV_PREFIX_ACCOUNT_SIGNATURE", { enumerable: true, get: function () { return WaAdvSignature_1.ADV_PREFIX_ACCOUNT_SIGNATURE; } });
50
+ Object.defineProperty(exports, "ADV_PREFIX_DEVICE_SIGNATURE", { enumerable: true, get: function () { return WaAdvSignature_1.ADV_PREFIX_DEVICE_SIGNATURE; } });
51
+ Object.defineProperty(exports, "ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE", { enumerable: true, get: function () { return WaAdvSignature_1.ADV_PREFIX_HOSTED_ACCOUNT_SIGNATURE; } });
52
+ Object.defineProperty(exports, "computeAdvIdentityHmac", { enumerable: true, get: function () { return WaAdvSignature_1.computeAdvIdentityHmac; } });
53
+ Object.defineProperty(exports, "generateDeviceIdentityAccountSignature", { enumerable: true, get: function () { return WaAdvSignature_1.generateDeviceIdentityAccountSignature; } });
54
+ Object.defineProperty(exports, "generateDeviceSignature", { enumerable: true, get: function () { return WaAdvSignature_1.generateDeviceSignature; } });
55
+ Object.defineProperty(exports, "signKeyIndexList", { enumerable: true, get: function () { return WaAdvSignature_1.signKeyIndexList; } });
56
+ Object.defineProperty(exports, "verifyDeviceIdentityAccountSignature", { enumerable: true, get: function () { return WaAdvSignature_1.verifyDeviceIdentityAccountSignature; } });
57
+ Object.defineProperty(exports, "verifyDeviceSignature", { enumerable: true, get: function () { return WaAdvSignature_1.verifyDeviceSignature; } });
58
+ Object.defineProperty(exports, "verifyKeyIndexListSignature", { enumerable: true, get: function () { return WaAdvSignature_1.verifyKeyIndexListSignature; } });
@@ -1,8 +1,8 @@
1
1
  export type { BinaryNode, RawWebSocket, RawWebSocketConstructor, WaRawWebSocketInit, SocketCloseInfo, SocketOpenInfo, WaCommsConfig, WaCommsState, WaNoiseConfig, WaProxyAgent, WaProxyDispatcher, WaProxyTransport, WaSocketConfig, WaSocketHandlers } from './types';
2
2
  export { decodeBinaryNode, decodeBinaryNodeStanza, encodeBinaryNode, encodeBinaryNodeStanza } from './binary';
3
3
  export { isProxyAgent, isProxyDispatcher, isProxyTransport, toProxyAgent, toProxyDispatcher } from './proxy';
4
- export { fetchLatestWaWebVersion } from './wa-web-version-fetcher';
5
- export type { WaFetchLatestWebVersionOptions, WaLatestWebVersion } from './wa-web-version-fetcher';
4
+ export { fetchLatestWaWebVersion, fetchLatestWaMobileVersion } from './wa-version-fetcher';
5
+ export type { WaFetchVersionOptions, WaFetchLatestWebVersionOptions, WaFetchLatestMobileVersionOptions, WaLatestWebVersion, WaLatestMobileVersion } from './wa-version-fetcher';
6
6
  export { WaComms } from './WaComms';
7
7
  export { verifyNoiseCertificateChain, type WaNoiseRootCa } from './noise/WaNoiseCert';
8
8
  export { WaNoiseHandshake } from './noise/WaNoiseHandshake';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.hasNodeChild = exports.getNodeTextContent = exports.getNodeChildrenByTag = exports.getNodeChildren = exports.getFirstNodeChild = exports.findNodeChild = exports.buildReceiptNode = exports.buildAckNode = exports.queryWithContext = exports.parseIqError = exports.buildIqNode = exports.assertIqResult = exports.buildMobileLoginPayload = exports.WaMobileTcpSocketCtor = exports.WaMobileTcpSocket = exports.WaNodeTransport = exports.WaNodeOrchestrator = exports.WaKeepAlive = exports.WaWebSocket = exports.WaNoiseSocket = exports.WaNoiseHandshake = exports.verifyNoiseCertificateChain = exports.WaComms = exports.fetchLatestWaWebVersion = exports.toProxyDispatcher = exports.toProxyAgent = exports.isProxyTransport = exports.isProxyDispatcher = exports.isProxyAgent = exports.encodeBinaryNodeStanza = exports.encodeBinaryNode = exports.decodeBinaryNodeStanza = exports.decodeBinaryNode = void 0;
3
+ exports.hasNodeChild = exports.getNodeTextContent = exports.getNodeChildrenByTag = exports.getNodeChildren = exports.getFirstNodeChild = exports.findNodeChild = exports.buildReceiptNode = exports.buildAckNode = exports.queryWithContext = exports.parseIqError = exports.buildIqNode = exports.assertIqResult = exports.buildMobileLoginPayload = exports.WaMobileTcpSocketCtor = exports.WaMobileTcpSocket = exports.WaNodeTransport = exports.WaNodeOrchestrator = exports.WaKeepAlive = exports.WaWebSocket = exports.WaNoiseSocket = exports.WaNoiseHandshake = exports.verifyNoiseCertificateChain = exports.WaComms = exports.fetchLatestWaMobileVersion = exports.fetchLatestWaWebVersion = exports.toProxyDispatcher = exports.toProxyAgent = exports.isProxyTransport = exports.isProxyDispatcher = exports.isProxyAgent = exports.encodeBinaryNodeStanza = exports.encodeBinaryNode = exports.decodeBinaryNodeStanza = exports.decodeBinaryNode = void 0;
4
4
  var binary_1 = require("./binary");
5
5
  Object.defineProperty(exports, "decodeBinaryNode", { enumerable: true, get: function () { return binary_1.decodeBinaryNode; } });
6
6
  Object.defineProperty(exports, "decodeBinaryNodeStanza", { enumerable: true, get: function () { return binary_1.decodeBinaryNodeStanza; } });
@@ -12,8 +12,9 @@ Object.defineProperty(exports, "isProxyDispatcher", { enumerable: true, get: fun
12
12
  Object.defineProperty(exports, "isProxyTransport", { enumerable: true, get: function () { return proxy_1.isProxyTransport; } });
13
13
  Object.defineProperty(exports, "toProxyAgent", { enumerable: true, get: function () { return proxy_1.toProxyAgent; } });
14
14
  Object.defineProperty(exports, "toProxyDispatcher", { enumerable: true, get: function () { return proxy_1.toProxyDispatcher; } });
15
- var wa_web_version_fetcher_1 = require("./wa-web-version-fetcher");
16
- Object.defineProperty(exports, "fetchLatestWaWebVersion", { enumerable: true, get: function () { return wa_web_version_fetcher_1.fetchLatestWaWebVersion; } });
15
+ var wa_version_fetcher_1 = require("./wa-version-fetcher");
16
+ Object.defineProperty(exports, "fetchLatestWaWebVersion", { enumerable: true, get: function () { return wa_version_fetcher_1.fetchLatestWaWebVersion; } });
17
+ Object.defineProperty(exports, "fetchLatestWaMobileVersion", { enumerable: true, get: function () { return wa_version_fetcher_1.fetchLatestWaMobileVersion; } });
17
18
  var WaComms_1 = require("./WaComms");
18
19
  Object.defineProperty(exports, "WaComms", { enumerable: true, get: function () { return WaComms_1.WaComms; } });
19
20
  var WaNoiseCert_1 = require("./noise/WaNoiseCert");
@@ -12,6 +12,7 @@ exports.buildSetGroupMemberShareGroupHistoryModeIq = buildSetGroupMemberShareGro
12
12
  exports.buildSetGroupEphemeralIq = buildSetGroupEphemeralIq;
13
13
  exports.buildJoinLinkedGroupIq = buildJoinLinkedGroupIq;
14
14
  const defaults_1 = require("../../../protocol/defaults");
15
+ const group_1 = require("../../../protocol/group");
15
16
  const nodes_1 = require("../../../protocol/nodes");
16
17
  const query_1 = require("../../node/query");
17
18
  function buildCreateGroupIq(input) {
@@ -89,20 +90,20 @@ function buildMembershipRequestsActionIq(input) {
89
90
  const children = [];
90
91
  if (approve.length > 0) {
91
92
  children.push({
92
- tag: 'approve',
93
+ tag: group_1.WA_GROUP_MEMBERSHIP_ACTION_TAGS.APPROVE,
93
94
  attrs: {},
94
95
  content: approve.map((jid) => ({ tag: 'participant', attrs: { jid } }))
95
96
  });
96
97
  }
97
98
  if (reject.length > 0) {
98
99
  children.push({
99
- tag: 'reject',
100
+ tag: group_1.WA_GROUP_MEMBERSHIP_ACTION_TAGS.REJECT,
100
101
  attrs: {},
101
102
  content: reject.map((jid) => ({ tag: 'participant', attrs: { jid } }))
102
103
  });
103
104
  }
104
105
  return (0, query_1.buildIqNode)(nodes_1.WA_IQ_TYPES.SET, input.groupJid, nodes_1.WA_XMLNS.GROUPS, [
105
- { tag: 'membership_requests_action', attrs: {}, content: children }
106
+ { tag: group_1.WA_GROUP_MEMBERSHIP_ACTION_TAGS.REQUESTS_ACTION, attrs: {}, content: children }
106
107
  ]);
107
108
  }
108
109
  function buildCancelMembershipRequestsIq(input) {
@@ -0,0 +1,68 @@
1
+ import type { BinaryNode } from '../../types';
2
+ /**
3
+ * `ClientPairingProps` the primary declares in the `<client-props>` pair-device
4
+ * element. A LID-native account must send `isChatDbLidMigrated: true` (with
5
+ * `isSyncdPureLidSession`) so the companion runs `setIsLidMigrated` before
6
+ * fetching its LID-addressed blocklist; without it the companion self-removes
7
+ * with `lid_blocklist_chat_db_unmigrated`.
8
+ */
9
+ export interface ClientPairingProps {
10
+ readonly isChatDbLidMigrated: boolean;
11
+ readonly isSyncdPureLidSession: boolean;
12
+ readonly isSyncdSnapshotRecoveryEnabled: boolean;
13
+ }
14
+ export interface PairDeviceIqInput {
15
+ readonly ref: string;
16
+ readonly companionNoisePublicKey: Uint8Array;
17
+ readonly deviceIdentityBytes: Uint8Array;
18
+ readonly keyIndexListBytes: Uint8Array;
19
+ readonly keyIndexListTimestampSeconds: number;
20
+ readonly clientProps?: ClientPairingProps;
21
+ readonly pem?: {
22
+ readonly aesGcmKeyBytes: Uint8Array;
23
+ readonly ttlSeconds: number;
24
+ };
25
+ }
26
+ /**
27
+ * Builds the primary's `<iq type="set" xmlns="md">` carrying `<pair-device>`
28
+ * with `ref`, `pub-key`, `device-identity`, `key-index-list`, and optional
29
+ * `client-props`/`pem` children. The `id` is assigned by the send path.
30
+ */
31
+ export declare function buildPairDeviceIq(input: PairDeviceIqInput): BinaryNode;
32
+ /**
33
+ * Builds the standalone key-index-list publish `<iq>` the primary sends when its
34
+ * companion set changes.
35
+ */
36
+ export declare function buildKeyIndexListPublishIq(input: {
37
+ readonly keyIndexListBytes: Uint8Array;
38
+ readonly timestampSeconds: number;
39
+ }): BinaryNode;
40
+ /**
41
+ * Builds the `remove-companion-device` IQ that unlinks a companion from the
42
+ * account. The device is identified by its full device jid; `reason` is a
43
+ * free-form label the server records.
44
+ */
45
+ export declare function buildRemoveCompanionDeviceIq(input: {
46
+ readonly deviceJid: string;
47
+ readonly reason: string;
48
+ }): BinaryNode;
49
+ /**
50
+ * Builds the `remove-companion-device` IQ that unlinks EVERY companion in one
51
+ * stanza: `all="true"` (no `jid`), mirroring the phone's "log out all companion
52
+ * devices". `excludeHostedCompanion` adds `exclude_hosted_companion="true"` to
53
+ * spare companions this account itself hosts.
54
+ */
55
+ export declare function buildRemoveAllCompanionDevicesIq(input: {
56
+ readonly reason: string;
57
+ readonly excludeHostedCompanion?: boolean;
58
+ }): BinaryNode;
59
+ /**
60
+ * Builds the `primary_hello` IQ the primary sends to drive a link-code (pairing
61
+ * code) handshake: the code-wrapped primary ephemeral, the primary ADV identity
62
+ * public key, and the companion's pairing ref.
63
+ */
64
+ export declare function buildPrimaryHelloIq(input: {
65
+ readonly ref: string;
66
+ readonly wrappedPrimaryEphemeralPub: Uint8Array;
67
+ readonly primaryIdentityPub: Uint8Array;
68
+ }): BinaryNode;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildPairDeviceIq = buildPairDeviceIq;
4
+ exports.buildKeyIndexListPublishIq = buildKeyIndexListPublishIq;
5
+ exports.buildRemoveCompanionDeviceIq = buildRemoveCompanionDeviceIq;
6
+ exports.buildRemoveAllCompanionDevicesIq = buildRemoveAllCompanionDevicesIq;
7
+ exports.buildPrimaryHelloIq = buildPrimaryHelloIq;
8
+ const _proto_1 = require("../../../proto");
9
+ const defaults_1 = require("../../../protocol/defaults");
10
+ const nodes_1 = require("../../../protocol/nodes");
11
+ const query_1 = require("../../node/query");
12
+ /**
13
+ * Builds the primary's `<iq type="set" xmlns="md">` carrying `<pair-device>`
14
+ * with `ref`, `pub-key`, `device-identity`, `key-index-list`, and optional
15
+ * `client-props`/`pem` children. The `id` is assigned by the send path.
16
+ */
17
+ function buildPairDeviceIq(input) {
18
+ const children = [
19
+ { tag: nodes_1.WA_NODE_TAGS.REF, attrs: {}, content: input.ref },
20
+ { tag: nodes_1.WA_NODE_TAGS.PUB_KEY, attrs: {}, content: input.companionNoisePublicKey },
21
+ { tag: nodes_1.WA_NODE_TAGS.DEVICE_IDENTITY, attrs: {}, content: input.deviceIdentityBytes },
22
+ {
23
+ tag: nodes_1.WA_NODE_TAGS.KEY_INDEX_LIST,
24
+ attrs: { ts: String(input.keyIndexListTimestampSeconds) },
25
+ content: input.keyIndexListBytes
26
+ }
27
+ ];
28
+ if (input.clientProps) {
29
+ children.push({
30
+ tag: nodes_1.WA_NODE_TAGS.CLIENT_PROPS,
31
+ attrs: {},
32
+ content: _proto_1.proto.ClientPairingProps.encode({
33
+ isChatDbLidMigrated: input.clientProps.isChatDbLidMigrated,
34
+ isSyncdPureLidSession: input.clientProps.isSyncdPureLidSession,
35
+ isSyncdSnapshotRecoveryEnabled: input.clientProps.isSyncdSnapshotRecoveryEnabled
36
+ }).finish()
37
+ });
38
+ }
39
+ if (input.pem) {
40
+ children.push({
41
+ tag: nodes_1.WA_NODE_TAGS.PEM,
42
+ attrs: { version: '1', algorithm: 'rsa2048' },
43
+ content: [
44
+ { tag: nodes_1.WA_NODE_TAGS.PEM, attrs: {}, content: input.pem.aesGcmKeyBytes },
45
+ { tag: nodes_1.WA_NODE_TAGS.TTL, attrs: { ts_s: String(input.pem.ttlSeconds) } },
46
+ { tag: nodes_1.WA_NODE_TAGS.KEY_ID, attrs: {}, content: '1' }
47
+ ]
48
+ });
49
+ }
50
+ return (0, query_1.buildIqNode)(nodes_1.WA_IQ_TYPES.SET, defaults_1.WA_DEFAULTS.HOST_DOMAIN, nodes_1.WA_XMLNS.MD, [
51
+ { tag: nodes_1.WA_NODE_TAGS.PAIR_DEVICE, attrs: {}, content: children }
52
+ ]);
53
+ }
54
+ /**
55
+ * Builds the standalone key-index-list publish `<iq>` the primary sends when its
56
+ * companion set changes.
57
+ */
58
+ function buildKeyIndexListPublishIq(input) {
59
+ return (0, query_1.buildIqNode)(nodes_1.WA_IQ_TYPES.SET, defaults_1.WA_DEFAULTS.HOST_DOMAIN, nodes_1.WA_XMLNS.MD, [
60
+ {
61
+ tag: nodes_1.WA_NODE_TAGS.KEY_INDEX_LIST,
62
+ attrs: { ts: String(input.timestampSeconds) },
63
+ content: input.keyIndexListBytes
64
+ }
65
+ ]);
66
+ }
67
+ /**
68
+ * Builds the `remove-companion-device` IQ that unlinks a companion from the
69
+ * account. The device is identified by its full device jid; `reason` is a
70
+ * free-form label the server records.
71
+ */
72
+ function buildRemoveCompanionDeviceIq(input) {
73
+ return (0, query_1.buildIqNode)(nodes_1.WA_IQ_TYPES.SET, defaults_1.WA_DEFAULTS.HOST_DOMAIN, nodes_1.WA_XMLNS.MD, [
74
+ {
75
+ tag: nodes_1.WA_NODE_TAGS.REMOVE_COMPANION_DEVICE,
76
+ attrs: { jid: input.deviceJid, reason: input.reason }
77
+ }
78
+ ]);
79
+ }
80
+ /**
81
+ * Builds the `remove-companion-device` IQ that unlinks EVERY companion in one
82
+ * stanza: `all="true"` (no `jid`), mirroring the phone's "log out all companion
83
+ * devices". `excludeHostedCompanion` adds `exclude_hosted_companion="true"` to
84
+ * spare companions this account itself hosts.
85
+ */
86
+ function buildRemoveAllCompanionDevicesIq(input) {
87
+ const attrs = { all: 'true', reason: input.reason };
88
+ if (input.excludeHostedCompanion) {
89
+ attrs.exclude_hosted_companion = 'true';
90
+ }
91
+ return (0, query_1.buildIqNode)(nodes_1.WA_IQ_TYPES.SET, defaults_1.WA_DEFAULTS.HOST_DOMAIN, nodes_1.WA_XMLNS.MD, [
92
+ { tag: nodes_1.WA_NODE_TAGS.REMOVE_COMPANION_DEVICE, attrs }
93
+ ]);
94
+ }
95
+ /**
96
+ * Builds the `primary_hello` IQ the primary sends to drive a link-code (pairing
97
+ * code) handshake: the code-wrapped primary ephemeral, the primary ADV identity
98
+ * public key, and the companion's pairing ref.
99
+ */
100
+ function buildPrimaryHelloIq(input) {
101
+ return (0, query_1.buildIqNode)(nodes_1.WA_IQ_TYPES.SET, defaults_1.WA_DEFAULTS.HOST_DOMAIN, nodes_1.WA_XMLNS.MD, [
102
+ {
103
+ tag: nodes_1.WA_NODE_TAGS.LINK_CODE_COMPANION_REG,
104
+ attrs: { stage: 'primary_hello' },
105
+ content: [
106
+ {
107
+ tag: nodes_1.WA_NODE_TAGS.LINK_CODE_PAIRING_WRAPPED_PRIMARY_EPHEMERAL_PUB,
108
+ attrs: {},
109
+ content: input.wrappedPrimaryEphemeralPub
110
+ },
111
+ {
112
+ tag: nodes_1.WA_NODE_TAGS.PRIMARY_IDENTITY_PUB,
113
+ attrs: {},
114
+ content: input.primaryIdentityPub
115
+ },
116
+ { tag: nodes_1.WA_NODE_TAGS.LINK_CODE_PAIRING_REF, attrs: {}, content: input.ref }
117
+ ]
118
+ }
119
+ ]);
120
+ }