@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.
@@ -149,12 +149,35 @@ var CEL_FIELD_MAPPINGS = {
149
149
  balanceTagRatRatio: "btrr",
150
150
  timestamp: "ts"
151
151
  },
152
- // New token subscription fields
152
+ // New token subscription fields (dex-new-token, supports CEL filter)
153
153
  subscribeNewToken: {
154
154
  tokenAddress: "a",
155
155
  name: "n",
156
156
  symbol: "s",
157
- createdAtMs: "cts"
157
+ decimals: "dec",
158
+ imageUrl: "iu",
159
+ description: "de",
160
+ createdAtMs: "cts",
161
+ coingeckoCoinId: "cgi",
162
+ "socialMedia.twitter": "sm.tw",
163
+ "socialMedia.telegram": "sm.tg",
164
+ "socialMedia.website": "sm.w",
165
+ "socialMedia.tiktok": "sm.tt",
166
+ "socialMedia.discord": "sm.dc",
167
+ "socialMedia.facebook": "sm.fb",
168
+ "socialMedia.github": "sm.gh",
169
+ "socialMedia.instagram": "sm.ig",
170
+ "socialMedia.linkedin": "sm.li",
171
+ "socialMedia.medium": "sm.md",
172
+ "socialMedia.reddit": "sm.rd",
173
+ "socialMedia.youtube": "sm.yt",
174
+ "socialMedia.bitbucket": "sm.bb",
175
+ "launchFrom.programAddress": "lf.pa",
176
+ "launchFrom.protocolFamily": "lf.pf",
177
+ "launchFrom.protocolName": "lf.pn",
178
+ "migratedTo.programAddress": "mt.pa",
179
+ "migratedTo.protocolFamily": "mt.pf",
180
+ "migratedTo.protocolName": "mt.pn"
158
181
  },
159
182
  // Token supply subscription fields
