Repository: econia-labs/emojicoin-dot-fun
Pull request #707: feat(ECO-3050): Add candlestick support to TS SDK
Author: login: CRBl69
Created: 2025-03-16T23:47:08Z | Merged: 2025-03-18T21:20:48Z

<!-- markdownlint-disable-file MD025 -->

# Description

This PR adds the newly added candlestick to the TS SDK.

# Checklist

- [x] Did you check all checkboxes from the linked Linear task? (Ignore if you
  are not a member of Econia Labs)



Diff:
diff --git a/src/docker/compose.yaml b/src/docker/compose.yaml
index 445e56fc7..d1392ed7a 100644
--- a/src/docker/compose.yaml
+++ b/src/docker/compose.yaml
@@ -83,7 +83,7 @@ services:
     depends_on:
       postgres:
         condition: 'service_healthy'
-    image: 'econialabs/emojicoin-dot-fun-indexer-processor:6.0.1'
+    image: 'econialabs/emojicoin-dot-fun-indexer-processor:7.0.0-rc.3'
     container_name: 'processor'
     healthcheck:
       test: 'curl -sf http://localhost:${PROCESSOR_WS_PORT} || exit 1'
diff --git a/src/rust/processor b/src/rust/processor
index 13e89804d..152e1d15a 160000
--- a/src/rust/processor
+++ b/src/rust/processor
@@ -1 +1 @@
-Subproject commit 13e89804dbf5959ebce8a30e187057b4d1063af2
+Subproject commit 152e1d15afa617a12c8738d11f88ccb7d8699799
diff --git a/src/typescript/sdk/src/broker-v2/types.ts b/src/typescript/sdk/src/broker-v2/types.ts
index 91bef8c3a..483cc263a 100644
--- a/src/typescript/sdk/src/broker-v2/types.ts
+++ b/src/typescript/sdk/src/broker-v2/types.ts
@@ -10,7 +10,7 @@ import {
   TableName,
 } from "../indexer-v2/types/json-types";
 import { type ARENA_CANDLESTICK_NAME } from "../types/arena-types";
-import { type AnyNumberString } from "../types/types";
+import { type CANDLESTICK_NAME, type AnyNumberString } from "../types/types";
 
 export type BrokerEvent = SubscribableBrokerEvents | BrokerArenaEvent;
 
@@ -21,7 +21,8 @@ export type SubscribableBrokerEvents =
   | "MarketLatestState"
   | "GlobalState"
   | "PeriodicState"
-  | "MarketRegistration";
+  | "MarketRegistration"
+  | typeof CANDLESTICK_NAME;
 
 export type BrokerArenaEvent =
   | "ArenaEnter"
@@ -38,6 +39,7 @@ const MarketLatestState = TableName.MarketLatestStateEvent;
 const GlobalState = TableName.GlobalStateEvents;
 const PeriodicState = TableName.PeriodicStateEvents;
 const MarketRegistration = TableName.MarketRegistrationEvents;
+const Candlestick = TableName.Candlesticks;
 const ArenaEnter = TableName.ArenaEnterEvents;
 const ArenaExit = TableName.ArenaExitEvents;
 const ArenaMelee = TableName.ArenaMeleeEvents;
@@ -51,6 +53,7 @@ type MarketLatestStateType = DatabaseJsonType[typeof MarketLatestState];
 type GlobalStateType = DatabaseJsonType[typeof GlobalState];
 type PeriodicStateType = DatabaseJsonType[typeof PeriodicState];
 type MarketRegistrationType = DatabaseJsonType[typeof MarketRegistration];
+type CandlestickType = DatabaseJsonType[typeof Candlestick];
 type ArenaEnterType = DatabaseJsonType[typeof ArenaEnter];
 type ArenaExitType = DatabaseJsonType[typeof ArenaExit];
 type ArenaMeleeType = DatabaseJsonType[typeof ArenaMelee];
@@ -66,6 +69,7 @@ export const brokerMessageConverter: Record<BrokerEvent, (data: unknown) => Brok
   GlobalState: (d) => DatabaseTypeConverter[GlobalState](d as GlobalStateType),
   PeriodicState: (d) => DatabaseTypeConverter[PeriodicState](d as PeriodicStateType),
   MarketRegistration: (d) => DatabaseTypeConverter[MarketRegistration](d as MarketRegistrationType),
