@pkcprotocol/pkc-js 0.0.93 → 0.0.94

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 (67) hide show
  1. package/dist/browser/clients/base-client-manager.d.ts +1 -0
  2. package/dist/browser/clients/base-client-manager.js +7 -1
  3. package/dist/browser/clients/base-client-manager.js.map +1 -1
  4. package/dist/browser/clients/rpc-client/pkc-rpc-client.d.ts +1 -0
  5. package/dist/browser/clients/rpc-client/pkc-rpc-client.js +27 -1
  6. package/dist/browser/clients/rpc-client/pkc-rpc-client.js.map +1 -1
  7. package/dist/browser/community/community-client-manager.d.ts +16 -0
  8. package/dist/browser/community/community-client-manager.js +307 -31
  9. package/dist/browser/community/community-client-manager.js.map +1 -1
  10. package/dist/browser/community/remote-community.js +7 -0
  11. package/dist/browser/community/remote-community.js.map +1 -1
  12. package/dist/browser/generated-version.d.ts +1 -1
  13. package/dist/browser/generated-version.js +1 -1
  14. package/dist/browser/helia/helia-for-pkc.js +56 -1
  15. package/dist/browser/helia/helia-for-pkc.js.map +1 -1
  16. package/dist/browser/helia/types.d.ts +16 -0
  17. package/dist/browser/helia/util.d.ts +1 -0
  18. package/dist/browser/helia/util.js +21 -1
  19. package/dist/browser/helia/util.js.map +1 -1
  20. package/dist/browser/rpc/src/index.d.ts +2 -0
  21. package/dist/browser/rpc/src/index.js +52 -19
  22. package/dist/browser/rpc/src/index.js.map +1 -1
  23. package/dist/browser/test/test-util.d.ts +353 -5
  24. package/dist/browser/test/test-util.js +88 -5
  25. package/dist/browser/test/test-util.js.map +1 -1
  26. package/dist/browser/util.d.ts +7 -0
  27. package/dist/browser/util.js +21 -11
  28. package/dist/browser/util.js.map +1 -1
  29. package/dist/bundled/bundle-manifest.json +25 -25
  30. package/dist/bundled/chunks/{helia-for-pkc-C8tOPlIj.js → helia-for-pkc-Bj-Zb4JN.js} +70 -33
  31. package/dist/bundled/chunks/{local-community-DYEWq5rq.js → local-community-BrMLMEmt.js} +1 -1
  32. package/dist/bundled/chunks/{local-community-DgbMuVAA.js → local-community-Ce7303vY.js} +30 -30
  33. package/dist/bundled/chunks/{node-BrLiC0qX.js → node-C37nDOa8.js} +21 -6
  34. package/dist/bundled/chunks/{rpc-local-community-DOSee621.js → rpc-local-community-Dr_-Lb8I.js} +151 -18
  35. package/dist/bundled/chunks/{schema-HH2zeH-j.js → schema-5-rYJ-bC.js} +29 -12
  36. package/dist/bundled/chunks/{util-DSIDv1Cb.js → util-_-fNQNIV.js} +11 -3
  37. package/dist/bundled/index.js +1 -1
  38. package/dist/bundled/rpc/src/index.js +43 -22
  39. package/dist/node/clients/base-client-manager.d.ts +1 -0
  40. package/dist/node/clients/base-client-manager.js +7 -1
  41. package/dist/node/clients/base-client-manager.js.map +1 -1
  42. package/dist/node/clients/rpc-client/pkc-rpc-client.d.ts +1 -0
  43. package/dist/node/clients/rpc-client/pkc-rpc-client.js +27 -1
  44. package/dist/node/clients/rpc-client/pkc-rpc-client.js.map +1 -1
  45. package/dist/node/community/community-client-manager.d.ts +16 -0
  46. package/dist/node/community/community-client-manager.js +307 -31
  47. package/dist/node/community/community-client-manager.js.map +1 -1
  48. package/dist/node/community/remote-community.js +7 -0
  49. package/dist/node/community/remote-community.js.map +1 -1
  50. package/dist/node/generated-version.d.ts +1 -1
  51. package/dist/node/generated-version.js +1 -1
  52. package/dist/node/helia/helia-for-pkc.js +56 -1
  53. package/dist/node/helia/helia-for-pkc.js.map +1 -1
  54. package/dist/node/helia/types.d.ts +16 -0
  55. package/dist/node/helia/util.d.ts +1 -0
  56. package/dist/node/helia/util.js +21 -1
  57. package/dist/node/helia/util.js.map +1 -1
  58. package/dist/node/rpc/src/index.d.ts +2 -0
  59. package/dist/node/rpc/src/index.js +52 -19
  60. package/dist/node/rpc/src/index.js.map +1 -1
  61. package/dist/node/test/test-util.d.ts +353 -5
  62. package/dist/node/test/test-util.js +88 -5
  63. package/dist/node/test/test-util.js.map +1 -1
  64. package/dist/node/util.d.ts +7 -0
  65. package/dist/node/util.js +21 -11
  66. package/dist/node/util.js.map +1 -1
  67. package/package.json +1 -1
