wao 0.5.6 → 0.6.0

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/esm/tar.js CHANGED
@@ -3,20 +3,27 @@ import { buildTags, tags as t } from "./utils.js"
3
3
  import * as WarpArBundles from "warp-arbundles"
4
4
  const pkg = WarpArBundles.default ?? WarpArBundles
5
5
  const { DataItem } = pkg
6
-
6
+ import { bundleAndSignData, ArweaveSigner } from "arbundles"
7
7
  import base64url from "base64url"
8
8
  import ArMem from "./armem.js"
9
9
  import GQL from "./tgql.js"
10
- import { last } from "ramda"
10
+ import { last, is, includes, isNil } from "ramda"
11
11
  class AR extends MAR {
12
12
  constructor(opt = {}) {
13
13
  super({ ...opt, in_memory: true })
14
+ this.log = opt.log === true
14
15
  this.in_memory = true
15
16
  this.mem = opt.mem ?? new ArMem()
16
17
  this.gql = new GQL({ mem: this.mem })
17
18
  this.arweave = this.mem.arweave
18
19
  }
19
-
20
+ async owner(di) {
21
+ const raw_owner = di.rawOwner
22
+ const hashBuffer = Buffer.from(
23
+ await crypto.subtle.digest("SHA-256", raw_owner),
24
+ )
25
+ return base64url.encode(hashBuffer)
26
+ }
20
27
  async dataitem({ target = "", data = "1984", tags = {}, signer, item }) {
21
28
  let di = item
22
29
  if (!di) {
@@ -26,65 +33,68 @@ class AR extends MAR {
26
33
  } else {
27
34
  tags = t(di.tags)
28
35
  }
29
- const raw_owner = di.rawOwner
30
- const hashBuffer = Buffer.from(
31
- await crypto.subtle.digest("SHA-256", raw_owner),
32
- )
33
- const owner = base64url.encode(hashBuffer)
36
+ const owner = await this.owner(di)
34
37
  return { id: await di.id, owner, item: di, tags }
35
38
  }
36
39
 
37
40
  async post({ data = "1984", tags = {}, jwk }) {
41
+ let err = null
42
+ ;({ err, jwk } = await this.checkWallet({ jwk }))
43
+ if (err) return { err }
38
44
  let tx = await this.arweave.createTransaction({ data: data })
39
45
  let _tags = buildTags(null, tags)
40
46
  for (const v of _tags) tx.addTag(v.name, v.value)
41
- const owner = await this.arweave.wallets.jwkToAddress(jwk)
42
- this.mem.addrmap[owner] = { address: owner, key: jwk.n }
43
- return await this.postTx(tx, jwk, {
44
- recipient: "",
45
- tags: _tags,
46
- data,
47
- owner,
48
- })
47
+ return await this.postTx(tx, jwk)
49
48
  }
50
49
 
51
- async postItem(di, jwk) {
50
+ async postItems(items, jwk) {
51
+ let err = null
52
+ ;({ err, jwk } = await this.checkWallet({ jwk }))
53
+ if (err) return { err }
54
+ if (!is(Array, items)) items = [items]
55
+ let _items = []
56
+ for (const di of items) {
57
+ di._id = await di.id
58
+ const data_size = Buffer.byteLength(di.rawData).toString()
59
+ let data_type = ""
60
+ for (const t of di.tags)
61
+ if (t.name === "Content-Type") data_type = t.value
62
+ const owner = await this.owner(di)
63
+ this.mem.addrmap[owner] = { key: di.owner, address: owner }
64
+ let data = di.data
65
+ try {
66
+ data = base64url.decode(di.data)
67
+ } catch (e) {}
68
+ let _item = {
69
+ _data: { size: data_size, type: data_type },
70
+ anchor: di.anchor,
71
+ signature: di.signature,
72
+ recipient: di.target,
73
+ id: await di.id,
74
+ item: di,
75
+ owner,
76
+ tags: di.tags,
77
+ data,
78
+ }
79
+ this.mem.txs[await di.id] = _item
80
+ _items.push(_item)
81
+ }
82
+ const bundle = await bundleAndSignData(items, new ArweaveSigner(jwk))
52
83
  const tx = await this.mem.arweave.createTransaction(
53
- { data: di.binary },
84
+ { data: bundle.binary },
54
85
  jwk,
55
86
  )
56
87
  tx.addTag("Bundle-Format", "binary")
57
88
  tx.addTag("Bundle-Version", "2.0.0")
58
- const data_size = Buffer.byteLength(di.rawData).toString()
59
- let data_type = ""
60
- for (const t of di.tags) if (t.name === "Content-Type") data_type = t.value
61
- const rowner = di.rawOwner
62
- const hashBuffer = Buffer.from(
63
- await crypto.subtle.digest("SHA-256", rowner),
64
- )
65
- const owner = base64url.encode(hashBuffer)
66
- this.mem.addrmap[owner] = { key: di.owner, address: owner }
67
- let data = di.data
68
- try {
69
- data = base64url.decode(di.data)
70
- } catch (e) {}
71
- let _item = {
72
- _data: { size: data_size, type: data_type },
73
- anchor: di.anchor,
74
- signature: di.signature,
75
- recipient: di.target,
76
- id: await di.id,
77
- item: di,
78
- owner,
79
- tags: di.tags,
80
- data,
81
- }
82
- this.mem.txs[await di.id] = _item
83
- return await this.postTx(tx, jwk, _item)
89
+ return await this.postTx(tx, jwk, _items)
84
90
  }
85
91
 
86
- async postTx(tx, jwk, item) {
87
- let [res, err] = [null, null]
92
+ async postTx(tx, jwk, items = []) {
93
+ let err = null
94
+ ;({ err, jwk } = await this.checkWallet({ jwk }))
95
+ if (err) return { err }
96
+
97
+ let res = null
88
98
  if (!tx.id) await this.mem.arweave.transactions.sign(tx, jwk)
89
99
  this.mem.height += 1
90
100
  let block = {
@@ -92,42 +102,51 @@ class AR extends MAR {
92
102
  timestamp: Date.now(),
93
103
  height: this.mem.height,
94
104
  previous: last(this.mem.blocks) ?? "",
105
+ txs: [],
95
106
  }
96
- if (item) {
97
- if (!item.id) {
98
- item.id = tx.id
99
- this.mem.txs[tx.id] = item
100
- this.mem.txs[tx.id].parent = null
101
- this.mem.txs[tx.id].signature = tx.signature
102
- this.mem.txs[tx.id].anchor = tx.last_tx
107
+ let msg = null
108
+ if (items) {
109
+ for (const item of items) {
110
+ this.mem.txs[item.id] = item
111
+ this.mem.txs[item.id].parent = { id: tx.id }
112
+ this.mem.txs[item.id].bundledIn = { id: tx.id }
113
+ this.mem.txs[item.id].anchor = ""
114
+ const _tags = t(item.tags)
115
+ if (
116
+ includes(_tags.Type, [
117
+ "Message",
118
+ "Process",
119
+ "Module",
120
+ "Scheduler-Location",
121
+ "Attestation",
122
+ "Available",
123
+ ])
124
+ ) {
125
+ msg = { id: item.id, type: _tags.Type }
126
+ if (msg.type === "Process") msg.pid = item.recipient
127
+ }
103
128
  let data_type = ""
104
- for (const v of tx.tags) {
105
- if (
106
- v.get("name", { decode: true, string: true }) === "Content-Type"
107
- ) {
108
- data_type = v.get("value", { decode: true, string: true })
109
- }
129
+ for (const v of item.item.tags) {
130
+ if (v.name === "Content-Type") data_type = v.value
110
131
  }
111
- this.mem.txs[tx.id]._data = { size: tx.data_size, type: data_type }
112
- } else {
113
- this.mem.txs[item.id].parent = { id: block.id }
132
+ //this.mem.txs[tx.id]._data = { size: tx.data_size, type: data_type }
133
+ block.txs.push(item.id)
134
+ this.mem.txs[item.id].block = block.id
114
135
  }
115
- block.txs = [item.id]
116
- this.mem.txs[item.id].block = block.id
117
- } else {
118
- let _tags = []
119
- for (const v of tx.tags) {
120
- _tags.push({
121
- name: base64url.decode(v.name),
122
- value: base64url.decode(v.value),
123
- })
124
- }
125
- tx.tags = _tags
126
- tx.owner = await this.arweave.wallets.jwkToAddress({ n: tx.owner })
127
- this.mem.txs[tx.id] = tx
128
- block.txs = [tx.id]
129
- this.mem.txs[tx.id].block = block.id
130
136
  }
137
+
138
+ let _tags = []
139
+ for (const v of tx.tags) {
140
+ _tags.push({
141
+ name: base64url.decode(v.name),
142
+ value: base64url.decode(v.value),
143
+ })
144
+ }
145
+ tx.tags = _tags
146
+ tx.owner = await this.arweave.wallets.jwkToAddress({ n: tx.owner })
147
+ this.mem.txs[tx.id] = tx
148
+ block.txs.push(tx.id)
149
+ this.mem.txs[tx.id].block = block.id
131
150
  this.mem.blocks.push(block.id)
132
151
  this.mem.blockmap[block.id] = block
133
152
 
@@ -136,6 +155,15 @@ class AR extends MAR {
136
155
  this.mem.addrmap[owner] = { address: owner, key: jwk.n }
137
156
  }
138
157
  res = { id: tx.id, status: 200, statusText: "200" }
158
+ if (this.log) {
159
+ if (msg) {
160
+ console.log(
161
+ `New ${msg.type}:\t${msg.id}${msg.pid ? ` > ${msg.pid}` : ""}`,
162
+ )
163
+ } else {
164
+ console.log(`New Post:\t${tx.id}`)
165
+ }
166
+ }
139
167
  return { res, err, id: tx.id }
140
168
  }
141
169
 
@@ -143,15 +171,27 @@ class AR extends MAR {
143
171
  return this.mem.txs[id]
144
172
  }
145
173
 
146
- async data(id, string) {
174
+ async data(id, _string) {
175
+ let decode = true
176
+ let string = _string
177
+ if (is(Object, _string)) {
178
+ if (!isNil(_string.decode)) decode = _string.decode
179
+ if (!isNil(_string.string)) string = _string.string
180
+ }
181
+
147
182
  let tx = this.mem.txs[id]
148
- let _data = this.mem.txs[id]?.data ?? null
149
- try {
150
- JSON.parse(_data)
151
- _data = Buffer.from(_data).toString("base64")
152
- } catch (e) {}
153
- if (tx.format === 2 && _data && string) {
154
- _data = base64url.decode(_data)
183
+ let _data = tx?.data ?? null
184
+ let isBuf = is(Uint8Array, _data) || is(ArrayBuffer, _data)
185
+ let isStr = is(String, _data)
186
+ if (decode === false) {
187
+ if (isStr) _data = new TextEncoder().encode(_data)
188
+ return base64url.encode(_data)
189
+ } else {
190
+ if (isBuf && string) {
191
+ return Buffer.from(_data).toString()
192
+ } else if (isStr && string !== true) {
193
+ return new TextEncoder().encode(_data)
194
+ }
155
195
  }
156
196
  return _data
157
197
  }
package/esm/test.js CHANGED
@@ -7,7 +7,7 @@ import AR from "./tar.js"
7
7
  import GQL from "./tgql.js"
8
8
  import ArMem from "./armem.js"
9
9
  import { dirname } from "./utils.js"
10
- import { Src, setup, ok, fail } from "./helpers.js"
10
+ import { Testnet, Src, setup, ok, fail } from "./helpers.js"
11
11
  import Server from "./server.js"
12
12
 
13
13
  const blueprint = async pkg => {
@@ -16,6 +16,7 @@ const blueprint = async pkg => {
16
16
  const scheduler = "_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA"
17
17
 
18
18
  export {
19
+ Testnet,
19
20
  Server,
20
21
  GQL,
21
22
  ArMem,
package/esm/tgql.js CHANGED
@@ -8,6 +8,7 @@ const subs = {
8
8
  tags: ["name", "value"],
9
9
  block: ["id", "timestamp", "height", "previous"],
10
10
  parent: ["id"],
11
+ bundledIn: ["id"],
11
12
  }
12
13
  const field = (key, val = true) => {
13
14
  if (includes(key, ["id", "anchor", "signature", "recipient"])) {
@@ -59,8 +60,11 @@ export default class GQL {
59
60
  _block = {}
60
61
  if (!isNil(opt.block[0])) _block.min = opt.block[0]
61
62
  if (!isNil(opt.block[1])) _block.max = opt.block[1]
63
+ } else if (is(Object, opt.block)) {
64
+ if (!isNil(opt.block.min)) _block.min = opt.block.min
65
+ if (!isNil(opt.block.max)) _block.max = opt.block.max
62
66
  }
63
- let first = opt.first ?? 20
67
+ let first = opt.first ?? 10
64
68
  let tags = []
65
69
  for (const k in opt.tags ?? {}) {
66
70
  if (is(String, opt.tags[k])) {
@@ -126,14 +130,18 @@ export default class GQL {
126
130
  if (tag_unmatch) continue
127
131
  let _tx = {
128
132
  cursor: tx.id,
129
- ...tx,
133
+ id: tx.id,
134
+ recipient: tx.recipient ?? "",
130
135
  data: tx._data,
136
+ tags: tx.tags,
137
+ parent: tx.parent ?? { id: "" },
138
+ bundledIn: tx.bundledIn ?? { id: "" },
131
139
  block: pick(["id", "timestamp", "height", "previous"], block),
132
140
  anchor: tx.anchor ?? "",
133
141
  signature: tx.signature ?? "",
134
142
  owner: { address: tx.owner, key: this.mem.addrmap[tx.owner] },
135
- fee: { ar: "0", winston: "0" },
136
- quantity: { ar: "0", winston: "0" },
143
+ fee: { ar: "0.000000000000", winston: "0" },
144
+ quantity: { ar: "0.000000000000", winston: "0" },
137
145
  data: { size: "0", type: "" },
138
146
  }
139
147
  if (!isNil(opt.fields)) {
package/esm/utils.js CHANGED
@@ -1,3 +1,5 @@
1
+ import { graphql, parse, validate, buildSchema } from "graphql"
2
+
1
3
  import { clone, is, includes, fromPairs, map, isNil } from "ramda"
2
4
 
3
5
  const allows = [
@@ -293,7 +295,232 @@ function isJSON(obj) {
293
295
  const jsonToStr = obj =>
294
296
  isJSON(obj) || (is(Number, obj) ? Number(obj).toString() : obj)
295
297
 
298
+ const schema = buildSchema(`
299
+ type Query {
300
+ transaction(id: ID!): Transaction
301
+ transactions(
302
+ ids: [ID!]
303
+ owners: [String!]
304
+ recipients: [String!]
305
+ tags: [TagFilter!]
306
+ bundledIn: [ID!]
307
+ block: BlockFilter
308
+ first: Int = 10
309
+ after: String
310
+ sort: SortOrder = HEIGHT_DESC
311
+ ): TransactionConnection!
312
+ block(id: String): Block
313
+ blocks(
314
+ ids: [ID!]
315
+ height: BlockFilter
316
+ first: Int = 10
317
+ after: String
318
+ sort: SortOrder = HEIGHT_DESC
319
+ ): BlockConnection!
320
+ }
321
+
322
+ enum SortOrder {
323
+ HEIGHT_ASC
324
+ HEIGHT_DESC
325
+ }
326
+
327
+ input TagFilter {
328
+ name: String!
329
+ values: [String!]!
330
+ op: TagOperator = EQ
331
+ }
332
+
333
+ input BlockFilter {
334
+ min: Int
335
+ max: Int
336
+ }
337
+
338
+ type BlockConnection {
339
+ pageInfo: PageInfo!
340
+ edges: [BlockEdge!]!
341
+ }
342
+
343
+ type BlockEdge {
344
+ cursor: String!
345
+ node: Block!
346
+ }
347
+
348
+ type TransactionConnection {
349
+ pageInfo: PageInfo!
350
+ edges: [TransactionEdge!]!
351
+ }
352
+
353
+ type TransactionEdge {
354
+ cursor: String!
355
+ node: Transaction!
356
+ }
357
+
358
+ type PageInfo {
359
+ hasNextPage: Boolean!
360
+ }
361
+
362
+ type Transaction {
363
+ id: ID!
364
+ anchor: String!
365
+ signature: String!
366
+ recipient: String!
367
+ owner: Owner!
368
+ fee: Amount!
369
+ quantity: Amount!
370
+ data: MetaData!
371
+ tags: [Tag!]!
372
+ block: Block
373
+ parent: Parent @deprecated(reason: "Use \`bundledIn\`")
374
+ bundledIn: Bundle
375
+ }
376
+
377
+ type Parent {
378
+ id: ID!
379
+ }
380
+
381
+ type Bundle {
382
+ id: ID!
383
+ }
384
+
385
+ type Block {
386
+ id: ID!
387
+ timestamp: Int!
388
+ height: Int!
389
+ previous: ID!
390
+ }
391
+
392
+ type MetaData {
393
+ size: String!
394
+ type: String
395
+ }
396
+
397
+ type Amount {
398
+ winston: String!
399
+ ar: String!
400
+ }
401
+
402
+ type Owner {
403
+ address: String!
404
+ key: String!
405
+ }
406
+
407
+ type Tag {
408
+ name: String!
409
+ value: String!
410
+ }
411
+
412
+ enum TagOperator {
413
+ EQ
414
+ NEQ
415
+ }
416
+ `)
417
+
418
+ const root = {
419
+ transactions: ({ first }) => ({
420
+ edges: [],
421
+ pageInfo: {
422
+ hasNextPage: false,
423
+ },
424
+ }),
425
+ block: ({ id }) => ({
426
+ id,
427
+ timestamp: Date.now(),
428
+ height: 123456,
429
+ previous: "previous-block-id",
430
+ transactions: [],
431
+ miner: "example-miner",
432
+ reward: "1000",
433
+ tags: [],
434
+ indepHash: "example-indep-hash",
435
+ nonce: "000000",
436
+ }),
437
+ }
438
+
439
+ const mapParsed = (parsedQuery, variables) => {
440
+ const operation = parsedQuery.definitions[0]
441
+
442
+ if (operation.operation !== "query") {
443
+ throw new Error("Only 'query' operations are supported.")
444
+ }
445
+
446
+ const rootField = operation.selectionSet.selections[0]
447
+ const rootFieldName = rootField.name.value
448
+
449
+ const parseArgumentValue = argValue => {
450
+ if (argValue.kind === "Variable") {
451
+ return variables[argValue.name.value]
452
+ }
453
+
454
+ if (argValue.kind === "ListValue") {
455
+ return argValue.values.map(value => parseArgumentValue(value))
456
+ }
457
+
458
+ if (argValue.kind === "ObjectValue") {
459
+ return argValue.fields.reduce((obj, field) => {
460
+ obj[field.name.value] = parseArgumentValue(field.value)
461
+ return obj
462
+ }, {})
463
+ }
464
+
465
+ return argValue.value
466
+ }
467
+
468
+ const args = rootField.arguments.reduce((acc, arg) => {
469
+ acc[arg.name.value] = parseArgumentValue(arg.value)
470
+ return acc
471
+ }, {})
472
+
473
+ const extractFields = selectionSet => {
474
+ return selectionSet.selections.map(selection => {
475
+ const fieldName = selection.name.value
476
+
477
+ if (selection.selectionSet) {
478
+ return {
479
+ [fieldName]: extractFields(selection.selectionSet),
480
+ }
481
+ }
482
+ return fieldName
483
+ })
484
+ }
485
+
486
+ const fields = extractFields(rootField.selectionSet)
487
+
488
+ return { rootFieldName, args, fields }
489
+ }
490
+
491
+ const toGraphObj = ({ query, variables }) => {
492
+ const parsedQuery = parse(query)
493
+ const errors = validate(schema, parsedQuery)
494
+ const parsed = mapParsed(parsedQuery, variables)
495
+ const tar = parsed.rootFieldName
496
+ let fields = null
497
+ for (const v of parsed.fields) {
498
+ if (v.edges) {
499
+ for (const v2 of v.edges) {
500
+ if (v2.node) {
501
+ fields = v2.node
502
+ break
503
+ }
504
+ }
505
+ }
506
+ }
507
+ const args = parsed.args
508
+ if (args.block) {
509
+ for (const k in args.block) args.block[k] *= 1
510
+ }
511
+ if (args.first) args.first *= 1
512
+ if (fields) args.fields = fields
513
+ if (args.sort && args.sort === "HEIGHT_ASC") args.asc = true
514
+ delete args.sort
515
+ if (args.tags) {
516
+ let _tags = {}
517
+ for (const v of args.tags) _tags[v.name] = v.values
518
+ args.tags = _tags
519
+ }
520
+ return { tar, args }
521
+ }
296
522
  export {
523
+ toGraphObj,
297
524
  jsonToStr,
298
525
  mergeChecks,
299
526
  isCheckComplete,
package/esm/weavedrive.js CHANGED
@@ -1,10 +1,13 @@
1
1
  import Arweave from "arweave"
2
+ import { toGraphObj } from "./utils.js"
3
+ import { map } from "ramda"
4
+
2
5
  const KB = 1024
3
6
  const MB = KB * 1024
4
7
  const CACHE_SZ = 32 * KB
5
8
  const CHUNK_SZ = 128 * MB
6
9
  const NOTIFY_SZ = 512 * MB
7
-
10
+ const log = console.log
8
11
  export default class WeaveDrive {
9
12
  constructor(ar) {
10
13
  this.drive = function WeaveDrive(mod, FS) {
@@ -76,9 +79,9 @@ export default class WeaveDrive {
76
79
  var bytesLength = await this.customFetch(`/${id}`, {
77
80
  method: "HEAD",
78
81
  }).then(res => res.headers.get("Content-Length"))
79
- */
82
+ */
80
83
  let data = await ar.data(id)
81
- const bytesLength = data ? new TextEncoder().encode(data).length : 100
84
+ const bytesLength = data?.length ?? 0
82
85
  node.total_size = Number(bytesLength)
83
86
  node.cache = new Uint8Array(0)
84
87
  node.position = 0
@@ -370,11 +373,8 @@ export default class WeaveDrive {
370
373
  })
371
374
 
372
375
  const reader = response.body.getReader()
373
- */
374
- const data = new TextEncoder().encode(
375
- (await ar.data(stream.node.name)) ?? "",
376
- )
377
-
376
+ */
377
+ const data = await ar.data(stream.node.name)
378
378
  // Extract the Range header to determine the start and end of the requested chunk
379
379
  const start = 0
380
380
  const end = data.length
@@ -520,7 +520,6 @@ export default class WeaveDrive {
520
520
  // CAUTION: If the module is initiated with `mode = test` we don't check availability.
521
521
  return true
522
522
  }
523
-
524
523
  // Check if we are attempting to load the On-Boot id, if so allow it
525
524
  // this was added for AOP 6 Boot loader See: https://github.com/permaweb/aos/issues/342
526
525
  const bootTag = this.getTagValue("On-Boot", mod.spawn.tags)
@@ -533,6 +532,7 @@ export default class WeaveDrive {
533
532
  mod.module.tags,
534
533
  )
535
534
  const moduleHasWeaveDrive = moduleExtensions.includes("WeaveDrive")
535
+
536
536
  const processExtensions = this.getTagValues(
537
537
  "Extension",
538
538
  mod.spawn.tags,
@@ -577,9 +577,9 @@ export default class WeaveDrive {
577
577
  ...this.getTagValues("Attestor", mod.spawn.tags),
578
578
  ].filter(t => !!t),
579
579
  )
580
-
581
580
  // Init a set of GraphQL queries to run in order to find a valid attestation
582
581
  // Every WeaveDrive process has at least the "Assignments" availability check form.
582
+
583
583
  const assignmentsHaveID = await this.queryHasResult(
584
584
  `query {
585
585
  transactions(
@@ -603,10 +603,7 @@ export default class WeaveDrive {
603
603
  }
604
604
  }`,
605
605
  )
606
-
607
- if (assignmentsHaveID) {
608
- return true
609
- }
606
+ if (assignmentsHaveID) return true
610
607
 
611
608
  if (processMode == "Individual") {
612
609
  const individualsHaveID = await this.queryHasResult(
@@ -633,9 +630,7 @@ export default class WeaveDrive {
633
630
  }`,
634
631
  )
635
632
 
636
- if (individualsHaveID) {
637
- return true
638
- }
633
+ if (individualsHaveID) return true
639
634
  }
640
635
 
641
636
  // Halt message processing if the process requires Library mode.
@@ -657,7 +652,7 @@ export default class WeaveDrive {
657
652
 
658
653
  getTagValues(key, tags) {
659
654
  var values = []
660
- for (i = 0; i < tags.length; i++) {
655
+ for (let i = 0; i < tags.length; i++) {
661
656
  if (tags[i].name == key) {
662
657
  values.push(tags[i].value)
663
658
  }
@@ -674,7 +669,6 @@ export default class WeaveDrive {
674
669
  const json = await this.gqlQuery(query, variables).then(res =>
675
670
  res.json(),
676
671
  )
677
-
678
672
  return !!json?.data?.transactions?.edges?.length
679
673
  },
680
674
 
@@ -695,13 +689,25 @@ export default class WeaveDrive {
695
689
  },
696
690
 
697
691
  async gqlQuery(query, variables) {
698
- const options = {
699
- method: "POST",
700
- body: JSON.stringify({ query, variables }),
701
- headers: { "Content-Type": "application/json" },
692
+ let json = null
693
+ try {
694
+ const { tar, args } = toGraphObj({ query, variables })
695
+ let res2 = null
696
+ if (tar === "transactions") {
697
+ res2 = await ar.gql.txs({ ...args })
698
+ } else if (tar === "blocks") {
699
+ res2 = await ar.gql.blocks({ ...args })
700
+ }
701
+ const edges = map(v => ({ node: v, cursor: v.cursor }), res2)
702
+ json = {
703
+ data: {
704
+ transactions: { pageInfo: { hasNextPage: true }, edges },
705
+ },
706
+ }
707
+ } catch (e) {
708
+ log(e)
702
709
  }
703
-
704
- return this.customFetch("graphql", options)
710
+ return { json: () => json }
705
711
  },
706
712
  }
707
713
  }