160
183
  subscribeTokenSupply: {
@@ -177,15 +200,65 @@ var CEL_FIELD_MAPPINGS = {
177
200
  value: "v",
178
201
  timestamp: "ts"
179
202
  },
180
- // New token metadata subscription fields
203
+ // New token metadata subscription fields (dex-new-tokens-metadata)
181
204
  subscribeNewTokensMetadata: {
182
205
  tokenAddress: "a",
183
206
  name: "n",
207
+ decimals: "dec",
184
208
  symbol: "s",
185
209
  imageUrl: "iu",
186
210
  description: "de",
187
- socialMedia: "sm",
188
- createdAtMs: "cts"
211
+ createdAtMs: "cts",
212
+ coingeckoCoinId: "cgi",
213
+ "socialMedia.twitter": "sm.tw",
214
+ "socialMedia.telegram": "sm.tg",
215
+ "socialMedia.website": "sm.w",
216
+ "socialMedia.tiktok": "sm.tt",
217
+ "socialMedia.discord": "sm.dc",
218
+ "socialMedia.facebook": "sm.fb",
219
+ "socialMedia.github": "sm.gh",
220
+ "socialMedia.instagram": "sm.ig",
221
+ "socialMedia.linkedin": "sm.li",
222
+ "socialMedia.medium": "sm.md",
223
+ "socialMedia.reddit": "sm.rd",
224
+ "socialMedia.youtube": "sm.yt",
225
+ "socialMedia.bitbucket": "sm.bb",
226
+ "launchFrom.programAddress": "lf.pa",
227
+ "launchFrom.protocolFamily": "lf.pf",
228
+ "launchFrom.protocolName": "lf.pn",
229
+ "migratedTo.programAddress": "mt.pa",
230
+ "migratedTo.protocolFamily": "mt.pf",
231
+ "migratedTo.protocolName": "mt.pn"
232
+ },
233
+ // New tokens list subscription fields (dex-new-tokens)
234
+ subscribeNewTokens: {
235
+ tokenAddress: "a",
236
+ name: "n",
237
+ decimals: "dec",
238
+ symbol: "s",
239
+ imageUrl: "iu",
240
+ description: "de",
241
+ createdAtMs: "cts",
242
+ coingeckoCoinId: "cgi",
243
+ "socialMedia.twitter": "sm.tw",
244
+ "socialMedia.telegram": "sm.tg",
245
+ "socialMedia.website": "sm.w",
246
+ "socialMedia.tiktok": "sm.tt",
247
+ "socialMedia.discord": "sm.dc",
248
+ "socialMedia.facebook": "sm.fb",
249
+ "socialMedia.github": "sm.gh",
250
+ "socialMedia.instagram": "sm.ig",
251
+ "socialMedia.linkedin": "sm.li",
252
+ "socialMedia.medium": "sm.md",
253
+ "socialMedia.reddit": "sm.rd",
254
+ "socialMedia.youtube": "sm.yt",
255
+ "socialMedia.bitbucket": "sm.bb",
256
+ "launchFrom.programAddress": "lf.pa",
257
+ "launchFrom.protocolFamily": "lf.pf",
258
+ "launchFrom.protocolName": "lf.pn",
259
+ "migratedTo.programAddress": "mt.pa",
260
+ "migratedTo.protocolFamily": "mt.pf",
261
+ "migratedTo.protocolName": "mt.pn"
189
262
  },
190
263
  // Token trades subscription fields
191
264
  subscribeTokenTrades: {
@@ -261,12 +334,14 @@ function replaceFilterFields(filter, methodName) {
261
334
  }
262
335
  const fieldMappings = getFieldMappings(methodName);
263
336
  let result = filter;
264
- for (const [longField, shortField] of Object.entries(fieldMappings)) {
337
+ const sortedEntries = Object.entries(fieldMappings).sort(([a], [b]) => b.length - a.length);
338
+ for (const [longField, shortField] of sortedEntries) {
339
+ const escapedField = longField.replace(/\./g, "\\.");
265
340
  const patterns = [
266
- // Pattern 1: fieldName (without meta. prefix)
267
- new RegExp(`\\b${longField}\\b`, "g"),
268
- // Pattern 2: meta.fieldName (with meta. prefix)
269
- new RegExp(`\\bmeta\\.${longField}\\b`, "g")
341
+ // Pattern 1: meta.fieldName (with meta. prefix) — check first to avoid double meta.
342
+ new RegExp(`\\bmeta\\.${escapedField}\\b`, "g"),
343
+ // Pattern 2: fieldName (without meta. prefix)
344
+ new RegExp(`\\b${escapedField}\\b`, "g")
270
345
  ];
271
346
  patterns.forEach((pattern) => {
272
347
  result = result.replace(pattern, `meta.${shortField}`);
@@ -573,6 +648,57 @@ var StreamApi = class {
573
648
  [`liquidityChangeRatio${suffix}`]: this.formatScientificNotation(data[`lpc${suffix}`])
574
649
  };
575
650
  }
651
+ /**
652
+ * Parse social media data from short field names
653
+ */
654
+ parseSocialMedia(sm) {
655
+ if (!sm) return void 0;
656
+ return {
657
+ twitter: sm.tw,
658
+ telegram: sm.tg,
659
+ website: sm.w,
660
+ tiktok: sm.tt,
661
+ discord: sm.dc,
662
+ facebook: sm.fb,
663
+ github: sm.gh,
664
+ instagram: sm.ig,
665
+ linkedin: sm.li,
666
+ medium: sm.md,
667
+ reddit: sm.rd,
668
+ youtube: sm.yt,
669
+ bitbucket: sm.bb
670
+ };
671
+ }
672
+ /**
673
+ * Parse DEX protocol data from short field names
674
+ */
675
+ parseDexProtocol(lf) {
676
+ if (!lf) return void 0;
677
+ const result = {};
678
+ if (lf.pa) result.programAddress = lf.pa;
679
+ if (lf.pf) result.protocolFamily = lf.pf;
680
+ if (lf.pn) result.protocolName = lf.pn;
681
+ return result;
682
+ }
683
+ /**
684
+ * Parse a TokenMetadataTimeEvent from raw WebSocket data
685
+ */
686
+ parseTokenMetadata(data) {
687
+ const result = {
688
+ tokenAddress: data.a
689
+ };
690
+ if (data.n != null) result.name = data.n;
691
+ if (data.dec != null) result.decimals = data.dec;
692
+ if (data.s != null) result.symbol = data.s;
693
+ if (data.iu != null) result.imageUrl = data.iu;
694
+ if (data.de != null) result.description = data.de;
695
+ if (data.sm) result.socialMedia = this.parseSocialMedia(data.sm);
696
+ if (data.cts != null) result.createdAtMs = data.cts;
697
+ if (data.cgi != null) result.coingeckoCoinId = data.cgi;
698
+ if (data.lf) result.launchFrom = this.parseDexProtocol(data.lf);
699
+ if (data.mt) result.migratedTo = this.parseDexProtocol(data.mt);
700
+ return result;
701
+ }
576
702
  /**
577
703
  * Subscribe to token trade statistics
578
704
  * Channel: dex-token-stats:{chain}_{tokenAddress}
@@ -673,6 +799,10 @@ var StreamApi = class {
673
799
  "subscribeTokenHolders"
674
800
  );
675
801
  }
802
+ /**
803
+ * Subscribe to new token events (single token per event, supports CEL filter)
804
+ * Channel: dex-new-token:{chain}
805
+ */
676
806
  subscribeNewToken({
677
807
  chain,
678
808
  callback,
@@ -688,28 +818,24 @@ var StreamApi = class {
688
818
  symbol: data.s,
689
819
  createdAtMs: data.cts
690
820
  };
691
- if (data.dec) {
692
- result.decimals = data.dec;
693
- }
694
- if (data.lf) {
695
- const lf = data.lf;
696
- result.launchFrom = {};
697
- if (lf.pa) {
698
- result.launchFrom.programAddress = lf.pa;
699
- }
700
- if (lf.pf) {
701
- result.launchFrom.protocolFamily = lf.pf;
702
- }
703
- if (lf.pn) {
704
- result.launchFrom.protocolName = lf.pn;
705
- }
706
- }
821
+ if (data.dec != null) result.decimals = data.dec;
822
+ if (data.iu != null) result.imageUrl = data.iu;
823
+ if (data.de != null) result.description = data.de;
824
+ if (data.sm) result.socialMedia = this.parseSocialMedia(data.sm);
825
+ if (data.cgi != null) result.coingeckoCoinId = data.cgi;
826
+ if (data.lf) result.launchFrom = this.parseDexProtocol(data.lf);
827
+ if (data.mt) result.migratedTo = this.parseDexProtocol(data.mt);
707
828
  callback(result);
708
829
  },
709
830
  filter,
710
831
  "subscribeNewToken"
711
832
  );
712
833
  }
834
+ /**
835
+ * Subscribe to new tokens metadata (batch, aggregated every 1 second)
836
+ * Channel: dex-new-tokens-metadata:{chain}
837
+ * No CEL filter support
838
+ */
713
839
  subscribeNewTokensMetadata({
714
840
  chain,
715
841
  callback
@@ -717,35 +843,22 @@ var StreamApi = class {
717
843
  const channel = `dex-new-tokens-metadata:${chain}`;
718
844
  return this.subscribe(
719
845
  channel,
720
- (data) => callback(
721
- data.map((it) => ({
722
- tokenAddress: it.a,
723
- name: it.n,
724
- symbol: it.s,
725
- imageUrl: it.iu,
726
- description: it.de,
727
- socialMedia: (() => {
728
- const sm = it.sm;
729
- if (!sm) return void 0;
730
- return {
731
- twitter: sm.tw,
732
- telegram: sm.tg,
733
- website: sm.w,
734
- tiktok: sm.tt,
735
- discord: sm.dc,
736
- facebook: sm.fb,
737
- github: sm.gh,
738
- instagram: sm.ig,
739
- linkedin: sm.li,
740
- medium: sm.md,
741
- reddit: sm.rd,
742
- youtube: sm.yt,
743
- bitbucket: sm.bb
744
- };
745
- })(),
746
- createdAtMs: it.cts
747
- }))
748
- )
846
+ (data) => callback(data.map((it) => this.parseTokenMetadata(it)))
847
+ );
848
+ }
849
+ /**
850
+ * Subscribe to new tokens list (batch from token-created-to-realtime-pipeline)
851
+ * Channel: dex-new-tokens:{chain}
852
+ * No CEL filter support
853
+ */
854
+ subscribeNewTokens({
855
+ chain,
856
+ callback
857
+ }) {
858
+ const channel = `dex-new-tokens:${chain}`;
859
+ return this.subscribe(
860
+ channel,
861
+ (data) => callback(data.map((it) => this.parseTokenMetadata(it)))
749
862
  );
750
863
  }
751
864
  subscribeTokenSupply({
@@ -894,73 +1007,13 @@ var StreamApi = class {
894
1007
  result.metadata.createdAtMs = t.cts;
895
1008
  }
896
1009
  if (t.lf) {
897
- const lf = t.lf;
898
- result.metadata.launchFrom = {};
899
- if (lf.pa) {
900
- result.metadata.launchFrom.programAddress = lf.pa;
901
- }
902
- if (lf.pf) {
903
- result.metadata.launchFrom.protocolFamily = lf.pf;
904
- }
905
- if (lf.pn) {
906
- result.metadata.launchFrom.protocolName = lf.pn;
907
- }
1010
+ result.metadata.launchFrom = this.parseDexProtocol(t.lf);
908
1011
  }
909
1012
  if (t.mt) {
910
- const mt = t.mt;
911
- result.metadata.migratedTo = {};
912
- if (mt.pa) {
913
- result.metadata.migratedTo.programAddress = mt.pa;
914
- }
915
- if (mt.pf) {
916
- result.metadata.migratedTo.protocolFamily = mt.pf;
917
- }
918
- if (mt.pn) {
919
- result.metadata.migratedTo.protocolName = mt.pn;
920
- }
1013
+ result.metadata.migratedTo = this.parseDexProtocol(t.mt);
921
1014
  }
922
1015
  if (t.sm) {
923
- const sm = t.sm;
924
- result.metadata.socialMedia = {};
925
- if (sm.tw) {
926
- result.metadata.socialMedia.twitter = sm.tw;
927
- }
928
- if (sm.tg) {
929
- result.metadata.socialMedia.telegram = sm.tg;
930
- }
931
- if (sm.w) {
932
- result.metadata.socialMedia.website = sm.w;
933
- }
934
- if (sm.tt) {
935
- result.metadata.socialMedia.tiktok = sm.tt;
936
- }
937
- if (sm.dc) {
938
- result.metadata.socialMedia.discord = sm.dc;
939
- }
940
- if (sm.fb) {
941
- result.metadata.socialMedia.facebook = sm.fb;
942
- }
943
- if (sm.gh) {
944
- result.metadata.socialMedia.github = sm.gh;
945
- }
946
- if (sm.ig) {
947
- result.metadata.socialMedia.instagram = sm.ig;
948
- }
949
- if (sm.li) {
950
- result.metadata.socialMedia.linkedin = sm.li;
951
- }
952
- if (sm.md) {
953
- result.metadata.socialMedia.medium = sm.md;
954
- }
955
- if (sm.rd) {
956
- result.metadata.socialMedia.reddit = sm.rd;
957
- }
958
- if (sm.yt) {
959
- result.metadata.socialMedia.youtube = sm.yt;
960
- }
961
- if (sm.bb) {
962
- result.metadata.socialMedia.bitbucket = sm.bb;
963
- }
1016
+ result.metadata.socialMedia = this.parseSocialMedia(t.sm);
964
1017
  }
965
1018
  }
966
1019
  if (bc) {