@@ -201,9 +201,13 @@ export declare function getAvailablePKCConfigsToTestAgainst(opts?: {
201
201
  }): PKCConfigWithName[];
202
202
  export declare function createNewIpns(): Promise<{
203
203
  signer: import("../signer/index.js").SignerWithPublicKeyAddress;
204
- publishToIpns: (content: string) => Promise<void>;
204
+ publishToIpns: (content: string, opts?: {
205
+ verifyResolves?: boolean;
206
+ ttl?: string;
207
+ }) => Promise<void>;
205
208
  publishToIpnsValue: (value: string, opts?: {
206
209
  verifyResolves?: boolean;
210
+ ttl?: string;
207
211
  }) => Promise<void>;
208
212
  pkc: PKC;
209
213
  }>;
@@ -538,15 +542,20 @@ export declare function createDelegatedCommunityIpns(communityOpts?: Partial<Com
538
542
  cid: string;
539
543
  }>;
540
544
  export declare function publishCommunityRecordWithExtraProp(opts?: {
541
- includeExtraPropInSignedPropertyNames: boolean;
542
- extraProps: Object;
545
+ includeExtraPropInSignedPropertyNames?: boolean;
546
+ extraProps?: Object;
547
+ ttl?: string;
543
548
  }): Promise<{
544
549
  communityRecord: any;
545
550
  ipnsObj: {
546
551
  signer: import("../signer/index.js").SignerWithPublicKeyAddress;
547
- publishToIpns: (content: string) => Promise<void>;
552
+ publishToIpns: (content: string, opts?: {
553
+ verifyResolves?: boolean;
554
+ ttl?: string;
555
+ }) => Promise<void>;
548
556
  publishToIpnsValue: (value: string, opts?: {
549
557
  verifyResolves?: boolean;
558
+ ttl?: string;
550
559
  }) => Promise<void>;
551
560
  pkc: PKC;
552
561
  };
@@ -877,9 +886,13 @@ export declare function createMockedCommunityIpns(communityOpts: CreateNewLocalC
877
886
  communityAddress: string;
878
887
  ipnsObj: {
879
888
  signer: import("../signer/index.js").SignerWithPublicKeyAddress;
880
- publishToIpns: (content: string) => Promise<void>;
889
+ publishToIpns: (content: string, opts?: {
890
+ verifyResolves?: boolean;
891
+ ttl?: string;
892
+ }) => Promise<void>;
881
893
  publishToIpnsValue: (value: string, opts?: {
882
894
  verifyResolves?: boolean;
895
+ ttl?: string;
883
896
  }) => Promise<void>;
884
897
  pkc: PKC;
885
898
  };
@@ -894,6 +907,341 @@ export declare function createStaticCommunityRecordForComment(opts?: {
894
907
  commentCid: string;
895
908
  communityAddress: string;
896
909
  }>;
910
+ export declare function publishStaticCommunityWithPostInPages(): Promise<{
911
+ communityAddress: string;
912
+ commentCid: string;
913
+ communityRecord: {
914
+ challenges: {
915
+ [x: string]: unknown;
916
+ type: string;
917
+ exclude?: {
918
+ [x: string]: unknown;
919
+ community?: {
920
+ addresses: string[];
921
+ maxCommentCids: number;
922
+ postScore?: number | undefined;
923
+ replyScore?: number | undefined;
924
+ firstCommentTimestamp?: number | undefined;
925
+ } | undefined;
926
+ postScore?: number | undefined;
927
+ replyScore?: number | undefined;
928
+ postCount?: number | undefined;
929
+ replyCount?: number | undefined;
930
+ firstCommentTimestamp?: number | undefined;
931
+ challenges?: number[] | undefined;
932
+ role?: string[] | undefined;
933
+ address?: string[] | undefined;
934
+ rateLimit?: number | undefined;
935
+ rateLimitChallengeSuccess?: boolean | undefined;
936
+ publicationType?: {
937
+ [x: string]: unknown;
938
+ post?: boolean | undefined;
939
+ reply?: boolean | undefined;
940
+ vote?: boolean | undefined;
941
+ commentEdit?: boolean | undefined;
942
+ commentModeration?: boolean | undefined;
943
+ communityEdit?: boolean | undefined;
944
+ } | undefined;
945
+ }[] | undefined;
946
+ description?: string | undefined;
947
+ challenge?: string | undefined;
948
+ caseInsensitive?: boolean | undefined;
949
+ pendingApproval?: boolean | undefined;
950
+ publicOptions?: Record<string, string> | undefined;
951
+ }[];
952
+ signature: {
953
+ type: string;
954
+ signature: string;
955
+ publicKey: string;
956
+ signedPropertyNames: string[];
957
+ };
958
+ encryption: {
959
+ [x: string]: unknown;
960
+ type: string;
961
+ publicKey: string;
962
+ };
963
+ createdAt: number;
964
+ updatedAt: number;
965
+ protocolVersion: string;
966
+ posts?: {
967
+ pages: Record<string, {
968
+ comments: {
969
+ comment: {
970
+ [x: string]: unknown;
971
+ timestamp: number;
972
+ signature: {
973
+ type: string;
974
+ signature: string;
975
+ publicKey: string;
976
+ signedPropertyNames: string[];
977
+ };
978
+ protocolVersion: string;
979
+ depth: number;
980
+ flairs?: {
981
+ [x: string]: unknown;
982
+ text: string;
983
+ backgroundColor?: string | undefined;
984
+ textColor?: string | undefined;
985
+ expiresAt?: number | undefined;
986
+ }[] | undefined;
987
+ communityPublicKey?: string | undefined;
988
+ communityName?: string | undefined;
989
+ link?: string | undefined;
990
+ spoiler?: boolean | undefined;
991
+ nsfw?: boolean | undefined;
992
+ content?: string | undefined;
993
+ title?: string | undefined;
994
+ linkWidth?: number | undefined;
995
+ linkHeight?: number | undefined;
996
+ linkHtmlTagName?: string | undefined;
997
+ parentCid?: string | undefined;
998
+ postCid?: string | undefined;
999
+ quotedCids?: string[] | undefined;
1000
+ crosspost?: import("../publications/comment/schema.js").Crosspost | undefined;
1001
+ author?: {
1002
+ [x: string]: unknown;
1003
+ name?: string | undefined;
1004
+ previousCommentCid?: string | undefined;
1005
+ displayName?: string | undefined;
1006
+ wallets?: Record<string, {
1007
+ address: string;
1008
+ timestamp: number;
1009
+ signature: {
1010
+ signature: string;
1011
+ type: string;
1012
+ };
1013
+ }> | undefined;
1014
+ avatar?: {
1015
+ [x: string]: unknown;
1016
+ chainTicker: string;
1017
+ address: string;
1018
+ id: string;
1019
+ timestamp: number;
1020
+ signature: {
1021
+ signature: string;
1022
+ type: string;
1023
+ };
1024
+ } | undefined;
1025
+ flairs?: {
1026
+ [x: string]: unknown;
1027
+ text: string;
1028
+ backgroundColor?: string | undefined;
1029
+ textColor?: string | undefined;
1030
+ expiresAt?: number | undefined;
1031
+ }[] | undefined;
1032
+ } | undefined;
1033
+ thumbnailUrl?: string | undefined;
1034
+ thumbnailUrlWidth?: number | undefined;
1035
+ thumbnailUrlHeight?: number | undefined;
1036
+ previousCid?: string | undefined;
1037
+ pseudonymityMode?: "per-post" | "per-reply" | "per-author" | undefined;
1038
+ };
1039
+ commentUpdate: {
1040
+ [x: string]: unknown;
1041
+ cid: string;
1042
+ upvoteCount: number;
1043
+ downvoteCount: number;
1044
+ replyCount: number;
1045
+ updatedAt: number;
1046
+ signature: {
1047
+ type: string;
1048
+ signature: string;
1049
+ publicKey: string;
1050
+ signedPropertyNames: string[];
1051
+ };
1052
+ protocolVersion: string;
1053
+ childCount?: number | undefined;
1054
+ number?: number | undefined;
1055
+ postNumber?: number | undefined;
1056
+ edit?: {
1057
+ [x: string]: unknown;
1058
+ timestamp: number;
1059
+ signature: {
1060
+ type: string;
1061
+ signature: string;
1062
+ publicKey: string;
1063
+ signedPropertyNames: string[];
1064
+ };
1065
+ protocolVersion: string;
1066
+ commentCid: string;
1067
+ flairs?: {
1068
+ [x: string]: unknown;
1069
+ text: string;
1070
+ backgroundColor?: string | undefined;
1071
+ textColor?: string | undefined;
1072
+ expiresAt?: number | undefined;
1073
+ }[] | undefined;
1074
+ communityPublicKey?: string | undefined;
1075
+ communityName?: string | undefined;
1076
+ spoiler?: boolean | undefined;
1077
+ nsfw?: boolean | undefined;
1078
+ reason?: string | undefined;
1079
+ content?: string | undefined;
1080
+ deleted?: boolean | undefined;
1081
+ author?: {
1082
+ [x: string]: unknown;
1083
+ name?: string | undefined;
1084
+ previousCommentCid?: string | undefined;
1085
+ displayName?: string | undefined;
1086
+ wallets?: Record<string, {
1087
+ address: string;
1088
+ timestamp: number;
1089
+ signature: {
1090
+ signature: string;
1091
+ type: string;
1092
+ };
1093
+ }> | undefined;
1094
+ avatar?: {
1095
+ [x: string]: unknown;
1096
+ chainTicker: string;
1097
+ address: string;
1098
+ id: string;
1099
+ timestamp: number;
1100
+ signature: {
1101
+ signature: string;
1102
+ type: string;
1103
+ };
1104
+ } | undefined;
1105
+ flairs?: {
1106
+ [x: string]: unknown;
1107
+ text: string;
1108
+ backgroundColor?: string | undefined;
1109
+ textColor?: string | undefined;
1110
+ expiresAt?: number | undefined;
1111
+ }[] | undefined;
1112
+ } | undefined;
1113
+ } | undefined;
1114
+ flairs?: {
1115
+ [x: string]: unknown;
1116
+ text: string;
1117
+ backgroundColor?: string | undefined;
1118
+ textColor?: string | undefined;
1119
+ expiresAt?: number | undefined;
1120
+ }[] | undefined;
1121
+ spoiler?: boolean | undefined;
1122
+ nsfw?: boolean | undefined;
1123
+ pinned?: boolean | undefined;
1124
+ locked?: boolean | undefined;
1125
+ archived?: boolean | undefined;
1126
+ removed?: boolean | undefined;
1127
+ reason?: string | undefined;
1128
+ approved?: boolean | undefined;
1129
+ author?: {
1130
+ [x: string]: unknown;
1131
+ community?: {
1132
+ [x: string]: unknown;
1133
+ postScore: number;
1134
+ replyScore: number;
1135
+ firstCommentTimestamp: number;
1136
+ lastCommentCid: string;
1137
+ banExpiresAt?: number | undefined;
1138
+ flairs?: {
1139
+ [x: string]: unknown;
1140
+ text: string;
1141
+ backgroundColor?: string | undefined;
1142
+ textColor?: string | undefined;
1143
+ expiresAt?: number | undefined;
1144
+ }[] | undefined;
1145
+ } | undefined;
1146
+ } | undefined;
1147
+ lastChildCid?: string | undefined;
1148
+ lastReplyTimestamp?: number | undefined;
1149
+ replies?: {
1150
+ pages: Record<string, /*elided*/ any>;
1151
+ pageCids?: Record<string, string> | undefined;
1152
+ } | undefined;
1153
+ };
1154
+ }[];
1155
+ nextCid?: string | undefined;
1156
+ }>;
1157
+ pageCids?: Record<string, string> | undefined;
1158
+ } | undefined;
1159
+ modQueue?: {
1160
+ pageCids: Record<string, string>;
1161
+ } | undefined;
1162
+ name?: string | undefined;
1163
+ anchor?: {
1164
+ publicKey: string;
1165
+ } | undefined;
1166
+ pubsubTopic?: string | undefined;
1167
+ statsCid?: string | undefined;
1168
+ postUpdates?: Record<string, string> | undefined;
1169
+ title?: string | undefined;
1170
+ description?: string | undefined;
1171
+ roles?: Record<string, {
1172
+ [x: string]: unknown;
1173
+ role: string;
1174
+ }> | undefined;
1175
+ rules?: string[] | undefined;
1176
+ lastPostCid?: string | undefined;
1177
+ lastCommentCid?: string | undefined;
1178
+ features?: {
1179
+ [x: string]: unknown;
1180
+ noVideos?: boolean | undefined;
1181
+ noSpoilers?: boolean | undefined;
1182
+ noImages?: boolean | undefined;
1183
+ noVideoReplies?: boolean | undefined;
1184
+ noSpoilerReplies?: boolean | undefined;
1185
+ noImageReplies?: boolean | undefined;
1186
+ noReplyLinks?: boolean | undefined;
1187
+ noPolls?: boolean | undefined;
1188
+ noCrossposts?: boolean | undefined;
1189
+ maxCrosspostDepth?: number | undefined;
1190
+ noNestedReplies?: boolean | undefined;
1191
+ safeForWork?: boolean | undefined;
1192
+ authorFlairs?: boolean | undefined;
1193
+ requireAuthorFlairs?: boolean | undefined;
1194
+ postFlairs?: boolean | undefined;
1195
+ requirePostFlairs?: boolean | undefined;
1196
+ noMarkdownImages?: boolean | undefined;
1197
+ noMarkdownVideos?: boolean | undefined;
1198
+ noMarkdownAudio?: boolean | undefined;
1199
+ noAudio?: boolean | undefined;
1200
+ noAudioReplies?: boolean | undefined;
1201
+ markdownImageReplies?: boolean | undefined;
1202
+ markdownVideoReplies?: boolean | undefined;
1203
+ noPostUpvotes?: boolean | undefined;
1204
+ noReplyUpvotes?: boolean | undefined;
1205
+ noPostDownvotes?: boolean | undefined;
1206
+ noReplyDownvotes?: boolean | undefined;
1207
+ noUpvotes?: boolean | undefined;
1208
+ noDownvotes?: boolean | undefined;
1209
+ requirePostLink?: boolean | undefined;
1210
+ requirePostLinkIsMedia?: boolean | undefined;
1211
+ requireReplyLink?: boolean | undefined;
1212
+ requireReplyLinkIsMedia?: boolean | undefined;
1213
+ pseudonymityMode?: "per-post" | "per-reply" | "per-author" | undefined;
1214
+ } | undefined;
1215
+ suggested?: {
1216
+ [x: string]: unknown;
1217
+ primaryColor?: string | undefined;
1218
+ secondaryColor?: string | undefined;
1219
+ avatarUrl?: string | undefined;
1220
+ bannerUrl?: string | undefined;
1221
+ backgroundUrl?: string | undefined;
1222
+ language?: string | undefined;
1223
+ } | undefined;
1224
+ flairs?: Record<string, {
1225
+ [x: string]: unknown;
1226
+ text: string;
1227
+ backgroundColor?: string | undefined;
1228
+ textColor?: string | undefined;
1229
+ expiresAt?: number | undefined;
1230
+ }[]> | undefined;
1231
+ };
1232
+ ipnsObj: {
1233
+ signer: import("../signer/index.js").SignerWithPublicKeyAddress;
1234
+ publishToIpns: (content: string, opts?: {
1235
+ verifyResolves?: boolean;
1236
+ ttl?: string;
1237
+ }) => Promise<void>;
1238
+ publishToIpnsValue: (value: string, opts?: {
1239
+ verifyResolves?: boolean;
1240
+ ttl?: string;
1241
+ }) => Promise<void>;
1242
+ pkc: PKC;
1243
+ };
1244
+ }>;
897
1245
  export declare function jsonifyCommunityAndRemoveInternalProps(community: RemoteCommunity): {
898
1246
  [x: string]: any;
899
1247
  };
@@ -11,7 +11,7 @@ import { clone, flat, isEmpty, keys, mergeDeep, omit, pick } from "remeda";
11
11
  import { LocalCommunity } from "../runtime/browser/community/local-community.js";
12
12
  import { findUpdatingComment, findUpdatingCommunity } from "../pkc/tracked-instance-registry-util.js";
13
13
  import pTimeout from "p-timeout";
14
- import { signComment, _signJson, signCommentEdit, cleanUpBeforePublishing, _signPubsubMsg, signChallengeVerification, signCommunity } from "../signer/signatures.js";
14
+ import { signComment, _signJson, signCommentEdit, cleanUpBeforePublishing, _signPubsubMsg, signChallengeVerification, signCommentUpdate, signCommunity } from "../signer/signatures.js";
15
15
  import { findCommentInHierarchicalPageIpfsRecursively, findCommentInPageInstance, mapPageIpfsCommentToPageJsonComment, TIMEFRAMES_TO_SECONDS } from "../pages/util.js";
16
16
  import { importSignerIntoKuboNode } from "../runtime/browser/util.js";
17
17
  import { getIpfsKeyFromPrivateKey, getPKCAddressFromPublicKeySync } from "../signer/util.js";
@@ -1199,6 +1199,11 @@ export async function createNewIpns() {
1199
1199
  // ONLY controls the helper's own post-publish name.resolve() sanity check (which syncs Kubo's
1200
1200
  // cache for RPC tests) — it does NOT change what name.publish does. Set it false when
1201
1201
  // publishing a hop whose target isn't resolvable yet, so that resolve check doesn't fail.
1202
+ // `ttl` (kubo duration string, e.g. "10s") overrides kubo's default record ttl, which is 5
1203
+ // MINUTES on kubo 0.43, not the 60s a LocalCommunity publishes (publishInterval * 3). The
1204
+ // ttl bounds how long the libp2p-js resolver may serve a name from its routing-layer cache
1205
+ // without revalidating (issue #301/#307), so any test that must observe a cache expiry
1206
+ // inside its own timeout has to shorten it here instead of waiting out kubo's default.
1202
1207
  const publishToIpnsValue = async (value, opts) => {
1203
1208
  const verifyResolves = opts?.verifyResolves ?? true;
1204
1209
  // Wrapped in retry because Kubo can transiently ETIMEDOUT in CI
@@ -1212,7 +1217,8 @@ export async function createNewIpns() {
1212
1217
  try {
1213
1218
  await ipfsClient._client.name.publish(value, {
1214
1219
  key: signer.address,
1215
- allowOffline: true
1220
+ allowOffline: true,
1221
+ ...(opts?.ttl ? { ttl: opts.ttl } : {})
1216
1222
  });
1217
1223
  resolve();
1218
1224
  }
@@ -1253,9 +1259,9 @@ export async function createNewIpns() {
1253
1259
  });
1254
1260
  });
1255
1261
  };
1256
- const publishToIpns = async (content) => {
1262
+ const publishToIpns = async (content, opts) => {
1257
1263
  const cid = await addStringToIpfs(content);
1258
- await publishToIpnsValue(cid);
1264
+ await publishToIpnsValue(cid, opts);
1259
1265
  };
1260
1266
  return {
1261
1267
  signer,
@@ -1344,7 +1350,7 @@ export async function publishCommunityRecordWithExtraProp(opts) {
1344
1350
  if (opts?.includeExtraPropInSignedPropertyNames)
1345
1351
  signedPropertyNames.push("extraProp");
1346
1352
  communityRecord.signature = await _signJson(signedPropertyNames, communityRecord, ipnsObj.signer, Logger("pkc-js:test-util:publishCommunityRecordWithExtraProp"));
1347
- await ipnsObj.publishToIpns(JSON.stringify(communityRecord));
1353
+ await ipnsObj.publishToIpns(JSON.stringify(communityRecord), opts?.ttl ? { ttl: opts.ttl } : undefined);
1348
1354
  return { communityRecord, ipnsObj };
1349
1355
  }
1350
1356
  // getTemplateCommunityRecord clones a live community's record, so its encryption block belongs to
@@ -1434,6 +1440,83 @@ export async function createStaticCommunityRecordForComment(opts) {
1434
1440
  await commentPKC.destroy();
1435
1441
  }
1436
1442
  }
1443
+ // Publish a STATIC community under a fresh IPNS key whose preloaded posts page embeds one post
1444
+ // (author-signed CommentIpfs + a CommentUpdate signed by the community key) and whose postUpdates
1445
+ // points at a real UnixFS folder on the test Kubo holding that post's CommentUpdate at
1446
+ // <folderCid>/<postCid>/update. The record is published exactly once and nothing ever publishes
1447
+ // to this key again, so an update loop watching it is deterministic: no gossip arrivals from
1448
+ // concurrent suites, no new records — the literal "community is not publishing new community
1449
+ // records" scenario the state-order suites pin. Built for those suites (PR #311 flake class):
1450
+ // the shared live communities (signers[0]) receive publishes from every concurrently-running
1451
+ // suite, and since the update loop became arrival-driven each of those publishes starts a fetch
1452
+ // cycle at a random moment, racing any exact state-sequence assertion.
1453
+ export async function publishStaticCommunityWithPostInPages() {
1454
+ const ipnsObj = await createNewIpns();
1455
+ const communityAddress = ipnsObj.signer.address;
1456
+ const commentPKC = await mockPKCNoDataPathWithOnlyKuboClient();
1457
+ try {
1458
+ const commentToPublish = await commentPKC.createComment({
1459
+ signer: await commentPKC.createSigner(),
1460
+ communityAddress,
1461
+ title: `Static post in pages - ${Date.now()}`,
1462
+ content: `Static content - ${Date.now()}`
1463
+ });
1464
+ if (!commentToPublish.raw.pubsubMessageToPublish) {
1465
+ // Directly set _community from in-memory data so signing doesn't fetch the community
1466
+ // record over the network (same trick as createStaticCommunityRecordForComment).
1467
+ commentToPublish["_community"] = {
1468
+ address: communityAddress,
1469
+ publicKey: communityAddress,
1470
+ encryption: encryptionForSigner(ipnsObj.signer),
1471
+ pubsubTopic: communityAddress
1472
+ };
1473
+ await commentToPublish._signPublicationWithCommunityFields();
1474
+ }
1475
+ // The SAME serialization is added to IPFS and embedded in the page, so the cid the page
1476
+ // verifier recomputes from the embedded comment matches commentUpdate.cid.
1477
+ const commentIpfs = { ...commentToPublish.raw.pubsubMessageToPublish, depth: 0 };
1478
+ if (!commentIpfs.protocolVersion)
1479
+ throw Error("The comment to embed in the static community must carry a protocolVersion");
1480
+ const commentIpfsJson = JSON.stringify(commentIpfs);
1481
+ const commentCid = await addStringToIpfs(commentIpfsJson);
1482
+ const commentUpdateWithoutSignature = {
1483
+ cid: commentCid,
1484
+ upvoteCount: 0,
1485
+ downvoteCount: 0,
1486
+ replyCount: 0,
1487
+ updatedAt: timestamp(),
1488
+ protocolVersion: commentIpfs.protocolVersion
1489
+ };
1490
+ const commentUpdate = {
1491
+ ...commentUpdateWithoutSignature,
1492
+ signature: await signCommentUpdate({ update: commentUpdateWithoutSignature, signer: ipnsObj.signer })
1493
+ };
1494
+ // postUpdates folder on the test Kubo: <folderCid>/<postCid>/update.
1495
+ const kuboClient = ipnsObj.pkc._clientsManager.getDefaultKuboRpcClient()._client;
1496
+ let folderCid;
1497
+ for await (const addedEntry of kuboClient.addAll([{ path: `${commentCid}/update`, content: JSON.stringify(commentUpdate) }], {
1498
+ wrapWithDirectory: true
1499
+ }))
1500
+ if (addedEntry.path === "")
1501
+ folderCid = addedEntry.cid.toString();
1502
+ if (!folderCid)
1503
+ throw Error("Failed to derive the postUpdates folder cid from the wrapped kubo add");
1504
+ const communityRecord = {
1505
+ ...(await getTemplateCommunityRecord(ipnsObj.pkc)),
1506
+ posts: { pages: { hot: { comments: [{ comment: JSON.parse(commentIpfsJson), commentUpdate }] } } },
1507
+ postUpdates: { "86400": folderCid },
1508
+ pubsubTopic: communityAddress,
1509
+ encryption: encryptionForSigner(ipnsObj.signer),
1510
+ updatedAt: timestamp()
1511
+ };
1512
+ communityRecord.signature = await signCommunity({ community: communityRecord, signer: ipnsObj.signer });
1513
+ await ipnsObj.publishToIpns(JSON.stringify(communityRecord));
1514
+ return { communityAddress, commentCid, communityRecord, ipnsObj };
1515
+ }
1516
+ finally {
1517
+ await commentPKC.destroy();
1518
+ }
1519
+ }
1437
1520
  function _stripNameResolvedFromPages(pagesContainer) {
1438
1521
  if (!pagesContainer?.pages)
1439
1522
  return;