@chainstream-io/sdk 0.2.11 → 0.2.13

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.
@@ -182,12 +182,35 @@ var CEL_FIELD_MAPPINGS = {
182
182
  balanceTagRatRatio: "btrr",
183
183
  timestamp: "ts"
184
184
  },
185
- // New token subscription fields
185
+ // New token subscription fields (dex-new-token, supports CEL filter)
186
186
  subscribeNewToken: {
187
187
  tokenAddress: "a",
188
188
  name: "n",
189
189
  symbol: "s",
190
- createdAtMs: "cts"
190
+ decimals: "dec",
191
+ imageUrl: "iu",
192
+ description: "de",
193
+ createdAtMs: "cts",
194
+ coingeckoCoinId: "cgi",
195
+ "socialMedia.twitter": "sm.tw",
196
+ "socialMedia.telegram": "sm.tg",
197
+ "socialMedia.website": "sm.w",
198
+ "socialMedia.tiktok": "sm.tt",
199
+ "socialMedia.discord": "sm.dc",
200
+ "socialMedia.facebook": "sm.fb",
201
+ "socialMedia.github": "sm.gh",
202
+ "socialMedia.instagram": "sm.ig",
203
+ "socialMedia.linkedin": "sm.li",
204
+ "socialMedia.medium": "sm.md",
205
+ "socialMedia.reddit": "sm.rd",
206
+ "socialMedia.youtube": "sm.yt",
207
+ "socialMedia.bitbucket": "sm.bb",
208
+ "launchFrom.programAddress": "lf.pa",
209
+ "launchFrom.protocolFamily": "lf.pf",
210
+ "launchFrom.protocolName": "lf.pn",
211
+ "migratedTo.programAddress": "mt.pa",
212
+ "migratedTo.protocolFamily": "mt.pf",
213
+ "migratedTo.protocolName": "mt.pn"
191
214
  },
192
215
  // Token supply subscription fields
