diff --git a/Cargo.toml b/Cargo.toml index 1dffdb50c58a564de27211f8c9c851959af2f010..86e84b812336c7227b4ebd145fa40df60c835af3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ sp-core = { git = "https://github.com/duniter/substrate.git", branch = "duniter- sp-runtime = { git = "https://github.com/duniter/substrate", branch = "duniter-substrate-v0.9.42" } subxt = { git = "https://github.com/duniter/subxt.git", branch = "subxt-v0.32.1-duniter-substrate-v0.9.42", features = ["substrate-compat"] } # subxt-signer = { git = "https://github.com/duniter/subxt.git", branch = "subxt-v0.32.1-duniter-substrate-v0.9.42", features = ["subxt"] } +# sp-api = { git = 'https://github.com/duniter/substrate', branch = 'duniter-substrate-v0.9.42'} tokio = { version = "1.26.0", features = ["macros"] } confy = "0.5.1" scrypt = { version = "0.11", default-features = false } # for old-style key generation diff --git a/res/README.md b/res/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e5fa97b4d1424c80a49dd4a334eb0dc625ce317d --- /dev/null +++ b/res/README.md @@ -0,0 +1,16 @@ +# Resources + +## Graphql schema and queries for Duniter indexer + +... + +## Metadata + +To update the scale-encoded Duniter metadata, spawn a node and run the subxt command. + +```sh +# spawn a node listening on localhost:9944 +duniter --dev +# fetch the metadata with subxt +subxt metadata -f bytes > res/metadata.scale +``` \ No newline at end of file diff --git a/res/indexer-queries.graphql b/res/indexer-queries.graphql index 570a7cd1f07c58e0b7dd07688eb16709cb30563e..7b022d468f5bb6f67c47c28d1e992a1f17f6469c 100644 --- a/res/indexer-queries.graphql +++ b/res/indexer-queries.graphql @@ -1,11 +1,23 @@ -query IdentityNameByPubkey($pubkey: String!) { - identity(where: { pubkey: { _eq: $pubkey } }) { +query IdentityByIndex($index: Int!) { + identity_by_pk(index: $index) { + index name + pubkey } } -query IdentityPubkeyByName($name: String!) { - identity_by_pk(name: $name) { +query IdentityByName($name: String!) { + identity(where: { name: { _eq: $name } }) { + index + name + pubkey + } +} + +query IdentityByPubkey($pubkey: String!) { + identity(where: { pubkey: { _eq: $pubkey } }) { + index + name pubkey } } diff --git a/res/indexer-schema.graphql b/res/indexer-schema.graphql index 4295c5b1087e564d3b38acf902d6f1eace0e7084..edffaeaf7b92d83025f5eb9616ab2002807745e9 100644 --- a/res/indexer-schema.graphql +++ b/res/indexer-schema.graphql @@ -26,9 +26,6 @@ type account { """ has_identity: Boolean - """Pubkey of the account.""" - id: String! - """An object relationship""" identity: identity killed_at: timestamptz @@ -36,6 +33,9 @@ type account { """Block number where account was killed.""" killed_on: Int + """Pubkey of the account.""" + pubkey: String! + """An array relationship""" transactions_issued( """distinct select on columns""" @@ -109,6 +109,40 @@ type account { ): transaction_aggregate! } +""" +aggregated selection of "account" +""" +type account_aggregate { + aggregate: account_aggregate_fields + nodes: [account!]! +} + +""" +aggregate fields of "account" +""" +type account_aggregate_fields { + avg: account_avg_fields + count(columns: [account_select_column!], distinct: Boolean): Int! + max: account_max_fields + min: account_min_fields + stddev: account_stddev_fields + stddev_pop: account_stddev_pop_fields + stddev_samp: account_stddev_samp_fields + sum: account_sum_fields + var_pop: account_var_pop_fields + var_samp: account_var_samp_fields + variance: account_variance_fields +} + +"""aggregate avg on columns""" +type account_avg_fields { + """Block number where account was created.""" + created_on: Float + + """Block number where account was killed.""" + killed_on: Float +} + """ Boolean expression to filter rows from the table "account". All fields are combined with a logical 'AND'. """ @@ -120,12 +154,44 @@ input account_bool_exp { created_at: timestamptz_comparison_exp created_on: Int_comparison_exp has_identity: Boolean_comparison_exp - id: String_comparison_exp identity: identity_bool_exp killed_at: timestamptz_comparison_exp killed_on: Int_comparison_exp + pubkey: String_comparison_exp transactions_issued: transaction_bool_exp + transactions_issued_aggregate: transaction_aggregate_bool_exp transactions_received: transaction_bool_exp + transactions_received_aggregate: transaction_aggregate_bool_exp +} + +"""aggregate max on columns""" +type account_max_fields { + created_at: timestamptz + + """Block number where account was created.""" + created_on: Int + killed_at: timestamptz + + """Block number where account was killed.""" + killed_on: Int + + """Pubkey of the account.""" + pubkey: String +} + +"""aggregate min on columns""" +type account_min_fields { + created_at: timestamptz + + """Block number where account was created.""" + created_on: Int + killed_at: timestamptz + + """Block number where account was killed.""" + killed_on: Int + + """Pubkey of the account.""" + pubkey: String } """Ordering options when selecting data from "account".""" @@ -134,10 +200,10 @@ input account_order_by { created_at: order_by created_on: order_by has_identity: order_by - id: order_by identity: identity_order_by killed_at: order_by killed_on: order_by + pubkey: order_by transactions_issued_aggregate: transaction_aggregate_order_by transactions_received_aggregate: transaction_aggregate_order_by } @@ -152,14 +218,41 @@ enum account_select_column { """column name""" created_on - """column name""" - id - """column name""" killed_at """column name""" killed_on + + """column name""" + pubkey +} + +"""aggregate stddev on columns""" +type account_stddev_fields { + """Block number where account was created.""" + created_on: Float + + """Block number where account was killed.""" + killed_on: Float +} + +"""aggregate stddev_pop on columns""" +type account_stddev_pop_fields { + """Block number where account was created.""" + created_on: Float + + """Block number where account was killed.""" + killed_on: Float +} + +"""aggregate stddev_samp on columns""" +type account_stddev_samp_fields { + """Block number where account was created.""" + created_on: Float + + """Block number where account was killed.""" + killed_on: Float } """ @@ -179,15 +272,51 @@ input account_stream_cursor_value_input { """Block number where account was created.""" created_on: Int + killed_at: timestamptz + + """Block number where account was killed.""" + killed_on: Int """Pubkey of the account.""" - id: String - killed_at: timestamptz + pubkey: String +} + +"""aggregate sum on columns""" +type account_sum_fields { + """Block number where account was created.""" + created_on: Int """Block number where account was killed.""" killed_on: Int } +"""aggregate var_pop on columns""" +type account_var_pop_fields { + """Block number where account was created.""" + created_on: Float + + """Block number where account was killed.""" + killed_on: Float +} + +"""aggregate var_samp on columns""" +type account_var_samp_fields { + """Block number where account was created.""" + created_on: Float + + """Block number where account was killed.""" + killed_on: Float +} + +"""aggregate variance on columns""" +type account_variance_fields { + """Block number where account was created.""" + created_on: Float + + """Block number where account was killed.""" + killed_on: Float +} + """Table of blocks.""" type block { created_at: timestamp! @@ -202,8 +331,39 @@ type block { ): jsonb hash: String! - """Index of the block in substrate.""" - index: Int! + """Number of the block in substrate.""" + number: Int! +} + +""" +aggregated selection of "block" +""" +type block_aggregate { + aggregate: block_aggregate_fields + nodes: [block!]! +} + +""" +aggregate fields of "block" +""" +type block_aggregate_fields { + avg: block_avg_fields + count(columns: [block_select_column!], distinct: Boolean): Int! + max: block_max_fields + min: block_min_fields + stddev: block_stddev_fields + stddev_pop: block_stddev_pop_fields + stddev_samp: block_stddev_samp_fields + sum: block_sum_fields + var_pop: block_var_pop_fields + var_samp: block_var_samp_fields + variance: block_variance_fields +} + +"""aggregate avg on columns""" +type block_avg_fields { + """Number of the block in substrate.""" + number: Float } """ @@ -216,7 +376,25 @@ input block_bool_exp { created_at: timestamp_comparison_exp data: jsonb_comparison_exp hash: String_comparison_exp - index: Int_comparison_exp + number: Int_comparison_exp +} + +"""aggregate max on columns""" +type block_max_fields { + created_at: timestamp + hash: String + + """Number of the block in substrate.""" + number: Int +} + +"""aggregate min on columns""" +type block_min_fields { + created_at: timestamp + hash: String + + """Number of the block in substrate.""" + number: Int } """Ordering options when selecting data from "block".""" @@ -224,7 +402,7 @@ input block_order_by { created_at: order_by data: order_by hash: order_by - index: order_by + number: order_by } """ @@ -241,7 +419,25 @@ enum block_select_column { hash """column name""" - index + number +} + +"""aggregate stddev on columns""" +type block_stddev_fields { + """Number of the block in substrate.""" + number: Float +} + +"""aggregate stddev_pop on columns""" +type block_stddev_pop_fields { + """Number of the block in substrate.""" + number: Float +} + +"""aggregate stddev_samp on columns""" +type block_stddev_samp_fields { + """Number of the block in substrate.""" + number: Float } """ @@ -266,8 +462,32 @@ input block_stream_cursor_value_input { data: jsonb hash: String - """Index of the block in substrate.""" - index: Int + """Number of the block in substrate.""" + number: Int +} + +"""aggregate sum on columns""" +type block_sum_fields { + """Number of the block in substrate.""" + number: Int +} + +"""aggregate var_pop on columns""" +type block_var_pop_fields { + """Number of the block in substrate.""" + number: Float +} + +"""aggregate var_samp on columns""" +type block_var_samp_fields { + """Number of the block in substrate.""" + number: Float +} + +"""aggregate variance on columns""" +type block_variance_fields { + """Number of the block in substrate.""" + number: Float } """ @@ -297,11 +517,15 @@ type certification { """An object relationship""" issuer: identity! - issuer_id: String! + + """Index of issuer""" + issuer_index: Int! """An object relationship""" receiver: identity! - receiver_id: String! + + """Index of receiver""" + receiver_index: Int! } """ @@ -312,6 +536,17 @@ type certification_aggregate { nodes: [certification!]! } +input certification_aggregate_bool_exp { + count: certification_aggregate_bool_exp_count +} + +input certification_aggregate_bool_exp_count { + arguments: [certification_select_column!] + distinct: Boolean + filter: certification_bool_exp + predicate: Int_comparison_exp! +} + """ aggregate fields of "certification" """ @@ -350,6 +585,12 @@ input certification_aggregate_order_by { type certification_avg_fields { """Block number where certification was created.""" created_on: Float + + """Index of issuer""" + issuer_index: Float + + """Index of receiver""" + receiver_index: Float } """ @@ -358,6 +599,12 @@ order by avg() on columns of table "certification" input certification_avg_order_by { """Block number where certification was created.""" created_on: order_by + + """Index of issuer""" + issuer_index: order_by + + """Index of receiver""" + receiver_index: order_by } """ @@ -371,9 +618,9 @@ input certification_bool_exp { created_on: Int_comparison_exp created_on_block: block_bool_exp issuer: identity_bool_exp - issuer_id: String_comparison_exp + issuer_index: Int_comparison_exp receiver: identity_bool_exp - receiver_id: String_comparison_exp + receiver_index: Int_comparison_exp } """aggregate max on columns""" @@ -382,8 +629,12 @@ type certification_max_fields { """Block number where certification was created.""" created_on: Int - issuer_id: String - receiver_id: String + + """Index of issuer""" + issuer_index: Int + + """Index of receiver""" + receiver_index: Int } """ @@ -394,8 +645,12 @@ input certification_max_order_by { """Block number where certification was created.""" created_on: order_by - issuer_id: order_by - receiver_id: order_by + + """Index of issuer""" + issuer_index: order_by + + """Index of receiver""" + receiver_index: order_by } """aggregate min on columns""" @@ -404,8 +659,12 @@ type certification_min_fields { """Block number where certification was created.""" created_on: Int - issuer_id: String - receiver_id: String + + """Index of issuer""" + issuer_index: Int + + """Index of receiver""" + receiver_index: Int } """ @@ -416,8 +675,12 @@ input certification_min_order_by { """Block number where certification was created.""" created_on: order_by - issuer_id: order_by - receiver_id: order_by + + """Index of issuer""" + issuer_index: order_by + + """Index of receiver""" + receiver_index: order_by } """Ordering options when selecting data from "certification".""" @@ -426,9 +689,9 @@ input certification_order_by { created_on: order_by created_on_block: block_order_by issuer: identity_order_by - issuer_id: order_by + issuer_index: order_by receiver: identity_order_by - receiver_id: order_by + receiver_index: order_by } """ @@ -442,16 +705,22 @@ enum certification_select_column { created_on """column name""" - issuer_id + issuer_index """column name""" - receiver_id + receiver_index } """aggregate stddev on columns""" type certification_stddev_fields { """Block number where certification was created.""" created_on: Float + + """Index of issuer""" + issuer_index: Float + + """Index of receiver""" + receiver_index: Float } """ @@ -460,12 +729,24 @@ order by stddev() on columns of table "certification" input certification_stddev_order_by { """Block number where certification was created.""" created_on: order_by + + """Index of issuer""" + issuer_index: order_by + + """Index of receiver""" + receiver_index: order_by } """aggregate stddev_pop on columns""" type certification_stddev_pop_fields { """Block number where certification was created.""" created_on: Float + + """Index of issuer""" + issuer_index: Float + + """Index of receiver""" + receiver_index: Float } """ @@ -474,12 +755,24 @@ order by stddev_pop() on columns of table "certification" input certification_stddev_pop_order_by { """Block number where certification was created.""" created_on: order_by + + """Index of issuer""" + issuer_index: order_by + + """Index of receiver""" + receiver_index: order_by } """aggregate stddev_samp on columns""" type certification_stddev_samp_fields { """Block number where certification was created.""" created_on: Float + + """Index of issuer""" + issuer_index: Float + + """Index of receiver""" + receiver_index: Float } """ @@ -488,6 +781,12 @@ order by stddev_samp() on columns of table "certification" input certification_stddev_samp_order_by { """Block number where certification was created.""" created_on: order_by + + """Index of issuer""" + issuer_index: order_by + + """Index of receiver""" + receiver_index: order_by } """ @@ -507,14 +806,24 @@ input certification_stream_cursor_value_input { """Block number where certification was created.""" created_on: Int - issuer_id: String - receiver_id: String + + """Index of issuer""" + issuer_index: Int + + """Index of receiver""" + receiver_index: Int } """aggregate sum on columns""" type certification_sum_fields { """Block number where certification was created.""" created_on: Int + + """Index of issuer""" + issuer_index: Int + + """Index of receiver""" + receiver_index: Int } """ @@ -523,12 +832,24 @@ order by sum() on columns of table "certification" input certification_sum_order_by { """Block number where certification was created.""" created_on: order_by + + """Index of issuer""" + issuer_index: order_by + + """Index of receiver""" + receiver_index: order_by } """aggregate var_pop on columns""" type certification_var_pop_fields { """Block number where certification was created.""" created_on: Float + + """Index of issuer""" + issuer_index: Float + + """Index of receiver""" + receiver_index: Float } """ @@ -537,12 +858,24 @@ order by var_pop() on columns of table "certification" input certification_var_pop_order_by { """Block number where certification was created.""" created_on: order_by + + """Index of issuer""" + issuer_index: order_by + + """Index of receiver""" + receiver_index: order_by } """aggregate var_samp on columns""" type certification_var_samp_fields { """Block number where certification was created.""" created_on: Float + + """Index of issuer""" + issuer_index: Float + + """Index of receiver""" + receiver_index: Float } """ @@ -551,12 +884,24 @@ order by var_samp() on columns of table "certification" input certification_var_samp_order_by { """Block number where certification was created.""" created_on: order_by + + """Index of issuer""" + issuer_index: order_by + + """Index of receiver""" + receiver_index: order_by } """aggregate variance on columns""" type certification_variance_fields { """Block number where certification was created.""" created_on: Float + + """Index of issuer""" + issuer_index: Float + + """Index of receiver""" + receiver_index: Float } """ @@ -565,6 +910,12 @@ order by variance() on columns of table "certification" input certification_variance_order_by { """Block number where certification was created.""" created_on: order_by + + """Index of issuer""" + issuer_index: order_by + + """Index of receiver""" + receiver_index: order_by } """ordering argument of a cursor""" @@ -576,6 +927,8 @@ enum cursor_ordering { DESC } +scalar date + """ Boolean expression to compare columns of type "Float". All fields are combined with logical 'AND'. """ @@ -597,7 +950,7 @@ type identity { account: account """An array relationship""" - certifications_issued( + cert_issued( """distinct select on columns""" distinct_on: [certification_select_column!] @@ -615,7 +968,7 @@ type identity { ): [certification!]! """An aggregate relationship""" - certifications_issued_aggregate( + cert_issued_aggregate( """distinct select on columns""" distinct_on: [certification_select_column!] @@ -633,7 +986,7 @@ type identity { ): certification_aggregate! """An array relationship""" - certifications_received( + cert_received( """distinct select on columns""" distinct_on: [certification_select_column!] @@ -651,7 +1004,7 @@ type identity { ): [certification!]! """An aggregate relationship""" - certifications_received_aggregate( + cert_received_aggregate( """distinct select on columns""" distinct_on: [certification_select_column!] @@ -674,19 +1027,19 @@ type identity { """An object relationship""" confirmed_on_block: block - created_at: timestamptz! """Block number where identity was created.""" - created_on: Int! + created_on: Int """An object relationship""" - created_on_block: block! - - """Pubkey of the account associated to this identity.""" - id: String! + created_on_block: block + index: Int! """Name of the identity.""" name: String + + """Pubkey of the account associated to this identity.""" + pubkey: String! revoked_at: timestamptz """Block number where identity was revoked.""" @@ -703,6 +1056,47 @@ type identity { validated_on_block: block } +""" +aggregated selection of "identity" +""" +type identity_aggregate { + aggregate: identity_aggregate_fields + nodes: [identity!]! +} + +""" +aggregate fields of "identity" +""" +type identity_aggregate_fields { + avg: identity_avg_fields + count(columns: [identity_select_column!], distinct: Boolean): Int! + max: identity_max_fields + min: identity_min_fields + stddev: identity_stddev_fields + stddev_pop: identity_stddev_pop_fields + stddev_samp: identity_stddev_samp_fields + sum: identity_sum_fields + var_pop: identity_var_pop_fields + var_samp: identity_var_samp_fields + variance: identity_variance_fields +} + +"""aggregate avg on columns""" +type identity_avg_fields { + """Block number where identity was confirmed.""" + confirmed_on: Float + + """Block number where identity was created.""" + created_on: Float + index: Float + + """Block number where identity was revoked.""" + revoked_on: Float + + """Block number where identity was validated.""" + validated_on: Float +} + """ Boolean expression to filter rows from the table "identity". All fields are combined with a logical 'AND'. """ @@ -711,16 +1105,18 @@ input identity_bool_exp { _not: identity_bool_exp _or: [identity_bool_exp!] account: account_bool_exp - certifications_issued: certification_bool_exp - certifications_received: certification_bool_exp + cert_issued: certification_bool_exp + cert_issued_aggregate: certification_aggregate_bool_exp + cert_received: certification_bool_exp + cert_received_aggregate: certification_aggregate_bool_exp confirmed_at: timestamptz_comparison_exp confirmed_on: Int_comparison_exp confirmed_on_block: block_bool_exp - created_at: timestamptz_comparison_exp created_on: Int_comparison_exp created_on_block: block_bool_exp - id: String_comparison_exp + index: Int_comparison_exp name: String_comparison_exp + pubkey: String_comparison_exp revoked_at: timestamptz_comparison_exp revoked_on: Int_comparison_exp revoked_on_block: block_bool_exp @@ -729,49 +1125,101 @@ input identity_bool_exp { validated_on_block: block_bool_exp } -"""Ordering options when selecting data from "identity".""" -input identity_order_by { - account: account_order_by - certifications_issued_aggregate: certification_aggregate_order_by - certifications_received_aggregate: certification_aggregate_order_by - confirmed_at: order_by - confirmed_on: order_by - confirmed_on_block: block_order_by - created_at: order_by - created_on: order_by - created_on_block: block_order_by - id: order_by - name: order_by - revoked_at: order_by - revoked_on: order_by - revoked_on_block: block_order_by - validated_at: order_by - validated_on: order_by - validated_on_block: block_order_by -} +"""aggregate max on columns""" +type identity_max_fields { + confirmed_at: timestamptz -""" -select columns of table "identity" -""" -enum identity_select_column { - """column name""" - confirmed_at + """Block number where identity was confirmed.""" + confirmed_on: Int + + """Block number where identity was created.""" + created_on: Int + index: Int + + """Name of the identity.""" + name: String + + """Pubkey of the account associated to this identity.""" + pubkey: String + revoked_at: timestamptz + + """Block number where identity was revoked.""" + revoked_on: Int + validated_at: timestamptz + + """Block number where identity was validated.""" + validated_on: Int +} + +"""aggregate min on columns""" +type identity_min_fields { + confirmed_at: timestamptz + + """Block number where identity was confirmed.""" + confirmed_on: Int + + """Block number where identity was created.""" + created_on: Int + index: Int + + """Name of the identity.""" + name: String + + """Pubkey of the account associated to this identity.""" + pubkey: String + revoked_at: timestamptz + + """Block number where identity was revoked.""" + revoked_on: Int + validated_at: timestamptz + + """Block number where identity was validated.""" + validated_on: Int +} + +"""Ordering options when selecting data from "identity".""" +input identity_order_by { + account: account_order_by + cert_issued_aggregate: certification_aggregate_order_by + cert_received_aggregate: certification_aggregate_order_by + confirmed_at: order_by + confirmed_on: order_by + confirmed_on_block: block_order_by + created_on: order_by + created_on_block: block_order_by + index: order_by + name: order_by + pubkey: order_by + revoked_at: order_by + revoked_on: order_by + revoked_on_block: block_order_by + validated_at: order_by + validated_on: order_by + validated_on_block: block_order_by +} +""" +select columns of table "identity" +""" +enum identity_select_column { """column name""" - confirmed_on + confirmed_at """column name""" - created_at + confirmed_on """column name""" created_on """column name""" - id + index """column name""" name + """column name""" + pubkey + """column name""" revoked_at @@ -785,6 +1233,54 @@ enum identity_select_column { validated_on } +"""aggregate stddev on columns""" +type identity_stddev_fields { + """Block number where identity was confirmed.""" + confirmed_on: Float + + """Block number where identity was created.""" + created_on: Float + index: Float + + """Block number where identity was revoked.""" + revoked_on: Float + + """Block number where identity was validated.""" + validated_on: Float +} + +"""aggregate stddev_pop on columns""" +type identity_stddev_pop_fields { + """Block number where identity was confirmed.""" + confirmed_on: Float + + """Block number where identity was created.""" + created_on: Float + index: Float + + """Block number where identity was revoked.""" + revoked_on: Float + + """Block number where identity was validated.""" + validated_on: Float +} + +"""aggregate stddev_samp on columns""" +type identity_stddev_samp_fields { + """Block number where identity was confirmed.""" + confirmed_on: Float + + """Block number where identity was created.""" + created_on: Float + index: Float + + """Block number where identity was revoked.""" + revoked_on: Float + + """Block number where identity was validated.""" + validated_on: Float +} + """ Streaming cursor of the table "identity" """ @@ -802,16 +1298,16 @@ input identity_stream_cursor_value_input { """Block number where identity was confirmed.""" confirmed_on: Int - created_at: timestamptz """Block number where identity was created.""" created_on: Int - - """Pubkey of the account associated to this identity.""" - id: String + index: Int """Name of the identity.""" name: String + + """Pubkey of the account associated to this identity.""" + pubkey: String revoked_at: timestamptz """Block number where identity was revoked.""" @@ -822,6 +1318,70 @@ input identity_stream_cursor_value_input { validated_on: Int } +"""aggregate sum on columns""" +type identity_sum_fields { + """Block number where identity was confirmed.""" + confirmed_on: Int + + """Block number where identity was created.""" + created_on: Int + index: Int + + """Block number where identity was revoked.""" + revoked_on: Int + + """Block number where identity was validated.""" + validated_on: Int +} + +"""aggregate var_pop on columns""" +type identity_var_pop_fields { + """Block number where identity was confirmed.""" + confirmed_on: Float + + """Block number where identity was created.""" + created_on: Float + index: Float + + """Block number where identity was revoked.""" + revoked_on: Float + + """Block number where identity was validated.""" + validated_on: Float +} + +"""aggregate var_samp on columns""" +type identity_var_samp_fields { + """Block number where identity was confirmed.""" + confirmed_on: Float + + """Block number where identity was created.""" + created_on: Float + index: Float + + """Block number where identity was revoked.""" + revoked_on: Float + + """Block number where identity was validated.""" + validated_on: Float +} + +"""aggregate variance on columns""" +type identity_variance_fields { + """Block number where identity was confirmed.""" + confirmed_on: Float + + """Block number where identity was created.""" + created_on: Float + index: Float + + """Block number where identity was revoked.""" + revoked_on: Float + + """Block number where identity was validated.""" + validated_on: Float +} + """ Boolean expression to compare columns of type "Int". All fields are combined with logical 'AND'. """ @@ -970,10 +1530,30 @@ type query_root { where: account_bool_exp ): [account!]! + """ + fetch aggregated fields from the table: "account" + """ + account_aggregate( + """distinct select on columns""" + distinct_on: [account_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [account_order_by!] + + """filter the rows returned""" + where: account_bool_exp + ): account_aggregate! + """fetch data from the table: "account" using primary key columns""" account_by_pk( """Pubkey of the account.""" - id: String! + pubkey: String! ): account """ @@ -996,10 +1576,30 @@ type query_root { where: block_bool_exp ): [block!]! + """ + fetch aggregated fields from the table: "block" + """ + block_aggregate( + """distinct select on columns""" + distinct_on: [block_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [block_order_by!] + + """filter the rows returned""" + where: block_bool_exp + ): block_aggregate! + """fetch data from the table: "block" using primary key columns""" block_by_pk( - """Index of the block in substrate.""" - index: Int! + """Number of the block in substrate.""" + number: Int! ): block """ @@ -1043,7 +1643,16 @@ type query_root { ): certification_aggregate! """fetch data from the table: "certification" using primary key columns""" - certification_by_pk(issuer_id: String!, receiver_id: String!): certification + certification_by_pk( + """Block number where certification was created.""" + created_on: Int! + + """Index of issuer""" + issuer_index: Int! + + """Index of receiver""" + receiver_index: Int! + ): certification """ fetch data from the table: "identity" @@ -1065,11 +1674,28 @@ type query_root { where: identity_bool_exp ): [identity!]! + """ + fetch aggregated fields from the table: "identity" + """ + identity_aggregate( + """distinct select on columns""" + distinct_on: [identity_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [identity_order_by!] + + """filter the rows returned""" + where: identity_bool_exp + ): identity_aggregate! + """fetch data from the table: "identity" using primary key columns""" - identity_by_pk( - """Pubkey of the account associated to this identity.""" - id: String! - ): identity + identity_by_pk(index: Int!): identity """ fetch data from the table: "parameters" @@ -1120,11 +1746,16 @@ type query_root { ): [identity!]! """ - fetch data from the table: "transaction" + execute function "search_identity" and query aggregates on result of table type "identity" """ - transaction( + search_identity_aggregate( + """ + input parameters for function "search_identity_aggregate" + """ + args: search_identity_args! + """distinct select on columns""" - distinct_on: [transaction_select_column!] + distinct_on: [identity_select_column!] """limit the number of rows returned""" limit: Int @@ -1133,18 +1764,38 @@ type query_root { offset: Int """sort the rows by one or more columns""" - order_by: [transaction_order_by!] + order_by: [identity_order_by!] """filter the rows returned""" - where: transaction_bool_exp - ): [transaction!]! + where: identity_bool_exp + ): identity_aggregate! """ - fetch aggregated fields from the table: "transaction" + fetch data from the table: "smith" """ - transaction_aggregate( + smith( """distinct select on columns""" - distinct_on: [transaction_select_column!] + distinct_on: [smith_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [smith_order_by!] + + """filter the rows returned""" + where: smith_bool_exp + ): [smith!]! + + """ + fetch aggregated fields from the table: "smith" + """ + smith_aggregate( + """distinct select on columns""" + distinct_on: [smith_select_column!] """limit the number of rows returned""" limit: Int @@ -1152,24 +1803,658 @@ type query_root { """skip the first n rows. Use only with order_by""" offset: Int - """sort the rows by one or more columns""" - order_by: [transaction_order_by!] + """sort the rows by one or more columns""" + order_by: [smith_order_by!] + + """filter the rows returned""" + where: smith_bool_exp + ): smith_aggregate! + + """fetch data from the table: "smith" using primary key columns""" + smith_by_pk(idty_index: Int!): smith + + """ + fetch data from the table: "smith_cert" + """ + smith_cert( + """distinct select on columns""" + distinct_on: [smith_cert_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [smith_cert_order_by!] + + """filter the rows returned""" + where: smith_cert_bool_exp + ): [smith_cert!]! + + """ + fetch aggregated fields from the table: "smith_cert" + """ + smith_cert_aggregate( + """distinct select on columns""" + distinct_on: [smith_cert_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [smith_cert_order_by!] + + """filter the rows returned""" + where: smith_cert_bool_exp + ): smith_cert_aggregate! + + """fetch data from the table: "smith_cert" using primary key columns""" + smith_cert_by_pk(created_on: Int!, issuer_index: Int!, receiver_index: Int!): smith_cert + + """ + fetch data from the table: "transaction" + """ + transaction( + """distinct select on columns""" + distinct_on: [transaction_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [transaction_order_by!] + + """filter the rows returned""" + where: transaction_bool_exp + ): [transaction!]! + + """ + fetch aggregated fields from the table: "transaction" + """ + transaction_aggregate( + """distinct select on columns""" + distinct_on: [transaction_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [transaction_order_by!] + + """filter the rows returned""" + where: transaction_bool_exp + ): transaction_aggregate! + + """fetch data from the table: "transaction" using primary key columns""" + transaction_by_pk( + """ + Primary Key `id` is used for postgreSQL and Hasura relationship, not related to any value in substrate. + """ + id: Int! + ): transaction + + """ + execute function "transaction_timeserie" which returns "transaction_timeserie_tmp" + """ + transaction_timeserie( + """ + input parameters for function "transaction_timeserie" + """ + args: transaction_timeserie_args! + + """distinct select on columns""" + distinct_on: [transaction_timeserie_tmp_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [transaction_timeserie_tmp_order_by!] + + """filter the rows returned""" + where: transaction_timeserie_tmp_bool_exp + ): [transaction_timeserie_tmp!]! + + """ + fetch data from the table: "transaction_timeserie_tmp" + """ + transaction_timeserie_tmp( + """distinct select on columns""" + distinct_on: [transaction_timeserie_tmp_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [transaction_timeserie_tmp_order_by!] + + """filter the rows returned""" + where: transaction_timeserie_tmp_bool_exp + ): [transaction_timeserie_tmp!]! + + """ + fetch data from the table: "transaction_timeserie_tmp" using primary key columns + """ + transaction_timeserie_tmp_by_pk(date: timestamptz!): transaction_timeserie_tmp +} + +input search_identity_args { + name: String +} + +"""identities with smith membership""" +type smith { + """An array relationship""" + cert_issued( + """distinct select on columns""" + distinct_on: [smith_cert_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [smith_cert_order_by!] + + """filter the rows returned""" + where: smith_cert_bool_exp + ): [smith_cert!]! + + """An aggregate relationship""" + cert_issued_aggregate( + """distinct select on columns""" + distinct_on: [smith_cert_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [smith_cert_order_by!] + + """filter the rows returned""" + where: smith_cert_bool_exp + ): smith_cert_aggregate! + + """An array relationship""" + cert_received( + """distinct select on columns""" + distinct_on: [smith_cert_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [smith_cert_order_by!] + + """filter the rows returned""" + where: smith_cert_bool_exp + ): [smith_cert!]! + + """An aggregate relationship""" + cert_received_aggregate( + """distinct select on columns""" + distinct_on: [smith_cert_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [smith_cert_order_by!] + + """filter the rows returned""" + where: smith_cert_bool_exp + ): smith_cert_aggregate! + + """An object relationship""" + identity: identity! + idty_index: Int! +} + +""" +aggregated selection of "smith" +""" +type smith_aggregate { + aggregate: smith_aggregate_fields + nodes: [smith!]! +} + +""" +aggregate fields of "smith" +""" +type smith_aggregate_fields { + avg: smith_avg_fields + count(columns: [smith_select_column!], distinct: Boolean): Int! + max: smith_max_fields + min: smith_min_fields + stddev: smith_stddev_fields + stddev_pop: smith_stddev_pop_fields + stddev_samp: smith_stddev_samp_fields + sum: smith_sum_fields + var_pop: smith_var_pop_fields + var_samp: smith_var_samp_fields + variance: smith_variance_fields +} + +"""aggregate avg on columns""" +type smith_avg_fields { + idty_index: Float +} + +""" +Boolean expression to filter rows from the table "smith". All fields are combined with a logical 'AND'. +""" +input smith_bool_exp { + _and: [smith_bool_exp!] + _not: smith_bool_exp + _or: [smith_bool_exp!] + cert_issued: smith_cert_bool_exp + cert_issued_aggregate: smith_cert_aggregate_bool_exp + cert_received: smith_cert_bool_exp + cert_received_aggregate: smith_cert_aggregate_bool_exp + identity: identity_bool_exp + idty_index: Int_comparison_exp +} + +"""smith certifications""" +type smith_cert { + created_at: timestamptz! + created_on: Int! + + """An object relationship""" + created_on_block: block! + + """An object relationship""" + issuer: smith! + issuer_index: Int! + + """An object relationship""" + receiver: smith! + receiver_index: Int! +} + +""" +aggregated selection of "smith_cert" +""" +type smith_cert_aggregate { + aggregate: smith_cert_aggregate_fields + nodes: [smith_cert!]! +} + +input smith_cert_aggregate_bool_exp { + count: smith_cert_aggregate_bool_exp_count +} + +input smith_cert_aggregate_bool_exp_count { + arguments: [smith_cert_select_column!] + distinct: Boolean + filter: smith_cert_bool_exp + predicate: Int_comparison_exp! +} + +""" +aggregate fields of "smith_cert" +""" +type smith_cert_aggregate_fields { + avg: smith_cert_avg_fields + count(columns: [smith_cert_select_column!], distinct: Boolean): Int! + max: smith_cert_max_fields + min: smith_cert_min_fields + stddev: smith_cert_stddev_fields + stddev_pop: smith_cert_stddev_pop_fields + stddev_samp: smith_cert_stddev_samp_fields + sum: smith_cert_sum_fields + var_pop: smith_cert_var_pop_fields + var_samp: smith_cert_var_samp_fields + variance: smith_cert_variance_fields +} + +""" +order by aggregate values of table "smith_cert" +""" +input smith_cert_aggregate_order_by { + avg: smith_cert_avg_order_by + count: order_by + max: smith_cert_max_order_by + min: smith_cert_min_order_by + stddev: smith_cert_stddev_order_by + stddev_pop: smith_cert_stddev_pop_order_by + stddev_samp: smith_cert_stddev_samp_order_by + sum: smith_cert_sum_order_by + var_pop: smith_cert_var_pop_order_by + var_samp: smith_cert_var_samp_order_by + variance: smith_cert_variance_order_by +} + +"""aggregate avg on columns""" +type smith_cert_avg_fields { + created_on: Float + issuer_index: Float + receiver_index: Float +} + +""" +order by avg() on columns of table "smith_cert" +""" +input smith_cert_avg_order_by { + created_on: order_by + issuer_index: order_by + receiver_index: order_by +} + +""" +Boolean expression to filter rows from the table "smith_cert". All fields are combined with a logical 'AND'. +""" +input smith_cert_bool_exp { + _and: [smith_cert_bool_exp!] + _not: smith_cert_bool_exp + _or: [smith_cert_bool_exp!] + created_at: timestamptz_comparison_exp + created_on: Int_comparison_exp + created_on_block: block_bool_exp + issuer: smith_bool_exp + issuer_index: Int_comparison_exp + receiver: smith_bool_exp + receiver_index: Int_comparison_exp +} + +"""aggregate max on columns""" +type smith_cert_max_fields { + created_at: timestamptz + created_on: Int + issuer_index: Int + receiver_index: Int +} + +""" +order by max() on columns of table "smith_cert" +""" +input smith_cert_max_order_by { + created_at: order_by + created_on: order_by + issuer_index: order_by + receiver_index: order_by +} + +"""aggregate min on columns""" +type smith_cert_min_fields { + created_at: timestamptz + created_on: Int + issuer_index: Int + receiver_index: Int +} + +""" +order by min() on columns of table "smith_cert" +""" +input smith_cert_min_order_by { + created_at: order_by + created_on: order_by + issuer_index: order_by + receiver_index: order_by +} + +"""Ordering options when selecting data from "smith_cert".""" +input smith_cert_order_by { + created_at: order_by + created_on: order_by + created_on_block: block_order_by + issuer: smith_order_by + issuer_index: order_by + receiver: smith_order_by + receiver_index: order_by +} + +""" +select columns of table "smith_cert" +""" +enum smith_cert_select_column { + """column name""" + created_at + + """column name""" + created_on + + """column name""" + issuer_index + + """column name""" + receiver_index +} + +"""aggregate stddev on columns""" +type smith_cert_stddev_fields { + created_on: Float + issuer_index: Float + receiver_index: Float +} + +""" +order by stddev() on columns of table "smith_cert" +""" +input smith_cert_stddev_order_by { + created_on: order_by + issuer_index: order_by + receiver_index: order_by +} + +"""aggregate stddev_pop on columns""" +type smith_cert_stddev_pop_fields { + created_on: Float + issuer_index: Float + receiver_index: Float +} + +""" +order by stddev_pop() on columns of table "smith_cert" +""" +input smith_cert_stddev_pop_order_by { + created_on: order_by + issuer_index: order_by + receiver_index: order_by +} + +"""aggregate stddev_samp on columns""" +type smith_cert_stddev_samp_fields { + created_on: Float + issuer_index: Float + receiver_index: Float +} + +""" +order by stddev_samp() on columns of table "smith_cert" +""" +input smith_cert_stddev_samp_order_by { + created_on: order_by + issuer_index: order_by + receiver_index: order_by +} + +""" +Streaming cursor of the table "smith_cert" +""" +input smith_cert_stream_cursor_input { + """Stream column input with initial value""" + initial_value: smith_cert_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input smith_cert_stream_cursor_value_input { + created_at: timestamptz + created_on: Int + issuer_index: Int + receiver_index: Int +} + +"""aggregate sum on columns""" +type smith_cert_sum_fields { + created_on: Int + issuer_index: Int + receiver_index: Int +} + +""" +order by sum() on columns of table "smith_cert" +""" +input smith_cert_sum_order_by { + created_on: order_by + issuer_index: order_by + receiver_index: order_by +} + +"""aggregate var_pop on columns""" +type smith_cert_var_pop_fields { + created_on: Float + issuer_index: Float + receiver_index: Float +} + +""" +order by var_pop() on columns of table "smith_cert" +""" +input smith_cert_var_pop_order_by { + created_on: order_by + issuer_index: order_by + receiver_index: order_by +} + +"""aggregate var_samp on columns""" +type smith_cert_var_samp_fields { + created_on: Float + issuer_index: Float + receiver_index: Float +} + +""" +order by var_samp() on columns of table "smith_cert" +""" +input smith_cert_var_samp_order_by { + created_on: order_by + issuer_index: order_by + receiver_index: order_by +} + +"""aggregate variance on columns""" +type smith_cert_variance_fields { + created_on: Float + issuer_index: Float + receiver_index: Float +} + +""" +order by variance() on columns of table "smith_cert" +""" +input smith_cert_variance_order_by { + created_on: order_by + issuer_index: order_by + receiver_index: order_by +} + +"""aggregate max on columns""" +type smith_max_fields { + idty_index: Int +} + +"""aggregate min on columns""" +type smith_min_fields { + idty_index: Int +} + +"""Ordering options when selecting data from "smith".""" +input smith_order_by { + cert_issued_aggregate: smith_cert_aggregate_order_by + cert_received_aggregate: smith_cert_aggregate_order_by + identity: identity_order_by + idty_index: order_by +} + +""" +select columns of table "smith" +""" +enum smith_select_column { + """column name""" + idty_index +} + +"""aggregate stddev on columns""" +type smith_stddev_fields { + idty_index: Float +} + +"""aggregate stddev_pop on columns""" +type smith_stddev_pop_fields { + idty_index: Float +} + +"""aggregate stddev_samp on columns""" +type smith_stddev_samp_fields { + idty_index: Float +} + +""" +Streaming cursor of the table "smith" +""" +input smith_stream_cursor_input { + """Stream column input with initial value""" + initial_value: smith_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input smith_stream_cursor_value_input { + idty_index: Int +} - """filter the rows returned""" - where: transaction_bool_exp - ): transaction_aggregate! +"""aggregate sum on columns""" +type smith_sum_fields { + idty_index: Int +} - """fetch data from the table: "transaction" using primary key columns""" - transaction_by_pk( - """ - Primary Key `id` is used for postgreSQL and Hasura relationship, not related to any value in substrate. - """ - id: Int! - ): transaction +"""aggregate var_pop on columns""" +type smith_var_pop_fields { + idty_index: Float } -input search_identity_args { - name: String +"""aggregate var_samp on columns""" +type smith_var_samp_fields { + idty_index: Float +} + +"""aggregate variance on columns""" +type smith_variance_fields { + idty_index: Float } """ @@ -1246,14 +2531,34 @@ type subscription_root { where: account_bool_exp ): [account!]! + """ + fetch aggregated fields from the table: "account" + """ + account_aggregate( + """distinct select on columns""" + distinct_on: [account_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [account_order_by!] + + """filter the rows returned""" + where: account_bool_exp + ): account_aggregate! + """fetch data from the table: "account" using primary key columns""" account_by_pk( """Pubkey of the account.""" - id: String! + pubkey: String! ): account """ - fetch data from the table in a streaming manner : "account" + fetch data from the table in a streaming manner: "account" """ account_stream( """maximum number of rows returned in a single batch""" @@ -1286,14 +2591,34 @@ type subscription_root { where: block_bool_exp ): [block!]! + """ + fetch aggregated fields from the table: "block" + """ + block_aggregate( + """distinct select on columns""" + distinct_on: [block_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [block_order_by!] + + """filter the rows returned""" + where: block_bool_exp + ): block_aggregate! + """fetch data from the table: "block" using primary key columns""" block_by_pk( - """Index of the block in substrate.""" - index: Int! + """Number of the block in substrate.""" + number: Int! ): block """ - fetch data from the table in a streaming manner : "block" + fetch data from the table in a streaming manner: "block" """ block_stream( """maximum number of rows returned in a single batch""" @@ -1347,10 +2672,19 @@ type subscription_root { ): certification_aggregate! """fetch data from the table: "certification" using primary key columns""" - certification_by_pk(issuer_id: String!, receiver_id: String!): certification + certification_by_pk( + """Block number where certification was created.""" + created_on: Int! + + """Index of issuer""" + issuer_index: Int! + + """Index of receiver""" + receiver_index: Int! + ): certification """ - fetch data from the table in a streaming manner : "certification" + fetch data from the table in a streaming manner: "certification" """ certification_stream( """maximum number of rows returned in a single batch""" @@ -1383,14 +2717,31 @@ type subscription_root { where: identity_bool_exp ): [identity!]! + """ + fetch aggregated fields from the table: "identity" + """ + identity_aggregate( + """distinct select on columns""" + distinct_on: [identity_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [identity_order_by!] + + """filter the rows returned""" + where: identity_bool_exp + ): identity_aggregate! + """fetch data from the table: "identity" using primary key columns""" - identity_by_pk( - """Pubkey of the account associated to this identity.""" - id: String! - ): identity + identity_by_pk(index: Int!): identity """ - fetch data from the table in a streaming manner : "identity" + fetch data from the table in a streaming manner: "identity" """ identity_stream( """maximum number of rows returned in a single batch""" @@ -1427,7 +2778,7 @@ type subscription_root { parameters_by_pk(key: String!): parameters """ - fetch data from the table in a streaming manner : "parameters" + fetch data from the table in a streaming manner: "parameters" """ parameters_stream( """maximum number of rows returned in a single batch""" @@ -1465,6 +2816,145 @@ type subscription_root { where: identity_bool_exp ): [identity!]! + """ + execute function "search_identity" and query aggregates on result of table type "identity" + """ + search_identity_aggregate( + """ + input parameters for function "search_identity_aggregate" + """ + args: search_identity_args! + + """distinct select on columns""" + distinct_on: [identity_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [identity_order_by!] + + """filter the rows returned""" + where: identity_bool_exp + ): identity_aggregate! + + """ + fetch data from the table: "smith" + """ + smith( + """distinct select on columns""" + distinct_on: [smith_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [smith_order_by!] + + """filter the rows returned""" + where: smith_bool_exp + ): [smith!]! + + """ + fetch aggregated fields from the table: "smith" + """ + smith_aggregate( + """distinct select on columns""" + distinct_on: [smith_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [smith_order_by!] + + """filter the rows returned""" + where: smith_bool_exp + ): smith_aggregate! + + """fetch data from the table: "smith" using primary key columns""" + smith_by_pk(idty_index: Int!): smith + + """ + fetch data from the table: "smith_cert" + """ + smith_cert( + """distinct select on columns""" + distinct_on: [smith_cert_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [smith_cert_order_by!] + + """filter the rows returned""" + where: smith_cert_bool_exp + ): [smith_cert!]! + + """ + fetch aggregated fields from the table: "smith_cert" + """ + smith_cert_aggregate( + """distinct select on columns""" + distinct_on: [smith_cert_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [smith_cert_order_by!] + + """filter the rows returned""" + where: smith_cert_bool_exp + ): smith_cert_aggregate! + + """fetch data from the table: "smith_cert" using primary key columns""" + smith_cert_by_pk(created_on: Int!, issuer_index: Int!, receiver_index: Int!): smith_cert + + """ + fetch data from the table in a streaming manner: "smith_cert" + """ + smith_cert_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [smith_cert_stream_cursor_input]! + + """filter the rows returned""" + where: smith_cert_bool_exp + ): [smith_cert!]! + + """ + fetch data from the table in a streaming manner: "smith" + """ + smith_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [smith_stream_cursor_input]! + + """filter the rows returned""" + where: smith_bool_exp + ): [smith!]! + """ fetch data from the table: "transaction" """ @@ -1514,7 +3004,7 @@ type subscription_root { ): transaction """ - fetch data from the table in a streaming manner : "transaction" + fetch data from the table in a streaming manner: "transaction" """ transaction_stream( """maximum number of rows returned in a single batch""" @@ -1526,8 +3016,74 @@ type subscription_root { """filter the rows returned""" where: transaction_bool_exp ): [transaction!]! + + """ + execute function "transaction_timeserie" which returns "transaction_timeserie_tmp" + """ + transaction_timeserie( + """ + input parameters for function "transaction_timeserie" + """ + args: transaction_timeserie_args! + + """distinct select on columns""" + distinct_on: [transaction_timeserie_tmp_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [transaction_timeserie_tmp_order_by!] + + """filter the rows returned""" + where: transaction_timeserie_tmp_bool_exp + ): [transaction_timeserie_tmp!]! + + """ + fetch data from the table: "transaction_timeserie_tmp" + """ + transaction_timeserie_tmp( + """distinct select on columns""" + distinct_on: [transaction_timeserie_tmp_select_column!] + + """limit the number of rows returned""" + limit: Int + + """skip the first n rows. Use only with order_by""" + offset: Int + + """sort the rows by one or more columns""" + order_by: [transaction_timeserie_tmp_order_by!] + + """filter the rows returned""" + where: transaction_timeserie_tmp_bool_exp + ): [transaction_timeserie_tmp!]! + + """ + fetch data from the table: "transaction_timeserie_tmp" using primary key columns + """ + transaction_timeserie_tmp_by_pk(date: timestamptz!): transaction_timeserie_tmp + + """ + fetch data from the table in a streaming manner: "transaction_timeserie_tmp" + """ + transaction_timeserie_tmp_stream( + """maximum number of rows returned in a single batch""" + batch_size: Int! + + """cursor to stream the results returned by the query""" + cursor: [transaction_timeserie_tmp_stream_cursor_input]! + + """filter the rows returned""" + where: transaction_timeserie_tmp_bool_exp + ): [transaction_timeserie_tmp!]! } +scalar time_period + scalar timestamp """ @@ -1566,6 +3122,7 @@ input timestamptz_comparison_exp { type transaction { """Amount of the transaction. 100 units = 1 Ğ1.""" amount: Float! + comment: String created_at: timestamptz! """Block number where transaction was created.""" @@ -1581,11 +3138,11 @@ type transaction { """An object relationship""" issuer: account! - issuer_id: String! + issuer_pubkey: String! """An object relationship""" receiver: account! - receiver_id: String! + receiver_pubkey: String! } """ @@ -1596,6 +3153,17 @@ type transaction_aggregate { nodes: [transaction!]! } +input transaction_aggregate_bool_exp { + count: transaction_aggregate_bool_exp_count +} + +input transaction_aggregate_bool_exp_count { + arguments: [transaction_select_column!] + distinct: Boolean + filter: transaction_bool_exp + predicate: Int_comparison_exp! +} + """ aggregate fields of "transaction" """ @@ -1668,20 +3236,22 @@ input transaction_bool_exp { _not: transaction_bool_exp _or: [transaction_bool_exp!] amount: Float_comparison_exp + comment: String_comparison_exp created_at: timestamptz_comparison_exp created_on: Int_comparison_exp created_on_block: block_bool_exp id: Int_comparison_exp issuer: account_bool_exp - issuer_id: String_comparison_exp + issuer_pubkey: String_comparison_exp receiver: account_bool_exp - receiver_id: String_comparison_exp + receiver_pubkey: String_comparison_exp } """aggregate max on columns""" type transaction_max_fields { """Amount of the transaction. 100 units = 1 Ğ1.""" amount: Float + comment: String created_at: timestamptz """Block number where transaction was created.""" @@ -1691,8 +3261,8 @@ type transaction_max_fields { Primary Key `id` is used for postgreSQL and Hasura relationship, not related to any value in substrate. """ id: Int - issuer_id: String - receiver_id: String + issuer_pubkey: String + receiver_pubkey: String } """ @@ -1701,6 +3271,7 @@ order by max() on columns of table "transaction" input transaction_max_order_by { """Amount of the transaction. 100 units = 1 Ğ1.""" amount: order_by + comment: order_by created_at: order_by """Block number where transaction was created.""" @@ -1710,14 +3281,15 @@ input transaction_max_order_by { Primary Key `id` is used for postgreSQL and Hasura relationship, not related to any value in substrate. """ id: order_by - issuer_id: order_by - receiver_id: order_by + issuer_pubkey: order_by + receiver_pubkey: order_by } """aggregate min on columns""" type transaction_min_fields { """Amount of the transaction. 100 units = 1 Ğ1.""" amount: Float + comment: String created_at: timestamptz """Block number where transaction was created.""" @@ -1727,8 +3299,8 @@ type transaction_min_fields { Primary Key `id` is used for postgreSQL and Hasura relationship, not related to any value in substrate. """ id: Int - issuer_id: String - receiver_id: String + issuer_pubkey: String + receiver_pubkey: String } """ @@ -1737,6 +3309,7 @@ order by min() on columns of table "transaction" input transaction_min_order_by { """Amount of the transaction. 100 units = 1 Ğ1.""" amount: order_by + comment: order_by created_at: order_by """Block number where transaction was created.""" @@ -1746,21 +3319,22 @@ input transaction_min_order_by { Primary Key `id` is used for postgreSQL and Hasura relationship, not related to any value in substrate. """ id: order_by - issuer_id: order_by - receiver_id: order_by + issuer_pubkey: order_by + receiver_pubkey: order_by } """Ordering options when selecting data from "transaction".""" input transaction_order_by { amount: order_by + comment: order_by created_at: order_by created_on: order_by created_on_block: block_order_by id: order_by issuer: account_order_by - issuer_id: order_by + issuer_pubkey: order_by receiver: account_order_by - receiver_id: order_by + receiver_pubkey: order_by } """ @@ -1770,6 +3344,9 @@ enum transaction_select_column { """column name""" amount + """column name""" + comment + """column name""" created_at @@ -1780,10 +3357,10 @@ enum transaction_select_column { id """column name""" - issuer_id + issuer_pubkey """column name""" - receiver_id + receiver_pubkey } """aggregate stddev on columns""" @@ -1891,6 +3468,7 @@ input transaction_stream_cursor_input { input transaction_stream_cursor_value_input { """Amount of the transaction. 100 units = 1 Ğ1.""" amount: Float + comment: String created_at: timestamptz """Block number where transaction was created.""" @@ -1900,8 +3478,8 @@ input transaction_stream_cursor_value_input { Primary Key `id` is used for postgreSQL and Hasura relationship, not related to any value in substrate. """ id: Int - issuer_id: String - receiver_id: String + issuer_pubkey: String + receiver_pubkey: String } """aggregate sum on columns""" @@ -1934,6 +3512,65 @@ input transaction_sum_order_by { id: order_by } +input transaction_timeserie_args { + from: date + issuer_pk: String + period: time_period + receiver_pk: String + to: date +} + +"""This table is empty. It's only for Hasura.""" +type transaction_timeserie_tmp { + amount: Float! + date: timestamptz! +} + +""" +Boolean expression to filter rows from the table "transaction_timeserie_tmp". All fields are combined with a logical 'AND'. +""" +input transaction_timeserie_tmp_bool_exp { + _and: [transaction_timeserie_tmp_bool_exp!] + _not: transaction_timeserie_tmp_bool_exp + _or: [transaction_timeserie_tmp_bool_exp!] + amount: Float_comparison_exp + date: timestamptz_comparison_exp +} + +"""Ordering options when selecting data from "transaction_timeserie_tmp".""" +input transaction_timeserie_tmp_order_by { + amount: order_by + date: order_by +} + +""" +select columns of table "transaction_timeserie_tmp" +""" +enum transaction_timeserie_tmp_select_column { + """column name""" + amount + + """column name""" + date +} + +""" +Streaming cursor of the table "transaction_timeserie_tmp" +""" +input transaction_timeserie_tmp_stream_cursor_input { + """Stream column input with initial value""" + initial_value: transaction_timeserie_tmp_stream_cursor_value_input! + + """cursor ordering""" + ordering: cursor_ordering +} + +"""Initial value of the column from where the streaming should start""" +input transaction_timeserie_tmp_stream_cursor_value_input { + amount: Float + date: timestamptz +} + """aggregate var_pop on columns""" type transaction_var_pop_fields { """Amount of the transaction. 100 units = 1 Ğ1.""" diff --git a/res/metadata.scale b/res/metadata.scale index d8de4291f43a4003606bc6b6f0183ff31a696c85..9b04918d2b88645a3e41c6d1ac9339d222188b2e 100644 Binary files a/res/metadata.scale and b/res/metadata.scale differ diff --git a/src/commands.rs b/src/commands.rs index cd474b727bc03567f2b895183914a9f53e2f7944..3ce40227796a407e7cd83fe8e806a3363632e896 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -3,6 +3,7 @@ pub mod blockchain; pub mod certification; pub mod cesium; pub mod collective; +pub mod distance; pub mod expire; pub mod identity; pub mod net_test; @@ -13,4 +14,3 @@ pub mod smith; pub mod sudo; pub mod transfer; pub mod ud; -pub mod distance; diff --git a/src/commands/account.rs b/src/commands/account.rs index ffeb3f17e45edf7eff10e901901b582c5f22b576..df5c5539e7f0d394a68550d5d9bee04a683ca069 100644 --- a/src/commands/account.rs +++ b/src/commands/account.rs @@ -35,9 +35,7 @@ pub enum Subcommand { pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliError> { let data = data.build_client().await?.fetch_system_properties().await?; match command { - Subcommand::Balance => { - get_balance(data).await? - } + Subcommand::Balance => get_balance(data).await?, Subcommand::Transfer { amount, dest, diff --git a/src/commands/cesium.rs b/src/commands/cesium.rs index cb6a104c18159611d89760d8c1b6c82c9d2951b6..bb071b18897c559b8bed7a5744d6ded2ff5bb11d 100644 --- a/src/commands/cesium.rs +++ b/src/commands/cesium.rs @@ -20,17 +20,15 @@ pub async fn handle_command(_data: Data, command: Subcommand) -> Result<(), Gcli Subcommand::Nothing => {} Subcommand::Pubkey { id, pass } => { let keypair = pair_from_cesium(id, pass); - println!( - "Pubkey: {}", - bs58::encode(keypair.pkey).into_string() - ); + println!("Pubkey: {}", bs58::encode(keypair.pkey).into_string()); + let address: AccountId = keypair.pkey.into(); + println!("Address: {}", address.to_string()); } Subcommand::Prompt => { let keypair = prompt_secret_cesium(); - println!( - "Pubkey: {}", - bs58::encode(keypair.pkey).into_string() - ); + println!("Pubkey: {}", bs58::encode(keypair.pkey).into_string()); + let address: AccountId = keypair.pkey.into(); + println!("Address: {}", address.to_string()); } } Ok(()) diff --git a/src/commands/distance.rs b/src/commands/distance.rs index 24c1fe677400bfbefaf6aafb434725e2cee4a2ec..6eaaf4c53ad3604e3eebda42eebef747054914fa 100644 --- a/src/commands/distance.rs +++ b/src/commands/distance.rs @@ -2,23 +2,36 @@ use crate::*; /// request distance evaluation pub async fn request_distance_evaluation(data: &Data) -> Result<(), subxt::Error> { - let progress = submit_call(data, &runtime::tx().distance().request_distance_evaluation()) + let progress = submit_call( + data, + &runtime::tx().distance().request_distance_evaluation(), + ) .await?; - if data.args.no_wait { - return Ok(()); - } - let _ = track_progress(progress).await?; - Ok(()) + if data.args.no_wait { + return Ok(()); + } + let _ = track_progress(progress).await?; + Ok(()) } /// get identity distance status pub async fn get_identity_distance_status( data: &Data, -) -> Result<Option<(AccountId, runtime::runtime_types::pallet_distance::types::DistanceStatus)>, subxt::Error> { +) -> Result< + Option<( + AccountId, + runtime::runtime_types::pallet_distance::types::DistanceStatus, + )>, + subxt::Error, +> { data.client() .storage() .at_latest() .await? - .fetch(&runtime::storage().distance().identity_distance_status(data.idty_index())) + .fetch( + &runtime::storage() + .distance() + .identity_distance_status(data.idty_index()), + ) .await -} \ No newline at end of file +} diff --git a/src/commands/identity.rs b/src/commands/identity.rs index 2ddcc678adeb21022ddb4d1ee6b7f5921a649c38..fc4e7ba3c7fd29b8f1612ee99d91722b4be96708 100644 --- a/src/commands/identity.rs +++ b/src/commands/identity.rs @@ -3,17 +3,15 @@ use crate::*; use crate::{ commands::revocation::generate_revoc_doc, runtime::runtime_types::{ - common_runtime::entities::{IdtyData, NewOwnerKeySignature}, - pallet_identity::types::*, - sp_runtime::MultiSignature, + common_runtime::entities::IdtyData, pallet_identity::types::*, sp_runtime::MultiSignature, }, }; -use std::str::FromStr; /// define identity subcommands #[derive(Clone, Default, Debug, clap::Parser)] pub enum Subcommand { - /// show identity + /// Show identity + /// (same as get but without arg) #[default] Show, /// Fetch identity @@ -62,6 +60,17 @@ pub enum Subcommand { #[clap(short, long)] secret: Option<String>, }, + /// Migrate identity to another account + /// Change Owner Key + ChangeOwnerKey { + /// Secret key format (seed, substrate) + #[clap(short = 'S', long, default_value = SecretFormat::Substrate)] + secret_format: SecretFormat, + /// Secret of account to link + /// most likely different from the one owning the identity + #[clap(short, long)] + secret: Option<String>, + }, } /// handle identity commands @@ -69,7 +78,10 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE let mut data = data.build_client().await?; match command { // TODO remove indexer where not necessary when BlakeConcat will be there - Subcommand::Show => {} + Subcommand::Show => { + data = data.build_indexer().await?; + get_identity(&data, Some(data.address()), None, None).await? + } Subcommand::Get { ref account_id, identity_id, @@ -132,6 +144,15 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE data = data.fetch_idty_index().await?; // idty index required for payload link_account(&data, address, keypair).await?; } + Subcommand::ChangeOwnerKey { + secret_format, + secret, + } => { + let keypair = get_keypair(secret_format, secret.as_deref())?; + let address = keypair.address(); + data = data.fetch_idty_index().await?; // idty index required for payload + change_owner_key(&data, address, keypair).await?; + } }; Ok(()) @@ -149,26 +170,31 @@ pub async fn get_identity( let client = data.client(); let indexer = data.indexer.clone(); - // fetch missing information + // fetch reachable information using Duniter only (no indexer) match (&account_id, identity_id, &username) { + // idty_id → account_id (None, Some(identity_id), None) => { account_id = get_identity_by_index(client, identity_id) .await? .map(|idty| idty.owner_key); + if account_id.is_none() { + return Err(anyhow!("no identity for this account id")); + } } + // account_id → idty_id (Some(account_id), None, None) => { identity_id = get_idty_index_by_account_id(client, account_id).await?; + if identity_id.is_none() { + return Err(anyhow!("no identity for this identity index")); + } } + // username → idty_id and account_id (None, None, Some(username)) => { - let indexer = indexer.as_ref().ok_or(anyhow!( - "Cannot fetch identity from username without indexer." - ))?; - if let Some(pubkey) = indexer.pubkey_by_username(username).await? { - // convert string to accountid - let fetched_account_id = AccountId::from_str(&pubkey).map_err(|e| anyhow!(e))?; - // in the future, also ask indexer the identity index - identity_id = get_idty_index_by_account_id(client, &fetched_account_id).await?; - account_id = Some(fetched_account_id); + identity_id = get_idty_index_by_name(client, username).await?; + if let Some(identity_id) = identity_id { + account_id = get_identity_by_index(client, identity_id) + .await? + .map(|idty| idty.owner_key); } else { return Err(anyhow!("no identity found for this username")); } @@ -181,24 +207,26 @@ pub async fn get_identity( }; // print result + // 1. identity index println!( - "Account id: {}", - account_id - .as_ref() - .map_or(String::new(), AccountId::to_string) - ); - println!( - "Identity id: {}", + "Identity index: {}", identity_id.map_or(String::new(), |identity_id| format!("{identity_id}")) ); - - if let (Some(indexer), Some(account_id), None) = (&indexer, &account_id, &username) { - username = indexer.username_by_pubkey(&account_id.to_string()).await?; + // 2. username (indexer needed if not provided) + if let (Some(indexer), Some(identity_id), None) = (&indexer, identity_id, &username) { + username = indexer.username_by_index(identity_id).await?; } println!( - "Username: {}", + "Username: {}", username.unwrap_or("<no indexer>".to_string()) ); + // 3. address + println!( + "Address: {}", + account_id + .as_ref() + .map_or(String::new(), AccountId::to_string) + ); Ok(()) } @@ -207,26 +235,39 @@ pub async fn get_identity( pub async fn get_idty_index_by_account_id( client: &Client, account_id: &AccountId, -) -> Result<Option<IdtyId>, anyhow::Error> { - Ok(client +) -> Result<Option<IdtyId>, subxt::Error> { + client .storage() .at_latest() .await? .fetch(&runtime::storage().identity().identity_index_of(account_id)) - .await?) + .await +} + +/// get identity index by name +pub async fn get_idty_index_by_name( + client: &Client, + name: &str, +) -> Result<Option<IdtyId>, subxt::Error> { + client + .storage() + .at_latest() + .await? + .fetch(&runtime::storage().identity().identities_names(name)) + .await } /// get identityt value by index pub async fn get_identity_by_index( client: &Client, idty_index: IdtyId, -) -> Result<Option<IdtyValue<IdtyId, AccountId, IdtyData>>, anyhow::Error> { - Ok(client +) -> Result<Option<IdtyValue<IdtyId, AccountId, IdtyData>>, subxt::Error> { + client .storage() .at_latest() .await? .fetch(&runtime::storage().identity().identities(idty_index)) - .await?) + .await } /// created identity @@ -292,13 +333,45 @@ pub fn generate_link_account( data: &Data, address: AccountId, keypair: KeyPair, -) -> (LinkAccountPayload, sr25519::Signature) { +) -> (LinkAccountPayload, Signature) { let payload = (b"link", data.genesis_hash, data.idty_index(), address).encode(); - let KeyPair::Sr25519(keypair) = keypair else { - panic!("Cesium keys not implemented there") - }; - let signature = keypair.sign(&payload); - (payload, signature) + match keypair { + KeyPair::Sr25519(keypair) => { + let signature = keypair.sign(&payload); + (payload, Signature::Sr25519(signature)) + } + KeyPair::Nacl(keypair) => { + let signature = nacl::sign::signature(&payload, &keypair.skey).expect("could not sign"); + (payload, Signature::Nacl(signature)) + } + } +} + +type ChOkPayload = Vec<u8>; +/// generate link account document +pub fn generate_chok_payload( + data: &Data, + _address: AccountId, + keypair: KeyPair, +) -> (ChOkPayload, Signature) { + let payload = ( + b"icok", + data.genesis_hash, + data.idty_index(), + data.address(), + ) + .encode(); + match keypair { + KeyPair::Sr25519(keypair) => { + let signature = keypair.sign(&payload); + (payload, Signature::Sr25519(signature)) + } + KeyPair::Nacl(keypair) => { + // should not migrate to Nacl + let signature = nacl::sign::signature(&payload, &keypair.skey).expect("could not sign"); + (payload, Signature::Nacl(signature)) + } + } } /// link an account to the identity @@ -311,16 +384,52 @@ pub async fn link_account( // this is a hack, see // https://substrate.stackexchange.com/questions/10309/how-to-use-core-crypto-types-instead-of-runtime-types - let signature = runtime::runtime_types::sp_core::sr25519::Signature(signature.0); + let signature = match signature { + Signature::Sr25519(signature) => MultiSignature::Sr25519( + runtime::runtime_types::sp_core::sr25519::Signature(signature.0), + ), + Signature::Nacl(signature) => MultiSignature::Ed25519( + runtime::runtime_types::sp_core::ed25519::Signature(signature.try_into().unwrap()), + ), + }; submit_call_and_look_event::< runtime::account::events::AccountLinked, Payload<runtime::identity::calls::types::LinkAccount>, + >( + data, + &runtime::tx().identity().link_account(address, signature), + ) + .await +} + +/// change owner key +pub async fn change_owner_key( + data: &Data, + address: AccountId, + keypair: KeyPair, +) -> Result<(), subxt::Error> { + let (_payload, signature) = generate_chok_payload(data, address.clone(), keypair); + + // this is a hack, see + // https://substrate.stackexchange.com/questions/10309/how-to-use-core-crypto-types-instead-of-runtime-types + let signature = match signature { + Signature::Sr25519(signature) => MultiSignature::Sr25519( + runtime::runtime_types::sp_core::sr25519::Signature(signature.0), + ), + Signature::Nacl(signature) => MultiSignature::Ed25519( + runtime::runtime_types::sp_core::ed25519::Signature(signature.try_into().unwrap()), + ), + }; + + submit_call_and_look_event::< + runtime::identity::events::IdtyChangedOwnerKey, + Payload<runtime::identity::calls::types::ChangeOwnerKey>, >( data, &runtime::tx() .identity() - .link_account(address, NewOwnerKeySignature(signature)), + .change_owner_key(address, signature), ) .await } diff --git a/src/commands/smith.rs b/src/commands/smith.rs index 366bc36cab8fd05e81d8717003a585b850cfb461..807381f2387033bf9fa659abee40ac129530fb51 100644 --- a/src/commands/smith.rs +++ b/src/commands/smith.rs @@ -1,23 +1,55 @@ use crate::*; +#[cfg(feature = "gdev")] +use runtime::runtime_types::gdev_runtime::opaque::SessionKeys as RuntimeSessionKeys; use std::ops::Deref; type SessionKeys = [u8; 128]; -#[cfg(feature = "gdev")] -type SmithMembershipMetaData = - runtime::runtime_types::common_runtime::entities::SmithMembershipMetaData<SessionKeys>; + +/// decode byte array into runtime session keys +// TODO find a way to avoid doing this manually by importing session keys trait implementation +fn session_keys_decode(session_keys: SessionKeys) -> RuntimeSessionKeys { + RuntimeSessionKeys { + grandpa: runtime::runtime_types::sp_consensus_grandpa::app::Public( + runtime::runtime_types::sp_core::ed25519::Public( + session_keys[0..32].try_into().unwrap(), + ), + ) + .into(), + babe: runtime::runtime_types::sp_consensus_babe::app::Public( + runtime::runtime_types::sp_core::sr25519::Public( + session_keys[32..64].try_into().unwrap(), + ), + ) + .into(), + im_online: runtime::runtime_types::pallet_im_online::sr25519::app_sr25519::Public( + runtime::runtime_types::sp_core::sr25519::Public( + session_keys[64..96].try_into().unwrap(), + ), + ) + .into(), + authority_discovery: runtime::runtime_types::sp_authority_discovery::app::Public( + runtime::runtime_types::sp_core::sr25519::Public( + session_keys[96..128].try_into().unwrap(), + ), + ) + .into(), + } +} /// define smith subcommands #[derive(Clone, Default, Debug, clap::Parser)] pub enum Subcommand { /// Request smith membership - Request { endpoint: String }, + Request, /// Emit a smith certification Cert { to: IdtyId }, /// Claim smith membership Claim, /// Renew smith membership Renew, + /// Revoke smith membership + Revoke, /// go online GoOnline, /// go offline @@ -25,6 +57,8 @@ pub enum Subcommand { GoOffline, /// Rotate and set session keys UpdateKeys, + /// Set session keys + SetSessionKeys { session_keys: String }, /// List upcoming expirations that require an action ShowExpire { /// Show certs that expire within less than this number of blocks @@ -44,8 +78,8 @@ pub enum Subcommand { pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliError> { let mut data = data.build_client().await?; match command { - Subcommand::Request { endpoint } => { - request_smith_membership(&data, endpoint).await?; + Subcommand::Request => { + request_smith_membership(&data).await?; } Subcommand::Claim => { claim_smith_membership(&data).await?; @@ -53,6 +87,9 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE Subcommand::Renew => { renew_smith_membership(&data).await?; } + Subcommand::Revoke => { + revoke_smith_membership(&data).await?; + } Subcommand::GoOnline => { go_online(&data).await?; } @@ -66,6 +103,15 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE Subcommand::UpdateKeys => { update_session_keys(&data).await?; } + Subcommand::SetSessionKeys { session_keys } => { + let session_keys = session_keys_decode( + hex::decode(session_keys) + .expect("wrong hexadecimal") + .try_into() + .expect("wrong format"), + ); // decode session keys from hex string + set_session_keys(&data, session_keys).await?; + } Subcommand::ShowExpire { blocks, sessions } => { data = data.build_client().await?.build_indexer().await?; commands::expire::monitor_expirations(&data, blocks, sessions).await? @@ -113,30 +159,18 @@ pub async fn rotate_keys(data: &Data) -> Result<SessionKeys, anyhow::Error> { } /// request smith membership -pub async fn request_smith_membership(data: &Data, endpoint: String) -> Result<(), anyhow::Error> { - let session_keys = rotate_keys(data).await?; - let metadata = SmithMembershipMetaData { - session_keys, - owner_key: data.address(), - p2p_endpoint: endpoint, - }; +pub async fn request_smith_membership(data: &Data) -> Result<(), subxt::Error> { submit_call_and_look_event::< runtime::smith_membership::events::MembershipRequested, Payload<runtime::smith_membership::calls::types::RequestMembership>, - >( - data, - &runtime::tx() - .smith_membership() - .request_membership(metadata), - ) + >(data, &runtime::tx().smith_membership().request_membership()) .await - .map_err(|e| anyhow!(e)) } /// set session keys pub async fn set_session_keys( data: &Data, - session_keys: SessionKeys, + session_keys: RuntimeSessionKeys, ) -> Result<TxProgress, subxt::Error> { submit_call::<Payload<runtime::authority_members::calls::types::SetSessionKeys>>( data, @@ -147,9 +181,13 @@ pub async fn set_session_keys( .await } +// use runtime::runtime_types::sp_consensus_grandpa::app::Public + /// update session keys pub async fn update_session_keys(data: &Data) -> Result<(), GcliError> { let session_keys = rotate_keys(data).await?; + // manual session key conversion + let session_keys = session_keys_decode(session_keys); let progress = set_session_keys(data, session_keys).await?; if data.args.no_wait { @@ -201,6 +239,15 @@ pub async fn renew_smith_membership(data: &Data) -> Result<(), subxt::Error> { .await } +/// revoke smith membership +pub async fn revoke_smith_membership(data: &Data) -> Result<(), subxt::Error> { + submit_call_and_look_event::< + runtime::smith_membership::events::MembershipRevoked, + Payload<runtime::smith_membership::calls::types::RevokeMembership>, + >(data, &runtime::tx().smith_membership().revoke_membership()) + .await +} + /// submit go_offline pub async fn go_offline(data: &Data) -> Result<(), subxt::Error> { submit_call_and_look_event::< diff --git a/src/commands/sudo.rs b/src/commands/sudo.rs index afd497bc4ecbf3057888b110819dae17eceea173..b54e5eb5dd6f2282e351964d4329a56e686cd904 100644 --- a/src/commands/sudo.rs +++ b/src/commands/sudo.rs @@ -1,6 +1,5 @@ use crate::*; - /// define sudo subcommands #[derive(Clone, Default, Debug, clap::Parser)] pub enum Subcommand { @@ -30,7 +29,6 @@ pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliE Ok(()) } - /// set sudo key pub async fn set_key(data: &Data, new_key: AccountId) -> Result<(), subxt::Error> { submit_call_and_look_event::< @@ -40,10 +38,15 @@ pub async fn set_key(data: &Data, new_key: AccountId) -> Result<(), subxt::Error .await } - /// set distance ok pub async fn set_distance_ok(data: &Data, identity: IdtyId) -> Result<(), subxt::Error> { - let inner = runtime::distance::Call::force_set_distance_status { identity, status: Some((data.address(), runtime::runtime_types::pallet_distance::types::DistanceStatus::Valid)) }; + let inner = runtime::distance::Call::force_set_distance_status { + identity, + status: Some(( + data.address(), + runtime::runtime_types::pallet_distance::types::DistanceStatus::Valid, + )), + }; let inner = runtime::Call::Distance(inner); submit_call_and_look_event::< runtime::sudo::events::Sudid, diff --git a/src/commands/ud.rs b/src/commands/ud.rs index 50606cb1921c3baed261e7842cb931436082c8fd..7d4ed84bcd8908bda81b278d7955426f7c3886fb 100644 --- a/src/commands/ud.rs +++ b/src/commands/ud.rs @@ -11,7 +11,7 @@ pub enum Subcommand { /// handle ud commands pub async fn handle_command(data: Data, command: Subcommand) -> Result<(), GcliError> { // build indexer because it is needed for all subcommands - let data = data.build_client().await?; + let data = data.build_client().await?.fetch_system_properties().await?; // match subcommand match command { Subcommand::Claim => { diff --git a/src/data.rs b/src/data.rs index bbeb551ec878aab4ea0a2afabea5d6af7ae6dbb7..dcfc11255caaf4c4421869d07c51e8641ce7486f 100644 --- a/src/data.rs +++ b/src/data.rs @@ -144,14 +144,18 @@ impl Data { if let Some(indexer_endpoint) = self.args.indexer.clone() { self.cfg.indexer_endpoint = indexer_endpoint } - // predefined secret format overwrites secret with mnemonic + // secret format and value if self.args.secret_format == SecretFormat::Predefined { + // predefined secret format overwrites secret with mnemonic match self.args.secret.clone() { None => {} Some(derivation) => { self.cfg.secret = Some(predefined_mnemonic(&derivation)); } }; + } else if self.args.secret_format == SecretFormat::Cesium { + // cesium secret format also overwrites, to force valid prompt + self.cfg.secret = None } else if let Some(secret) = self.args.secret.clone() { // other secret type self.cfg.secret = Some(secret); diff --git a/src/display.rs b/src/display.rs index 5631a07d06962909ceae41095de905e7a72d0a56..7f68d8d97b3c7cdc3ffa19ee88f72d59adce27b7 100644 --- a/src/display.rs +++ b/src/display.rs @@ -9,7 +9,8 @@ impl DisplayEvent for runtime::universal_dividend::events::UdsClaimed { fn display(&self, data: &Data) -> String { format!( "claimed {} UD, for a total of {}", - self.count, data.format_balance(self.total) + self.count, + data.format_balance(self.total) ) } } @@ -45,12 +46,18 @@ impl DisplayEvent for runtime::technical_committee::events::Voted { } impl DisplayEvent for runtime::identity::events::IdtyCreated { fn display(&self, _data: &Data) -> String { - format!("identity created for {} with index {}", self.owner_key, self.idty_index) + format!( + "identity created for {} with index {}", + self.owner_key, self.idty_index + ) } } impl DisplayEvent for runtime::identity::events::IdtyConfirmed { fn display(&self, _data: &Data) -> String { - format!("identity confirmed with name \"{}\" (index {}, owner key {})", self.name, self.idty_index, self.owner_key) + format!( + "identity confirmed with name \"{}\" (index {}, owner key {})", + self.name, self.idty_index, self.owner_key + ) } } impl DisplayEvent for runtime::identity::events::IdtyValidated { @@ -58,6 +65,11 @@ impl DisplayEvent for runtime::identity::events::IdtyValidated { format!("identity validated {:?}", self) } } +impl DisplayEvent for runtime::identity::events::IdtyChangedOwnerKey { + fn display(&self, _data: &Data) -> String { + format!("identity changed owner key {:?}", self) + } +} impl DisplayEvent for runtime::membership::events::MembershipRenewed { fn display(&self, _data: &Data) -> String { format!("membership renewed {:?}", self) @@ -100,7 +112,12 @@ impl DisplayEvent for runtime::smith_membership::events::MembershipAcquired { } impl DisplayEvent for runtime::smith_membership::events::MembershipRenewed { fn display(&self, _data: &Data) -> String { - format!("membership renewed {:?}", self) + format!("smith membership renewed {:?}", self) + } +} +impl DisplayEvent for runtime::smith_membership::events::MembershipRevoked { + fn display(&self, _data: &Data) -> String { + format!("smith membership revoked {:?}", self) } } impl DisplayEvent for runtime::authority_members::events::MemberGoOffline { @@ -115,7 +132,12 @@ impl DisplayEvent for runtime::sudo::events::KeyChanged { } impl DisplayEvent for runtime::balances::events::Transfer { fn display(&self, data: &Data) -> String { - format!("transfered {} ({} → {})", data.format_balance(self.amount), self.from, self.to) + format!( + "transfered {} ({} → {})", + data.format_balance(self.amount), + self.from, + self.to + ) } } impl DisplayEvent for runtime::utility::events::BatchCompleted { diff --git a/src/indexer.rs b/src/indexer.rs index 3f7b0d22586abf1ef05ee6b2fa2227cda6ffae6c..4a97cbcf613eb6ee82245a177375998678fc01c7 100644 --- a/src/indexer.rs +++ b/src/indexer.rs @@ -6,30 +6,40 @@ use crate::*; #[allow(non_camel_case_types)] type jsonb = serde_json::Value; +// index → identity #[derive(GraphQLQuery)] #[graphql( - schema_path = "res/indexer-schema.json", + schema_path = "res/indexer-schema.graphql", query_path = "res/indexer-queries.graphql" )] -pub struct IdentityNameByPubkey; +pub struct IdentityByIndex; +// // name → identity +// #[derive(GraphQLQuery)] +// #[graphql( +// schema_path = "res/indexer-schema.graphql", +// query_path = "res/indexer-queries.graphql" +// )] +// pub struct IdentityByName; + +// pubkey → identity #[derive(GraphQLQuery)] #[graphql( - schema_path = "res/indexer-schema.json", + schema_path = "res/indexer-schema.graphql", query_path = "res/indexer-queries.graphql" )] -pub struct IdentityPubkeyByName; +pub struct IdentityByPubkey; #[derive(GraphQLQuery)] #[graphql( - schema_path = "res/indexer-schema.json", + schema_path = "res/indexer-schema.graphql", query_path = "res/indexer-queries.graphql" )] pub struct LatestBlock; #[derive(GraphQLQuery)] #[graphql( - schema_path = "res/indexer-schema.json", + schema_path = "res/indexer-schema.graphql", query_path = "res/indexer-queries.graphql" )] pub struct GenesisHash; @@ -41,32 +51,48 @@ pub struct Indexer { } impl Indexer { - pub async fn username_by_pubkey(&self, pubkey: &str) -> anyhow::Result<Option<String>> { - Ok(post_graphql::<IdentityNameByPubkey, _>( + pub async fn username_by_index(&self, index: u32) -> anyhow::Result<Option<String>> { + Ok(post_graphql::<IdentityByIndex, _>( &self.gql_client, &self.gql_url, - identity_name_by_pubkey::Variables { - pubkey: pubkey.to_string(), + identity_by_index::Variables { + index: index.into(), }, ) .await? .data - .and_then(|data| data.identity.into_iter().next().map(|idty| idty.name))) + .and_then(|data| data.identity_by_pk.map(|idty| idty.name)) + .unwrap()) } - pub async fn pubkey_by_username(&self, username: &str) -> anyhow::Result<Option<String>> { - Ok(post_graphql::<IdentityPubkeyByName, _>( + pub async fn username_by_pubkey(&self, pubkey: &str) -> anyhow::Result<Option<String>> { + Ok(post_graphql::<IdentityByPubkey, _>( &self.gql_client, - self.gql_url.clone(), - identity_pubkey_by_name::Variables { - name: username.to_string(), + &self.gql_url, + identity_by_pubkey::Variables { + pubkey: pubkey.to_string(), }, ) .await? .data - .and_then(|data| data.identity_by_pk.map(|idty| idty.pubkey))) + .and_then(|data| data.identity.into_iter().next().map(|idty| idty.name)) + .unwrap()) } + // // not used anymore because available with Duniter + // pub async fn pubkey_by_username(&self, username: &str) -> anyhow::Result<Option<String>> { + // Ok(post_graphql::<IdentityByName, _>( + // &self.gql_client, + // self.gql_url.clone(), + // identity_by_name::Variables { + // name: username.to_string(), + // }, + // ) + // .await? + // .data + // .and_then(|data| data.identity.into_iter().next().map(|idty| idty.pubkey))) + // } + /// fetch latest block number pub async fn fetch_latest_block(&self) -> Result<u64, anyhow::Error> { Ok(post_graphql::<LatestBlock, _>( diff --git a/src/keys.rs b/src/keys.rs index f646cd61e5b322bba5a0ea2bd2db419cb1dc3139..e2243dc4d39c5525fc0abcc31e9519e3c674b102 100644 --- a/src/keys.rs +++ b/src/keys.rs @@ -48,7 +48,7 @@ impl From<SecretFormat> for OsStr { } } -/// wrapper type for keys +/// wrapper type for keys + signature pub enum KeyPair { Sr25519(Sr25519Pair), Nacl(nacl::sign::Keypair), @@ -83,6 +83,10 @@ impl From<nacl::sign::Keypair> for KeyPair { KeyPair::Nacl(pair) } } +pub enum Signature { + Sr25519(sr25519::Signature), + Nacl(Vec<u8>), +} /// get keypair in any possible way /// at this point, if secret is predefined, it's not replaced yet diff --git a/src/main.rs b/src/main.rs index 33910a75db12b475c1e3ea6bbafca302e513d766..d934e0250581e87a2d78d6e0dc10fbd4dbdbd301 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,10 +12,10 @@ use anyhow::anyhow; use clap::Parser; use codec::Encode; use data::*; +use display::DisplayEvent; use keys::*; use runtime_config::*; use serde::Deserialize; -use display::DisplayEvent; use subxt::{ blocks::ExtrinsicEvents, config::DefaultExtrinsicParamsBuilder,