antelopeql 2.0.0-rc.9 → 3.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/antelopeql.mjs +5 -4
- package/blockchain/{deserialize_action_data.mjs → abi_bin_to_json.mjs} +7 -3
- package/blockchain/get_abi.mjs +5 -5
- package/blockchain/get_account.mjs +9 -20
- package/blockchain/get_accounts_by_authorizers.mjs +17 -6
- package/blockchain/get_block.mjs +5 -5
- package/blockchain/get_currency_balance.mjs +5 -1
- package/blockchain/get_currency_stats.mjs +5 -5
- package/blockchain/get_info.mjs +16 -1
- package/blockchain/get_producers.mjs +6 -4
- package/blockchain/get_ram_price.mjs +15 -7
- package/blockchain/get_required_keys.mjs +7 -6
- package/blockchain/get_smart_contract.mjs +5 -5
- package/blockchain/get_table_by_scope.mjs +44 -5
- package/blockchain_query_field.mjs +7 -3
- package/build_graphql_fields_from_abis.mjs +17 -6
- package/eosio_abi_to_graphql_ast.mjs +31 -29
- package/eosio_types/name_type.mjs +1 -1
- package/eosio_types/public_key_type.mjs +3 -3
- package/eosio_types/symbol_type.mjs +1 -0
- package/graphql_input_types/actions.mjs +2 -2
- package/graphql_input_types/configuration.mjs +1 -1
- package/graphql_object_types/packed_transaction.mjs +9 -2
- package/mutation_resolver.mjs +6 -7
- package/package.json +16 -9
- package/query_resolver.mjs +3 -1
- package/readme.md +1 -1
- package/send_serialized_transaction.mjs +4 -3
- package/send_transaction.mjs +3 -1
- package/send_transaction_rpc.mjs +2 -0
- package/serialize_abi.mjs +1 -1
- package/serialize_transaction.mjs +3 -1
- package/types.mjs +13 -0
package/antelopeql.mjs
CHANGED
|
@@ -51,7 +51,8 @@ export default async function AntelopeQL({
|
|
|
51
51
|
signal
|
|
52
52
|
}) {
|
|
53
53
|
try {
|
|
54
|
-
if (!fetch)
|
|
54
|
+
if (!fetch)
|
|
55
|
+
throw new GraphQLError("No fetch implementation found in global scope");
|
|
55
56
|
|
|
56
57
|
const fetchOptions = {};
|
|
57
58
|
if (headers) fetchOptions.headers = headers;
|
|
@@ -66,7 +67,7 @@ export default async function AntelopeQL({
|
|
|
66
67
|
const queries = new GraphQLObjectType({
|
|
67
68
|
name: "Query",
|
|
68
69
|
description: "Query table data from Antelope blockchains.",
|
|
69
|
-
fields: {
|
|
70
|
+
fields: { get_blockchain: blockchain_query_field, ...query_fields }
|
|
70
71
|
});
|
|
71
72
|
|
|
72
73
|
let mutations;
|
|
@@ -102,10 +103,10 @@ export default async function AntelopeQL({
|
|
|
102
103
|
schema,
|
|
103
104
|
document,
|
|
104
105
|
rootValue: "",
|
|
105
|
-
contextValue: {
|
|
106
|
+
contextValue: () => ({
|
|
106
107
|
network: { rpc_url, fetch, ...fetchOptions },
|
|
107
108
|
signTransaction
|
|
108
|
-
},
|
|
109
|
+
}),
|
|
109
110
|
variableValues,
|
|
110
111
|
operationName,
|
|
111
112
|
fieldResolver(rootValue, args, ctx, { fieldName }) {
|
|
@@ -3,7 +3,7 @@ import { GraphQLError, GraphQLNonNull, GraphQLString } from "graphql";
|
|
|
3
3
|
import bytes_type from "../eosio_types/bytes_type.mjs";
|
|
4
4
|
import name_type from "../eosio_types/name_type.mjs";
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const abi_bin_to_json = {
|
|
7
7
|
description: "Returns a JSON object containing deserialized action data.",
|
|
8
8
|
type: GraphQLString,
|
|
9
9
|
args: {
|
|
@@ -20,7 +20,11 @@ const deserialize_action_data = {
|
|
|
20
20
|
type: new GraphQLNonNull(bytes_type)
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
|
-
async resolve(
|
|
23
|
+
async resolve(root, args, getContext, info) {
|
|
24
|
+
const {
|
|
25
|
+
network: { fetch, rpc_url, ...fetchOptions }
|
|
26
|
+
} = getContext(root, args, info);
|
|
27
|
+
|
|
24
28
|
const uri = `${rpc_url}/v1/chain/abi_bin_to_json`;
|
|
25
29
|
const req = await fetch(uri, {
|
|
26
30
|
method: "POST",
|
|
@@ -38,4 +42,4 @@ const deserialize_action_data = {
|
|
|
38
42
|
}
|
|
39
43
|
};
|
|
40
44
|
|
|
41
|
-
export default
|
|
45
|
+
export default abi_bin_to_json;
|
package/blockchain/get_abi.mjs
CHANGED
|
@@ -148,11 +148,11 @@ const get_abi = {
|
|
|
148
148
|
type: new GraphQLNonNull(name_type)
|
|
149
149
|
}
|
|
150
150
|
},
|
|
151
|
-
async resolve(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
151
|
+
async resolve(root, { account_name }, getContext, info) {
|
|
152
|
+
const {
|
|
153
|
+
network: { fetch, rpc_url, ...fetchOptions }
|
|
154
|
+
} = getContext(root, { account_name }, info);
|
|
155
|
+
|
|
156
156
|
const uri = `${rpc_url}/v1/chain/get_abi`;
|
|
157
157
|
const req = await fetch(uri, {
|
|
158
158
|
method: "POST",
|
|
@@ -27,7 +27,10 @@ const bandwidth_type = new GraphQLObjectType({
|
|
|
27
27
|
fields: () => ({
|
|
28
28
|
used: { type: GraphQLString },
|
|
29
29
|
available: { type: GraphQLString },
|
|
30
|
-
max: { type: GraphQLString }
|
|
30
|
+
max: { type: GraphQLString },
|
|
31
|
+
last_usage_update_time: {
|
|
32
|
+
type: GraphQLString
|
|
33
|
+
}
|
|
31
34
|
})
|
|
32
35
|
});
|
|
33
36
|
|
|
@@ -54,19 +57,6 @@ const require_auth_type = new GraphQLObjectType({
|
|
|
54
57
|
})
|
|
55
58
|
})
|
|
56
59
|
)
|
|
57
|
-
},
|
|
58
|
-
waits: {
|
|
59
|
-
type: new GraphQLList(
|
|
60
|
-
new GraphQLObjectType({
|
|
61
|
-
name: "account_auth_waits_type",
|
|
62
|
-
description:
|
|
63
|
-
"specifies that a transaction will not be executed without a required delay",
|
|
64
|
-
fields: () => ({
|
|
65
|
-
wait_sec: { type: GraphQLInt },
|
|
66
|
-
weight: { type: GraphQLInt }
|
|
67
|
-
})
|
|
68
|
-
})
|
|
69
|
-
)
|
|
70
60
|
}
|
|
71
61
|
})
|
|
72
62
|
});
|
|
@@ -207,11 +197,11 @@ const get_account = {
|
|
|
207
197
|
type: new GraphQLNonNull(name_type)
|
|
208
198
|
}
|
|
209
199
|
},
|
|
210
|
-
async resolve(
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
200
|
+
async resolve(root, { account_name }, getContext, info) {
|
|
201
|
+
const {
|
|
202
|
+
network: { fetch, rpc_url, ...fetchOptions }
|
|
203
|
+
} = getContext(root, { account_name }, info);
|
|
204
|
+
|
|
215
205
|
const uri = `${rpc_url}/v1/chain/get_account`;
|
|
216
206
|
const req = await fetch(uri, {
|
|
217
207
|
method: "POST",
|
|
@@ -223,7 +213,6 @@ const get_account = {
|
|
|
223
213
|
});
|
|
224
214
|
|
|
225
215
|
const data = await req.json();
|
|
226
|
-
|
|
227
216
|
if (data.error) throw new GraphQLError(data.message, { extensions: data });
|
|
228
217
|
|
|
229
218
|
return data;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import legacy_from_public_key from "antelope-ecc/keys/legacy_from_public_key.js";
|
|
2
|
+
import public_key_from_wif from "antelope-ecc/keys/public_key_from_wif.js";
|
|
1
3
|
import {
|
|
2
4
|
GraphQLError,
|
|
3
5
|
GraphQLList,
|
|
@@ -55,17 +57,26 @@ const accounts_by_authorizers = {
|
|
|
55
57
|
type: new GraphQLList(new GraphQLNonNull(public_key_type))
|
|
56
58
|
}
|
|
57
59
|
},
|
|
58
|
-
async resolve(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
async resolve(root, { accounts = [], keys = [] }, getContext, info) {
|
|
61
|
+
const {
|
|
62
|
+
network: { fetch, rpc_url, symbol = "EOS", ...fetchOptions }
|
|
63
|
+
} = getContext(root, { accounts, keys }, info);
|
|
64
|
+
|
|
63
65
|
const uri = `${rpc_url}/v1/chain/get_accounts_by_authorizers`;
|
|
66
|
+
|
|
67
|
+
const awaited_keys = await Promise.all(keys);
|
|
68
|
+
|
|
64
69
|
const data = await fetch(uri, {
|
|
65
70
|
method: "POST",
|
|
66
71
|
...fetchOptions,
|
|
67
72
|
body: JSON.stringify({
|
|
68
|
-
keys: await Promise.all(
|
|
73
|
+
keys: await Promise.all(
|
|
74
|
+
awaited_keys.map((x) =>
|
|
75
|
+
x.startsWith("PUB_K1")
|
|
76
|
+
? legacy_from_public_key(public_key_from_wif(x), symbol)
|
|
77
|
+
: x
|
|
78
|
+
)
|
|
79
|
+
),
|
|
69
80
|
accounts,
|
|
70
81
|
json: true
|
|
71
82
|
})
|
package/blockchain/get_block.mjs
CHANGED
|
@@ -212,11 +212,11 @@ const get_block = {
|
|
|
212
212
|
type: new GraphQLNonNull(GraphQLString)
|
|
213
213
|
}
|
|
214
214
|
},
|
|
215
|
-
async resolve(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
215
|
+
async resolve(root, { block_num_or_id }, getContext, info) {
|
|
216
|
+
const {
|
|
217
|
+
network: { fetch, rpc_url, ...fetchOptions }
|
|
218
|
+
} = getContext(root, { block_num_or_id }, info);
|
|
219
|
+
|
|
220
220
|
const uri = `${rpc_url}/v1/chain/get_block`;
|
|
221
221
|
const req = await fetch(uri, {
|
|
222
222
|
method: "POST",
|
|
@@ -26,7 +26,11 @@ const currency_balance = {
|
|
|
26
26
|
type: new GraphQLNonNull(symbol_code_type)
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
|
-
async resolve(
|
|
29
|
+
async resolve(root, args, getContext, info) {
|
|
30
|
+
const {
|
|
31
|
+
network: { fetch, rpc_url, ...fetchOptions }
|
|
32
|
+
} = getContext(root, args, info);
|
|
33
|
+
|
|
30
34
|
const uri = `${rpc_url}/v1/chain/get_currency_balance`;
|
|
31
35
|
const req = await fetch(uri, {
|
|
32
36
|
method: "POST",
|
|
@@ -34,11 +34,11 @@ const get_currency_stats = {
|
|
|
34
34
|
type: new GraphQLNonNull(symbol_code_type)
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
|
-
async resolve(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
async resolve(root, { symbol, ...args }, getContext, info) {
|
|
38
|
+
const {
|
|
39
|
+
network: { fetch, rpc_url, ...fetchOptions }
|
|
40
|
+
} = getContext(root, args, info);
|
|
41
|
+
|
|
42
42
|
const uri = `${rpc_url}/v1/chain/get_currency_stats`;
|
|
43
43
|
const req = await fetch(uri, {
|
|
44
44
|
method: "POST",
|
package/blockchain/get_info.mjs
CHANGED
|
@@ -12,6 +12,13 @@ const info_type = new GraphQLObjectType({
|
|
|
12
12
|
type: GraphQLString,
|
|
13
13
|
description: "Hash representing the ID of the chain"
|
|
14
14
|
},
|
|
15
|
+
earliest_available_block_num: {
|
|
16
|
+
type: GraphQLString,
|
|
17
|
+
description: "First available block for transaction history query"
|
|
18
|
+
},
|
|
19
|
+
server_full_version_string: {
|
|
20
|
+
type: GraphQLString
|
|
21
|
+
},
|
|
15
22
|
head_block_num: {
|
|
16
23
|
type: GraphQLString,
|
|
17
24
|
description: "Highest block number on the chain"
|
|
@@ -38,6 +45,10 @@ const info_type = new GraphQLObjectType({
|
|
|
38
45
|
description:
|
|
39
46
|
"Highest block ID on the chain that has been irreversibly applied to state"
|
|
40
47
|
},
|
|
48
|
+
last_irreversible_block_time: {
|
|
49
|
+
type: GraphQLString,
|
|
50
|
+
description: "First available block for transaction history query"
|
|
51
|
+
},
|
|
41
52
|
virtual_block_cpu_limit: {
|
|
42
53
|
type: GraphQLString,
|
|
43
54
|
description:
|
|
@@ -78,7 +89,11 @@ const info = {
|
|
|
78
89
|
description: "Return info about the operational state of the blockchain.",
|
|
79
90
|
type: info_type,
|
|
80
91
|
args: {},
|
|
81
|
-
async resolve(
|
|
92
|
+
async resolve(root, args, getContext, info) {
|
|
93
|
+
const {
|
|
94
|
+
network: { fetch, rpc_url, ...fetchOptions }
|
|
95
|
+
} = getContext(root, args, info);
|
|
96
|
+
|
|
82
97
|
const uri = `${rpc_url}/v1/chain/get_info`;
|
|
83
98
|
const req = await fetch(uri, {
|
|
84
99
|
method: "POST",
|
|
@@ -56,7 +56,7 @@ const producers = new GraphQLObjectType({
|
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
const get_producers = {
|
|
59
|
-
description: "Return info about
|
|
59
|
+
description: "Return info about block producers.",
|
|
60
60
|
type: new GraphQLObjectType({
|
|
61
61
|
name: "antelope_producers",
|
|
62
62
|
fields: {
|
|
@@ -79,12 +79,14 @@ const get_producers = {
|
|
|
79
79
|
defaultValue: "10"
|
|
80
80
|
},
|
|
81
81
|
lower_bound: {
|
|
82
|
-
description:
|
|
83
|
-
"In conjunction with limit can be used to paginate through the results. For example, limit=10 and lower_bound=10 would be page 2.",
|
|
84
82
|
type: GraphQLString
|
|
85
83
|
}
|
|
86
84
|
},
|
|
87
|
-
async resolve(
|
|
85
|
+
async resolve(root, args, getContext, info) {
|
|
86
|
+
const {
|
|
87
|
+
network: { fetch, rpc_url, ...fetchOptions }
|
|
88
|
+
} = getContext(root, args, info);
|
|
89
|
+
|
|
88
90
|
const uri = `${rpc_url}/v1/chain/get_producers`;
|
|
89
91
|
|
|
90
92
|
const req = await fetch(uri, {
|
|
@@ -19,11 +19,11 @@ const get_ram_price = {
|
|
|
19
19
|
description: "Number of bytes of RAM."
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
|
-
async resolve(
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
async resolve(root, { quantity }, getContext, info) {
|
|
23
|
+
const {
|
|
24
|
+
network: { fetch, rpc_url, ...fetchOptions }
|
|
25
|
+
} = getContext(root, { quantity }, info);
|
|
26
|
+
|
|
27
27
|
const data = await fetch(rpc_url + "/v1/chain/get_table_rows", {
|
|
28
28
|
method: "POST",
|
|
29
29
|
...fetchOptions,
|
|
@@ -44,12 +44,20 @@ const get_ram_price = {
|
|
|
44
44
|
if (data.rows) {
|
|
45
45
|
// Connector Balance / (Smart Token’s Outstanding supply × Connector Weight)
|
|
46
46
|
const [RAM] = data.rows;
|
|
47
|
-
|
|
47
|
+
|
|
48
|
+
const CORE_ASSET = RAM.quote.balance;
|
|
49
|
+
const CORE_TOKEN = CORE_ASSET.match(/[\sA-Z]+/gmu);
|
|
50
|
+
|
|
51
|
+
const [, decimal] = String(
|
|
52
|
+
CORE_ASSET.replace(/[A-Za-z\s]+/gmu, "")
|
|
53
|
+
).split(".");
|
|
54
|
+
|
|
55
|
+
const precision = decimal?.length ?? 0;
|
|
48
56
|
|
|
49
57
|
const supply = RAM.base.balance.replace(" RAM", "");
|
|
50
58
|
const total_value = RAM.quote.balance.replace(CORE_TOKEN, "");
|
|
51
59
|
const byte_price = quantity * (total_value / supply);
|
|
52
|
-
return byte_price + CORE_TOKEN;
|
|
60
|
+
return parseFloat(byte_price).toFixed(precision) + CORE_TOKEN;
|
|
53
61
|
}
|
|
54
62
|
}
|
|
55
63
|
};
|
|
@@ -48,11 +48,11 @@ const get_required_keys = {
|
|
|
48
48
|
type: new GraphQLList(public_key_type)
|
|
49
49
|
}
|
|
50
50
|
},
|
|
51
|
-
async resolve(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
51
|
+
async resolve(root, { available_keys, transaction }, getContext, info) {
|
|
52
|
+
const {
|
|
53
|
+
network: { fetch, rpc_url, ...fetchOptions }
|
|
54
|
+
} = getContext(root, { available_keys, transaction }, info);
|
|
55
|
+
|
|
56
56
|
const uri = `${rpc_url}/v1/chain/get_required_keys`;
|
|
57
57
|
|
|
58
58
|
const { actions, ...txn } = transaction;
|
|
@@ -68,7 +68,8 @@ const get_required_keys = {
|
|
|
68
68
|
...(data ? { data: JSON.parse(data) } : {})
|
|
69
69
|
}))
|
|
70
70
|
}
|
|
71
|
-
})
|
|
71
|
+
}),
|
|
72
|
+
...fetchOptions
|
|
72
73
|
});
|
|
73
74
|
|
|
74
75
|
const { required_keys, ...error } = await data.json();
|
|
@@ -30,11 +30,11 @@ const get_smart_contract = {
|
|
|
30
30
|
type: new GraphQLNonNull(name_type)
|
|
31
31
|
}
|
|
32
32
|
},
|
|
33
|
-
async resolve(
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
async resolve(root, { account_name }, getContext, info) {
|
|
34
|
+
const {
|
|
35
|
+
network: { fetch, rpc_url, ...fetchOptions }
|
|
36
|
+
} = getContext(root, { account_name }, info);
|
|
37
|
+
|
|
38
38
|
const uri = `${rpc_url}/v1/chain/get_raw_code_and_abi`;
|
|
39
39
|
const data = await fetch(uri, {
|
|
40
40
|
method: "POST",
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import serializeName from "eosio-wasm-js/name.js";
|
|
1
2
|
import {
|
|
3
|
+
GraphQLEnumType,
|
|
2
4
|
GraphQLError,
|
|
3
5
|
GraphQLInt,
|
|
4
6
|
GraphQLList,
|
|
@@ -9,6 +11,13 @@ import {
|
|
|
9
11
|
|
|
10
12
|
import name_type from "../eosio_types/name_type.mjs";
|
|
11
13
|
|
|
14
|
+
function convertNameToSymbol(scope) {
|
|
15
|
+
return (serializeName(scope).match(/[0-9A-Fa-f]{2}/g) || [])
|
|
16
|
+
.map((hex) => String.fromCharCode(parseInt(hex, 16)))
|
|
17
|
+
.filter((x) => !!x.charCodeAt())
|
|
18
|
+
.join("");
|
|
19
|
+
}
|
|
20
|
+
|
|
12
21
|
const table_type = new GraphQLObjectType({
|
|
13
22
|
name: "table_type",
|
|
14
23
|
fields: {
|
|
@@ -17,7 +26,9 @@ const table_type = new GraphQLObjectType({
|
|
|
17
26
|
new GraphQLObjectType({
|
|
18
27
|
name: "table_rows_type",
|
|
19
28
|
fields: {
|
|
20
|
-
scope: {
|
|
29
|
+
scope: {
|
|
30
|
+
type: name_type
|
|
31
|
+
},
|
|
21
32
|
table_name: { type: name_type, resolve: ({ table }) => table },
|
|
22
33
|
ram_payer: {
|
|
23
34
|
type: name_type,
|
|
@@ -65,14 +76,34 @@ const get_table = {
|
|
|
65
76
|
description:
|
|
66
77
|
"Filters results to return the first element that is greater than provided value in the table.",
|
|
67
78
|
type: GraphQLString
|
|
79
|
+
},
|
|
80
|
+
scope_type: {
|
|
81
|
+
defaultValue: 0,
|
|
82
|
+
type: new GraphQLEnumType({
|
|
83
|
+
name: "scope_type",
|
|
84
|
+
values: {
|
|
85
|
+
name: { value: 0 },
|
|
86
|
+
symbol_code: { value: 1 }
|
|
87
|
+
}
|
|
88
|
+
})
|
|
68
89
|
}
|
|
69
90
|
},
|
|
70
91
|
async resolve(
|
|
71
|
-
|
|
72
|
-
{ account_name, table_name, limit, lower_bound, upper_bound },
|
|
73
|
-
|
|
92
|
+
root,
|
|
93
|
+
{ account_name, table_name, limit, lower_bound, upper_bound, scope_type },
|
|
94
|
+
getContext,
|
|
95
|
+
info
|
|
74
96
|
) {
|
|
97
|
+
const {
|
|
98
|
+
network: { fetch, rpc_url, ...fetchOptions }
|
|
99
|
+
} = getContext(
|
|
100
|
+
root,
|
|
101
|
+
{ account_name, table_name, limit, lower_bound, upper_bound },
|
|
102
|
+
info
|
|
103
|
+
);
|
|
104
|
+
|
|
75
105
|
const uri = `${rpc_url}/v1/chain/get_table_by_scope`;
|
|
106
|
+
|
|
76
107
|
const data = await fetch(uri, {
|
|
77
108
|
method: "POST",
|
|
78
109
|
...fetchOptions,
|
|
@@ -88,8 +119,16 @@ const get_table = {
|
|
|
88
119
|
}).then((req) => req.json());
|
|
89
120
|
|
|
90
121
|
if (data.error) throw new GraphQLError(data.message, { extensions: data });
|
|
122
|
+
if (!scope_type) return data;
|
|
91
123
|
|
|
92
|
-
|
|
124
|
+
if (scope_type == 1)
|
|
125
|
+
return {
|
|
126
|
+
...data,
|
|
127
|
+
rows: data.rows.map((x) => ({
|
|
128
|
+
...x,
|
|
129
|
+
scope: convertNameToSymbol(x.scope)
|
|
130
|
+
}))
|
|
131
|
+
};
|
|
93
132
|
}
|
|
94
133
|
};
|
|
95
134
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { GraphQLError, GraphQLObjectType } from "graphql";
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import abi_bin_to_json from "./blockchain/abi_bin_to_json.mjs";
|
|
4
4
|
import get_abi from "./blockchain/get_abi.mjs";
|
|
5
5
|
import get_account from "./blockchain/get_account.mjs";
|
|
6
6
|
import get_accounts_by_authorizers from "./blockchain/get_accounts_by_authorizers.mjs";
|
|
@@ -31,10 +31,14 @@ const blockchain_query_field = {
|
|
|
31
31
|
get_producers,
|
|
32
32
|
get_table,
|
|
33
33
|
get_ram_price,
|
|
34
|
-
|
|
34
|
+
abi_bin_to_json
|
|
35
35
|
}
|
|
36
36
|
}),
|
|
37
|
-
resolve(
|
|
37
|
+
resolve(root, arg, getContext, info) {
|
|
38
|
+
const {
|
|
39
|
+
network: { rpc_url }
|
|
40
|
+
} = getContext(root, arg, info);
|
|
41
|
+
|
|
38
42
|
if (!rpc_url)
|
|
39
43
|
throw new GraphQLError("No RPC url supplied to `antelopeql_context`");
|
|
40
44
|
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
/**
|
|
22
22
|
* Builds GraphQL query and mutation fields from a list of ABIs. These GraphQL fields can readily be consumed by a GraphQL Schema, enabling developers the ability to integrate a varienty of EOSIO based blockchains into their GraphQL service.
|
|
23
23
|
* @param {Array<AccountABI>} abi_list Argument.
|
|
24
|
+
* @param {String} [typeResolution] Used for GraphQL type resolution.
|
|
24
25
|
* @returns {Object} AntelopeQL fields.
|
|
25
26
|
* @example <caption>`Usage` in a custom GraphQL API.</caption>
|
|
26
27
|
* ```js
|
|
@@ -62,14 +63,17 @@ import {
|
|
|
62
63
|
* schema,
|
|
63
64
|
* document,
|
|
64
65
|
* rootValue: '',
|
|
65
|
-
* contextValue: { network },
|
|
66
|
+
* contextValue: () => ({ network }),
|
|
66
67
|
* fieldResolver(rootValue, args, ctx, { fieldName }) {
|
|
67
68
|
* return rootValue[fieldName]
|
|
68
69
|
* }
|
|
69
70
|
* })
|
|
70
71
|
* ```
|
|
71
72
|
*/
|
|
72
|
-
export default function build_graphql_fields_from_abis(
|
|
73
|
+
export default function build_graphql_fields_from_abis(
|
|
74
|
+
abi_list,
|
|
75
|
+
typeResolution = ""
|
|
76
|
+
) {
|
|
73
77
|
const contract_query_fields = {};
|
|
74
78
|
const contract_mutation_fields = {};
|
|
75
79
|
const ast_list = {};
|
|
@@ -79,20 +83,27 @@ export default function build_graphql_fields_from_abis(abi_list) {
|
|
|
79
83
|
const AST = eosio_abi_to_graphql_ast(abi);
|
|
80
84
|
|
|
81
85
|
ast_list[name] = AST; // For use in serializing data in mutation resolver.
|
|
86
|
+
|
|
82
87
|
const { query_fields, mutation_fields } = get_graphql_fields_from_AST(
|
|
83
88
|
AST,
|
|
84
89
|
abi,
|
|
85
|
-
name
|
|
90
|
+
name,
|
|
91
|
+
typeResolution
|
|
86
92
|
);
|
|
87
93
|
|
|
88
94
|
if (Object.keys(query_fields).length)
|
|
89
95
|
contract_query_fields[name] = {
|
|
90
96
|
name,
|
|
91
97
|
type: new GraphQLObjectType({
|
|
92
|
-
name: name
|
|
98
|
+
name: `${name}_query${typeResolution}`,
|
|
93
99
|
fields: query_fields
|
|
94
100
|
}),
|
|
95
|
-
resolve(
|
|
101
|
+
resolve(root, arg, getContext, { fieldName, ...info }) {
|
|
102
|
+
const { network: { rpc_url, fetch } = {} } = getContext(root, arg, {
|
|
103
|
+
fieldName,
|
|
104
|
+
...info
|
|
105
|
+
});
|
|
106
|
+
|
|
96
107
|
if (!fetch)
|
|
97
108
|
throw new GraphQLError(
|
|
98
109
|
"No fetch argument found on the context of the GraphQL.execute."
|
|
@@ -110,7 +121,7 @@ export default function build_graphql_fields_from_abis(abi_list) {
|
|
|
110
121
|
if (Object.keys(mutation_fields).length)
|
|
111
122
|
contract_mutation_fields[name] = {
|
|
112
123
|
type: new GraphQLInputObjectType({
|
|
113
|
-
name,
|
|
124
|
+
name: name + typeResolution,
|
|
114
125
|
fields: mutation_fields
|
|
115
126
|
})
|
|
116
127
|
};
|
|
@@ -66,31 +66,26 @@ function handleStructs(structs) {
|
|
|
66
66
|
* @returns {Object} a GraphQL AST for a given smart contract.
|
|
67
67
|
*/
|
|
68
68
|
export function eosio_abi_to_graphql_ast(abi) {
|
|
69
|
-
const { types, variants } = abi;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}))
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (types?.length)
|
|
69
|
+
const { types, variants, structs } = abi;
|
|
70
|
+
const new_structs = structs;
|
|
71
|
+
|
|
72
|
+
if (variants?.length)
|
|
73
|
+
for (const { name, types: variant_types } of variants)
|
|
74
|
+
new_structs.push({
|
|
75
|
+
name,
|
|
76
|
+
base: "",
|
|
77
|
+
fields: variant_types.map((item) => ({ name: item, type: item + "$@" })) // @ indiacted a variant type and binary extention.
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (types?.length) {
|
|
83
81
|
for (const { type: real_type, new_type_name } of types)
|
|
84
|
-
|
|
85
|
-
...
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
: { name, type }
|
|
90
|
-
)
|
|
91
|
-
}));
|
|
82
|
+
new_structs.push({
|
|
83
|
+
...new_structs.find((x) => x.name == real_type),
|
|
84
|
+
name: new_type_name
|
|
85
|
+
});
|
|
86
|
+
}
|
|
92
87
|
|
|
93
|
-
const structs_ast = handleStructs(
|
|
88
|
+
const structs_ast = handleStructs(new_structs);
|
|
94
89
|
|
|
95
90
|
return Object.freeze(structs_ast);
|
|
96
91
|
}
|
|
@@ -117,7 +112,12 @@ function Wrap(type, { optional, list }) {
|
|
|
117
112
|
* @param {String} [account_name] Blockchain account name.
|
|
118
113
|
* @returns {Object} GraphQL query and mutation fields.
|
|
119
114
|
*/
|
|
120
|
-
export function get_graphql_fields_from_AST(
|
|
115
|
+
export function get_graphql_fields_from_AST(
|
|
116
|
+
AST,
|
|
117
|
+
ABI,
|
|
118
|
+
account_name = "",
|
|
119
|
+
chainName = ""
|
|
120
|
+
) {
|
|
121
121
|
const { tables, actions } = ABI;
|
|
122
122
|
const gql_account_name = account_name.replace(/\./gmu, "_") + "_";
|
|
123
123
|
|
|
@@ -127,6 +127,7 @@ export function get_graphql_fields_from_AST(AST, ABI, account_name = "") {
|
|
|
127
127
|
|
|
128
128
|
for (const table of tables) {
|
|
129
129
|
let { name: table_name, type: table_type } = table;
|
|
130
|
+
|
|
130
131
|
table_name = table_name.replace(/\./gmu, "_");
|
|
131
132
|
const table_fields = AST[table_type];
|
|
132
133
|
|
|
@@ -143,7 +144,7 @@ export function get_graphql_fields_from_AST(AST, ABI, account_name = "") {
|
|
|
143
144
|
if ($info.object) {
|
|
144
145
|
if (!GQL_TYPES[type])
|
|
145
146
|
GQL_TYPES[type] = new GraphQLObjectType({
|
|
146
|
-
name: gql_account_name + type,
|
|
147
|
+
name: gql_account_name + type + chainName,
|
|
147
148
|
fields: buildQGL(AST[type])
|
|
148
149
|
});
|
|
149
150
|
|
|
@@ -160,11 +161,11 @@ export function get_graphql_fields_from_AST(AST, ABI, account_name = "") {
|
|
|
160
161
|
return acc;
|
|
161
162
|
};
|
|
162
163
|
|
|
163
|
-
if (!queryTypes[table_type])
|
|
164
|
+
if (!queryTypes[table_type]) {
|
|
164
165
|
queryTypes[table_type] = {
|
|
165
166
|
type: new GraphQLList(
|
|
166
167
|
new GraphQLObjectType({
|
|
167
|
-
name: gql_account_name + table_type + "_query",
|
|
168
|
+
name: gql_account_name + table_type + "_query" + chainName,
|
|
168
169
|
fields: buildQGL(table_fields)
|
|
169
170
|
})
|
|
170
171
|
),
|
|
@@ -176,6 +177,7 @@ export function get_graphql_fields_from_AST(AST, ABI, account_name = "") {
|
|
|
176
177
|
},
|
|
177
178
|
resolve
|
|
178
179
|
};
|
|
180
|
+
}
|
|
179
181
|
|
|
180
182
|
query_fields[table_name] = queryTypes[table_type];
|
|
181
183
|
}
|
|
@@ -199,7 +201,7 @@ export function get_graphql_fields_from_AST(AST, ABI, account_name = "") {
|
|
|
199
201
|
if ($info.object) {
|
|
200
202
|
if (!GQL_MTYPES[type])
|
|
201
203
|
GQL_MTYPES[type] = new GraphQLInputObjectType({
|
|
202
|
-
name: gql_account_name + "input_" + type,
|
|
204
|
+
name: gql_account_name + "input_" + type + chainName,
|
|
203
205
|
fields: buildQGL(AST[type])
|
|
204
206
|
});
|
|
205
207
|
acc = { ...acc, [name]: { type: Wrap(GQL_MTYPES[type], $info) } };
|
|
@@ -212,7 +214,7 @@ export function get_graphql_fields_from_AST(AST, ABI, account_name = "") {
|
|
|
212
214
|
if (!mutationTypes[action_type]) {
|
|
213
215
|
mutationTypes[action_type] = {
|
|
214
216
|
type: new GraphQLInputObjectType({
|
|
215
|
-
name: gql_account_name + action_type,
|
|
217
|
+
name: gql_account_name + action_type + chainName,
|
|
216
218
|
description: ricardian_contract
|
|
217
219
|
.replace(/(https?|http|ftp):\/\/[^\s$.?#].[^\s]*$/gmu, "")
|
|
218
220
|
.replace(/icon:/gmu, "")
|
|
@@ -19,7 +19,7 @@ Names are unique identifiers on the blockchain.
|
|
|
19
19
|
parseValue(_name) {
|
|
20
20
|
if (_name == "") return _name;
|
|
21
21
|
|
|
22
|
-
if (!_name.match(/^[1-5a-z
|
|
22
|
+
if (!_name.match(/^[1-5a-z.]{0,11}[1-5a-z]{1}$/gmu))
|
|
23
23
|
throw new TypeError(`Invalid name “${_name}”.`);
|
|
24
24
|
|
|
25
25
|
return _name;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import base58_to_binary from "base58-js/base58_to_binary
|
|
2
|
-
import binary_to_base58 from "base58-js/binary_to_base58
|
|
1
|
+
import base58_to_binary from "base58-js/base58_to_binary";
|
|
2
|
+
import binary_to_base58 from "base58-js/binary_to_base58";
|
|
3
3
|
import { GraphQLScalarType } from "graphql";
|
|
4
|
-
import ripemd160 from "ripemd160-js/ripemd160.
|
|
4
|
+
import ripemd160 from "ripemd160-js/ripemd160.js";
|
|
5
5
|
|
|
6
6
|
const public_key_type = new GraphQLScalarType({
|
|
7
7
|
name: "public_key",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { GraphQLInputObjectType, GraphQLList, GraphQLNonNull } from "graphql";
|
|
2
2
|
|
|
3
|
-
const actions_type = (fields) =>
|
|
3
|
+
const actions_type = (fields, typeResolution = "") =>
|
|
4
4
|
new GraphQLNonNull(
|
|
5
5
|
new GraphQLList(
|
|
6
6
|
new GraphQLNonNull(
|
|
7
7
|
new GraphQLInputObjectType({
|
|
8
|
-
name: "actions_type",
|
|
8
|
+
name: "actions_type" + typeResolution,
|
|
9
9
|
fields
|
|
10
10
|
})
|
|
11
11
|
)
|
|
@@ -20,7 +20,13 @@ export const packed_transaction_fields = {
|
|
|
20
20
|
required_keys: {
|
|
21
21
|
type: new GraphQLList(public_key_type),
|
|
22
22
|
description: "List of public keys needed to authorize transaction",
|
|
23
|
-
async resolve({ available_keys, transaction }, args,
|
|
23
|
+
async resolve({ available_keys, transaction }, args, getContext, info) {
|
|
24
|
+
const { network } = getContext(
|
|
25
|
+
{ available_keys, transaction },
|
|
26
|
+
args,
|
|
27
|
+
info
|
|
28
|
+
);
|
|
29
|
+
|
|
24
30
|
if (available_keys?.length) {
|
|
25
31
|
const keys = await Promise.all(available_keys);
|
|
26
32
|
|
|
@@ -38,7 +44,8 @@ export const packed_transaction_fields = {
|
|
|
38
44
|
}))
|
|
39
45
|
},
|
|
40
46
|
available_keys: keys
|
|
41
|
-
})
|
|
47
|
+
}),
|
|
48
|
+
...network.fetchOptions
|
|
42
49
|
}
|
|
43
50
|
).then((res) => res.json());
|
|
44
51
|
|
package/mutation_resolver.mjs
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
import serialize from "eosio-wasm-js/serialize.
|
|
2
|
-
import serialize_transaction_header from "eosio-wasm-js/transaction_header.
|
|
1
|
+
import serialize from "eosio-wasm-js/serialize.js";
|
|
2
|
+
import serialize_transaction_header from "eosio-wasm-js/transaction_header.js";
|
|
3
3
|
import { GraphQLError } from "graphql";
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const default_config = {
|
|
6
6
|
blocksBehind: 3,
|
|
7
7
|
expireSeconds: 30,
|
|
8
8
|
max_net_usage_words: 0,
|
|
9
|
-
max_cpu_usage_ms: 0
|
|
10
|
-
delay_sec: 0
|
|
9
|
+
max_cpu_usage_ms: 0
|
|
11
10
|
};
|
|
12
11
|
|
|
13
12
|
const validate_actions = () => {
|
|
@@ -163,7 +162,7 @@ async function get_transaction_body(actions, ast_list) {
|
|
|
163
162
|
* @returns {Object} Transaction object.
|
|
164
163
|
*/
|
|
165
164
|
async function mutation_resolver(
|
|
166
|
-
{ actions, configuration =
|
|
165
|
+
{ actions, configuration = default_config },
|
|
167
166
|
network,
|
|
168
167
|
ast_list
|
|
169
168
|
) {
|
|
@@ -212,7 +211,7 @@ async function mutation_resolver(
|
|
|
212
211
|
ref_block_prefix,
|
|
213
212
|
max_net_usage_words: configuration.max_net_usage_words,
|
|
214
213
|
max_cpu_usage_ms: configuration.max_cpu_usage_ms,
|
|
215
|
-
delay_sec:
|
|
214
|
+
delay_sec: 0
|
|
216
215
|
};
|
|
217
216
|
|
|
218
217
|
// Generates a transaction header for a Antelope transaction.
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "antelopeql",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-alpha.1",
|
|
4
4
|
"description": "A GraphQL implementation for interacting with Antelope based blockchains.",
|
|
5
|
-
"repository":
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/pur3miish/antelopeql.git"
|
|
8
|
+
},
|
|
6
9
|
"bugs": "https://github.com/pur3miish/antelopeql/issues",
|
|
7
10
|
"homepage": "https://github.com/pur3miish/antelopeql#readme",
|
|
8
11
|
"author": "pur3miish",
|
|
@@ -16,9 +19,10 @@
|
|
|
16
19
|
"snapshot": "SAVE_SNAPSHOTS=1 coverage-node test/index.test.mjs",
|
|
17
20
|
"coverage": "coverage-node test/index.test.mjs",
|
|
18
21
|
"tests": "node test/index.test.mjs",
|
|
19
|
-
"test": "npm run eslint
|
|
22
|
+
"test": "npm run eslint",
|
|
20
23
|
"prepublishOnly": "npm test"
|
|
21
24
|
},
|
|
25
|
+
"type": "module",
|
|
22
26
|
"engines": {
|
|
23
27
|
"node": ">= 18.0.0"
|
|
24
28
|
},
|
|
@@ -79,21 +83,24 @@
|
|
|
79
83
|
],
|
|
80
84
|
"devDependencies": {
|
|
81
85
|
"@types/node": "^18.13.0",
|
|
82
|
-
"antelope-ecc": "^2.0.0-rc.7",
|
|
83
86
|
"coverage-node": "^8.0.0",
|
|
84
87
|
"eslint": "^8.34.0",
|
|
85
88
|
"eslint-plugin-simple-import-sort": "^10.0.0",
|
|
86
|
-
"graphql": "^
|
|
89
|
+
"graphql": "^15.9.0",
|
|
87
90
|
"nodemon": "^3.0.1",
|
|
88
91
|
"prettier": "^2.8.4",
|
|
89
92
|
"snapshot-assertion": "^5.0.0",
|
|
90
93
|
"test-director": "^10.0.0",
|
|
91
|
-
"typescript": "^
|
|
94
|
+
"typescript": "^5.7.3"
|
|
95
|
+
},
|
|
96
|
+
"peerDependencies": {
|
|
97
|
+
"graphql": "^15.9.0"
|
|
92
98
|
},
|
|
93
99
|
"dependencies": {
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
100
|
+
"antelope-ecc": "^4.0.1",
|
|
101
|
+
"base58-js": "^3.0.0",
|
|
102
|
+
"eosio-wasm-js": "^5.0.2",
|
|
103
|
+
"ripemd160-js": "^3.0.4",
|
|
97
104
|
"universal-sha256-js": "^2.0.0"
|
|
98
105
|
}
|
|
99
106
|
}
|
package/query_resolver.mjs
CHANGED
|
@@ -14,9 +14,11 @@ import { GraphQLError } from "graphql";
|
|
|
14
14
|
export default async function query_resolver(
|
|
15
15
|
{ code },
|
|
16
16
|
{ arg },
|
|
17
|
-
|
|
17
|
+
getContext,
|
|
18
18
|
info
|
|
19
19
|
) {
|
|
20
|
+
const { network } = getContext({ code }, { arg }, info);
|
|
21
|
+
|
|
20
22
|
const { fetch, rpc_url, ...fetchOptions } = network;
|
|
21
23
|
const { fieldName: query_name } = info;
|
|
22
24
|
const table = query_name.replace(/_/gmu, ".");
|
package/readme.md
CHANGED
|
@@ -96,7 +96,7 @@ const { data } = await AntelopeQL({
|
|
|
96
96
|
signTransaction: async (hash) => {
|
|
97
97
|
const wif_private_key = "PVT_K1_…"; // your private key
|
|
98
98
|
const signature = await sign_txn({ hash, wif_private_key });
|
|
99
|
-
return [signature]; //
|
|
99
|
+
return [signature]; // signatures must return array
|
|
100
100
|
},
|
|
101
101
|
rpc_url: "https://eos.relocke.io" // eos blockchain url.
|
|
102
102
|
});
|
|
@@ -14,10 +14,11 @@ const send_serialized_transaction = {
|
|
|
14
14
|
args: {
|
|
15
15
|
transaction_header: { type: new GraphQLNonNull(bytes_type) },
|
|
16
16
|
transaction_body: { type: new GraphQLNonNull(bytes_type) },
|
|
17
|
-
|
|
17
|
+
signatures: { type: new GraphQLNonNull(new GraphQLList(signature_type)) }
|
|
18
18
|
},
|
|
19
|
-
resolve(
|
|
20
|
-
|
|
19
|
+
resolve(root, args, getContext, info) {
|
|
20
|
+
const { network } = getContext(root, args, info);
|
|
21
|
+
return send_transaction_rpc(args, network);
|
|
21
22
|
}
|
|
22
23
|
};
|
|
23
24
|
|
package/send_transaction.mjs
CHANGED
|
@@ -18,7 +18,9 @@ const send_transaction = (actions, ast_list) => ({
|
|
|
18
18
|
type: configuration_type
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
|
-
async resolve(
|
|
21
|
+
async resolve(root, args, getContext, info) {
|
|
22
|
+
const { network, signTransaction } = getContext(root, args, info);
|
|
23
|
+
|
|
22
24
|
const { chain_id, transaction_header, transaction_body, transaction } =
|
|
23
25
|
await mutation_resolver(args, network, ast_list);
|
|
24
26
|
|
package/send_transaction_rpc.mjs
CHANGED
|
@@ -30,6 +30,8 @@ export default async function send_transaction_rpc(
|
|
|
30
30
|
});
|
|
31
31
|
|
|
32
32
|
const pushed_transaction = await pushed_txn_req.json();
|
|
33
|
+
console.log(pushed_transaction.error);
|
|
34
|
+
|
|
33
35
|
if (pushed_transaction.error)
|
|
34
36
|
throw new GraphQLError(pushed_transaction.message, {
|
|
35
37
|
extensions: pushed_transaction.error
|
package/serialize_abi.mjs
CHANGED
|
@@ -19,7 +19,9 @@ const serialize_transaction = (actions, ast_list) => ({
|
|
|
19
19
|
type: new GraphQLList(public_key_type)
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
|
-
async resolve(
|
|
22
|
+
async resolve(root, { available_keys, ...args }, getContext, info) {
|
|
23
|
+
const { network } = getContext(root, { available_keys, ...args }, info);
|
|
24
|
+
|
|
23
25
|
const { transaction, ...serialized_txn } = await mutation_resolver(
|
|
24
26
|
args,
|
|
25
27
|
network,
|
package/types.mjs
CHANGED
|
@@ -62,3 +62,16 @@
|
|
|
62
62
|
* @property {Boolean} binary_ex
|
|
63
63
|
* @property {Boolean} variant
|
|
64
64
|
*/
|
|
65
|
+
|
|
66
|
+
export const supported_antelope_chain_endpoints = [
|
|
67
|
+
"get_info",
|
|
68
|
+
"get_abi",
|
|
69
|
+
"get_accounts_by_authorizers",
|
|
70
|
+
"get_block",
|
|
71
|
+
"get_currency_balance",
|
|
72
|
+
"get_currency_stats",
|
|
73
|
+
"get_required_keys",
|
|
74
|
+
"get_producers",
|
|
75
|
+
"get_table",
|
|
76
|
+
"abi_bin_to_json"
|
|
77
|
+
];
|