diff --git a/apps/indexer/README.md b/apps/indexer/README.md index 3c9031f..b49c392 100644 --- a/apps/indexer/README.md +++ b/apps/indexer/README.md @@ -6,6 +6,7 @@ Petra Vault uses the No-Code Indexing (NCI) service from [Geomi](https://geomi.d - [Setup Instructions](#setup-instructions) - [Environment Configuration](#environment-configuration) +- [Initial-owner Discovery on Mainnet](#initial-owner-discovery-on-mainnet) ## Setup Instructions @@ -63,3 +64,52 @@ NEXT_PUBLIC_MULTISIG_INDEXER_TESTNET_ENDPOINT="https://api.testnet.aptoslabs.com | `NEXT_PUBLIC_MULTISIG_INDEXER_MAINNET_ENDPOINT` | GraphQL endpoint for mainnet | `https://api.mainnet.aptoslabs.com/nocode/v1/api/[id]/v1/graphql` | | `NEXT_PUBLIC_MULTISIG_INDEXER_TESTNET_API_KEY` | API key for testnet processor | `AG-...` | | `NEXT_PUBLIC_MULTISIG_INDEXER_TESTNET_ENDPOINT` | GraphQL endpoint for testnet | `https://api.testnet.aptoslabs.com/nocode/v1/api/[id]/v1/graphql` | + +## Initial-owner Discovery on Mainnet + +`multisig-mainnet.yaml` adds `multisig_creation_candidates` alongside the existing +transaction and owner-activity tables. It maps argument `0` of +`0x1::multisig_account::create_with_owners` into a nullable `owners` address array. +The YAML uses the full framework address because Geomi's editor otherwise drops +the payload mapping during its function ABI lookup. + +The mapping was tested in `multisig-creation-probe-v2` with Mainnet creation +versions `7345859301` and `7350673760`. Both were returned for the invited owner +once indexing reached their versions. The production table uses the same mappings +under the name `multisig_creation_candidates`. + +After deploying, indexing the required history, and exposing the new table to the +mobile API key, query candidate versions for the active wallet: + +```graphql +query VaultCreationCandidates( + $owner: String! + $afterVersion: bigint! = "0" + $limit: Int! = 100 +) { + multisig_creation_candidates( + where: { owners: { _contains: [$owner] }, version: { _gt: $afterVersion } } + order_by: { version: asc } + limit: $limit + ) { + version + owners + } +} +``` + +For each subsequent page, use the last returned version as `afterVersion` until +the result is empty. Mobile integration is still required: merge these versions +with existing creator-history and owner-event discovery, resolve successful +transactions into vault addresses, deduplicate them, and verify current ownership. +The query returns creation candidates, not vault addresses or current membership. +Argument `0` contains additional owners only; it excludes the creator and does +not cover other creation functions or custom wrappers. + +**Deployment remains a separate step.** The processor needs `FeeStatement` events +to create rows before payload enrichment. This stores a row for every matching +fee event, including unrelated transactions with null owners and failed creation +calls. Filtering the GraphQL query does not reduce ingestion. Plan ingestion cost +and backfill before deployment; the YAML's `starting_version: 0` requests history +from genesis. The promoted config has been checked locally, but has not been +deployed or verified using the mobile API key. diff --git a/apps/indexer/multisig-mainnet.yaml b/apps/indexer/multisig-mainnet.yaml index 1c535be..4dd2ffb 100644 --- a/apps/indexer/multisig-mainnet.yaml +++ b/apps/indexer/multisig-mainnet.yaml @@ -1,22 +1,42 @@ spec_identifier: spec_creator: shepherd@aptoslabs.com spec_name: remapping-processor - spec_version: 0.0.10 + spec_version: "0.0.21" common_config: network: mainnet starting_version: 0 starting_version_override: null custom_config: transaction_metadata: - timestamp: [] + timestamp: + - table: multisig_transactions + column: timestamp version: - table: multisig_transactions column: version - table: multisig_owner_activities column: version + - table: multisig_creation_candidates + column: version epoch: [] block_height: [] + hash: [] events: + # Payload mappings enrich event-created rows; they do not filter ingestion. + 0x1::transaction_fee::FeeStatement: + event_fields: + $.total_charge_gas_units: + - table: multisig_creation_candidates + column: total_charge_gas_units + event_metadata: + sequence_number: [] + creation_number: [] + account_address: [] + event_type: + - table: multisig_creation_candidates + column: fee_event_type + event_index: [] + constant_values: [] 0x1::multisig_account::AddOwners: event_fields: $.multisig_account: @@ -263,11 +283,16 @@ custom_config: column: event_type event_index: [] constant_values: [] - payload: {} + payload: + # Geomi's function ABI lookup requires the full address. + 0x0000000000000000000000000000000000000000000000000000000000000001::multisig_account::create_with_owners: + '0': + - table: multisig_creation_candidates + column: owners db_schema: multisig_transactions: version: - is_index: false + is_index: true is_nullable: false is_option: false is_primary_key: false @@ -276,6 +301,16 @@ custom_config: column_type: type: transaction_metadata column_type: version + timestamp: + is_index: false + is_nullable: false + is_option: false + is_primary_key: false + is_vec: false + default_value: null + column_type: + type: transaction_metadata + column_type: timestamp executor: is_index: false is_nullable: false @@ -287,15 +322,15 @@ custom_config: type: move_type column_type: address multisig_account: - is_index: false + is_index: true is_nullable: false is_option: false is_primary_key: true is_vec: false default_value: null column_type: - type: event_metadata - column_type: account_address + type: move_type + column_type: address num_rejections: is_index: false is_nullable: true @@ -348,7 +383,7 @@ custom_config: column_type: string multisig_owner_activities: version: - is_index: false + is_index: true is_nullable: false is_option: false is_primary_key: true @@ -365,10 +400,10 @@ custom_config: is_vec: false default_value: null column_type: - type: event_metadata - column_type: account_address + type: move_type + column_type: address owners_added: - is_index: false + is_index: true is_nullable: true is_option: false is_primary_key: false @@ -388,7 +423,7 @@ custom_config: type: event_metadata column_type: event_type owners_removed: - is_index: false + is_index: true is_nullable: true is_option: false is_primary_key: false @@ -398,7 +433,7 @@ custom_config: type: move_type column_type: address owner_vote: - is_index: false + is_index: true is_nullable: true is_option: false is_primary_key: false @@ -407,3 +442,45 @@ custom_config: column_type: type: move_type column_type: address + multisig_creation_candidates: + version: + is_index: true + is_nullable: false + is_option: false + is_primary_key: true + is_vec: false + default_value: null + column_type: + type: transaction_metadata + column_type: version + fee_event_type: + is_index: false + is_nullable: false + is_option: false + is_primary_key: false + is_vec: false + default_value: null + column_type: + type: event_metadata + column_type: event_type + total_charge_gas_units: + is_index: false + is_nullable: false + is_option: false + is_primary_key: false + is_vec: false + default_value: null + column_type: + type: move_type + column_type: u64 + owners: + is_index: true + # Unrelated fee rows have no matching payload argument. + is_nullable: true + is_option: false + is_primary_key: false + is_vec: true + default_value: null + column_type: + type: move_type + column_type: address diff --git a/apps/indexer/multisig-testnet.yaml b/apps/indexer/multisig-testnet.yaml index 0fa74d9..d956a6a 100644 --- a/apps/indexer/multisig-testnet.yaml +++ b/apps/indexer/multisig-testnet.yaml @@ -1,14 +1,16 @@ spec_identifier: spec_creator: shepherd@aptoslabs.com spec_name: remapping-processor - spec_version: 0.0.10 + spec_version: "0.0.21" common_config: network: testnet starting_version: 4500665800 starting_version_override: null custom_config: transaction_metadata: - timestamp: [] + timestamp: + - table: multisig_transactions + column: timestamp version: - table: multisig_transactions column: version @@ -16,6 +18,7 @@ custom_config: column: version epoch: [] block_height: [] + hash: [] events: 0x1::multisig_account::AddOwners: event_fields: @@ -276,6 +279,16 @@ custom_config: column_type: type: transaction_metadata column_type: version + timestamp: + is_index: false + is_nullable: false + is_option: false + is_primary_key: false + is_vec: false + default_value: null + column_type: + type: transaction_metadata + column_type: timestamp executor: is_index: false is_nullable: false @@ -294,8 +307,8 @@ custom_config: is_vec: false default_value: null column_type: - type: event_metadata - column_type: account_address + type: move_type + column_type: address num_rejections: is_index: false is_nullable: true @@ -365,8 +378,8 @@ custom_config: is_vec: false default_value: null column_type: - type: event_metadata - column_type: account_address + type: move_type + column_type: address owners_added: is_index: false is_nullable: true