+  Candlestick: (d) => DatabaseTypeConverter[Candlestick](d as CandlestickType),
   ArenaEnter: (d) => DatabaseTypeConverter[ArenaEnter](d as ArenaEnterType),
   ArenaExit: (d) => DatabaseTypeConverter[ArenaExit](d as ArenaExitType),
   ArenaMelee: (d) => DatabaseTypeConverter[ArenaMelee](d as ArenaMeleeType),
diff --git a/src/typescript/sdk/src/indexer-v2/types/index.ts b/src/typescript/sdk/src/indexer-v2/types/index.ts
index 8e9941868..a3dcabf1f 100644
--- a/src/typescript/sdk/src/indexer-v2/types/index.ts
+++ b/src/typescript/sdk/src/indexer-v2/types/index.ts
@@ -1,6 +1,7 @@
 import { type Uint64String, type AccountAddressString } from "../../emojicoin_dot_fun";
 import {
   type AnyNumberString,
+  CANDLESTICK_NAME,
   EVENT_NAMES,
   type Flatten,
   toCumulativeStats,
@@ -498,6 +499,7 @@ export type Market1MPeriodsInLastDayModel = ReturnType<typeof toMarket1MPeriodsI
 export type MarketStateModel = ReturnType<typeof toMarketStateModel>;
 export type ProcessorStatusModel = ReturnType<typeof toProcessorStatus>;
 export type PriceFeedModel = ReturnType<typeof toPriceFeed>;
+export type CandlestickModel = ReturnType<typeof toCandlestickModel>;
 export type ArenaMeleeModel = ReturnType<typeof toArenaMeleeModel>;
 export type ArenaEnterModel = ReturnType<typeof toArenaEnterModel>;
 export type ArenaExitModel = ReturnType<typeof toArenaExitModel>;
@@ -644,6 +646,11 @@ export const GuidGetters = {
     eventName: EVENT_NAMES.State,
     guid: `${formatEmojis(data)}::${EVENT_NAMES.State}::${getMarketNonce(data)}` as const,
   }),