193
216
  subscribeTokenSupply: {
@@ -210,15 +233,65 @@ var CEL_FIELD_MAPPINGS = {
210
233
  value: "v",
211
234
  timestamp: "ts"
212
235
  },
213
- // New token metadata subscription fields
236
+ // New token metadata subscription fields (dex-new-tokens-metadata)
214
237
  subscribeNewTokensMetadata: {
215
238
  tokenAddress: "a",
216
239
  name: "n",
240
+ decimals: "dec",
217
241
  symbol: "s",
218
242
  imageUrl: "iu",
219
243
  description: "de",
220
- socialMedia: "sm",
221
- createdAtMs: "cts"
244
+ createdAtMs: "cts",
245
+ coingeckoCoinId: "cgi",
246
+ "socialMedia.twitter": "sm.tw",
247
+ "socialMedia.telegram": "sm.tg",
248
+ "socialMedia.website": "sm.w",
249
+ "socialMedia.tiktok": "sm.tt",
250
+ "socialMedia.discord": "sm.dc",
251
+ "socialMedia.facebook": "sm.fb",
252
+ "socialMedia.github": "sm.gh",
253
+ "socialMedia.instagram": "sm.ig",
254
+ "socialMedia.linkedin": "sm.li",
255
+ "socialMedia.medium": "sm.md",
256
+ "socialMedia.reddit": "sm.rd",
257
+ "socialMedia.youtube": "sm.yt",
258
+ "socialMedia.bitbucket": "sm.bb",
259
+ "launchFrom.programAddress": "lf.pa",
260
+ "launchFrom.protocolFamily": "lf.pf",
261
+ "launchFrom.protocolName": "lf.pn",
262
+ "migratedTo.programAddress": "mt.pa",
263
+ "migratedTo.protocolFamily": "mt.pf",
264
+ "migratedTo.protocolName": "mt.pn"
265
+ },
266
+ // New tokens list subscription fields (dex-new-tokens)
267
+ subscribeNewTokens: {
268
+ tokenAddress: "a",
269
+ name: "n",
270
+ decimals: "dec",
271
+ symbol: "s",
272
+ imageUrl: "iu",
273
+ description: "de",
274
+ createdAtMs: "cts",
275
+ coingeckoCoinId: "cgi",
276
+ "socialMedia.twitter": "sm.tw",
277
+ "socialMedia.telegram": "sm.tg",
278
+ "socialMedia.website": "sm.w",
279
+ "socialMedia.tiktok": "sm.tt",
280
+ "socialMedia.discord": "sm.dc",
281
+ "socialMedia.facebook": "sm.fb",
282
+ "socialMedia.github": "sm.gh",
283
+ "socialMedia.instagram": "sm.ig",
284
+ "socialMedia.linkedin": "sm.li",
285
+ "socialMedia.medium": "sm.md",
286
+ "socialMedia.reddit": "sm.rd",
287
+ "socialMedia.youtube": "sm.yt",
288
+ "socialMedia.bitbucket": "sm.bb",
289
+ "launchFrom.programAddress": "lf.pa",
290
+ "launchFrom.protocolFamily": "lf.pf",
291
+ "launchFrom.protocolName": "lf.pn",
292
+ "migratedTo.programAddress": "mt.pa",
293
+ "migratedTo.protocolFamily": "mt.pf",
294
+ "migratedTo.protocolName": "mt.pn"
222
295
  },
223
296
  // Token trades subscription fields
224
297
  subscribeTokenTrades: {
@@ -294,12 +367,14 @@ function replaceFilterFields(filter, methodName) {
294
367
  }
295
368
  const fieldMappings = getFieldMappings(methodName);
296
369
  let result = filter;
297
- for (const [longField, shortField] of Object.entries(fieldMappings)) {
370
+ const sortedEntries = Object.entries(fieldMappings).sort(([a], [b]) => b.length - a.length);
371
+ for (const [longField, shortField] of sortedEntries) {
372
+ const escapedField = longField.replace(/\./g, "\\.");
298
373
  const patterns = [
299
- // Pattern 1: fieldName (without meta. prefix)
300
- new RegExp(`\\b${longField}\\b`, "g"),
301
- // Pattern 2: meta.fieldName (with meta. prefix)
302
- new RegExp(`\\bmeta\\.${longField}\\b`, "g")
374
+ // Pattern 1: meta.fieldName (with meta. prefix) — check first to avoid double meta.
375
+ new RegExp(`\\bmeta\\.${escapedField}\\b`, "g"),
376
+ // Pattern 2: fieldName (without meta. prefix)
377
+ new RegExp(`\\b${escapedField}\\b`, "g")
303
378
  ];
304
379
  patterns.forEach((pattern) => {
305
380
  result = result.replace(pattern, `meta.${shortField}`);
@@ -606,6 +681,57 @@ var StreamApi = class {
606
681
  [`liquidityChangeRatio${suffix}`]: this.formatScientificNotation(data[`lpc${suffix}`])
607
682
  };
608
683
  }
684
+ /**
685
+ * Parse social media data from short field names
686
+ */
687
+ parseSocialMedia(sm) {
688
+ if (!sm) return void 0;
689
+ return {
690
+ twitter: sm.tw,
691
+ telegram: sm.tg,
692
+ website: sm.w,
693
+ tiktok: sm.tt,
694
+ discord: sm.dc,
695
+ facebook: sm.fb,
696
+ github: sm.gh,
697
+ instagram: sm.ig,
698
+ linkedin: sm.li,
699
+ medium: sm.md,
700
+ reddit: sm.rd,
701
+ youtube: sm.yt,
702
+ bitbucket: sm.bb
703
+ };
704
+ }
705
+ /**
706
+ * Parse DEX protocol data from short field names
707
+ */
708
+ parseDexProtocol(lf) {
709
+ if (!lf) return void 0;
710
+ const result = {};
711
+ if (lf.pa) result.programAddress = lf.pa;
712
+ if (lf.pf) result.protocolFamily = lf.pf;
713
+ if (lf.pn) result.protocolName = lf.pn;
714
+ return result;
715
+ }
716
+ /**
717
+ * Parse a TokenMetadataTimeEvent from raw WebSocket data
718
+ */
719
+ parseTokenMetadata(data) {
720
+ const result = {
721
+ tokenAddress: data.a
722
+ };
723
+ if (data.n != null) result.name = data.n;
724
+ if (data.dec != null) result.decimals = data.dec;
725
+ if (data.s != null) result.symbol = data.s;
726
+ if (data.iu != null) result.imageUrl = data.iu;
727
+ if (data.de != null) result.description = data.de;
728
+ if (data.sm) result.socialMedia = this.parseSocialMedia(data.sm);
729
+ if (data.cts != null) result.createdAtMs = data.cts;
730
+ if (data.cgi != null) result.coingeckoCoinId = data.cgi;
731
+ if (data.lf) result.launchFrom = this.parseDexProtocol(data.lf);
732
+ if (data.mt) result.migratedTo = this.parseDexProtocol(data.mt);
733
+ return result;
734
+ }
609
735
  /**
610
736
  * Subscribe to token trade statistics
611
737
  * Channel: dex-token-stats:{chain}_{tokenAddress}
@@ -706,6 +832,10 @@ var StreamApi = class {
706
832
  "subscribeTokenHolders"
707
833
  );
708
834
  }
835
+ /**
836
+ * Subscribe to new token events (single token per event, supports CEL filter)
837
+ * Channel: dex-new-token:{chain}
838
+ */
709
839
  subscribeNewToken({
710
840
  chain,
711
841
  callback,
@@ -721,28 +851,24 @@ var StreamApi = class {
721
851
  symbol: data.s,
722
852
  createdAtMs: data.cts
723
853
  };
724
- if (data.dec) {
725
- result.decimals = data.dec;
726
- }
727
- if (data.lf) {
728
- const lf = data.lf;
729
- result.launchFrom = {};
730
- if (lf.pa) {
731
- result.launchFrom.programAddress = lf.pa;
732
- }
733
- if (lf.pf) {
734
- result.launchFrom.protocolFamily = lf.pf;
735
- }
736
- if (lf.pn) {
737
- result.launchFrom.protocolName = lf.pn;
738
- }
739
- }
854
+ if (data.dec != null) result.decimals = data.dec;
855
+ if (data.iu != null) result.imageUrl = data.iu;
856
+ if (data.de != null) result.description = data.de;
857
+ if (data.sm) result.socialMedia = this.parseSocialMedia(data.sm);
858
+ if (data.cgi != null) result.coingeckoCoinId = data.cgi;
859
+ if (data.lf) result.launchFrom = this.parseDexProtocol(data.lf);
860
+ if (data.mt) result.migratedTo = this.parseDexProtocol(data.mt);
740
861
  callback(result);
741
862
  },
742
863
  filter,
743
864
  "subscribeNewToken"
744
865
  );
745
866
  }
867
+ /**
868
+ * Subscribe to new tokens metadata (batch, aggregated every 1 second)
869
+ * Channel: dex-new-tokens-metadata:{chain}
870
+ * No CEL filter support
871
+ */
746
872
  subscribeNewTokensMetadata({
747
873
  chain,
748
874
  callback
@@ -750,35 +876,22 @@ var StreamApi = class {
750
876
  const channel = `dex-new-tokens-metadata:${chain}`;
751
877
  return this.subscribe(
752
878
  channel,
753
- (data) => callback(
754
- data.map((it) => ({
755
- tokenAddress: it.a,
756
- name: it.n,
757
- symbol: it.s,
758
- imageUrl: it.iu,
759
- description: it.de,
760
- socialMedia: (() => {
761
- const sm = it.sm;
762
- if (!sm) return void 0;
763
- return {
764
- twitter: sm.tw,
765
- telegram: sm.tg,
766
- website: sm.w,
767
- tiktok: sm.tt,
768
- discord: sm.dc,
769
- facebook: sm.fb,
770
- github: sm.gh,
771
- instagram: sm.ig,
772
- linkedin: sm.li,
773
- medium: sm.md,
774
- reddit: sm.rd,
775
- youtube: sm.yt,
776
- bitbucket: sm.bb
777
- };
778
- })(),
779
- createdAtMs: it.cts
780
- }))
781
- )
879
+ (data) => callback(data.map((it) => this.parseTokenMetadata(it)))
880
+ );
881
+ }
882
+ /**
883
+ * Subscribe to new tokens list (batch from token-created-to-realtime-pipeline)
884
+ * Channel: dex-new-tokens:{chain}
885
+ * No CEL filter support
886
+ */
887
+ subscribeNewTokens({
888
+ chain,
889
+ callback
890
+ }) {
891
+ const channel = `dex-new-tokens:${chain}`;
892
+ return this.subscribe(
893
+ channel,
894
+ (data) => callback(data.map((it) => this.parseTokenMetadata(it)))
782
895
  );
783
896
  }
784
897
  subscribeTokenSupply({
@@ -927,73 +1040,13 @@ var StreamApi = class {
927
1040
  result.metadata.createdAtMs = t.cts;
928
1041
  }
929
1042
  if (t.lf) {
930
- const lf = t.lf;
931
- result.metadata.launchFrom = {};
932
- if (lf.pa) {
933
- result.metadata.launchFrom.programAddress = lf.pa;
934
- }
935
- if (lf.pf) {
936
- result.metadata.launchFrom.protocolFamily = lf.pf;
937
- }
938
- if (lf.pn) {
939
- result.metadata.launchFrom.protocolName = lf.pn;
940
- }
1043
+ result.metadata.launchFrom = this.parseDexProtocol(t.lf);
941
1044
  }
942
1045
  if (t.mt) {
943
- const mt = t.mt;
944
- result.metadata.migratedTo = {};
945
- if (mt.pa) {
946
- result.metadata.migratedTo.programAddress = mt.pa;
947
- }
948
- if (mt.pf) {
949
- result.metadata.migratedTo.protocolFamily = mt.pf;
950
- }
951
- if (mt.pn) {
952
- result.metadata.migratedTo.protocolName = mt.pn;
953
- }
1046
+ result.metadata.migratedTo = this.parseDexProtocol(t.mt);
954
1047
  }
955
1048
  if (t.sm) {
956
- const sm = t.sm;
957
- result.metadata.socialMedia = {};
958
- if (sm.tw) {
959
- result.metadata.socialMedia.twitter = sm.tw;
960
- }
961
- if (sm.tg) {
962
- result.metadata.socialMedia.telegram = sm.tg;
963
- }
964
- if (sm.w) {
965
- result.metadata.socialMedia.website = sm.w;
966
- }
967
- if (sm.tt) {
968
- result.metadata.socialMedia.tiktok = sm.tt;
969
- }
970
- if (sm.dc) {
971
- result.metadata.socialMedia.discord = sm.dc;
972
- }
973
- if (sm.fb) {
974
- result.metadata.socialMedia.facebook = sm.fb;
975
- }
976
- if (sm.gh) {
977
- result.metadata.socialMedia.github = sm.gh;
978
- }
979
- if (sm.ig) {
980
- result.metadata.socialMedia.instagram = sm.ig;
981
- }
982
- if (sm.li) {
983
- result.metadata.socialMedia.linkedin = sm.li;
984
- }
985
- if (sm.md) {
986
- result.metadata.socialMedia.medium = sm.md;
987
- }
988
- if (sm.rd) {
989
- result.metadata.socialMedia.reddit = sm.rd;
990
- }
991
- if (sm.yt) {
992
- result.metadata.socialMedia.youtube = sm.yt;
993
- }
994
- if (sm.bb) {
995
- result.metadata.socialMedia.bitbucket = sm.bb;
996
- }
1049
+ result.metadata.socialMedia = this.parseSocialMedia(t.sm);
997
1050
  }
998
1051
  }
999
1052
  if (bc) {