@xyo-network/event-kit-node 0.1.0 → 0.1.2
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/LICENSE +310 -0
- package/README.md +23 -3
- package/dist/node/handshake.mjs +122 -249
- package/dist/node/handshake.mjs.map +2 -2
- package/dist/node/handshakeClients.d.ts +7 -4
- package/dist/node/handshakeClients.d.ts.map +1 -1
- package/dist/node/handshakeMutationIntent.d.ts +118 -34
- package/dist/node/handshakeMutationIntent.d.ts.map +1 -1
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.mjs +1582 -291
- package/dist/node/index.mjs.map +4 -4
- package/dist/node/runtime/abort.d.ts +6 -0
- package/dist/node/runtime/abort.d.ts.map +1 -0
- package/dist/node/runtime/boundedFetch.d.ts +20 -0
- package/dist/node/runtime/boundedFetch.d.ts.map +1 -0
- package/dist/node/runtime/handshakeDiscovery.d.ts +16 -0
- package/dist/node/runtime/handshakeDiscovery.d.ts.map +1 -0
- package/dist/node/runtime/httpsTransport.d.ts +24 -0
- package/dist/node/runtime/httpsTransport.d.ts.map +1 -0
- package/dist/node/runtime/publisherRuntime.d.ts +84 -0
- package/dist/node/runtime/publisherRuntime.d.ts.map +1 -0
- package/dist/node/runtime/restGateway.d.ts +36 -0
- package/dist/node/runtime/restGateway.d.ts.map +1 -0
- package/dist/node/runtime/sourceSigner.d.ts +41 -0
- package/dist/node/runtime/sourceSigner.d.ts.map +1 -0
- package/dist/node/runtime/sources.d.ts +35 -0
- package/dist/node/runtime/sources.d.ts.map +1 -0
- package/dist/node/runtime/sqliteHandshakeStores.d.ts +15 -0
- package/dist/node/runtime/sqliteHandshakeStores.d.ts.map +1 -0
- package/dist/node/runtime/sqlitePublisherState.d.ts +21 -0
- package/dist/node/runtime/sqlitePublisherState.d.ts.map +1 -0
- package/dist/node/runtime.d.ts +10 -0
- package/dist/node/runtime.d.ts.map +1 -0
- package/dist/node/runtime.mjs +1640 -0
- package/dist/node/runtime.mjs.map +7 -0
- package/package.json +17 -12
package/dist/node/handshake.mjs
CHANGED
|
@@ -793,6 +793,7 @@ function requireTime(value) {
|
|
|
793
793
|
// src/handshakeClients.ts
|
|
794
794
|
import {
|
|
795
795
|
beginPublisherEndpointChallengeAttempt,
|
|
796
|
+
canonicalJson,
|
|
796
797
|
completePublisherEndpointChallenge,
|
|
797
798
|
createEncryptedWakeSubscription,
|
|
798
799
|
createPublisherEncryptionKeyRevocation,
|
|
@@ -841,10 +842,7 @@ function createSynchronizedEventKitHandshakeReader(options) {
|
|
|
841
842
|
function assertIdentity() {
|
|
842
843
|
const checkpoint = options.replay.snapshot();
|
|
843
844
|
if (checkpoint.chainId !== chainId || checkpoint.network !== options.session.network || checkpoint.publisher !== publisher) {
|
|
844
|
-
throw new EventKitHandshakeClientError(
|
|
845
|
-
"identity-mismatch",
|
|
846
|
-
"Finalized replay identity does not match the pinned Event Kit network and publisher"
|
|
847
|
-
);
|
|
845
|
+
throw new EventKitHandshakeClientError("identity-mismatch", "Finalized replay identity does not match the pinned Event Kit network and publisher");
|
|
848
846
|
}
|
|
849
847
|
}
|
|
850
848
|
return Object.freeze({
|
|
@@ -897,10 +895,7 @@ function createEventKitHandshakePublicationPort(transport) {
|
|
|
897
895
|
const raw = String(await transport.signer.address());
|
|
898
896
|
const normalized = NormalizedAddressZod3.parse(normalizeAddress(raw));
|
|
899
897
|
if (raw !== normalized) {
|
|
900
|
-
throw new EventKitHandshakeClientError(
|
|
901
|
-
"identity-mismatch",
|
|
902
|
-
"XL1 publication signer address is not canonical lowercase hexadecimal without 0x"
|
|
903
|
-
);
|
|
898
|
+
throw new EventKitHandshakeClientError("identity-mismatch", "XL1 publication signer address is not canonical lowercase hexadecimal without 0x");
|
|
904
899
|
}
|
|
905
900
|
return normalized;
|
|
906
901
|
}
|
|
@@ -916,10 +911,7 @@ function nextBlock(head) {
|
|
|
916
911
|
function samplePublisherClock(nowSeconds) {
|
|
917
912
|
const sampled = nowSeconds();
|
|
918
913
|
if (!Number.isSafeInteger(sampled) || sampled < 0) {
|
|
919
|
-
throw new EventKitHandshakeClientError(
|
|
920
|
-
"challenge-rejected",
|
|
921
|
-
"Publisher clock must return a nonnegative JSON-safe Unix second"
|
|
922
|
-
);
|
|
914
|
+
throw new EventKitHandshakeClientError("challenge-rejected", "Publisher clock must return a nonnegative JSON-safe Unix second");
|
|
923
915
|
}
|
|
924
916
|
return sampled;
|
|
925
917
|
}
|
|
@@ -942,37 +934,25 @@ function serviceQuery(reader, snapshot, serviceId) {
|
|
|
942
934
|
}
|
|
943
935
|
function requireService(discovery) {
|
|
944
936
|
if (!discovery.ok) {
|
|
945
|
-
throw new EventKitHandshakeClientError(
|
|
946
|
-
"service-unavailable",
|
|
947
|
-
`Publisher service is unavailable: ${discovery.reason}`
|
|
948
|
-
);
|
|
937
|
+
throw new EventKitHandshakeClientError("service-unavailable", `Publisher service is unavailable: ${discovery.reason}`);
|
|
949
938
|
}
|
|
950
939
|
return discovery;
|
|
951
940
|
}
|
|
952
941
|
function requireExpectedService(discovery, expected) {
|
|
953
942
|
const expectedHash = HashZod4.parse(expected);
|
|
954
943
|
if (discovery.service.objectHash !== expectedHash) {
|
|
955
|
-
throw new EventKitHandshakeClientError(
|
|
956
|
-
"service-mismatch",
|
|
957
|
-
"Currently selected publisher service does not match the expected object hash"
|
|
958
|
-
);
|
|
944
|
+
throw new EventKitHandshakeClientError("service-mismatch", "Currently selected publisher service does not match the expected object hash");
|
|
959
945
|
}
|
|
960
946
|
return expectedHash;
|
|
961
947
|
}
|
|
962
948
|
function assertPublicationIdentity(publication, reader) {
|
|
963
949
|
if (publication.chainId !== reader.chainId) {
|
|
964
|
-
throw new EventKitHandshakeClientError(
|
|
965
|
-
"identity-mismatch",
|
|
966
|
-
"Publication transport chain ID does not match the synchronized handshake reader"
|
|
967
|
-
);
|
|
950
|
+
throw new EventKitHandshakeClientError("identity-mismatch", "Publication transport chain ID does not match the synchronized handshake reader");
|
|
968
951
|
}
|
|
969
952
|
}
|
|
970
953
|
async function assertPublicationSource(publication, expected) {
|
|
971
954
|
if (await publication.source() !== expected) {
|
|
972
|
-
throw new EventKitHandshakeClientError(
|
|
973
|
-
"identity-mismatch",
|
|
974
|
-
"Publication signer does not match the required handshake Claim source"
|
|
975
|
-
);
|
|
955
|
+
throw new EventKitHandshakeClientError("identity-mismatch", "Publication signer does not match the required handshake Claim source");
|
|
976
956
|
}
|
|
977
957
|
}
|
|
978
958
|
function intentLookup(reader, kind, operationId, source) {
|
|
@@ -985,15 +965,13 @@ function intentLookup(reader, kind, operationId, source) {
|
|
|
985
965
|
};
|
|
986
966
|
}
|
|
987
967
|
function mutationIntentError(error) {
|
|
988
|
-
return error instanceof HandshakeMutationIntentConflictError ? new EventKitHandshakeClientError("mutation-intent-conflict", error.message) : new EventKitHandshakeClientError(
|
|
989
|
-
"mutation-intent-unavailable",
|
|
990
|
-
"Handshake mutation intent storage is unavailable or invalid"
|
|
991
|
-
);
|
|
968
|
+
return error instanceof HandshakeMutationIntentConflictError ? new EventKitHandshakeClientError("mutation-intent-conflict", error.message) : new EventKitHandshakeClientError("mutation-intent-unavailable", "Handshake mutation intent storage is unavailable or invalid");
|
|
992
969
|
}
|
|
993
970
|
async function loadMutationIntent(store, reader, kind, operationId, source, requestFingerprint) {
|
|
994
971
|
try {
|
|
995
972
|
const existing = await store.get(intentLookup(reader, kind, operationId, source));
|
|
996
|
-
if (existing === void 0)
|
|
973
|
+
if (existing === void 0)
|
|
974
|
+
return void 0;
|
|
997
975
|
if (existing.kind !== kind || existing.requestFingerprint !== requestFingerprint) {
|
|
998
976
|
throw new HandshakeMutationIntentConflictError();
|
|
999
977
|
}
|
|
@@ -1012,7 +990,8 @@ async function persistMutationIntent(store, intent) {
|
|
|
1012
990
|
async function publisherServiceRequestFingerprint(input) {
|
|
1013
991
|
return await handshakeMutationRequestFingerprint({
|
|
1014
992
|
expiresAtBlock: input.expiresAtBlock ?? null,
|
|
1015
|
-
|
|
993
|
+
maxPositionsPerWake: input.maxPositionsPerWake,
|
|
994
|
+
sources: input.sources,
|
|
1016
995
|
maxSubscriptionLifetimeBlocks: input.maxSubscriptionLifetimeBlocks,
|
|
1017
996
|
validFromBlock: input.validFromBlock ?? null
|
|
1018
997
|
});
|
|
@@ -1021,7 +1000,7 @@ async function publisherRotationRequestFingerprint(input) {
|
|
|
1021
1000
|
return await handshakeMutationRequestFingerprint({
|
|
1022
1001
|
expiresAtBlock: input.expiresAtBlock ?? null,
|
|
1023
1002
|
keyExpiresAtBlock: input.keyExpiresAtBlock ?? null,
|
|
1024
|
-
|
|
1003
|
+
maxPositionsPerWake: input.maxPositionsPerWake ?? null,
|
|
1025
1004
|
maxSubscriptionLifetimeBlocks: input.maxSubscriptionLifetimeBlocks ?? null,
|
|
1026
1005
|
service: HashZod4.parse(input.service),
|
|
1027
1006
|
validFromBlock: input.validFromBlock ?? null
|
|
@@ -1035,7 +1014,9 @@ async function subscriberSubscriptionRequestFingerprint(input) {
|
|
|
1035
1014
|
endpoint: input.endpoint,
|
|
1036
1015
|
expiresAtBlock: input.expiresAtBlock,
|
|
1037
1016
|
grantId: input.grantId ?? null,
|
|
1038
|
-
|
|
1017
|
+
source: input.source,
|
|
1018
|
+
fromPosition: input.fromPosition,
|
|
1019
|
+
maxPositionsPerWake: input.maxPositionsPerWake ?? null,
|
|
1039
1020
|
queueId: input.queueId ?? null,
|
|
1040
1021
|
revision: input.revision ?? null,
|
|
1041
1022
|
subscriptionId: input.subscriptionId ?? null,
|
|
@@ -1078,10 +1059,7 @@ function protocolCandidate(reader, discovery, candidate, keys) {
|
|
|
1078
1059
|
};
|
|
1079
1060
|
}
|
|
1080
1061
|
function validationError(reason) {
|
|
1081
|
-
return new EventKitHandshakeClientError(
|
|
1082
|
-
"subscription-invalid",
|
|
1083
|
-
`Publisher subscription candidate failed validation: ${reason}`
|
|
1084
|
-
);
|
|
1062
|
+
return new EventKitHandshakeClientError("subscription-invalid", `Publisher subscription candidate failed validation: ${reason}`);
|
|
1085
1063
|
}
|
|
1086
1064
|
function challengeError(result) {
|
|
1087
1065
|
const reason = result.ok ? "unknown" : result.reason;
|
|
@@ -1106,7 +1084,8 @@ function createPublisherHandshakeClient(options) {
|
|
|
1106
1084
|
}
|
|
1107
1085
|
async function resolveCandidate(selector) {
|
|
1108
1086
|
const found = await candidateDiscovery(selector);
|
|
1109
|
-
if (!found.ok)
|
|
1087
|
+
if (!found.ok)
|
|
1088
|
+
throw new EventKitHandshakeClientError("service-unavailable", `Publisher service is unavailable: ${found.reason}`);
|
|
1110
1089
|
const subscriber = NormalizedAddressZod3.parse(selector.subscriber);
|
|
1111
1090
|
const subscription = selector.subscription === void 0 ? void 0 : HashZod4.parse(selector.subscription);
|
|
1112
1091
|
const candidates = found.candidates.filter((candidate2) => candidate2.subscriber === subscriber && (subscription === void 0 || candidate2.tuple.subscription.objectHash === subscription));
|
|
@@ -1117,10 +1096,9 @@ function createPublisherHandshakeClient(options) {
|
|
|
1117
1096
|
throw new EventKitHandshakeClientError("candidate-ambiguous", "More than one finalized acceptance candidate matched");
|
|
1118
1097
|
}
|
|
1119
1098
|
const candidate = candidates[0];
|
|
1120
|
-
const validated = await validateAndDecryptPublisherSubscription(
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
if (!validated.ok) throw validationError(validated.reason);
|
|
1099
|
+
const validated = await validateAndDecryptPublisherSubscription(protocolCandidate(options.reader, found, candidate, options.keys));
|
|
1100
|
+
if (!validated.ok)
|
|
1101
|
+
throw validationError(validated.reason);
|
|
1124
1102
|
return { candidate, validated };
|
|
1125
1103
|
}
|
|
1126
1104
|
async function candidateForChallenge(challenge) {
|
|
@@ -1129,10 +1107,7 @@ function createPublisherHandshakeClient(options) {
|
|
|
1129
1107
|
subscription: challenge.subscription
|
|
1130
1108
|
});
|
|
1131
1109
|
if (!endpointChallengeMatchesPublisherContext(challenge, resolved.validated.context)) {
|
|
1132
|
-
throw new EventKitHandshakeClientError(
|
|
1133
|
-
"challenge-context-invalid",
|
|
1134
|
-
"Endpoint challenge does not match the current finalized subscription candidate"
|
|
1135
|
-
);
|
|
1110
|
+
throw new EventKitHandshakeClientError("challenge-context-invalid", "Endpoint challenge does not match the current finalized subscription candidate");
|
|
1136
1111
|
}
|
|
1137
1112
|
return resolved;
|
|
1138
1113
|
}
|
|
@@ -1222,12 +1197,7 @@ function createPublisherHandshakeClient(options) {
|
|
|
1222
1197
|
operationId: intent.operationId,
|
|
1223
1198
|
response: intent.response
|
|
1224
1199
|
});
|
|
1225
|
-
const reconciliation = await reconcileAcceptance(
|
|
1226
|
-
acceptanceHash,
|
|
1227
|
-
publication,
|
|
1228
|
-
intent.challenge.subscriber,
|
|
1229
|
-
intent.challenge.subscription
|
|
1230
|
-
);
|
|
1200
|
+
const reconciliation = await reconcileAcceptance(acceptanceHash, publication, intent.challenge.subscriber, intent.challenge.subscription);
|
|
1231
1201
|
return Object.freeze({
|
|
1232
1202
|
acceptance: Object.freeze({ body: intent.acceptance, objectHash: acceptanceHash }),
|
|
1233
1203
|
challenge: intent.operationId,
|
|
@@ -1248,10 +1218,7 @@ function createPublisherHandshakeClient(options) {
|
|
|
1248
1218
|
publisher: options.reader.publisher
|
|
1249
1219
|
});
|
|
1250
1220
|
} catch {
|
|
1251
|
-
throw new EventKitHandshakeClientError(
|
|
1252
|
-
"key-custody-failed",
|
|
1253
|
-
"Publisher encryption private key was not durably retained; publication was not attempted"
|
|
1254
|
-
);
|
|
1221
|
+
throw new EventKitHandshakeClientError("key-custody-failed", "Publisher encryption private key was not durably retained; publication was not attempted");
|
|
1255
1222
|
}
|
|
1256
1223
|
const [keyHash, serviceHash] = await Promise.all([
|
|
1257
1224
|
handshakeObjectHash2(intent.encryptionKey),
|
|
@@ -1274,19 +1241,19 @@ function createPublisherHandshakeClient(options) {
|
|
|
1274
1241
|
const client = {
|
|
1275
1242
|
async acceptanceCandidates(selector = {}) {
|
|
1276
1243
|
const found = await candidateDiscovery(selector);
|
|
1277
|
-
if (!found.ok || selector.subscription === void 0)
|
|
1244
|
+
if (!found.ok || selector.subscription === void 0)
|
|
1245
|
+
return found;
|
|
1278
1246
|
const subscription = HashZod4.parse(selector.subscription);
|
|
1279
1247
|
return Object.freeze({
|
|
1280
1248
|
...found,
|
|
1281
|
-
candidates: found.candidates.filter(
|
|
1282
|
-
(candidate) => candidate.tuple.subscription.objectHash === subscription
|
|
1283
|
-
)
|
|
1249
|
+
candidates: found.candidates.filter((candidate) => candidate.tuple.subscription.objectHash === subscription)
|
|
1284
1250
|
});
|
|
1285
1251
|
},
|
|
1286
1252
|
async beginChallenge(input) {
|
|
1287
1253
|
const challengeHash = HashZod4.parse(input.challengeHash);
|
|
1288
1254
|
const record = await options.challenges.get(challengeHash);
|
|
1289
|
-
if (record === void 0)
|
|
1255
|
+
if (record === void 0)
|
|
1256
|
+
return { kind: "missing" };
|
|
1290
1257
|
const resolved = await candidateForChallenge(record.challenge);
|
|
1291
1258
|
const begun = await beginPublisherEndpointChallengeAttempt({
|
|
1292
1259
|
challengeHash,
|
|
@@ -1321,10 +1288,7 @@ function createPublisherHandshakeClient(options) {
|
|
|
1321
1288
|
throw new EventKitHandshakeClientError("challenge-not-found", "Endpoint challenge was not found");
|
|
1322
1289
|
}
|
|
1323
1290
|
if (record.challenge.subscriber !== subscriber || record.challenge.subscription !== subscription) {
|
|
1324
|
-
throw new EventKitHandshakeClientError(
|
|
1325
|
-
"challenge-context-invalid",
|
|
1326
|
-
"Stored endpoint challenge does not match the caller expected subscriber and subscription"
|
|
1327
|
-
);
|
|
1291
|
+
throw new EventKitHandshakeClientError("challenge-context-invalid", "Stored endpoint challenge does not match the caller expected subscriber and subscription");
|
|
1328
1292
|
}
|
|
1329
1293
|
const responseHash = await handshakeObjectHash2(input.response);
|
|
1330
1294
|
const requestFingerprint = await exactMutationRequestFingerprint({
|
|
@@ -1333,20 +1297,10 @@ function createPublisherHandshakeClient(options) {
|
|
|
1333
1297
|
subscriber,
|
|
1334
1298
|
subscription
|
|
1335
1299
|
});
|
|
1336
|
-
const existing = await loadMutationIntent(
|
|
1337
|
-
options.intents,
|
|
1338
|
-
options.reader,
|
|
1339
|
-
"publisher-subscription-accept",
|
|
1340
|
-
challengeHash,
|
|
1341
|
-
options.reader.publisher,
|
|
1342
|
-
requestFingerprint
|
|
1343
|
-
);
|
|
1300
|
+
const existing = await loadMutationIntent(options.intents, options.reader, "publisher-subscription-accept", challengeHash, options.reader.publisher, requestFingerprint);
|
|
1344
1301
|
if (existing !== void 0) {
|
|
1345
1302
|
if (record.state !== "verified" || record.responseHash !== responseHash) {
|
|
1346
|
-
throw new EventKitHandshakeClientError(
|
|
1347
|
-
"mutation-intent-conflict",
|
|
1348
|
-
"Acceptance intent does not match the durable verified challenge decision"
|
|
1349
|
-
);
|
|
1303
|
+
throw new EventKitHandshakeClientError("mutation-intent-conflict", "Acceptance intent does not match the durable verified challenge decision");
|
|
1350
1304
|
}
|
|
1351
1305
|
return await publishAcceptanceIntent(existing, "resumed");
|
|
1352
1306
|
}
|
|
@@ -1358,36 +1312,22 @@ function createPublisherHandshakeClient(options) {
|
|
|
1358
1312
|
store: options.challenges,
|
|
1359
1313
|
subscription: resolved.validated
|
|
1360
1314
|
});
|
|
1361
|
-
if (!completed.ok)
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
"
|
|
1366
|
-
challengeHash,
|
|
1367
|
-
options.reader.publisher,
|
|
1368
|
-
requestFingerprint
|
|
1369
|
-
);
|
|
1370
|
-
if (concurrentlyPersisted !== void 0) return await publishAcceptanceIntent(concurrentlyPersisted, "resumed");
|
|
1315
|
+
if (!completed.ok)
|
|
1316
|
+
throw challengeError(completed);
|
|
1317
|
+
const concurrentlyPersisted = await loadMutationIntent(options.intents, options.reader, "publisher-subscription-accept", challengeHash, options.reader.publisher, requestFingerprint);
|
|
1318
|
+
if (concurrentlyPersisted !== void 0)
|
|
1319
|
+
return await publishAcceptanceIntent(concurrentlyPersisted, "resumed");
|
|
1371
1320
|
let current;
|
|
1372
1321
|
try {
|
|
1373
1322
|
current = await candidateForChallenge(record.challenge);
|
|
1374
1323
|
} catch (error) {
|
|
1375
|
-
const recovered = await loadMutationIntent(
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
"publisher-subscription-accept",
|
|
1379
|
-
challengeHash,
|
|
1380
|
-
options.reader.publisher,
|
|
1381
|
-
requestFingerprint
|
|
1382
|
-
);
|
|
1383
|
-
if (recovered !== void 0) return await publishAcceptanceIntent(recovered, "resumed");
|
|
1324
|
+
const recovered = await loadMutationIntent(options.intents, options.reader, "publisher-subscription-accept", challengeHash, options.reader.publisher, requestFingerprint);
|
|
1325
|
+
if (recovered !== void 0)
|
|
1326
|
+
return await publishAcceptanceIntent(recovered, "resumed");
|
|
1384
1327
|
throw error;
|
|
1385
1328
|
}
|
|
1386
1329
|
if (!endpointChallengeMatchesPublisherContext(record.challenge, current.validated.context)) {
|
|
1387
|
-
throw new EventKitHandshakeClientError(
|
|
1388
|
-
"challenge-context-invalid",
|
|
1389
|
-
"Endpoint challenge candidate changed before acceptance publication"
|
|
1390
|
-
);
|
|
1330
|
+
throw new EventKitHandshakeClientError("challenge-context-invalid", "Endpoint challenge candidate changed before acceptance publication");
|
|
1391
1331
|
}
|
|
1392
1332
|
const resolvedIntent = await persistMutationIntent(options.intents, {
|
|
1393
1333
|
acceptance: completed.acceptance,
|
|
@@ -1429,42 +1369,35 @@ function createPublisherHandshakeClient(options) {
|
|
|
1429
1369
|
async publishService(input) {
|
|
1430
1370
|
await assertPublicationSource(options.publication, options.reader.publisher);
|
|
1431
1371
|
if (serviceId !== void 0) {
|
|
1432
|
-
throw new EventKitHandshakeClientError(
|
|
1433
|
-
"service-root-requires-fresh-id",
|
|
1434
|
-
"Root service publication requires an unconfigured client so a fresh serviceId is generated"
|
|
1435
|
-
);
|
|
1372
|
+
throw new EventKitHandshakeClientError("service-root-requires-fresh-id", "Root service publication requires an unconfigured client so a fresh serviceId is generated");
|
|
1436
1373
|
}
|
|
1437
1374
|
const operationId = HandshakeIdZod3.parse(input.operationId);
|
|
1438
1375
|
const requestFingerprint = await publisherServiceRequestFingerprint(input);
|
|
1439
|
-
const priorIntent = await loadMutationIntent(
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
"publisher-service-publish",
|
|
1443
|
-
operationId,
|
|
1444
|
-
options.reader.publisher,
|
|
1445
|
-
requestFingerprint
|
|
1446
|
-
);
|
|
1447
|
-
if (priorIntent !== void 0) return await publishPublisherServiceIntent(priorIntent, "resumed");
|
|
1376
|
+
const priorIntent = await loadMutationIntent(options.intents, options.reader, "publisher-service-publish", operationId, options.reader.publisher, requestFingerprint);
|
|
1377
|
+
if (priorIntent !== void 0)
|
|
1378
|
+
return await publishPublisherServiceIntent(priorIntent, "resumed");
|
|
1448
1379
|
const current = await snapshot();
|
|
1449
1380
|
const existing = await discovery(current);
|
|
1450
1381
|
if (existing.ok) {
|
|
1451
|
-
throw new EventKitHandshakeClientError(
|
|
1452
|
-
"service-already-exists",
|
|
1453
|
-
"An active publisher service already exists; rotate its key to publish a successor"
|
|
1454
|
-
);
|
|
1382
|
+
throw new EventKitHandshakeClientError("service-already-exists", "An active publisher service already exists; rotate its key to publish a successor");
|
|
1455
1383
|
}
|
|
1456
1384
|
if (existing.reason !== "service-not-found") {
|
|
1457
1385
|
throw new EventKitHandshakeClientError("service-unavailable", `Cannot declare service: ${existing.reason}`);
|
|
1458
1386
|
}
|
|
1459
1387
|
const validFromBlock = input.validFromBlock ?? nextBlock(current.finalizedHead);
|
|
1460
1388
|
const generated = await generatePublisherEncryptionKey({ validFromBlock });
|
|
1461
|
-
const
|
|
1389
|
+
const serviceInput = {
|
|
1462
1390
|
encryptionKeys: [generated.descriptorHash],
|
|
1463
1391
|
...input.expiresAtBlock === void 0 ? {} : { expiresAtBlock: input.expiresAtBlock },
|
|
1464
|
-
maxBlocksPerWake: input.maxBlocksPerWake,
|
|
1465
1392
|
maxSubscriptionLifetimeBlocks: input.maxSubscriptionLifetimeBlocks,
|
|
1466
1393
|
preferredEncryptionKey: generated.descriptorHash,
|
|
1467
1394
|
validFromBlock
|
|
1395
|
+
};
|
|
1396
|
+
const service = createPublisherService({
|
|
1397
|
+
...serviceInput,
|
|
1398
|
+
authorizationChainId: options.reader.chainId,
|
|
1399
|
+
sources: input.sources,
|
|
1400
|
+
maxPositionsPerWake: input.maxPositionsPerWake
|
|
1468
1401
|
});
|
|
1469
1402
|
const resolvedIntent = await persistMutationIntent(options.intents, {
|
|
1470
1403
|
chainId: options.reader.chainId,
|
|
@@ -1484,23 +1417,13 @@ function createPublisherHandshakeClient(options) {
|
|
|
1484
1417
|
await assertPublicationSource(options.publication, options.reader.publisher);
|
|
1485
1418
|
const keyHash = HashZod4.parse(key);
|
|
1486
1419
|
const requestFingerprint = await exactMutationRequestFingerprint({ key: keyHash });
|
|
1487
|
-
let resolvedIntent = await loadMutationIntent(
|
|
1488
|
-
options.intents,
|
|
1489
|
-
options.reader,
|
|
1490
|
-
"publisher-encryption-key-retire",
|
|
1491
|
-
keyHash,
|
|
1492
|
-
options.reader.publisher,
|
|
1493
|
-
requestFingerprint
|
|
1494
|
-
);
|
|
1420
|
+
let resolvedIntent = await loadMutationIntent(options.intents, options.reader, "publisher-encryption-key-retire", keyHash, options.reader.publisher, requestFingerprint);
|
|
1495
1421
|
let intentDisposition = "resumed";
|
|
1496
1422
|
if (resolvedIntent === void 0) {
|
|
1497
1423
|
const current = await snapshot();
|
|
1498
1424
|
const selected = requireService(await discovery(current));
|
|
1499
1425
|
if (selected.key.objectHash !== keyHash || !selected.service.body.encryptionKeys.includes(keyHash) || selected.service.body.preferredEncryptionKey !== keyHash) {
|
|
1500
|
-
throw new EventKitHandshakeClientError(
|
|
1501
|
-
"key-mismatch",
|
|
1502
|
-
"Encryption key does not match the exact current preferred descriptor evidence"
|
|
1503
|
-
);
|
|
1426
|
+
throw new EventKitHandshakeClientError("key-mismatch", "Encryption key does not match the exact current preferred descriptor evidence");
|
|
1504
1427
|
}
|
|
1505
1428
|
const persisted = await persistMutationIntent(options.intents, {
|
|
1506
1429
|
chainId: options.reader.chainId,
|
|
@@ -1532,14 +1455,7 @@ function createPublisherHandshakeClient(options) {
|
|
|
1532
1455
|
await assertPublicationSource(options.publication, options.reader.publisher);
|
|
1533
1456
|
const service = HashZod4.parse(expectedService);
|
|
1534
1457
|
const requestFingerprint = await exactMutationRequestFingerprint({ service });
|
|
1535
|
-
let resolvedIntent = await loadMutationIntent(
|
|
1536
|
-
options.intents,
|
|
1537
|
-
options.reader,
|
|
1538
|
-
"publisher-service-retire",
|
|
1539
|
-
service,
|
|
1540
|
-
options.reader.publisher,
|
|
1541
|
-
requestFingerprint
|
|
1542
|
-
);
|
|
1458
|
+
let resolvedIntent = await loadMutationIntent(options.intents, options.reader, "publisher-service-retire", service, options.reader.publisher, requestFingerprint);
|
|
1543
1459
|
let intentDisposition = "resumed";
|
|
1544
1460
|
if (resolvedIntent === void 0) {
|
|
1545
1461
|
const current = await snapshot();
|
|
@@ -1575,15 +1491,9 @@ function createPublisherHandshakeClient(options) {
|
|
|
1575
1491
|
await assertPublicationSource(options.publication, options.reader.publisher);
|
|
1576
1492
|
const operationId = HandshakeIdZod3.parse(input.operationId);
|
|
1577
1493
|
const requestFingerprint = await publisherRotationRequestFingerprint(input);
|
|
1578
|
-
const priorIntent = await loadMutationIntent(
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
"publisher-service-rotate-key",
|
|
1582
|
-
operationId,
|
|
1583
|
-
options.reader.publisher,
|
|
1584
|
-
requestFingerprint
|
|
1585
|
-
);
|
|
1586
|
-
if (priorIntent !== void 0) return await publishPublisherServiceIntent(priorIntent, "resumed");
|
|
1494
|
+
const priorIntent = await loadMutationIntent(options.intents, options.reader, "publisher-service-rotate-key", operationId, options.reader.publisher, requestFingerprint);
|
|
1495
|
+
if (priorIntent !== void 0)
|
|
1496
|
+
return await publishPublisherServiceIntent(priorIntent, "resumed");
|
|
1587
1497
|
const current = await snapshot();
|
|
1588
1498
|
const selected = requireService(await discovery(current));
|
|
1589
1499
|
requireExpectedService(selected, input.service);
|
|
@@ -1592,16 +1502,21 @@ function createPublisherHandshakeClient(options) {
|
|
|
1592
1502
|
...input.keyExpiresAtBlock === void 0 ? {} : { expiresAtBlock: input.keyExpiresAtBlock },
|
|
1593
1503
|
validFromBlock
|
|
1594
1504
|
});
|
|
1595
|
-
const
|
|
1505
|
+
const serviceInput = {
|
|
1596
1506
|
encryptionKeys: [generated.descriptorHash],
|
|
1597
1507
|
...input.expiresAtBlock === void 0 ? selected.service.body.expiresAtBlock === void 0 ? {} : { expiresAtBlock: selected.service.body.expiresAtBlock } : { expiresAtBlock: input.expiresAtBlock },
|
|
1598
|
-
maxBlocksPerWake: input.maxBlocksPerWake ?? selected.service.body.limits.maxBlocksPerWake,
|
|
1599
1508
|
maxSubscriptionLifetimeBlocks: input.maxSubscriptionLifetimeBlocks ?? selected.service.body.limits.maxSubscriptionLifetimeBlocks,
|
|
1600
1509
|
preferredEncryptionKey: generated.descriptorHash,
|
|
1601
1510
|
revision: selected.service.body.revision + 1,
|
|
1602
1511
|
serviceId: selected.service.body.serviceId,
|
|
1603
1512
|
supersedes: HashZod4.parse(selected.service.objectHash),
|
|
1604
1513
|
validFromBlock
|
|
1514
|
+
};
|
|
1515
|
+
const service = createPublisherService({
|
|
1516
|
+
...serviceInput,
|
|
1517
|
+
authorizationChainId: options.reader.chainId,
|
|
1518
|
+
sources: selected.service.body.events.map((event) => event.source),
|
|
1519
|
+
maxPositionsPerWake: input.maxPositionsPerWake ?? selected.service.body.limits.maxPositionsPerWake
|
|
1605
1520
|
});
|
|
1606
1521
|
const resolvedIntent = await persistMutationIntent(options.intents, {
|
|
1607
1522
|
chainId: options.reader.chainId,
|
|
@@ -1645,9 +1560,7 @@ function createSubscriberHandshakeClient(options) {
|
|
|
1645
1560
|
return readySnapshot(await options.reader.sync());
|
|
1646
1561
|
}
|
|
1647
1562
|
async function serviceAt(current) {
|
|
1648
|
-
return requireService(
|
|
1649
|
-
await current.readModel.discoverPublisherService(serviceQuery(options.reader, current, serviceId))
|
|
1650
|
-
);
|
|
1563
|
+
return requireService(await current.readModel.discoverPublisherService(serviceQuery(options.reader, current, serviceId)));
|
|
1651
1564
|
}
|
|
1652
1565
|
async function lookup(subscriptionId) {
|
|
1653
1566
|
const current = await options.reader.sync();
|
|
@@ -1664,29 +1577,21 @@ function createSubscriberHandshakeClient(options) {
|
|
|
1664
1577
|
const revision = input.revision ?? 1;
|
|
1665
1578
|
if (revision === 1) {
|
|
1666
1579
|
if (input.supersedes !== void 0) {
|
|
1667
|
-
throw new EventKitHandshakeClientError(
|
|
1668
|
-
"subscription-invalid",
|
|
1669
|
-
"Subscription revision 1 must not declare supersedes"
|
|
1670
|
-
);
|
|
1580
|
+
throw new EventKitHandshakeClientError("subscription-invalid", "Subscription revision 1 must not declare supersedes");
|
|
1671
1581
|
}
|
|
1672
|
-
if (input.subscriptionId === void 0)
|
|
1582
|
+
if (input.subscriptionId === void 0)
|
|
1583
|
+
return;
|
|
1673
1584
|
const view2 = await lookupAt(current, input.subscriptionId);
|
|
1674
1585
|
if (!view2.ok) {
|
|
1675
1586
|
throw new EventKitHandshakeClientError("service-unavailable", `Cannot validate subscription identity: ${view2.reason}`);
|
|
1676
1587
|
}
|
|
1677
1588
|
if (view2.subscriptions.some((item) => item.subscriptionId === input.subscriptionId)) {
|
|
1678
|
-
throw new EventKitHandshakeClientError(
|
|
1679
|
-
"subscription-invalid",
|
|
1680
|
-
"Subscription revision 1 would duplicate an existing finalized stable identity"
|
|
1681
|
-
);
|
|
1589
|
+
throw new EventKitHandshakeClientError("subscription-invalid", "Subscription revision 1 would duplicate an existing finalized stable identity");
|
|
1682
1590
|
}
|
|
1683
1591
|
return;
|
|
1684
1592
|
}
|
|
1685
1593
|
if (input.subscriptionId === void 0 || input.supersedes === void 0) {
|
|
1686
|
-
throw new EventKitHandshakeClientError(
|
|
1687
|
-
"subscription-invalid",
|
|
1688
|
-
"A replacement subscription requires subscriptionId and supersedes"
|
|
1689
|
-
);
|
|
1594
|
+
throw new EventKitHandshakeClientError("subscription-invalid", "A replacement subscription requires subscriptionId and supersedes");
|
|
1690
1595
|
}
|
|
1691
1596
|
const view = await lookupAt(current, input.subscriptionId);
|
|
1692
1597
|
if (!view.ok) {
|
|
@@ -1694,24 +1599,15 @@ function createSubscriberHandshakeClient(options) {
|
|
|
1694
1599
|
}
|
|
1695
1600
|
const lifecycles = view.subscriptions.filter((item) => item.subscriptionId === input.subscriptionId);
|
|
1696
1601
|
if (lifecycles.length !== 1) {
|
|
1697
|
-
throw new EventKitHandshakeClientError(
|
|
1698
|
-
"subscription-invalid",
|
|
1699
|
-
"Replacement subscription does not resolve one finalized stable identity"
|
|
1700
|
-
);
|
|
1602
|
+
throw new EventKitHandshakeClientError("subscription-invalid", "Replacement subscription does not resolve one finalized stable identity");
|
|
1701
1603
|
}
|
|
1702
1604
|
if (lifecycles[0].state === "rejected") {
|
|
1703
|
-
throw new EventKitHandshakeClientError(
|
|
1704
|
-
"subscription-invalid",
|
|
1705
|
-
"Replacement subscription cannot extend a rejected finalized revision chain"
|
|
1706
|
-
);
|
|
1605
|
+
throw new EventKitHandshakeClientError("subscription-invalid", "Replacement subscription cannot extend a rejected finalized revision chain");
|
|
1707
1606
|
}
|
|
1708
1607
|
const highestRevision = Math.max(...lifecycles[0].tuples.map((tuple) => tuple.subscription.body.revision));
|
|
1709
1608
|
const latest = lifecycles[0].tuples.filter((tuple) => tuple.subscription.body.revision === highestRevision);
|
|
1710
1609
|
if (latest.length !== 1 || revision !== highestRevision + 1 || latest[0].subscription.objectHash !== input.supersedes) {
|
|
1711
|
-
throw new EventKitHandshakeClientError(
|
|
1712
|
-
"subscription-invalid",
|
|
1713
|
-
"Replacement subscription revision and supersedes must extend the exact finalized chain tip"
|
|
1714
|
-
);
|
|
1610
|
+
throw new EventKitHandshakeClientError("subscription-invalid", "Replacement subscription revision and supersedes must extend the exact finalized chain tip");
|
|
1715
1611
|
}
|
|
1716
1612
|
}
|
|
1717
1613
|
async function publishSubscriberSubscriptionIntent(intent, intentDisposition) {
|
|
@@ -1740,23 +1636,13 @@ function createSubscriberHandshakeClient(options) {
|
|
|
1740
1636
|
await assertPublicationSource(options.publication, subscriber);
|
|
1741
1637
|
const grantHash = HashZod4.parse(grant);
|
|
1742
1638
|
const requestFingerprint = await exactMutationRequestFingerprint({ grant: grantHash });
|
|
1743
|
-
let resolvedIntent = await loadMutationIntent(
|
|
1744
|
-
options.intents,
|
|
1745
|
-
options.reader,
|
|
1746
|
-
"subscriber-grant-revoke",
|
|
1747
|
-
grantHash,
|
|
1748
|
-
subscriber,
|
|
1749
|
-
requestFingerprint
|
|
1750
|
-
);
|
|
1639
|
+
let resolvedIntent = await loadMutationIntent(options.intents, options.reader, "subscriber-grant-revoke", grantHash, subscriber, requestFingerprint);
|
|
1751
1640
|
let intentDisposition = "resumed";
|
|
1752
1641
|
if (resolvedIntent === void 0) {
|
|
1753
1642
|
const current = await snapshot();
|
|
1754
1643
|
const view = await current.readModel.subscriber({ ...serviceQuery(options.reader, current, serviceId), subscriber });
|
|
1755
1644
|
if (!view.ok || !tupleHashes(view).grants.has(grantHash)) {
|
|
1756
|
-
throw new EventKitHandshakeClientError(
|
|
1757
|
-
"subscription-not-found",
|
|
1758
|
-
"Grant is not present in this subscriber finalization view"
|
|
1759
|
-
);
|
|
1645
|
+
throw new EventKitHandshakeClientError("subscription-not-found", "Grant is not present in this subscriber finalization view");
|
|
1760
1646
|
}
|
|
1761
1647
|
const persisted = await persistMutationIntent(options.intents, {
|
|
1762
1648
|
chainId: options.reader.chainId,
|
|
@@ -1789,23 +1675,13 @@ function createSubscriberHandshakeClient(options) {
|
|
|
1789
1675
|
await assertPublicationSource(options.publication, subscriber);
|
|
1790
1676
|
const subscriptionHash = HashZod4.parse(subscription);
|
|
1791
1677
|
const requestFingerprint = await exactMutationRequestFingerprint({ subscription: subscriptionHash });
|
|
1792
|
-
let resolvedIntent = await loadMutationIntent(
|
|
1793
|
-
options.intents,
|
|
1794
|
-
options.reader,
|
|
1795
|
-
"subscriber-subscription-revoke",
|
|
1796
|
-
subscriptionHash,
|
|
1797
|
-
subscriber,
|
|
1798
|
-
requestFingerprint
|
|
1799
|
-
);
|
|
1678
|
+
let resolvedIntent = await loadMutationIntent(options.intents, options.reader, "subscriber-subscription-revoke", subscriptionHash, subscriber, requestFingerprint);
|
|
1800
1679
|
let intentDisposition = "resumed";
|
|
1801
1680
|
if (resolvedIntent === void 0) {
|
|
1802
1681
|
const current = await snapshot();
|
|
1803
1682
|
const view = await current.readModel.subscriber({ ...serviceQuery(options.reader, current, serviceId), subscriber });
|
|
1804
1683
|
if (!view.ok || !tupleHashes(view).subscriptions.has(subscriptionHash)) {
|
|
1805
|
-
throw new EventKitHandshakeClientError(
|
|
1806
|
-
"subscription-not-found",
|
|
1807
|
-
"Subscription is not present in this subscriber finalization view"
|
|
1808
|
-
);
|
|
1684
|
+
throw new EventKitHandshakeClientError("subscription-not-found", "Subscription is not present in this subscriber finalization view");
|
|
1809
1685
|
}
|
|
1810
1686
|
const persisted = await persistMutationIntent(options.intents, {
|
|
1811
1687
|
chainId: options.reader.chainId,
|
|
@@ -1842,19 +1718,18 @@ function createSubscriberHandshakeClient(options) {
|
|
|
1842
1718
|
const subscriptionHash = HashZod4.parse(subscription);
|
|
1843
1719
|
const current = await options.reader.sync();
|
|
1844
1720
|
const view = await lookupAt(current);
|
|
1845
|
-
if (!view.ok)
|
|
1721
|
+
if (!view.ok)
|
|
1722
|
+
return view;
|
|
1846
1723
|
const matches = view.subscriptions.flatMap((lifecycle) => lifecycle.tuples.filter((tuple) => tuple.subscription.objectHash === subscriptionHash).map((tuple) => ({ lifecycle, tuple })));
|
|
1847
1724
|
if (matches.length > 1) {
|
|
1848
|
-
throw new EventKitHandshakeClientError(
|
|
1849
|
-
"subscription-invalid",
|
|
1850
|
-
"Exact subscription hash appears more than once in the subscriber view"
|
|
1851
|
-
);
|
|
1725
|
+
throw new EventKitHandshakeClientError("subscription-invalid", "Exact subscription hash appears more than once in the subscriber view");
|
|
1852
1726
|
}
|
|
1853
|
-
if (matches.length === 0)
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1727
|
+
if (matches.length === 0)
|
|
1728
|
+
return Object.freeze({
|
|
1729
|
+
found: false,
|
|
1730
|
+
lookup: view,
|
|
1731
|
+
ok: true
|
|
1732
|
+
});
|
|
1858
1733
|
return Object.freeze({
|
|
1859
1734
|
found: true,
|
|
1860
1735
|
lifecycle: matches[0].lifecycle,
|
|
@@ -1867,36 +1742,22 @@ function createSubscriberHandshakeClient(options) {
|
|
|
1867
1742
|
await assertPublicationSource(options.publication, subscriber);
|
|
1868
1743
|
const operationId = HandshakeIdZod3.parse(input.operationId);
|
|
1869
1744
|
const requestFingerprint = await subscriberSubscriptionRequestFingerprint(input);
|
|
1870
|
-
const priorIntent = await loadMutationIntent(
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
"subscriber-subscription-subscribe",
|
|
1874
|
-
operationId,
|
|
1875
|
-
subscriber,
|
|
1876
|
-
requestFingerprint
|
|
1877
|
-
);
|
|
1878
|
-
if (priorIntent !== void 0) return await publishSubscriberSubscriptionIntent(priorIntent, "resumed");
|
|
1745
|
+
const priorIntent = await loadMutationIntent(options.intents, options.reader, "subscriber-subscription-subscribe", operationId, subscriber, requestFingerprint);
|
|
1746
|
+
if (priorIntent !== void 0)
|
|
1747
|
+
return await publishSubscriberSubscriptionIntent(priorIntent, "resumed");
|
|
1879
1748
|
const current = await snapshot();
|
|
1880
1749
|
const selected = await serviceAt(current);
|
|
1881
1750
|
if (input.expiresAtBlock - current.finalizedHead <= 3) {
|
|
1882
|
-
throw new EventKitHandshakeClientError(
|
|
1883
|
-
"subscription-invalid",
|
|
1884
|
-
"Requested subscription expiry must leave finalized blocks for tuple publication, acceptance, and activation"
|
|
1885
|
-
);
|
|
1751
|
+
throw new EventKitHandshakeClientError("subscription-invalid", "Requested subscription expiry must leave finalized blocks for tuple publication, acceptance, and activation");
|
|
1886
1752
|
}
|
|
1887
1753
|
await validateRevision(current, input);
|
|
1888
|
-
const
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
"Requested maxBlocksPerWake exceeds the selected publisher service limit"
|
|
1893
|
-
);
|
|
1754
|
+
const maximum = selected.service.body.limits.maxPositionsPerWake;
|
|
1755
|
+
const maxPositionsPerWake = input.maxPositionsPerWake ?? maximum;
|
|
1756
|
+
if (maxPositionsPerWake > maximum) {
|
|
1757
|
+
throw new EventKitHandshakeClientError("subscription-invalid", "Requested maxPositionsPerWake exceeds the selected publisher service limit");
|
|
1894
1758
|
}
|
|
1895
1759
|
if (input.expiresAtBlock > current.finalizedHead + selected.service.body.limits.maxSubscriptionLifetimeBlocks) {
|
|
1896
|
-
throw new EventKitHandshakeClientError(
|
|
1897
|
-
"subscription-invalid",
|
|
1898
|
-
"Requested subscription expiry exceeds the selected publisher service lifetime limit"
|
|
1899
|
-
);
|
|
1760
|
+
throw new EventKitHandshakeClientError("subscription-invalid", "Requested subscription expiry exceeds the selected publisher service lifetime limit");
|
|
1900
1761
|
}
|
|
1901
1762
|
const grant = createWakeGrant({
|
|
1902
1763
|
deploymentId: input.deploymentId,
|
|
@@ -1905,19 +1766,11 @@ function createSubscriberHandshakeClient(options) {
|
|
|
1905
1766
|
...input.queueId === void 0 || input.queueId === null ? {} : { queueId: input.queueId }
|
|
1906
1767
|
});
|
|
1907
1768
|
const grantHash = await handshakeObjectHash2(grant);
|
|
1908
|
-
const plaintext =
|
|
1909
|
-
|
|
1910
|
-
challengeSecret: input.challengeSecret,
|
|
1911
|
-
deploymentId: input.deploymentId,
|
|
1912
|
-
endpoint: input.endpoint,
|
|
1913
|
-
maxBlocksPerWake,
|
|
1914
|
-
queueId: input.queueId
|
|
1915
|
-
});
|
|
1916
|
-
const subscription = await createEncryptedWakeSubscription({
|
|
1769
|
+
const plaintext = subscriberPlaintext(selected.service.body, input, maxPositionsPerWake);
|
|
1770
|
+
const subscriptionInput = {
|
|
1917
1771
|
chainId: options.reader.chainId,
|
|
1918
1772
|
expiresAtBlock: input.expiresAtBlock,
|
|
1919
1773
|
grant: grantHash,
|
|
1920
|
-
plaintext,
|
|
1921
1774
|
publisher: options.reader.publisher,
|
|
1922
1775
|
publisherKey: {
|
|
1923
1776
|
encryptionKey: HashZod4.parse(selected.key.objectHash),
|
|
@@ -1929,7 +1782,8 @@ function createSubscriberHandshakeClient(options) {
|
|
|
1929
1782
|
subscriber,
|
|
1930
1783
|
...input.subscriptionId === void 0 ? {} : { subscriptionId: input.subscriptionId },
|
|
1931
1784
|
...input.supersedes === void 0 ? {} : { supersedes: input.supersedes }
|
|
1932
|
-
}
|
|
1785
|
+
};
|
|
1786
|
+
const subscription = await createEncryptedWakeSubscription({ ...subscriptionInput, plaintext });
|
|
1933
1787
|
const resolvedIntent = await persistMutationIntent(options.intents, {
|
|
1934
1788
|
chainId: options.reader.chainId,
|
|
1935
1789
|
encryptionKey: selected.key.body,
|
|
@@ -1953,6 +1807,25 @@ function createSubscriberHandshakeClient(options) {
|
|
|
1953
1807
|
};
|
|
1954
1808
|
return Object.freeze(client);
|
|
1955
1809
|
}
|
|
1810
|
+
function subscriberPlaintext(service, input, maxPositionsPerWake) {
|
|
1811
|
+
const plaintextInput = {
|
|
1812
|
+
audience: input.audience,
|
|
1813
|
+
challengeSecret: input.challengeSecret,
|
|
1814
|
+
deploymentId: input.deploymentId,
|
|
1815
|
+
endpoint: input.endpoint,
|
|
1816
|
+
queueId: input.queueId
|
|
1817
|
+
};
|
|
1818
|
+
const source = input.source;
|
|
1819
|
+
if (!service.events.some((event) => canonicalJson(event.source) === canonicalJson(source))) {
|
|
1820
|
+
throw new Error("Requested source is not advertised by the selected service");
|
|
1821
|
+
}
|
|
1822
|
+
return createWakeSubscriptionPlaintext({
|
|
1823
|
+
...plaintextInput,
|
|
1824
|
+
source,
|
|
1825
|
+
fromPosition: input.fromPosition,
|
|
1826
|
+
maxPositionsPerWake
|
|
1827
|
+
});
|
|
1828
|
+
}
|
|
1956
1829
|
export {
|
|
1957
1830
|
EventKitHandshakeClientError,
|
|
1958
1831
|
HandshakeMutationIntentConflictError,
|