+  candlestick: ({ market_id, start_time, period }: DatabaseJsonType["candlesticks"]) => ({
+    // Not a real contract event, but used to classify the type of data.
+    eventName: CANDLESTICK_NAME,
+    guid: `${CANDLESTICK_NAME}::${market_id}::${period}::${start_time}`,
+  }),
   arenaEnterEvent: ({
     melee_id,
     transaction_version: version,
@@ -779,6 +786,21 @@ export const toMarketStateModel = (data: DatabaseJsonType["market_state"]) => ({
   dailyBaseVolume: BigInt(data.daily_base_volume),
 });
 
+const toCandlestickFromDatabase = (
+  data: DatabaseStructType["Candlestick"]
+): Types["Candlestick"] => ({
+  marketID: BigInt(data.market_id),
+  version: BigInt(data.last_transaction_version),
+  volume: BigInt(data.volume),
+  period: toArenaPeriod(data.period),
+  startTime: safeParseBigIntOrPostgresTimestamp(data.start_time),
+  openPrice: Number(data.open_price),
+  closePrice: Number(data.close_price),
+  highPrice: Number(data.high_price),
+  lowPrice: Number(data.low_price),
+  symbolEmojis: data.symbol_emojis,
+});
+
 export const toTransactionMetadataForUserLiquidityPools = (
   transaction: TransactionMetadata
 ): Omit<TransactionMetadata, "sender" | "entryFunction"> => ({
@@ -922,6 +944,11 @@ export const toPriceFeed = (data: DatabaseJsonType["price_feed"]) => ({
   ...toPriceFeedData(data),
 });
 
+export const toCandlestickModel = (data: DatabaseJsonType["candlesticks"]) => ({
+  ...toCandlestickFromDatabase(data),
+  ...GuidGetters.candlestick(data),
+});
+
 export const toAggregateMarketState = (data: DatabaseJsonType["aggregate_market_state"]) => ({
   lastEmojicoinTransactionVersion: BigInt(data.last_emojicoin_transaction_version),
   cumulativeChatMessages: BigInt(data.cumulative_chat_messages),
@@ -958,6 +985,7 @@ export const DatabaseTypeConverter = {
   [TableName.MarketState]: toMarketStateModel,
   [TableName.ProcessorStatus]: toProcessorStatus,
   [TableName.PriceFeed]: toPriceFeed,
+  [TableName.Candlesticks]: toCandlestickModel,
   [TableName.ArenaEnterEvents]: toArenaEnterModel,
   [TableName.ArenaMeleeEvents]: toArenaMeleeModel,
   [TableName.ArenaExitEvents]: toArenaExitModel,
@@ -987,6 +1015,7 @@ export type DatabaseModels = {
   [TableName.MarketState]: MarketStateModel;
   [TableName.ProcessorStatus]: ProcessorStatusModel;
   [TableName.PriceFeed]: PriceFeedModel;
+  [TableName.Candlesticks]: CandlestickModel;
   [TableName.ArenaMeleeEvents]: ArenaMeleeModel;
   [TableName.ArenaEnterEvents]: ArenaEnterModel;
   [TableName.ArenaExitEvents]: ArenaExitModel;
@@ -1019,6 +1048,7 @@ export type BrokerEventModels =
   | DatabaseModels[TableName.MarketLatestStateEvent]
   | DatabaseModels[TableName.LiquidityEvents]
   | DatabaseModels[TableName.GlobalStateEvents]
+  | DatabaseModels[TableName.Candlesticks]
   | DatabaseModels[TableName.ArenaEnterEvents]
   | DatabaseModels[TableName.ArenaMeleeEvents]
   | DatabaseModels[TableName.ArenaExitEvents]
diff --git a/src/typescript/sdk/src/indexer-v2/types/json-types.ts b/src/typescript/sdk/src/indexer-v2/types/json-types.ts
index 4c70a3271..d221e1de5 100644
--- a/src/typescript/sdk/src/indexer-v2/types/json-types.ts
+++ b/src/typescript/sdk/src/indexer-v2/types/json-types.ts
@@ -265,6 +265,21 @@ type FlattenedExchangeRateWithEventIndex<T extends keyof JsonTypes> = Flatten<
     emojicoin_1_exchange_rate_quote: Uint64String;
   }
 >;
+type CandlestickData = {
+  market_id: Uint64String;
+  last_transaction_version: Uint64String;
+  period: PeriodTypeFromDatabase | PeriodTypeFromBroker;
+  start_time: PostgresTimestamp;
+
+  open_price: number;
+  close_price: number;
+  high_price: number;
+  low_price: number;
+
+  symbol_emojis: SymbolEmoji[];
+
+  volume: Uint64String;
+};
 
 type ArenaMeleeEventData = Flatten<
   Omit<JsonTypes["ArenaMeleeEvent"], "start_time"> & {
@@ -398,6 +413,7 @@ export type DatabaseStructType = {
   ChatEventData: ChatEventData;
   StateEventData: StateEventData;
   GlobalStateEventData: GlobalStateEventData;
+  Candlestick: CandlestickData;
   ArenaMelee: ArenaMeleeEventData;
   ArenaEnter: ArenaEnterEventData;
   ArenaExit: ArenaExitEventData;
@@ -439,6 +455,7 @@ export enum TableName {
   MarketState = "market_state",
   ProcessorStatus = "processor_status",
   PriceFeed = "price_feed",
+  Candlesticks = "candlesticks",
   ArenaMeleeEvents = "arena_melee_events",
   ArenaEnterEvents = "arena_enter_events",
   ArenaExitEvents = "arena_exit_events",
@@ -539,6 +556,7 @@ export type DatabaseJsonType = {
       close_price_q64: Uint64String;
     }
   >;
+  [TableName.Candlesticks]: CandlestickData;
   [TableName.ArenaMeleeEvents]: Flatten<TransactionMetadata & ArenaMeleeEventData>;
   [TableName.ArenaEnterEvents]: Flatten<TransactionMetadata & ArenaEnterEventData>;
   [TableName.ArenaExitEvents]: Flatten<TransactionMetadata & ArenaExitEventData>;
diff --git a/src/typescript/sdk/src/types/types.ts b/src/typescript/sdk/src/types/types.ts
index 239786ea1..24ebf324f 100644
--- a/src/typescript/sdk/src/types/types.ts
+++ b/src/typescript/sdk/src/types/types.ts
@@ -4,7 +4,12 @@ import { type AccountAddressString } from "../emojicoin_dot_fun/types";
 import type JsonTypes from "./json-types";
 import { fromAggregatorSnapshot } from "./core";
 import { standardizeAddress } from "../utils/account-address";
-import { type Trigger, type EMOJICOIN_DOT_FUN_MODULE_NAME, rawTriggerToEnum } from "../const";
+import {
+  type Trigger,
+  type EMOJICOIN_DOT_FUN_MODULE_NAME,
+  rawTriggerToEnum,
+  type ArenaPeriod,
+} from "../const";
 import {
   type AnyEmojicoinJSONEvent,
   isJSONChatEvent,
@@ -18,12 +23,15 @@ import {
 import { type STRUCT_STRINGS } from "../utils";
 import { type Flatten } from ".";
 import { type ArenaTypes } from "./arena-types";
+import { type SymbolEmoji } from "../emoji_data";
 
 export type AnyNumberString = number | string | bigint;
 const strToBigInt = (data: string): bigint => BigInt(data);
 
 export type EventName = (typeof EVENT_NAMES)[keyof typeof EVENT_NAMES];
 
+export const CANDLESTICK_NAME = "Candlestick";
+
 export const EVENT_NAMES = {
   GlobalState: "GlobalState",
   PeriodicState: "PeriodicState",
@@ -374,6 +382,19 @@ export type Types = ArenaTypes & {
     swap: Types["SwapEvent"];
     octasRewardAmount: bigint;
   };
+
+  Candlestick: {
+    marketID: bigint;
+    version: bigint;
+    period: ArenaPeriod;
+    startTime: Date;
+    openPrice: number;
+    closePrice: number;
+    highPrice: number;
+    lowPrice: number;
+    volume: bigint;
+    symbolEmojis: SymbolEmoji[];
+  };
 };
 
 export const toExtendRef = (data: JsonTypes["ExtendRef"]): Types["ExtendRef"] => ({


Reviews:
user: login: xbtmatt
body: We should rename `ArenaPeriod` to `DatabasePeriod` to make it clear, otherwise it's kind of confusing why the normal candlesticks use an `ArenaPeriod`, other than that this is pretty straightforward, looks good

Bunch of suggestions, entirely just to rename
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-17T19:12:31Z
user: login: xbtmatt
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T19:36:24Z
user: login: xbtmatt
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T19:36:26Z
user: login: xbtmatt
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T19:36:32Z
user: login: xbtmatt
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T19:36:35Z
user: login: xbtmatt
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T19:36:40Z
user: login: xbtmatt
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T19:36:45Z
user: login: xbtmatt
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T19:37:40Z
user: login: xbtmatt
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T19:38:30Z
user: login: xbtmatt
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-03-18T21:14:07Z

Review comments:
diff_hunk: @@ -642,6 +643,11 @@ export const GuidGetters = {
     eventName: EVENT_NAMES.State,
     guid: `${formatEmojis(data)}::${EVENT_NAMES.State}::${getMarketNonce(data)}` as const,
   }),
+  candlestick: ({ market_id, start_time, period }: DatabaseJsonType["normal_candlesticks"]) => ({
+    // Not a real contract event, but used to classify the type of data.
+    eventName: ARENA_CANDLESTICK_NAME,
+    guid: `${ARENA_CANDLESTICK_NAME}::${market_id}::${period}::${start_time}`,
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: ```suggestion
    eventName: NORMAL_CANDLESTICK_NAME,
    guid: `${NORMAL_CANDLESTICK_NAME}::${market_id}::${period}::${start_time}`,
```

these `guid`s are just to avoid duplicate insertions in the global state, but if they conflict (arena with normal ones) it might lead to some weird issues if a melee id ever matches a market id
created_at: 2025-03-17T19:03:08Z
author_association: CONTRIBUTOR
diff_hunk: @@ -21,7 +21,8 @@ export type SubscribableBrokerEvents =
   | "MarketLatestState"
   | "GlobalState"
   | "PeriodicState"
-  | "MarketRegistration";
+  | "MarketRegistration"
+  | "Candlestick";
path: src/typescript/sdk/src/broker-v2/types.ts
user: login: xbtmatt
body: ```suggestion
  | typeof NORMAL_CANDLESTICK_NAME;
```

And just define it in guidgetters (down below) as `NORMAL_CANDLESTICK_NAME = "NormalCandlestick"`
created_at: 2025-03-17T19:06:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -920,6 +941,11 @@ export const toPriceFeed = (data: DatabaseJsonType["price_feed"]) => ({
   ...toPriceFeedData(data),
 });
 
+export const toCandlestickModel = (data: DatabaseJsonType["normal_candlesticks"]) => ({
+  ...toCandlestickFromDatabase(data),
+  ...GuidGetters.candlestick(data),
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: ```suggestion
  ...GuidGetters.normalCandlestick(data),
```
created_at: 2025-03-17T19:08:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -373,6 +379,19 @@ export type Types = ArenaTypes & {
     swap: Types["SwapEvent"];
     octasRewardAmount: bigint;
   };
+
+  Candlestick: {
path: src/typescript/sdk/src/types/types.ts
user: login: xbtmatt
body: ```suggestion
  NormalCandlestick: {
```
created_at: 2025-03-17T19:10:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -538,6 +555,7 @@ export type DatabaseJsonType = {
       close_price_q64: Uint64String;
     }
   >;
+  [TableName.Candlesticks]: CandlestickData;
path: src/typescript/sdk/src/indexer-v2/types/json-types.ts
user: login: xbtmatt
body: ```suggestion
  [TableName.NormalCandlesticks]: NormalCandlestickData;
```
created_at: 2025-03-17T19:10:19Z
author_association: CONTRIBUTOR
diff_hunk: @@ -397,6 +412,7 @@ export type DatabaseStructType = {
   ChatEventData: ChatEventData;
   StateEventData: StateEventData;
   GlobalStateEventData: GlobalStateEventData;
+  Candlestick: CandlestickData;
path: src/typescript/sdk/src/indexer-v2/types/json-types.ts
user: login: xbtmatt
body: ```suggestion
  NormalCandlestick: NormalCandlestickData;
```

just to keep things consistent
created_at: 2025-03-17T19:10:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1017,6 +1045,7 @@ export type BrokerEventModels =
   | DatabaseModels[TableName.MarketLatestStateEvent]
   | DatabaseModels[TableName.LiquidityEvents]
   | DatabaseModels[TableName.GlobalStateEvents]
+  | DatabaseModels[TableName.Candlesticks]
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: ```suggestion
  | DatabaseModels[TableName.NormalCandlesticks]
```
created_at: 2025-03-17T19:10:28Z
author_association: CONTRIBUTOR
diff_hunk: @@ -985,6 +1012,7 @@ export type DatabaseModels = {
   [TableName.MarketState]: MarketStateModel;
   [TableName.ProcessorStatus]: ProcessorStatusModel;
   [TableName.PriceFeed]: PriceFeedModel;
+  [TableName.Candlesticks]: CandlestickModel;
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: ```suggestion
  [TableName.NormalCandlesticks]: NormalCandlestickModel;
```
created_at: 2025-03-17T19:10:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -956,6 +982,7 @@ export const DatabaseTypeConverter = {
   [TableName.MarketState]: toMarketStateModel,
   [TableName.ProcessorStatus]: toProcessorStatus,
   [TableName.PriceFeed]: toPriceFeed,
+  [TableName.Candlesticks]: toCandlestickModel,
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: ```suggestion
  [TableName.NormalCandlesticks]: toNormalCandlestickModel,
```
created_at: 2025-03-17T19:10:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -920,6 +941,11 @@ export const toPriceFeed = (data: DatabaseJsonType["price_feed"]) => ({
   ...toPriceFeedData(data),
 });
 
+export const toCandlestickModel = (data: DatabaseJsonType["normal_candlesticks"]) => ({
+  ...toCandlestickFromDatabase(data),
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: ```suggestion
  ...toNormalCandlestickFromDatabase(data),
```
created_at: 2025-03-17T19:10:56Z
author_association: CONTRIBUTOR
diff_hunk: @@ -777,6 +783,21 @@ export const toMarketStateModel = (data: DatabaseJsonType["market_state"]) => ({
   dailyBaseVolume: BigInt(data.daily_base_volume),
 });
 
+const toCandlestickFromDatabase = (
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: ```suggestion
const toNormalCandlestickFromDatabase = (
```
created_at: 2025-03-17T19:11:02Z
author_association: CONTRIBUTOR
diff_hunk: @@ -642,6 +643,11 @@ export const GuidGetters = {
     eventName: EVENT_NAMES.State,
     guid: `${formatEmojis(data)}::${EVENT_NAMES.State}::${getMarketNonce(data)}` as const,
   }),
+  candlestick: ({ market_id, start_time, period }: DatabaseJsonType["normal_candlesticks"]) => ({
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: ```suggestion
  normalCandlestick: ({ market_id, start_time, period }: DatabaseJsonType["normal_candlesticks"]) => ({
```
created_at: 2025-03-17T19:11:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -496,6 +496,7 @@ export type Market1MPeriodsInLastDayModel = ReturnType<typeof toMarket1MPeriodsI
 export type MarketStateModel = ReturnType<typeof toMarketStateModel>;
 export type ProcessorStatusModel = ReturnType<typeof toProcessorStatus>;
 export type PriceFeedModel = ReturnType<typeof toPriceFeed>;
+export type CandlestickModel = ReturnType<typeof toCandlestickModel>;
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: ```suggestion
export type NormalCandlestickModel = ReturnType<typeof toNormalCandlestickModel>;
```
created_at: 2025-03-17T19:11:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -66,6 +69,7 @@ export const brokerMessageConverter: Record<BrokerEvent, (data: unknown) => Brok
   GlobalState: (d) => DatabaseTypeConverter[GlobalState](d as GlobalStateType),
   PeriodicState: (d) => DatabaseTypeConverter[PeriodicState](d as PeriodicStateType),
   MarketRegistration: (d) => DatabaseTypeConverter[MarketRegistration](d as MarketRegistrationType),
+  Candlestick: (d) => DatabaseTypeConverter[Candlestick](d as CandlestickType),
path: src/typescript/sdk/src/broker-v2/types.ts
user: login: xbtmatt
body: ```suggestion
  NormalCandlestick: (d) => DatabaseTypeConverter[NormalCandlestick](d as NormalCandlestickType),
```
created_at: 2025-03-17T19:11:30Z
author_association: CONTRIBUTOR
diff_hunk: @@ -51,6 +53,7 @@ type MarketLatestStateType = DatabaseJsonType[typeof MarketLatestState];
 type GlobalStateType = DatabaseJsonType[typeof GlobalState];
 type PeriodicStateType = DatabaseJsonType[typeof PeriodicState];
 type MarketRegistrationType = DatabaseJsonType[typeof MarketRegistration];
+type CandlestickType = DatabaseJsonType[typeof Candlestick];
path: src/typescript/sdk/src/broker-v2/types.ts
user: login: xbtmatt
body: ```suggestion
type NormalCandlestickType = DatabaseJsonType[typeof NormalCandlestick];
```
created_at: 2025-03-17T19:11:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -38,6 +39,7 @@ const MarketLatestState = TableName.MarketLatestStateEvent;
 const GlobalState = TableName.GlobalStateEvents;
 const PeriodicState = TableName.PeriodicStateEvents;
 const MarketRegistration = TableName.MarketRegistrationEvents;
+const Candlestick = TableName.Candlesticks;
path: src/typescript/sdk/src/broker-v2/types.ts
user: login: xbtmatt
body: ```suggestion
const NormalCandlestick = TableName.NormalCandlesticks;
```
created_at: 2025-03-17T19:11:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -38,6 +39,7 @@ const MarketLatestState = TableName.MarketLatestStateEvent;
 const GlobalState = TableName.GlobalStateEvents;
 const PeriodicState = TableName.PeriodicStateEvents;
 const MarketRegistration = TableName.MarketRegistrationEvents;
+const Candlestick = TableName.Candlesticks;
path: src/typescript/sdk/src/broker-v2/types.ts
user: login: xbtmatt
body: Resolving bc we are using `candlesticks` as the table name now
created_at: 2025-03-18T19:36:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -51,6 +53,7 @@ type MarketLatestStateType = DatabaseJsonType[typeof MarketLatestState];
 type GlobalStateType = DatabaseJsonType[typeof GlobalState];
 type PeriodicStateType = DatabaseJsonType[typeof PeriodicState];
 type MarketRegistrationType = DatabaseJsonType[typeof MarketRegistration];
+type CandlestickType = DatabaseJsonType[typeof Candlestick];
path: src/typescript/sdk/src/broker-v2/types.ts
user: login: xbtmatt
body: Resolving bc we are using `candlesticks` as the table name now
created_at: 2025-03-18T19:36:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -66,6 +69,7 @@ export const brokerMessageConverter: Record<BrokerEvent, (data: unknown) => Brok
   GlobalState: (d) => DatabaseTypeConverter[GlobalState](d as GlobalStateType),
   PeriodicState: (d) => DatabaseTypeConverter[PeriodicState](d as PeriodicStateType),
   MarketRegistration: (d) => DatabaseTypeConverter[MarketRegistration](d as MarketRegistrationType),
+  Candlestick: (d) => DatabaseTypeConverter[Candlestick](d as CandlestickType),
path: src/typescript/sdk/src/broker-v2/types.ts
user: login: xbtmatt
body: Resolving bc we are using `candlesticks` as the table name now
created_at: 2025-03-18T19:36:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -496,6 +496,7 @@ export type Market1MPeriodsInLastDayModel = ReturnType<typeof toMarket1MPeriodsI
 export type MarketStateModel = ReturnType<typeof toMarketStateModel>;
 export type ProcessorStatusModel = ReturnType<typeof toProcessorStatus>;
 export type PriceFeedModel = ReturnType<typeof toPriceFeed>;
+export type CandlestickModel = ReturnType<typeof toCandlestickModel>;
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: Resolving bc we are using `candlesticks` as the table name now
created_at: 2025-03-18T19:36:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -777,6 +783,21 @@ export const toMarketStateModel = (data: DatabaseJsonType["market_state"]) => ({
   dailyBaseVolume: BigInt(data.daily_base_volume),
 });
 
+const toCandlestickFromDatabase = (
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: Resolving bc we are using `candlesticks` as the table name now
created_at: 2025-03-18T19:36:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -920,6 +941,11 @@ export const toPriceFeed = (data: DatabaseJsonType["price_feed"]) => ({
   ...toPriceFeedData(data),
 });
 
+export const toCandlestickModel = (data: DatabaseJsonType["normal_candlesticks"]) => ({
+  ...toCandlestickFromDatabase(data),
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: Resolving bc we are using `candlesticks` as the table name now
created_at: 2025-03-18T19:36:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -920,6 +941,11 @@ export const toPriceFeed = (data: DatabaseJsonType["price_feed"]) => ({
   ...toPriceFeedData(data),
 });
 
+export const toCandlestickModel = (data: DatabaseJsonType["normal_candlesticks"]) => ({
+  ...toCandlestickFromDatabase(data),
+  ...GuidGetters.candlestick(data),
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: Resolving bc we are using `candlesticks` as the table name now
created_at: 2025-03-18T19:36:52Z
author_association: CONTRIBUTOR
diff_hunk: @@ -956,6 +982,7 @@ export const DatabaseTypeConverter = {
   [TableName.MarketState]: toMarketStateModel,
   [TableName.ProcessorStatus]: toProcessorStatus,
   [TableName.PriceFeed]: toPriceFeed,
+  [TableName.Candlesticks]: toCandlestickModel,
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: Resolving bc we are using `candlesticks` as the table name now
created_at: 2025-03-18T19:36:55Z
author_association: CONTRIBUTOR
diff_hunk: @@ -985,6 +1012,7 @@ export type DatabaseModels = {
   [TableName.MarketState]: MarketStateModel;
   [TableName.ProcessorStatus]: ProcessorStatusModel;
   [TableName.PriceFeed]: PriceFeedModel;
+  [TableName.Candlesticks]: CandlestickModel;
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: Resolving bc we are using `candlesticks` as the table name now
created_at: 2025-03-18T19:36:58Z
author_association: CONTRIBUTOR
diff_hunk: @@ -1017,6 +1045,7 @@ export type BrokerEventModels =
   | DatabaseModels[TableName.MarketLatestStateEvent]
   | DatabaseModels[TableName.LiquidityEvents]
   | DatabaseModels[TableName.GlobalStateEvents]
+  | DatabaseModels[TableName.Candlesticks]
path: src/typescript/sdk/src/indexer-v2/types/index.ts
user: login: xbtmatt
body: Resolving bc we are using `candlesticks` as the table name now
created_at: 2025-03-18T19:37:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -397,6 +412,7 @@ export type DatabaseStructType = {
   ChatEventData: ChatEventData;
   StateEventData: StateEventData;
   GlobalStateEventData: GlobalStateEventData;
+  Candlestick: CandlestickData;
path: src/typescript/sdk/src/indexer-v2/types/json-types.ts
user: login: xbtmatt
body: Resolving bc we are using `candlesticks` as the table name now
created_at: 2025-03-18T19:37:03Z
author_association: CONTRIBUTOR
diff_hunk: @@ -538,6 +555,7 @@ export type DatabaseJsonType = {
       close_price_q64: Uint64String;
     }
   >;
+  [TableName.Candlesticks]: CandlestickData;
path: src/typescript/sdk/src/indexer-v2/types/json-types.ts
user: login: xbtmatt
body: Resolving bc we are using `candlesticks` as the table name now
created_at: 2025-03-18T19:37:06Z
author_association: CONTRIBUTOR
diff_hunk: @@ -373,6 +379,19 @@ export type Types = ArenaTypes & {
     swap: Types["SwapEvent"];
     octasRewardAmount: bigint;
   };
+
+  Candlestick: {
path: src/typescript/sdk/src/types/types.ts
user: login: xbtmatt
body: Resolving bc we are using `candlesticks` as the table name now
created_at: 2025-03-18T19:37:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -18,12 +23,15 @@ import {
 import { type STRUCT_STRINGS } from "../utils";
 import { type Flatten } from ".";
 import { type ArenaTypes } from "./arena-types";
+import { SymbolEmoji } from "../emoji_data";
path: src/typescript/sdk/src/types/types.ts
user: login: xbtmatt
body: ```suggestion
import { type SymbolEmoji } from "../emoji_data";
```
created_at: 2025-03-18T19:37:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -10,7 +10,7 @@ import {
   TableName,
 } from "../indexer-v2/types/json-types";
 import { type ARENA_CANDLESTICK_NAME } from "../types/arena-types";
-import { type AnyNumberString } from "../types/types";
+import { CANDLESTICK_NAME, type AnyNumberString } from "../types/types";
path: src/typescript/sdk/src/broker-v2/types.ts
user: login: xbtmatt
body: ```suggestion
import { type CANDLESTICK_NAME, type AnyNumberString } from "../types/types";
```
created_at: 2025-03-18T19:38:29Z
author_association: CONTRIBUTOR

PR comments:
user: login: vercel[bot]
created_at: 2025-03-16T23:47:12Z
body: [vc]: #P/Tk4QQojCS69OWu8asxHoos0bm0wiefO7th88JqYmU=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJlbW9qaWNvaW4tZG90LWZ1biIsInJvb3REaXJlY3RvcnkiOiJzcmMvdHlwZXNjcmlwdC9mcm9udGVuZCIsImluc3BlY3RvclVybCI6Imh0dHBzOi8vdmVyY2VsLmNvbS9lY29uaWEtbGFicy9lbW9qaWNvaW4tZG90LWZ1bi83SzhpWERDdmNIeFhTYnZhcnE3eEh6NU5yeWRHIiwicHJldmlld1VybCI6ImVtb2ppY29pbi1kb3QtZnVuLWdpdC1lY28tMzA1MC1lY29uaWEtbGFicy52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IkRFUExPWUVEIiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6ImVtb2ppY29pbi1kb3QtZnVuLWdpdC1lY28tMzA1MC1lY29uaWEtbGFicy52ZXJjZWwuYXBwIn19LHsibmFtZSI6ImVtb2ppY29pbi1kb3QtZnVuLWRvY3MiLCJyb290RGlyZWN0b3J5IjoiZG9jL2RvYy1zaXRlIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL2Vjb25pYS1sYWJzL2Vtb2ppY29pbi1kb3QtZnVuLWRvY3MvRDZwWXhOZFRXcVNWVjQ5dzZlQ1VQSG03ZEZxbyIsInByZXZpZXdVcmwiOiJlbW9qaWNvaW4tZG90LWZ1bi1kb2NzLWdpdC1lY28tMzA1MC1lY29uaWEtbGFicy52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IkRFUExPWUVEIiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6ImVtb2ppY29pbi1kb3QtZnVuLWRvY3MtZ2l0LWVjby0zMDUwLWVjb25pYS1sYWJzLnZlcmNlbC5hcHAifX1dfQ==
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **emojicoin-dot-fun** | ✅ Ready ([Inspect](https://vercel.com/econia-labs/emojicoin-dot-fun/7K8iXDCvcHxXSbvarq7xHz5NrydG)) | [Visit Preview](https://emojicoin-dot-fun-git-eco-3050-econia-labs.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/emojicoin-dot-fun-git-eco-3050-econia-labs.vercel.app?via=pr-comment-feedback-link) | Mar 18, 2025 8:23pm |
| **emojicoin-dot-fun-docs** | ✅ Ready ([Inspect](https://vercel.com/econia-labs/emojicoin-dot-fun-docs/D6pYxNdTWqSVV49w6eCUPHm7dFqo)) | [Visit Preview](https://emojicoin-dot-fun-docs-git-eco-3050-econia-labs.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/emojicoin-dot-fun-docs-git-eco-3050-econia-labs.vercel.app?via=pr-comment-feedback-link) | Mar 18, 2025 8:23pm |



author_association: NONE
user: login: CRBl69
created_at: 2025-03-18T13:36:32Z
body: I changed the names from `normal_candlesticks` to `candlesticks` in the DB. I think it's cleaner that way. MB for doing that in the first place
author_association: CONTRIBUTOR