diff --git a/lib/client/indexer/__generated__/schema.graphql b/lib/client/indexer/__generated__/schema.graphql index 846ee25..81c0063 100644 --- a/lib/client/indexer/__generated__/schema.graphql +++ b/lib/client/indexer/__generated__/schema.graphql @@ -3989,9 +3989,15 @@ type markets { """An object relationship""" token: tokens! + """An object relationship""" + tokenAcctByAsksTokenAcct: token_accts + """An object relationship""" tokenAcctByBidsTokenAcct: token_accts + """An object relationship""" + tokenByBaseMintAcct: tokens + """An object relationship""" tokenByQuoteMintAcct: tokens! @@ -4163,7 +4169,9 @@ input markets_bool_exp { takes: takes_bool_exp takes_aggregate: takes_aggregate_bool_exp token: tokens_bool_exp + tokenAcctByAsksTokenAcct: token_accts_bool_exp tokenAcctByBidsTokenAcct: token_accts_bool_exp + tokenByBaseMintAcct: tokens_bool_exp tokenByQuoteMintAcct: tokens_bool_exp token_acct: token_accts_bool_exp twaps: twaps_bool_exp @@ -4224,7 +4232,9 @@ input markets_insert_input { quote_tick_size: bigint takes: takes_arr_rel_insert_input token: tokens_obj_rel_insert_input + tokenAcctByAsksTokenAcct: token_accts_obj_rel_insert_input tokenAcctByBidsTokenAcct: token_accts_obj_rel_insert_input + tokenByBaseMintAcct: tokens_obj_rel_insert_input tokenByQuoteMintAcct: tokens_obj_rel_insert_input token_acct: token_accts_obj_rel_insert_input twaps: twaps_arr_rel_insert_input @@ -4379,7 +4389,9 @@ input markets_order_by { quote_tick_size: order_by takes_aggregate: takes_aggregate_order_by token: tokens_order_by + tokenAcctByAsksTokenAcct: token_accts_order_by tokenAcctByBidsTokenAcct: token_accts_order_by + tokenByBaseMintAcct: tokens_order_by tokenByQuoteMintAcct: tokens_order_by token_acct: token_accts_order_by twaps_aggregate: twaps_aggregate_order_by @@ -15334,6 +15346,9 @@ type transactions { """filter the rows returned""" where: indexer_account_dependencies_bool_exp ): indexer_account_dependencies_aggregate! + + """An object relationship""" + order: orders payload: String! serializer_logic_version: smallint! slot: bigint! @@ -15490,6 +15505,7 @@ input transactions_bool_exp { failed: Boolean_comparison_exp indexer_account_dependencies: indexer_account_dependencies_bool_exp indexer_account_dependencies_aggregate: indexer_account_dependencies_aggregate_bool_exp + order: orders_bool_exp payload: String_comparison_exp serializer_logic_version: smallint_comparison_exp slot: bigint_comparison_exp @@ -15527,6 +15543,7 @@ input transactions_insert_input { block_time: timestamp failed: Boolean indexer_account_dependencies: indexer_account_dependencies_arr_rel_insert_input + order: orders_obj_rel_insert_input payload: String serializer_logic_version: smallint slot: bigint @@ -15589,6 +15606,7 @@ input transactions_order_by { block_time: order_by failed: order_by indexer_account_dependencies_aggregate: indexer_account_dependencies_aggregate_order_by + order: orders_order_by payload: order_by serializer_logic_version: order_by slot: order_by diff --git a/lib/client/indexer/__generated__/schema.ts b/lib/client/indexer/__generated__/schema.ts index 075ef7b..5eb2f6d 100644 --- a/lib/client/indexer/__generated__/schema.ts +++ b/lib/client/indexer/__generated__/schema.ts @@ -1245,8 +1245,12 @@ export interface markets { /** An object relationship */ token: tokens /** An object relationship */ + tokenAcctByAsksTokenAcct: (token_accts | null) + /** An object relationship */ tokenAcctByBidsTokenAcct: (token_accts | null) /** An object relationship */ + tokenByBaseMintAcct: (tokens | null) + /** An object relationship */ tokenByQuoteMintAcct: tokens /** An object relationship */ token_acct: (token_accts | null) @@ -4249,6 +4253,8 @@ export interface transactions { indexer_account_dependencies: indexer_account_dependencies[] /** An aggregate relationship */ indexer_account_dependencies_aggregate: indexer_account_dependencies_aggregate + /** An object relationship */ + order: (orders | null) payload: Scalars['String'] serializer_logic_version: Scalars['smallint'] slot: Scalars['bigint'] @@ -6906,8 +6912,12 @@ export interface marketsGenqlSelection{ /** An object relationship */ token?: tokensGenqlSelection /** An object relationship */ + tokenAcctByAsksTokenAcct?: token_acctsGenqlSelection + /** An object relationship */ tokenAcctByBidsTokenAcct?: token_acctsGenqlSelection /** An object relationship */ + tokenByBaseMintAcct?: tokensGenqlSelection + /** An object relationship */ tokenByQuoteMintAcct?: tokensGenqlSelection /** An object relationship */ token_acct?: token_acctsGenqlSelection @@ -7002,7 +7012,7 @@ export interface markets_avg_order_by {active_slot?: (order_by | null),base_lot_ /** Boolean expression to filter rows from the table "markets". All fields are combined with a logical 'AND'. */ -export interface markets_bool_exp {_and?: (markets_bool_exp[] | null),_not?: (markets_bool_exp | null),_or?: (markets_bool_exp[] | null),active_slot?: (bigint_comparison_exp | null),asks_token_acct?: (String_comparison_exp | null),base_lot_size?: (bigint_comparison_exp | null),base_maker_fee?: (smallint_comparison_exp | null),base_mint_acct?: (String_comparison_exp | null),base_taker_fee?: (smallint_comparison_exp | null),bids_token_acct?: (String_comparison_exp | null),candles?: (candles_bool_exp | null),candles_aggregate?: (candles_aggregate_bool_exp | null),create_tx_sig?: (String_comparison_exp | null),created_at?: (timestamp_comparison_exp | null),inactive_slot?: (bigint_comparison_exp | null),makes?: (makes_bool_exp | null),makes_aggregate?: (makes_aggregate_bool_exp | null),market_acct?: (String_comparison_exp | null),market_type?: (String_comparison_exp | null),orders?: (orders_bool_exp | null),orders_aggregate?: (orders_aggregate_bool_exp | null),prices?: (prices_bool_exp | null),prices_aggregate?: (prices_aggregate_bool_exp | null),proposal?: (proposals_bool_exp | null),proposal_acct?: (String_comparison_exp | null),quote_lot_size?: (bigint_comparison_exp | null),quote_maker_fee?: (smallint_comparison_exp | null),quote_mint_acct?: (String_comparison_exp | null),quote_taker_fee?: (smallint_comparison_exp | null),quote_tick_size?: (bigint_comparison_exp | null),takes?: (takes_bool_exp | null),takes_aggregate?: (takes_aggregate_bool_exp | null),token?: (tokens_bool_exp | null),tokenAcctByBidsTokenAcct?: (token_accts_bool_exp | null),tokenByQuoteMintAcct?: (tokens_bool_exp | null),token_acct?: (token_accts_bool_exp | null),twaps?: (twaps_bool_exp | null),twaps_aggregate?: (twaps_aggregate_bool_exp | null)} +export interface markets_bool_exp {_and?: (markets_bool_exp[] | null),_not?: (markets_bool_exp | null),_or?: (markets_bool_exp[] | null),active_slot?: (bigint_comparison_exp | null),asks_token_acct?: (String_comparison_exp | null),base_lot_size?: (bigint_comparison_exp | null),base_maker_fee?: (smallint_comparison_exp | null),base_mint_acct?: (String_comparison_exp | null),base_taker_fee?: (smallint_comparison_exp | null),bids_token_acct?: (String_comparison_exp | null),candles?: (candles_bool_exp | null),candles_aggregate?: (candles_aggregate_bool_exp | null),create_tx_sig?: (String_comparison_exp | null),created_at?: (timestamp_comparison_exp | null),inactive_slot?: (bigint_comparison_exp | null),makes?: (makes_bool_exp | null),makes_aggregate?: (makes_aggregate_bool_exp | null),market_acct?: (String_comparison_exp | null),market_type?: (String_comparison_exp | null),orders?: (orders_bool_exp | null),orders_aggregate?: (orders_aggregate_bool_exp | null),prices?: (prices_bool_exp | null),prices_aggregate?: (prices_aggregate_bool_exp | null),proposal?: (proposals_bool_exp | null),proposal_acct?: (String_comparison_exp | null),quote_lot_size?: (bigint_comparison_exp | null),quote_maker_fee?: (smallint_comparison_exp | null),quote_mint_acct?: (String_comparison_exp | null),quote_taker_fee?: (smallint_comparison_exp | null),quote_tick_size?: (bigint_comparison_exp | null),takes?: (takes_bool_exp | null),takes_aggregate?: (takes_aggregate_bool_exp | null),token?: (tokens_bool_exp | null),tokenAcctByAsksTokenAcct?: (token_accts_bool_exp | null),tokenAcctByBidsTokenAcct?: (token_accts_bool_exp | null),tokenByBaseMintAcct?: (tokens_bool_exp | null),tokenByQuoteMintAcct?: (tokens_bool_exp | null),token_acct?: (token_accts_bool_exp | null),twaps?: (twaps_bool_exp | null),twaps_aggregate?: (twaps_aggregate_bool_exp | null)} /** input type for incrementing numeric columns in table "markets" */ @@ -7010,7 +7020,7 @@ export interface markets_inc_input {active_slot?: (Scalars['bigint'] | null),bas /** input type for inserting data into table "markets" */ -export interface markets_insert_input {active_slot?: (Scalars['bigint'] | null),asks_token_acct?: (Scalars['String'] | null),base_lot_size?: (Scalars['bigint'] | null),base_maker_fee?: (Scalars['smallint'] | null),base_mint_acct?: (Scalars['String'] | null),base_taker_fee?: (Scalars['smallint'] | null),bids_token_acct?: (Scalars['String'] | null),candles?: (candles_arr_rel_insert_input | null),create_tx_sig?: (Scalars['String'] | null),created_at?: (Scalars['timestamp'] | null),inactive_slot?: (Scalars['bigint'] | null),makes?: (makes_arr_rel_insert_input | null),market_acct?: (Scalars['String'] | null),market_type?: (Scalars['String'] | null),orders?: (orders_arr_rel_insert_input | null),prices?: (prices_arr_rel_insert_input | null),proposal?: (proposals_obj_rel_insert_input | null),proposal_acct?: (Scalars['String'] | null),quote_lot_size?: (Scalars['bigint'] | null),quote_maker_fee?: (Scalars['smallint'] | null),quote_mint_acct?: (Scalars['String'] | null),quote_taker_fee?: (Scalars['smallint'] | null),quote_tick_size?: (Scalars['bigint'] | null),takes?: (takes_arr_rel_insert_input | null),token?: (tokens_obj_rel_insert_input | null),tokenAcctByBidsTokenAcct?: (token_accts_obj_rel_insert_input | null),tokenByQuoteMintAcct?: (tokens_obj_rel_insert_input | null),token_acct?: (token_accts_obj_rel_insert_input | null),twaps?: (twaps_arr_rel_insert_input | null)} +export interface markets_insert_input {active_slot?: (Scalars['bigint'] | null),asks_token_acct?: (Scalars['String'] | null),base_lot_size?: (Scalars['bigint'] | null),base_maker_fee?: (Scalars['smallint'] | null),base_mint_acct?: (Scalars['String'] | null),base_taker_fee?: (Scalars['smallint'] | null),bids_token_acct?: (Scalars['String'] | null),candles?: (candles_arr_rel_insert_input | null),create_tx_sig?: (Scalars['String'] | null),created_at?: (Scalars['timestamp'] | null),inactive_slot?: (Scalars['bigint'] | null),makes?: (makes_arr_rel_insert_input | null),market_acct?: (Scalars['String'] | null),market_type?: (Scalars['String'] | null),orders?: (orders_arr_rel_insert_input | null),prices?: (prices_arr_rel_insert_input | null),proposal?: (proposals_obj_rel_insert_input | null),proposal_acct?: (Scalars['String'] | null),quote_lot_size?: (Scalars['bigint'] | null),quote_maker_fee?: (Scalars['smallint'] | null),quote_mint_acct?: (Scalars['String'] | null),quote_taker_fee?: (Scalars['smallint'] | null),quote_tick_size?: (Scalars['bigint'] | null),takes?: (takes_arr_rel_insert_input | null),token?: (tokens_obj_rel_insert_input | null),tokenAcctByAsksTokenAcct?: (token_accts_obj_rel_insert_input | null),tokenAcctByBidsTokenAcct?: (token_accts_obj_rel_insert_input | null),tokenByBaseMintAcct?: (tokens_obj_rel_insert_input | null),tokenByQuoteMintAcct?: (tokens_obj_rel_insert_input | null),token_acct?: (token_accts_obj_rel_insert_input | null),twaps?: (twaps_arr_rel_insert_input | null)} /** aggregate max on columns */ @@ -7093,7 +7103,7 @@ export interface markets_on_conflict {constraint: markets_constraint,update_colu /** Ordering options when selecting data from "markets". */ -export interface markets_order_by {active_slot?: (order_by | null),asks_token_acct?: (order_by | null),base_lot_size?: (order_by | null),base_maker_fee?: (order_by | null),base_mint_acct?: (order_by | null),base_taker_fee?: (order_by | null),bids_token_acct?: (order_by | null),candles_aggregate?: (candles_aggregate_order_by | null),create_tx_sig?: (order_by | null),created_at?: (order_by | null),inactive_slot?: (order_by | null),makes_aggregate?: (makes_aggregate_order_by | null),market_acct?: (order_by | null),market_type?: (order_by | null),orders_aggregate?: (orders_aggregate_order_by | null),prices_aggregate?: (prices_aggregate_order_by | null),proposal?: (proposals_order_by | null),proposal_acct?: (order_by | null),quote_lot_size?: (order_by | null),quote_maker_fee?: (order_by | null),quote_mint_acct?: (order_by | null),quote_taker_fee?: (order_by | null),quote_tick_size?: (order_by | null),takes_aggregate?: (takes_aggregate_order_by | null),token?: (tokens_order_by | null),tokenAcctByBidsTokenAcct?: (token_accts_order_by | null),tokenByQuoteMintAcct?: (tokens_order_by | null),token_acct?: (token_accts_order_by | null),twaps_aggregate?: (twaps_aggregate_order_by | null)} +export interface markets_order_by {active_slot?: (order_by | null),asks_token_acct?: (order_by | null),base_lot_size?: (order_by | null),base_maker_fee?: (order_by | null),base_mint_acct?: (order_by | null),base_taker_fee?: (order_by | null),bids_token_acct?: (order_by | null),candles_aggregate?: (candles_aggregate_order_by | null),create_tx_sig?: (order_by | null),created_at?: (order_by | null),inactive_slot?: (order_by | null),makes_aggregate?: (makes_aggregate_order_by | null),market_acct?: (order_by | null),market_type?: (order_by | null),orders_aggregate?: (orders_aggregate_order_by | null),prices_aggregate?: (prices_aggregate_order_by | null),proposal?: (proposals_order_by | null),proposal_acct?: (order_by | null),quote_lot_size?: (order_by | null),quote_maker_fee?: (order_by | null),quote_mint_acct?: (order_by | null),quote_taker_fee?: (order_by | null),quote_tick_size?: (order_by | null),takes_aggregate?: (takes_aggregate_order_by | null),token?: (tokens_order_by | null),tokenAcctByAsksTokenAcct?: (token_accts_order_by | null),tokenAcctByBidsTokenAcct?: (token_accts_order_by | null),tokenByBaseMintAcct?: (tokens_order_by | null),tokenByQuoteMintAcct?: (tokens_order_by | null),token_acct?: (token_accts_order_by | null),twaps_aggregate?: (twaps_aggregate_order_by | null)} /** primary key columns input for table: markets */ @@ -13295,6 +13305,8 @@ export interface transactionsGenqlSelection{ order_by?: (indexer_account_dependencies_order_by[] | null), /** filter the rows returned */ where?: (indexer_account_dependencies_bool_exp | null)} }) + /** An object relationship */ + order?: ordersGenqlSelection payload?: boolean | number serializer_logic_version?: boolean | number slot?: boolean | number @@ -13413,7 +13425,7 @@ export interface transactions_avg_fieldsGenqlSelection{ /** Boolean expression to filter rows from the table "transactions". All fields are combined with a logical 'AND'. */ -export interface transactions_bool_exp {_and?: (transactions_bool_exp[] | null),_not?: (transactions_bool_exp | null),_or?: (transactions_bool_exp[] | null),block_time?: (timestamp_comparison_exp | null),failed?: (Boolean_comparison_exp | null),indexer_account_dependencies?: (indexer_account_dependencies_bool_exp | null),indexer_account_dependencies_aggregate?: (indexer_account_dependencies_aggregate_bool_exp | null),payload?: (String_comparison_exp | null),serializer_logic_version?: (smallint_comparison_exp | null),slot?: (bigint_comparison_exp | null),transactionWatchersByLatestTxSig?: (transaction_watchers_bool_exp | null),transactionWatchersByLatestTxSig_aggregate?: (transaction_watchers_aggregate_bool_exp | null),transaction_watcher_transactions?: (transaction_watcher_transactions_bool_exp | null),transaction_watcher_transactions_aggregate?: (transaction_watcher_transactions_aggregate_bool_exp | null),transaction_watchers?: (transaction_watchers_bool_exp | null),transaction_watchers_aggregate?: (transaction_watchers_aggregate_bool_exp | null),tx_sig?: (String_comparison_exp | null)} +export interface transactions_bool_exp {_and?: (transactions_bool_exp[] | null),_not?: (transactions_bool_exp | null),_or?: (transactions_bool_exp[] | null),block_time?: (timestamp_comparison_exp | null),failed?: (Boolean_comparison_exp | null),indexer_account_dependencies?: (indexer_account_dependencies_bool_exp | null),indexer_account_dependencies_aggregate?: (indexer_account_dependencies_aggregate_bool_exp | null),order?: (orders_bool_exp | null),payload?: (String_comparison_exp | null),serializer_logic_version?: (smallint_comparison_exp | null),slot?: (bigint_comparison_exp | null),transactionWatchersByLatestTxSig?: (transaction_watchers_bool_exp | null),transactionWatchersByLatestTxSig_aggregate?: (transaction_watchers_aggregate_bool_exp | null),transaction_watcher_transactions?: (transaction_watcher_transactions_bool_exp | null),transaction_watcher_transactions_aggregate?: (transaction_watcher_transactions_aggregate_bool_exp | null),transaction_watchers?: (transaction_watchers_bool_exp | null),transaction_watchers_aggregate?: (transaction_watchers_aggregate_bool_exp | null),tx_sig?: (String_comparison_exp | null)} /** input type for incrementing numeric columns in table "transactions" */ @@ -13421,7 +13433,7 @@ export interface transactions_inc_input {serializer_logic_version?: (Scalars['sm /** input type for inserting data into table "transactions" */ -export interface transactions_insert_input {block_time?: (Scalars['timestamp'] | null),failed?: (Scalars['Boolean'] | null),indexer_account_dependencies?: (indexer_account_dependencies_arr_rel_insert_input | null),payload?: (Scalars['String'] | null),serializer_logic_version?: (Scalars['smallint'] | null),slot?: (Scalars['bigint'] | null),transactionWatchersByLatestTxSig?: (transaction_watchers_arr_rel_insert_input | null),transaction_watcher_transactions?: (transaction_watcher_transactions_arr_rel_insert_input | null),transaction_watchers?: (transaction_watchers_arr_rel_insert_input | null),tx_sig?: (Scalars['String'] | null)} +export interface transactions_insert_input {block_time?: (Scalars['timestamp'] | null),failed?: (Scalars['Boolean'] | null),indexer_account_dependencies?: (indexer_account_dependencies_arr_rel_insert_input | null),order?: (orders_obj_rel_insert_input | null),payload?: (Scalars['String'] | null),serializer_logic_version?: (Scalars['smallint'] | null),slot?: (Scalars['bigint'] | null),transactionWatchersByLatestTxSig?: (transaction_watchers_arr_rel_insert_input | null),transaction_watcher_transactions?: (transaction_watcher_transactions_arr_rel_insert_input | null),transaction_watchers?: (transaction_watchers_arr_rel_insert_input | null),tx_sig?: (Scalars['String'] | null)} /** aggregate max on columns */ @@ -13470,7 +13482,7 @@ export interface transactions_on_conflict {constraint: transactions_constraint,u /** Ordering options when selecting data from "transactions". */ -export interface transactions_order_by {block_time?: (order_by | null),failed?: (order_by | null),indexer_account_dependencies_aggregate?: (indexer_account_dependencies_aggregate_order_by | null),payload?: (order_by | null),serializer_logic_version?: (order_by | null),slot?: (order_by | null),transactionWatchersByLatestTxSig_aggregate?: (transaction_watchers_aggregate_order_by | null),transaction_watcher_transactions_aggregate?: (transaction_watcher_transactions_aggregate_order_by | null),transaction_watchers_aggregate?: (transaction_watchers_aggregate_order_by | null),tx_sig?: (order_by | null)} +export interface transactions_order_by {block_time?: (order_by | null),failed?: (order_by | null),indexer_account_dependencies_aggregate?: (indexer_account_dependencies_aggregate_order_by | null),order?: (orders_order_by | null),payload?: (order_by | null),serializer_logic_version?: (order_by | null),slot?: (order_by | null),transactionWatchersByLatestTxSig_aggregate?: (transaction_watchers_aggregate_order_by | null),transaction_watcher_transactions_aggregate?: (transaction_watcher_transactions_aggregate_order_by | null),transaction_watchers_aggregate?: (transaction_watchers_aggregate_order_by | null),tx_sig?: (order_by | null)} /** primary key columns input for table: transactions */ diff --git a/lib/client/indexer/__generated__/types.ts b/lib/client/indexer/__generated__/types.ts index 4ad448d..9a7e9f5 100644 --- a/lib/client/indexer/__generated__/types.ts +++ b/lib/client/indexer/__generated__/types.ts @@ -6191,9 +6191,15 @@ export default { "token": [ 750 ], + "tokenAcctByAsksTokenAcct": [ + 708 + ], "tokenAcctByBidsTokenAcct": [ 708 ], + "tokenByBaseMintAcct": [ + 750 + ], "tokenByQuoteMintAcct": [ 750 ], @@ -6544,9 +6550,15 @@ export default { "token": [ 754 ], + "tokenAcctByAsksTokenAcct": [ + 717 + ], "tokenAcctByBidsTokenAcct": [ 717 ], + "tokenByBaseMintAcct": [ + 754 + ], "tokenByQuoteMintAcct": [ 754 ], @@ -6672,9 +6684,15 @@ export default { "token": [ 761 ], + "tokenAcctByAsksTokenAcct": [ + 726 + ], "tokenAcctByBidsTokenAcct": [ 726 ], + "tokenByBaseMintAcct": [ + 761 + ], "tokenByQuoteMintAcct": [ 761 ], @@ -7036,9 +7054,15 @@ export default { "token": [ 763 ], + "tokenAcctByAsksTokenAcct": [ + 728 + ], "tokenAcctByBidsTokenAcct": [ 728 ], + "tokenByBaseMintAcct": [ + 763 + ], "tokenByQuoteMintAcct": [ 763 ], @@ -17873,6 +17897,9 @@ export default { ] } ], + "order": [ + 341 + ], "payload": [ 5 ], @@ -18112,6 +18139,9 @@ export default { "indexer_account_dependencies_aggregate": [ 197 ], + "order": [ + 352 + ], "payload": [ 6 ], @@ -18168,6 +18198,9 @@ export default { "indexer_account_dependencies": [ 201 ], + "order": [ + 361 + ], "payload": [ 5 ], @@ -18279,6 +18312,9 @@ export default { "indexer_account_dependencies_aggregate": [ 200 ], + "order": [ + 363 + ], "payload": [ 340 ], diff --git a/lib/client/indexer/markets.ts b/lib/client/indexer/markets.ts index d79627c..ce156ee 100644 --- a/lib/client/indexer/markets.ts +++ b/lib/client/indexer/markets.ts @@ -22,6 +22,8 @@ import { } from "./__generated__"; import { Client as GQLWebSocketClient } from "graphql-ws"; import { FutarchyMarketsRPCClient } from "../rpc/markets"; +import { PriceMath } from "@metadaoproject/futarchy-ts"; +import { BN } from "@coral-xyz/anchor"; export class FutarchyIndexerMarketsClient implements FutarchyMarketsClient { public openbook: FutarchyIndexerOpenbookMarketsClient; @@ -66,9 +68,18 @@ export class FutarchyIndexerMarketsClient implements FutarchyMarketsClient { { created_at: "asc" } - ] + ], + distinct_on: ["created_at"] }, token_amount: true, + market: { + tokenByQuoteMintAcct: { + decimals: true + }, + tokenByBaseMintAcct: { + decimals: true + } + }, updated_slot: true, created_at: true } @@ -80,6 +91,15 @@ export class FutarchyIndexerMarketsClient implements FutarchyMarketsClient { token_amount: number; updated_slot: number; created_at: Date; + // TODO this query might be a bit slow... hasura warned about caching directive, we need to watch for this + market: { + tokenByQuoteMintAcct: { + decimals: number; + }; + tokenByBaseMintAcct: { + decimals: number; + }; + }; }[]; }>( { query, variables }, @@ -87,7 +107,12 @@ export class FutarchyIndexerMarketsClient implements FutarchyMarketsClient { next: (data) => { const twapObservations = data.data?.twaps?.map( (d) => ({ - price: d.token_amount, + priceUi: PriceMath.getHumanPrice( + new BN(d.token_amount), + d.market?.tokenByBaseMintAcct.decimals!!, + d.market?.tokenByQuoteMintAcct.decimals!! + ), + priceRaw: d.token_amount, slot: d.updated_slot, createdAt: d.created_at }) @@ -281,29 +306,52 @@ export class FutarchyIndexerMarketsClient implements FutarchyMarketsClient { }, order_by: [ { - created_at: "desc" + created_at: "asc" } - ] + ], + distinct_on: ["created_at"] }, created_at: true, - price: true + price: true, + quote_amount: true, + base_amount: true, + market: { + tokenByQuoteMintAcct: { + decimals: true + }, + tokenByBaseMintAcct: { + decimals: true + } + } } }); return new Observable((subscriber) => { const subscriptionCleanup = this.graphqlWSClient.subscribe<{ - takes: { + prices: { created_at: Date; price: number; + quote_amount: number; + base_amount: number; + market: { + tokenByQuoteMintAcct: { + decimals: number; + }; + tokenByBaseMintAcct: { + decimals: number; + }; + }; }[]; }>( { query, variables }, { next: (data) => { - const spotObservations = data.data?.takes?.map( + const spotObservations = data.data?.prices?.map( (d) => ({ - price: d.price, - createdAt: d.created_at + priceUi: d.price, + createdAt: d.created_at, + quoteAmount: d.quote_amount, + baseAmount: d.base_amount }) ); subscriber.next(spotObservations ?? []); diff --git a/lib/client/indexer/proposals.ts b/lib/client/indexer/proposals.ts index a4ef218..69e47dc 100644 --- a/lib/client/indexer/proposals.ts +++ b/lib/client/indexer/proposals.ts @@ -46,10 +46,18 @@ export class FutarchyIndexerProposalsClient implements FutarchyProposalsClient { dao_acct: true, treasury_acct: true, tokenByBaseAcct: { - mint_acct: true + mint_acct: true, + image_url: true, + decimals: true, + symbol: true, + name: true }, tokenByQuoteAcct: { - mint_acct: true + mint_acct: true, + image_url: true, + decimals: true, + symbol: true, + name: true }, program: { program_acct: true, @@ -247,6 +255,20 @@ export class FutarchyIndexerProposalsClient implements FutarchyProposalsClient { tokenMint: d.tokenByBaseAcct ? new PublicKey(d.tokenByBaseAcct.mint_acct) : undefined + }, + baseToken: { + decimals: d.tokenByBaseAcct?.decimals ?? 0, + name: d.tokenByBaseAcct?.name ?? "", + symbol: d.tokenByBaseAcct?.symbol ?? "", + url: d.tokenByBaseAcct?.image_url ?? "", + publicKey: d.tokenByBaseAcct?.mint_acct ?? "" + }, + quoteToken: { + decimals: d.tokenByQuoteAcct?.decimals ?? 0, + name: d.tokenByQuoteAcct?.name ?? "", + symbol: d.tokenByQuoteAcct?.symbol ?? "", + url: d.tokenByQuoteAcct?.image_url ?? "", + publicKey: d.tokenByQuoteAcct?.mint_acct ?? "" } }, participants: [], diff --git a/lib/client/rpc/balances.ts b/lib/client/rpc/balances.ts index db9797c..e714164 100644 --- a/lib/client/rpc/balances.ts +++ b/lib/client/rpc/balances.ts @@ -1,6 +1,6 @@ import { AccountLayout, - getAssociatedTokenAddressSync, + getAssociatedTokenAddressSync } from "@solana/spl-token"; import { Dao, @@ -9,7 +9,7 @@ import { TokenProps, TokenWithBalance, TokenWithBalancePDAAndProposal, - TokenWithPDA, + TokenWithPDA } from "@/types"; import { FutarchyBalancesClient } from "@/client"; import { PublicKey } from "@solana/web3.js"; @@ -27,13 +27,13 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient { //TODO create a more general function for fetching balances on an array of token mints async fetchMainTokenWalletBalances( daoAggregate: DaoAggregate, - ownerWallet: PublicKey, + ownerWallet: PublicKey ): Promise { if (ownerWallet) { //dedupe mints const tokensByMint = this.getDaoAggregateMainTokensByMint( daoAggregate, - ownerWallet, + ownerWallet ); return ( @@ -44,25 +44,25 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient { try { const tokenBalance = await this.rpcProvider.connection.getTokenAccountBalance( - t.pda, + t.pda ); return { balance: tokenBalance.value.uiAmount ?? 0, - token: t.token, + token: t.token }; } catch (e) { if (!JSON.stringify(e).includes("not found")) { console.info( "error fetching wallet balance for token:", - t.token.symbol, + t.token.symbol ); } return { balance: 0, - token: t.token, + token: t.token }; } - }), + }) ) ).filter((b): b is TokenWithBalance => !!b); } @@ -71,13 +71,13 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient { watchMainTokenWalletBalances( daoAggregate: DaoAggregate, - ownerWallet: PublicKey, + ownerWallet: PublicKey ): Observable[] { if (ownerWallet) { //dedupe mints const tokensByMint = this.getDaoAggregateMainTokensByMint( daoAggregate, - ownerWallet, + ownerWallet ); return Array.from(tokensByMint.values()) .filter((t): t is TokenWithPDA => !!t.pda) @@ -90,7 +90,7 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient { public getDaoAggregateMainTokensByMint( daoAggregate: DaoAggregate, - owner: PublicKey | null, + owner: PublicKey | null ): Map & { pda: PublicKey | null }> { return daoAggregate.daos.reduce((mapping, dao) => { if (!dao.baseToken.publicKey || !dao.quoteToken.publicKey) return mapping; @@ -100,10 +100,10 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient { ? getAssociatedTokenAddressSync( new PublicKey(dao.baseToken.publicKey), owner, - true, + true ) : null, - token: dao.baseToken, + token: dao.baseToken }); } if (!mapping.get(dao.quoteToken.publicKey)) { @@ -112,10 +112,10 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient { ? getAssociatedTokenAddressSync( new PublicKey(dao.quoteToken.publicKey), owner, - true, + true ) : null, - token: dao.quoteToken, + token: dao.quoteToken }); } @@ -124,18 +124,16 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient { } public watchTokenBalance( - tokenWithPDA: TokenWithPDA, + tokenWithPDA: TokenWithPDA ): Observable { - console.log("fetching pda", tokenWithPDA.pda.toBase58()); return new Observable((subscriber) => { // yield initial fetch - console.log("fetching pda inside observer", tokenWithPDA.pda.toBase58()); this.rpcProvider.connection .getTokenAccountBalance(tokenWithPDA.pda) .then((tokenBalance) => { subscriber.next({ balance: tokenBalance.value.uiAmount ?? 0, - token: tokenWithPDA.token, + token: tokenWithPDA.token }); }) .catch((e) => { @@ -152,10 +150,10 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient { new BN(10).pow(new BN(tokenWithPDA.token.decimals)); const tokenVal: TokenWithBalance = { balance: dividedTokenAmount, - token: tokenWithPDA.token, + token: tokenWithPDA.token }; subscriber.next(tokenVal); - }, + } ); return () => subscriber.complete(); @@ -173,7 +171,7 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient { ownerWallet: PublicKey, baseToken: TokenProps, quoteToken: TokenProps, - proposals: Proposal[], + proposals: Proposal[] ): Promise { const tokenBalances = await Promise.all( proposals.map(async (proposal) => { @@ -183,67 +181,67 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient { { pda: getAssociatedTokenAddressSync( new PublicKey( - proposal.baseVaultAccount.conditionalOnFinalizeTokenMint, + proposal.baseVaultAccount.conditionalOnFinalizeTokenMint ), ownerWallet, - true, + true ), token: { ...baseToken, publicKey: proposal.baseVaultAccount.conditionalOnFinalizeTokenMint.toString(), - symbol: "p" + baseToken.symbol, + symbol: "p" + baseToken.symbol } as TokenProps, - proposal: proposal.publicKey, + proposal: proposal.publicKey }, { pda: getAssociatedTokenAddressSync( new PublicKey( - proposal.baseVaultAccount.conditionalOnRevertTokenMint, + proposal.baseVaultAccount.conditionalOnRevertTokenMint ), ownerWallet, - true, + true ), token: { ...baseToken, publicKey: proposal.baseVaultAccount.conditionalOnRevertTokenMint.toString(), - symbol: "f" + baseToken.symbol, + symbol: "f" + baseToken.symbol } as TokenProps, - proposal: proposal.publicKey, + proposal: proposal.publicKey }, { pda: getAssociatedTokenAddressSync( new PublicKey( - proposal.quoteVaultAccount.conditionalOnFinalizeTokenMint, + proposal.quoteVaultAccount.conditionalOnFinalizeTokenMint ), ownerWallet, - true, + true ), token: { ...quoteToken, publicKey: proposal.quoteVaultAccount.conditionalOnFinalizeTokenMint.toString(), - symbol: "p" + quoteToken.symbol, + symbol: "p" + quoteToken.symbol } as TokenProps, - proposal: proposal.publicKey, + proposal: proposal.publicKey }, { pda: getAssociatedTokenAddressSync( new PublicKey( - proposal.quoteVaultAccount.conditionalOnRevertTokenMint, + proposal.quoteVaultAccount.conditionalOnRevertTokenMint ), ownerWallet, - true, + true ), token: { ...quoteToken, publicKey: proposal.quoteVaultAccount.conditionalOnRevertTokenMint.toString(), - symbol: "f" + quoteToken.symbol, + symbol: "f" + quoteToken.symbol } as TokenProps, - proposal: proposal.publicKey, - }, + proposal: proposal.publicKey + } ]; const tokensBalances = await Promise.all( @@ -251,36 +249,36 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient { try { const tokenBalance = await this.rpcProvider.connection.getTokenAccountBalance( - t.pda, + t.pda ); return { balance: tokenBalance.value.uiAmount ?? 0, token: t.token, proposal: t.proposal, - pda: t.pda, + pda: t.pda }; } catch (e) { if (!JSON.stringify(e).includes("could not find account")) { console.info( "error fetching wallet balance for token:", - t.token.symbol, + t.token.symbol ); } return { balance: 0, token: t.token, proposal: t.proposal, - pda: t.pda, + pda: t.pda }; } - }), + }) ); return tokensBalances.filter( - (b): b is TokenWithBalancePDAAndProposal => !!b, + (b): b is TokenWithBalancePDAAndProposal => !!b ); } - }), + }) ); return tokenBalances .filter((tb): tb is TokenWithBalancePDAAndProposal[] => !!tb) @@ -291,7 +289,7 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient { proposals: Proposal[], owner: PublicKey | null, quoteToken: TokenProps, - baseToken: TokenProps, + baseToken: TokenProps ): Array { if (!owner) return []; @@ -303,67 +301,67 @@ export class FutarchyRPCBalancesClient implements FutarchyBalancesClient { { pda: getAssociatedTokenAddressSync( new PublicKey( - proposal.baseVaultAccount.conditionalOnFinalizeTokenMint, + proposal.baseVaultAccount.conditionalOnFinalizeTokenMint ), owner, - true, + true ), token: { ...baseToken, publicKey: proposal.baseVaultAccount.conditionalOnFinalizeTokenMint.toString(), - symbol: "p" + baseToken.symbol, + symbol: "p" + baseToken.symbol } as TokenProps, - proposal: proposal.publicKey, + proposal: proposal.publicKey }, { pda: getAssociatedTokenAddressSync( new PublicKey( - proposal.baseVaultAccount.conditionalOnRevertTokenMint, + proposal.baseVaultAccount.conditionalOnRevertTokenMint ), owner, - true, + true ), token: { ...baseToken, publicKey: proposal.baseVaultAccount.conditionalOnRevertTokenMint.toString(), - symbol: "f" + baseToken.symbol, + symbol: "f" + baseToken.symbol } as TokenProps, - proposal: proposal.publicKey, + proposal: proposal.publicKey }, { pda: getAssociatedTokenAddressSync( new PublicKey( - proposal.quoteVaultAccount.conditionalOnFinalizeTokenMint, + proposal.quoteVaultAccount.conditionalOnFinalizeTokenMint ), owner, - true, + true ), token: { ...quoteToken, publicKey: proposal.quoteVaultAccount.conditionalOnFinalizeTokenMint.toString(), - symbol: "p" + quoteToken.symbol, + symbol: "p" + quoteToken.symbol } as TokenProps, - proposal: proposal.publicKey, + proposal: proposal.publicKey }, { pda: getAssociatedTokenAddressSync( new PublicKey( - proposal.quoteVaultAccount.conditionalOnRevertTokenMint, + proposal.quoteVaultAccount.conditionalOnRevertTokenMint ), owner, - true, + true ), token: { ...quoteToken, publicKey: proposal.quoteVaultAccount.conditionalOnRevertTokenMint.toString(), - symbol: "f" + quoteToken.symbol, + symbol: "f" + quoteToken.symbol } as TokenProps, - proposal: proposal.publicKey, - }, + proposal: proposal.publicKey + } ]; } }) diff --git a/lib/client/rpc/markets.ts b/lib/client/rpc/markets.ts index 43615ad..7dfb168 100644 --- a/lib/client/rpc/markets.ts +++ b/lib/client/rpc/markets.ts @@ -84,15 +84,17 @@ export class FutarchyMarketsRPCClient implements FutarchyMarketsClient { this.amm .fetchMarket(new AmmMarketFetchRequest(marketKey)) .then((market) => { + const twapPrice = market?.twapAggregator.div( + market.twapLastUpdatedSlot.sub(market.createdAtSlot) + ); subscriber.next([ { - price: PriceMath.getHumanPrice( - market?.twapAggregator.div( - market.twapLastUpdatedSlot.sub(market.createdAtSlot) - ), + priceUi: PriceMath.getHumanPrice( + twapPrice, market?.baseToken.decimals!!, market?.quoteToken.decimals!! ), + priceRaw: twapPrice.toNumber(), createdAt: new Date(), slot: 0 } @@ -109,16 +111,18 @@ export class FutarchyMarketsRPCClient implements FutarchyMarketsClient { this.amm .fetchMarket(new AmmMarketFetchRequest(marketKey)) .then((market) => { + const ammPrice = PriceMath.getAmmPriceFromReserves( + market?.baseAmount, + market?.quoteAmount + ); subscriber.next([ { - price: PriceMath.getHumanPrice( - PriceMath.getAmmPriceFromReserves( - market?.baseAmount, - market?.quoteAmount - ), + priceUi: PriceMath.getHumanPrice( + ammPrice, market?.baseToken.decimals!!, market?.quoteToken.decimals!! ), + priceRaw: ammPrice.toNumber(), createdAt: new Date() } ]); diff --git a/lib/client/rpc/proposals/finalizeProposal.ts b/lib/client/rpc/proposals/finalizeProposal.ts index a20c511..bd3eb8c 100644 --- a/lib/client/rpc/proposals/finalizeProposal.ts +++ b/lib/client/rpc/proposals/finalizeProposal.ts @@ -1,192 +1,238 @@ import { FinalizeProposal, FutarchyProposalsClient } from "@/client"; -import { AUTOCRAT_VERSIONS, autocratVersionToConditionalVaultMap } from "@/constants"; +import { + AUTOCRAT_VERSIONS, + autocratVersionToConditionalVaultMap +} from "@/constants"; import { Proposal } from "@/types"; import { AnchorProvider, Program } from "@coral-xyz/anchor"; import { PublicKey } from "@metaplex-foundation/js"; -import { AutocratV0 as AutocratV0_2, IDL as AutocratV0_2_IDL } from "@/idl/autocrat_v0.2"; -import { ConditionalVault, } from "@/idl/conditional_vault_v0.2"; +import { + AutocratV0 as AutocratV0_2, + IDL as AutocratV0_2_IDL +} from "@/idl/autocrat_v0.2"; +import { ConditionalVault } from "@/idl/conditional_vault_v0.2"; import { TransactionSender } from "@/transactions"; -import { AutocratClient, getAmmAddr, getAmmLpMintAddr, getDaoTreasuryAddr, getVaultAddr, getVaultFinalizeMintAddr, getVaultRevertMintAddr } from "@metadaoproject/futarchy-ts"; +import { + AutocratClient, + getAmmAddr, + getAmmLpMintAddr, + getDaoTreasuryAddr, + getVaultAddr, + getVaultFinalizeMintAddr, + getVaultRevertMintAddr +} from "@metadaoproject/futarchy-ts"; import { getAssociatedTokenAddressSync } from "@solana/spl-token"; export class FinalizeProposalClient implements FinalizeProposal { - private proposalsClient: FutarchyProposalsClient; - private rpcProvider: AnchorProvider; - private transactionSender: TransactionSender | undefined; - private autocratClient: AutocratClient - - constructor(proposalsClient: FutarchyProposalsClient, rpcProvider: AnchorProvider, autocratClient: AutocratClient, transactionSender: TransactionSender | undefined) { - this.proposalsClient = proposalsClient; - this.autocratClient = autocratClient; - this.rpcProvider = rpcProvider; - this.transactionSender= transactionSender; - } - - private async finalizeProposalv02( proposal: Proposal) { - const autocratProgramId = AUTOCRAT_VERSIONS.find((a) => a.label == "V0.2")?.programId - if(!autocratProgramId) return - const autocrat = new Program(AutocratV0_2_IDL, autocratProgramId, this.rpcProvider) - - // @ts-ignore - const proposalAccount = await autocrat.account.proposal.fetch(proposal.publicKey) - - console.log(proposalAccount, proposalAccount.dao) - //@ts-ignore - const dao = await autocrat.account.dao.fetch(proposal.dao.publicKey) - - const daoTreasury = dao.treasury - - const vault = autocratVersionToConditionalVaultMap["V0.2"] - const vaultProgram = new Program(vault.idl as ConditionalVault, vault.programId, this.rpcProvider) - - // @ts-ignore - const storedProposal = await autocrat.account.proposal.fetch(proposal.publicKey); - const expirySlot = storedProposal.slotEnqueued.toNumber() + 1_080_000; // TODO: This may be different - const current_slot = 0; - if (expirySlot < current_slot) { - throw new Error('Unable to process request, the time period has not passed'); - } - - const accounts = storedProposal.instruction.accounts - const program = storedProposal.instruction.programId - - try { - accounts[2].isSigner = false - } catch (e) { - console.error('Error:', e) - } - - const _program = { - pubkey: program, - isSigner: false, - isWritable: false, - } - - accounts.push(_program) - - let tx = await autocrat.methods - .finalizeProposal() - .accounts({ - proposal: proposal.publicKey, - openbookTwapPassMarket: storedProposal.openbookTwapPassMarket, - openbookTwapFailMarket: storedProposal.openbookTwapFailMarket, - dao: proposal.dao.publicKey, - baseVault: storedProposal.baseVault, - quoteVault: storedProposal.quoteVault, - vaultProgram: vaultProgram.programId, - daoTreasury, - }) - .remainingAccounts(accounts) - .transaction() - - return await this.transactionSender?.send([tx], this.rpcProvider.connection) + private proposalsClient: FutarchyProposalsClient; + private rpcProvider: AnchorProvider; + private transactionSender: TransactionSender | undefined; + private autocratClient: AutocratClient; + + constructor( + proposalsClient: FutarchyProposalsClient, + rpcProvider: AnchorProvider, + autocratClient: AutocratClient, + transactionSender: TransactionSender | undefined + ) { + this.proposalsClient = proposalsClient; + this.autocratClient = autocratClient; + this.rpcProvider = rpcProvider; + this.transactionSender = transactionSender; + } + + private async finalizeProposalv02(proposal: Proposal) { + const autocratProgramId = AUTOCRAT_VERSIONS.find( + (a) => a.label == "V0.2" + )?.programId; + if (!autocratProgramId) return; + const autocrat = new Program( + AutocratV0_2_IDL, + autocratProgramId, + this.rpcProvider + ); + + // @ts-ignore + const proposalAccount = await autocrat.account.proposal.fetch( + proposal.publicKey + ); + + //@ts-ignore + const dao = await autocrat.account.dao.fetch(proposal.dao.publicKey); + + const daoTreasury = dao.treasury; + + const vault = autocratVersionToConditionalVaultMap["V0.2"]; + const vaultProgram = new Program( + vault.idl as ConditionalVault, + vault.programId, + this.rpcProvider + ); + + // @ts-ignore + const storedProposal = await autocrat.account.proposal.fetch( + proposal.publicKey + ); + const expirySlot = storedProposal.slotEnqueued.toNumber() + 1_080_000; // TODO: This may be different + const current_slot = 0; + if (expirySlot < current_slot) { + throw new Error( + "Unable to process request, the time period has not passed" + ); } + const accounts = storedProposal.instruction.accounts; + const program = storedProposal.instruction.programId; - private async finalizeProposalIx( - proposal: PublicKey, - instruction: any, - dao: PublicKey, - daoToken: PublicKey, - usdc: PublicKey, - proposer: PublicKey - ) { - let vaultProgramId = this.autocratClient.vaultClient.vaultProgram.programId; - - const [daoTreasury] = getDaoTreasuryAddr(this.autocratClient.autocrat.programId, dao); - const [baseVault] = getVaultAddr( - this.autocratClient.vaultClient.vaultProgram.programId, - daoTreasury, - daoToken, - proposal - ); - const [quoteVault] = getVaultAddr( - this.autocratClient.vaultClient.vaultProgram.programId, - daoTreasury, - usdc, - proposal - ); - - const [passBase] = getVaultFinalizeMintAddr(vaultProgramId, baseVault); - const [passQuote] = getVaultFinalizeMintAddr(vaultProgramId, quoteVault); - - const [failBase] = getVaultRevertMintAddr(vaultProgramId, baseVault); - const [failQuote] = getVaultRevertMintAddr(vaultProgramId, quoteVault); - - const [passAmm] = getAmmAddr( - this.autocratClient.ammClient.program.programId, - passBase, - passQuote, - proposal - ); - const [failAmm] = getAmmAddr( - this.autocratClient.ammClient.program.programId, - failBase, - failQuote, - proposal - ); - - const [passLp] = getAmmLpMintAddr( - this.autocratClient.ammClient.program.programId, - passAmm - ); - const [failLp] = getAmmLpMintAddr( - this.autocratClient.ammClient.program.programId, - failAmm - ); - - return this.autocratClient.autocrat.methods.finalizeProposal().accounts({ - proposal, - passAmm, - failAmm, - dao, - baseVault, - quoteVault, - passLpUserAccount: getAssociatedTokenAddressSync( - passLp, - proposer - ), - failLpUserAccount: getAssociatedTokenAddressSync( - failLp, - proposer - ), - passLpVaultAccount: getAssociatedTokenAddressSync( - passLp, - daoTreasury, - true - ), - failLpVaultAccount: getAssociatedTokenAddressSync( - failLp, - daoTreasury, - true - ), - vaultProgram: this.autocratClient.vaultClient.vaultProgram.programId, - treasury: daoTreasury, - }); - } - - //CURRENT VERSION - private async finalizeProposalv1(proposal: Proposal){ - try{ - const proposalAccount = await this.autocratClient.getProposal(proposal.publicKey) - const dao = await this.autocratClient.getDao(proposalAccount.dao) - const finalizeProposalTx = await (await this.finalizeProposalIx(proposal.publicKey, proposalAccount.instruction, proposalAccount.dao, dao.tokenMint, dao.usdcMint, proposalAccount.proposer)).transaction() - - return await this.transactionSender?.send([finalizeProposalTx], this.rpcProvider.connection) - }catch(e){ - console.log("error", e) - } + try { + accounts[2].isSigner = false; + } catch (e) { + console.error("Error:", e); } - public async finalizeProposal(proposal:Proposal) { - switch (proposal.protocol.deploymentVersion) { - case "V0.2": - return await this.finalizeProposalv02(proposal) - case "V1": - return await this.finalizeProposalv1(proposal) - default: - throw Error("Version incompatible") - } - + const _program = { + pubkey: program, + isSigner: false, + isWritable: false + }; + + accounts.push(_program); + + let tx = await autocrat.methods + .finalizeProposal() + .accounts({ + proposal: proposal.publicKey, + openbookTwapPassMarket: storedProposal.openbookTwapPassMarket, + openbookTwapFailMarket: storedProposal.openbookTwapFailMarket, + dao: proposal.dao.publicKey, + baseVault: storedProposal.baseVault, + quoteVault: storedProposal.quoteVault, + vaultProgram: vaultProgram.programId, + daoTreasury + }) + .remainingAccounts(accounts) + .transaction(); + + return await this.transactionSender?.send( + [tx], + this.rpcProvider.connection + ); + } + + private async finalizeProposalIx( + proposal: PublicKey, + instruction: any, + dao: PublicKey, + daoToken: PublicKey, + usdc: PublicKey, + proposer: PublicKey + ) { + let vaultProgramId = this.autocratClient.vaultClient.vaultProgram.programId; + + const [daoTreasury] = getDaoTreasuryAddr( + this.autocratClient.autocrat.programId, + dao + ); + const [baseVault] = getVaultAddr( + this.autocratClient.vaultClient.vaultProgram.programId, + daoTreasury, + daoToken, + proposal + ); + const [quoteVault] = getVaultAddr( + this.autocratClient.vaultClient.vaultProgram.programId, + daoTreasury, + usdc, + proposal + ); + + const [passBase] = getVaultFinalizeMintAddr(vaultProgramId, baseVault); + const [passQuote] = getVaultFinalizeMintAddr(vaultProgramId, quoteVault); + + const [failBase] = getVaultRevertMintAddr(vaultProgramId, baseVault); + const [failQuote] = getVaultRevertMintAddr(vaultProgramId, quoteVault); + + const [passAmm] = getAmmAddr( + this.autocratClient.ammClient.program.programId, + passBase, + passQuote, + proposal + ); + const [failAmm] = getAmmAddr( + this.autocratClient.ammClient.program.programId, + failBase, + failQuote, + proposal + ); + + const [passLp] = getAmmLpMintAddr( + this.autocratClient.ammClient.program.programId, + passAmm + ); + const [failLp] = getAmmLpMintAddr( + this.autocratClient.ammClient.program.programId, + failAmm + ); + + return this.autocratClient.autocrat.methods.finalizeProposal().accounts({ + proposal, + passAmm, + failAmm, + dao, + baseVault, + quoteVault, + passLpUserAccount: getAssociatedTokenAddressSync(passLp, proposer), + failLpUserAccount: getAssociatedTokenAddressSync(failLp, proposer), + passLpVaultAccount: getAssociatedTokenAddressSync( + passLp, + daoTreasury, + true + ), + failLpVaultAccount: getAssociatedTokenAddressSync( + failLp, + daoTreasury, + true + ), + vaultProgram: this.autocratClient.vaultClient.vaultProgram.programId, + treasury: daoTreasury + }); + } + + //CURRENT VERSION + private async finalizeProposalv1(proposal: Proposal) { + try { + const proposalAccount = await this.autocratClient.getProposal( + proposal.publicKey + ); + const dao = await this.autocratClient.getDao(proposalAccount.dao); + const finalizeProposalTx = await ( + await this.finalizeProposalIx( + proposal.publicKey, + proposalAccount.instruction, + proposalAccount.dao, + dao.tokenMint, + dao.usdcMint, + proposalAccount.proposer + ) + ).transaction(); + + return await this.transactionSender?.send( + [finalizeProposalTx], + this.rpcProvider.connection + ); + } catch (e) { + console.log("error", e); + } + } + + public async finalizeProposal(proposal: Proposal) { + switch (proposal.protocol.deploymentVersion) { + case "V0.2": + return await this.finalizeProposalv02(proposal); + case "V1": + return await this.finalizeProposalv1(proposal); + default: + throw Error("Version incompatible"); } + } } diff --git a/lib/types/prices.ts b/lib/types/prices.ts index 922f987..92bf321 100644 --- a/lib/types/prices.ts +++ b/lib/types/prices.ts @@ -1,9 +1,17 @@ export type TwapObservation = { - price: number; + priceRaw?: number; + priceUi: number; slot: number; createdAt: Date; }; + +/** + * Quote and Base amounts generally available on market spot prices + */ export type SpotObservation = { - price: number; + priceRaw?: number; + priceUi: number; createdAt: Date; + quoteAmount?: number; + baseAmount?: number; }; diff --git a/lib/types/proposals.ts b/lib/types/proposals.ts index c921899..9566fb7 100644 --- a/lib/types/proposals.ts +++ b/lib/types/proposals.ts @@ -9,7 +9,7 @@ import { FutarchyProtocol, VaultAccountWithProtocol, Dao, - MarketType, + MarketType } from "@/types"; import { PublicKey } from "@metaplex-foundation/js"; import { TransactionInstruction } from "@solana/web3.js"; @@ -22,7 +22,10 @@ export type ProposalInstruction = MergeWithOptionalFields< > >; -export type ProposalInstructionWithPreinstructions = { preInstructions: (TransactionInstruction[] | undefined), instruction: ProposalInstruction } +export type ProposalInstructionWithPreinstructions = { + preInstructions: TransactionInstruction[] | undefined; + instruction: ProposalInstruction; +}; export type ProposalAccount = MergeWithOptionalFields< IdlAccounts["Proposal"], @@ -35,8 +38,6 @@ export type ProposalAccount = MergeWithOptionalFields< > >; - - export type ProposalAccountWithKey = AccountWithKey; export type ProposalAccountWithKeyNoState = AccountWithKey< @@ -50,7 +51,7 @@ export type ProposalState = "pending" | "passed" | "failed"; export type Proposal = ProposalAccountWithKeyNoState & { title: string; description: string; - dao: Pick; + dao: Pick; protocol: FutarchyProtocol; marketType: MarketType; baseVaultAccount: VaultAccountWithProtocol; @@ -70,7 +71,6 @@ export type Proposal = ProposalAccountWithKeyNoState & { tags: string[]; participants: GovernanceParticipant[]; reactions: string[]; - }; export type GovernanceParticipant = { @@ -89,10 +89,10 @@ export type MarketPrices = { }; export type ProposalAccounts = { - proposer_acct: PublicKey, - base_cond_vault_acct: PublicKey | null, - quote_cond_vault_acct: PublicKey | null, - pass_market_acct: PublicKey | null, - fail_market_acct: PublicKey | null, - proposal_acct: PublicKey | null, -} + proposer_acct: PublicKey; + base_cond_vault_acct: PublicKey | null; + quote_cond_vault_acct: PublicKey | null; + pass_market_acct: PublicKey | null; + fail_market_acct: PublicKey | null; + proposal_acct: PublicKey | null; +}; diff --git a/package.json b/package.json index 5425591..7827874 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@metadaoproject/futarchy-sdk", - "version": "1.1.0-alpha.34", + "version": "1.1.0-alpha.35", "main": "dist", "scripts": { "build": "tsc --project tsconfig.build.json && tscpaths -p tsconfig.json -s ./lib -o ./dist",