diff --git a/hasura-api/metadata-json/unified.json b/hasura-api/metadata-json/unified.json index 13af9bb62..bdeed841b 100644 --- a/hasura-api/metadata-json/unified.json +++ b/hasura-api/metadata-json/unified.json @@ -1,5 +1,5 @@ { - "resource_version": 307, + "resource_version": 313, "metadata": { "version": 3, "sources": [ @@ -7,6 +7,263 @@ "name": "indexer-v2", "kind": "postgres", "tables": [ + { + "table": { + "name": "current_nft_marketplace_auctions", + "schema": "nft_marketplace_v2" + }, + "object_relationships": [ + { + "name": "current_token_data", + "using": { + "manual_configuration": { + "column_mapping": { + "token_data_id": "token_data_id" + }, + "insertion_order": null, + "remote_table": { + "name": "current_token_datas_v2", + "schema": "public" + } + } + } + } + ], + "select_permissions": [ + { + "role": "anonymous", + "permission": { + "columns": [ + "buy_it_now_price", + "coin_type", + "collection_id", + "contract_address", + "current_bid_price", + "current_bidder", + "entry_function_id_str", + "expiration_time", + "fee_schedule_id", + "is_deleted", + "last_transaction_timestamp", + "last_transaction_version", + "listing_id", + "marketplace", + "seller", + "starting_bid_price", + "token_amount", + "token_data_id", + "token_standard" + ], + "filter": {}, + "limit": 100 + } + } + ] + }, + { + "table": { + "name": "current_nft_marketplace_collection_offers", + "schema": "nft_marketplace_v2" + }, + "object_relationships": [ + { + "name": "current_collection_v2", + "using": { + "manual_configuration": { + "column_mapping": { + "collection_id": "collection_id" + }, + "insertion_order": null, + "remote_table": { + "name": "current_collections_v2", + "schema": "public" + } + } + } + } + ], + "select_permissions": [ + { + "role": "anonymous", + "permission": { + "columns": [ + "buyer", + "coin_type", + "collection_id", + "collection_offer_id", + "contract_address", + "entry_function_id_str", + "expiration_time", + "fee_schedule_id", + "is_deleted", + "item_price", + "last_transaction_timestamp", + "last_transaction_version", + "marketplace", + "remaining_token_amount", + "token_standard" + ], + "filter": {}, + "limit": 100 + } + } + ] + }, + { + "table": { + "name": "current_nft_marketplace_listings", + "schema": "nft_marketplace_v2" + }, + "object_relationships": [ + { + "name": "current_token_data", + "using": { + "manual_configuration": { + "column_mapping": { + "token_data_id": "token_data_id" + }, + "insertion_order": null, + "remote_table": { + "name": "current_token_datas_v2", + "schema": "public" + } + } + } + } + ], + "select_permissions": [ + { + "role": "anonymous", + "permission": { + "columns": [ + "coin_type", + "collection_id", + "contract_address", + "entry_function_id_str", + "fee_schedule_id", + "is_deleted", + "last_transaction_timestamp", + "last_transaction_version", + "listing_id", + "marketplace", + "price", + "seller", + "token_amount", + "token_data_id", + "token_standard" + ], + "filter": {}, + "limit": 100, + "allow_aggregations": true + } + } + ] + }, + { + "table": { + "name": "current_nft_marketplace_token_offers", + "schema": "nft_marketplace_v2" + }, + "object_relationships": [ + { + "name": "current_token_data", + "using": { + "manual_configuration": { + "column_mapping": { + "token_data_id": "token_data_id" + }, + "insertion_order": null, + "remote_table": { + "name": "current_token_datas_v2", + "schema": "public" + } + } + } + } + ], + "select_permissions": [ + { + "role": "anonymous", + "permission": { + "columns": [ + "buyer", + "coin_type", + "collection_id", + "contract_address", + "entry_function_id_str", + "expiration_time", + "fee_schedule_id", + "is_deleted", + "last_transaction_timestamp", + "last_transaction_version", + "marketplace", + "offer_id", + "price", + "token_amount", + "token_data_id", + "token_standard" + ], + "filter": {}, + "limit": 100 + } + } + ] + }, + { + "table": { + "name": "nft_marketplace_activities", + "schema": "nft_marketplace_v2" + }, + "object_relationships": [ + { + "name": "current_token_data", + "using": { + "manual_configuration": { + "column_mapping": { + "token_data_id": "token_data_id" + }, + "insertion_order": null, + "remote_table": { + "name": "current_token_datas_v2", + "schema": "public" + } + } + } + } + ], + "select_permissions": [ + { + "role": "anonymous", + "permission": { + "columns": [ + "buyer", + "coin_type", + "collection_id", + "collection_name", + "contract_address", + "creator_address", + "entry_function_id_str", + "event_index", + "event_type", + "fee_schedule_id", + "marketplace", + "offer_or_listing_id", + "price", + "property_version", + "seller", + "token_amount", + "token_data_id", + "token_name", + "token_standard", + "transaction_timestamp", + "transaction_version" + ], + "filter": {}, + "limit": 100 + } + } + ] + }, { "table": { "name": "parsed_asset_uris", @@ -622,17 +879,19 @@ "role": "anonymous", "permission": { "columns": [ - "last_transaction_version", + "domain", + "domain_expiration_timestamp", + "domain_with_suffix", + "expiration_timestamp", "is_active", "is_primary", - "domain", + "last_transaction_version", "owner_address", "registered_address", "subdomain", + "subdomain_expiration_policy", "token_name", - "token_standard", - "domain_with_suffix", - "expiration_timestamp" + "token_standard" ], "filter": {}, "limit": 100, diff --git a/rust/processor/migrations/2024-04-09-204519_ans_expiration_policy/down.sql b/rust/processor/migrations/2024-04-09-204519_ans_expiration_policy/down.sql new file mode 100644 index 000000000..29d6c0618 --- /dev/null +++ b/rust/processor/migrations/2024-04-09-204519_ans_expiration_policy/down.sql @@ -0,0 +1,40 @@ +-- This file should undo anything in `up.sql` +DROP VIEW IF EXISTS current_aptos_names; +CREATE OR REPLACE VIEW current_aptos_names AS +SELECT cal.domain, + cal.subdomain, + cal.token_name, + cal.token_standard, + cal.registered_address, + cal.expiration_timestamp, + greatest( + cal.last_transaction_version, + capn.last_transaction_version + ) as last_transaction_version, + coalesce(not capn.is_deleted, false) as is_primary, + concat(cal.domain, '.apt') as domain_with_suffix, + c.owner_address as owner_address, + cal.expiration_timestamp >= CURRENT_TIMESTAMP as is_active +FROM current_ans_lookup_v2 cal + LEFT JOIN current_ans_primary_name_v2 capn ON cal.token_name = capn.token_name + AND cal.token_standard = capn.token_standard + JOIN current_token_datas_v2 b ON cal.token_name = b.token_name + AND cal.token_standard = b.token_standard + JOIN current_token_ownerships_v2 c ON b.token_data_id = c.token_data_id + AND b.token_standard = c.token_standard +WHERE cal.is_deleted IS false + AND c.amount > 0 + AND b.collection_id IN ( + '0x1c380887f0cfcc8a82c0df44b24116985a92c58e686a0ea4a441c9f423a72b47', + -- Testnet ANS v1 domain collection + '0x56654f4bf4e528bfef33094d11a3475f0638e949b0976ec831ca0d66a2efb673', + -- Testnet ANS v2 domain collection + '0x3a2c902067bb4f0e37a2a89675d5cbceb07cf1a27479229b269fb1afffa62230', + -- Testnet ANS v2 subdomain collection + '0x09e63a48047b1c2bc51c0abc4b67ffcd9922e0adc99a6cc36532662172976a4b', + -- Mainnet ANS v1 domain collection + '0x63d26a4e3a8aeececf9b878e46bad78997fb38e50936efeabb2c4453f4d7f746', + -- Mainnet ANS v2 domain collection + '0x63d26a4e3a8aeececf9b878e46bad78997fb38e50936efeabb2c4453f4d7f746' -- Mainnet ANS v2 subdomain collection + ); +ALTER TABLE current_ans_lookup_v2 DROP COLUMN IF EXISTS subdomain_expiration_policy; \ No newline at end of file diff --git a/rust/processor/migrations/2024-04-09-204519_ans_expiration_policy/up.sql b/rust/processor/migrations/2024-04-09-204519_ans_expiration_policy/up.sql new file mode 100644 index 000000000..7933cc972 --- /dev/null +++ b/rust/processor/migrations/2024-04-09-204519_ans_expiration_policy/up.sql @@ -0,0 +1,47 @@ +ALTER TABLE current_ans_lookup_v2 +ADD COLUMN IF NOT EXISTS subdomain_expiration_policy BIGINT; +ALTER TABLE ans_lookup_v2 +ADD COLUMN IF NOT EXISTS subdomain_expiration_policy BIGINT; +CREATE OR REPLACE VIEW current_aptos_names AS +SELECT cal.domain, + cal.subdomain, + cal.token_name, + cal.token_standard, + cal.registered_address, + cal.expiration_timestamp, + greatest( + cal.last_transaction_version, + capn.last_transaction_version + ) as last_transaction_version, + coalesce(not capn.is_deleted, false) as is_primary, + concat(cal.domain, '.apt') as domain_with_suffix, + c.owner_address as owner_address, + cal.expiration_timestamp >= CURRENT_TIMESTAMP as is_active, + cal2.expiration_timestamp as domain_expiration_timestamp, + b.token_data_id as token_data_id, + cal.subdomain_expiration_policy as subdomain_expiration_policy +FROM current_ans_lookup_v2 cal + LEFT JOIN current_ans_primary_name_v2 capn ON cal.token_name = capn.token_name + AND cal.token_standard = capn.token_standard + JOIN current_token_datas_v2 b ON cal.token_name = b.token_name + AND cal.token_standard = b.token_standard + JOIN current_token_ownerships_v2 c ON b.token_data_id = c.token_data_id + AND b.token_standard = c.token_standard + LEFT JOIN current_ans_lookup_v2 cal2 ON cal.domain = cal2.domain + AND cal2.subdomain = '' + AND cal.token_standard = cal2.token_standard +WHERE cal.is_deleted IS false + AND c.amount > 0 + AND b.collection_id IN ( + '0x1c380887f0cfcc8a82c0df44b24116985a92c58e686a0ea4a441c9f423a72b47', + -- Testnet ANS v1 domain collection + '0x56654f4bf4e528bfef33094d11a3475f0638e949b0976ec831ca0d66a2efb673', + -- Testnet ANS v2 domain collection + '0x3a2c902067bb4f0e37a2a89675d5cbceb07cf1a27479229b269fb1afffa62230', + -- Testnet ANS v2 subdomain collection + '0x09e63a48047b1c2bc51c0abc4b67ffcd9922e0adc99a6cc36532662172976a4b', + -- Mainnet ANS v1 domain collection + '0x63d26a4e3a8aeececf9b878e46bad78997fb38e50936efeabb2c4453f4d7f746', + -- Mainnet ANS v2 domain collection + '0x30fbc956f0f38db2d314bd9c018d34be3e047a804a71e30a4e5d43d8b7c539eb' -- Mainnet ANS v2 subdomain collection + ); \ No newline at end of file diff --git a/rust/processor/src/models/ans_models/ans_lookup_v2.rs b/rust/processor/src/models/ans_models/ans_lookup_v2.rs index 090cb00e5..e4a62d44c 100644 --- a/rust/processor/src/models/ans_models/ans_lookup_v2.rs +++ b/rust/processor/src/models/ans_models/ans_lookup_v2.rs @@ -55,6 +55,7 @@ pub struct CurrentAnsLookupV2 { pub expiration_timestamp: chrono::NaiveDateTime, pub token_name: String, pub is_deleted: bool, + pub subdomain_expiration_policy: Option, } #[derive(Clone, Default, Debug, Deserialize, FieldCount, Identifiable, Insertable, Serialize)] @@ -71,6 +72,7 @@ pub struct AnsLookupV2 { pub expiration_timestamp: chrono::NaiveDateTime, pub token_name: String, pub is_deleted: bool, + pub subdomain_expiration_policy: Option, } #[derive( @@ -150,6 +152,7 @@ impl CurrentAnsLookupV2 { expiration_timestamp: v1_current_ans_lookup.expiration_timestamp, token_name: v1_current_ans_lookup.token_name, is_deleted: v1_current_ans_lookup.is_deleted, + subdomain_expiration_policy: None, }, AnsLookupV2 { transaction_version: v1_ans_lookup.transaction_version, @@ -161,6 +164,7 @@ impl CurrentAnsLookupV2 { expiration_timestamp: v1_ans_lookup.expiration_timestamp, token_name: v1_ans_lookup.token_name, is_deleted: v1_ans_lookup.is_deleted, + subdomain_expiration_policy: None, }, ) } @@ -177,12 +181,11 @@ impl CurrentAnsLookupV2 { .unwrap() { // If this resource account has a SubdomainExt, then it's a subdomain - let maybe_subdomain_name = address_to_subdomain_ext + let (subdomain_name, subdomain_expiration_policy) = match address_to_subdomain_ext .get(&standardize_address(write_resource.address.as_str())) - .map(|subdomain_ext| subdomain_ext.get_subdomain_trunc()); - let subdomain_name = match maybe_subdomain_name.clone() { - Some(subdomain) => subdomain, - None => "".to_string(), + { + Some(s) => (s.get_subdomain_trunc(), Some(s.subdomain_expiration_policy)), + None => ("".to_string(), None), }; let token_name = get_token_name( @@ -200,6 +203,7 @@ impl CurrentAnsLookupV2 { token_name: token_name.clone(), last_transaction_version: txn_version, is_deleted: false, + subdomain_expiration_policy, }, AnsLookupV2 { transaction_version: txn_version, @@ -211,6 +215,7 @@ impl CurrentAnsLookupV2 { expiration_timestamp: inner.get_expiration_time(), token_name, is_deleted: false, + subdomain_expiration_policy, }, ))); } diff --git a/rust/processor/src/models/ans_models/ans_utils.rs b/rust/processor/src/models/ans_models/ans_utils.rs index b1f800531..4562d79c1 100644 --- a/rust/processor/src/models/ans_models/ans_utils.rs +++ b/rust/processor/src/models/ans_models/ans_utils.rs @@ -181,7 +181,7 @@ impl NameRecordV2 { #[derive(Serialize, Deserialize, Debug, Clone)] pub struct SubdomainExtV2 { - subdomain_expiration_policy: BigDecimal, + pub subdomain_expiration_policy: i64, subdomain_name: String, } diff --git a/rust/processor/src/processors/ans_processor.rs b/rust/processor/src/processors/ans_processor.rs index 54fb87ea1..1521325cf 100644 --- a/rust/processor/src/processors/ans_processor.rs +++ b/rust/processor/src/processors/ans_processor.rs @@ -285,6 +285,7 @@ fn insert_current_ans_lookups_v2_query( token_name.eq(excluded(token_name)), is_deleted.eq(excluded(is_deleted)), inserted_at.eq(excluded(inserted_at)), + subdomain_expiration_policy.eq(excluded(subdomain_expiration_policy)), )), Some(" WHERE current_ans_lookup_v2.last_transaction_version <= excluded.last_transaction_version "), ) @@ -302,7 +303,11 @@ fn insert_ans_lookups_v2_query( diesel::insert_into(schema::ans_lookup_v2::table) .values(item_to_insert) .on_conflict((transaction_version, write_set_change_index)) - .do_nothing(), + .do_update() + .set(( + inserted_at.eq(excluded(inserted_at)), + subdomain_expiration_policy.eq(excluded(subdomain_expiration_policy)), + )), None, ) } diff --git a/rust/processor/src/schema.rs b/rust/processor/src/schema.rs index 5fb567a42..2c606fdc8 100644 --- a/rust/processor/src/schema.rs +++ b/rust/processor/src/schema.rs @@ -44,6 +44,7 @@ diesel::table! { token_name -> Varchar, is_deleted -> Bool, inserted_at -> Timestamp, + subdomain_expiration_policy -> Nullable, } } @@ -263,6 +264,7 @@ diesel::table! { last_transaction_version -> Int8, is_deleted -> Bool, inserted_at -> Timestamp, + subdomain_expiration_policy -> Nullable, } }