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/cjs/ao.js +145 -50
- package/cjs/aoconnect.js +127 -114
- package/cjs/ar.js +14 -6
- package/cjs/armem.js +2 -1
- package/cjs/gql.js +27 -15
- package/cjs/helpers.js +217 -82
- package/cjs/lua/process.wasm +0 -0
- package/cjs/run.js +3 -1
- package/cjs/server.js +80 -153
- package/cjs/tao.js +13 -11
- package/cjs/tar.js +347 -206
- package/cjs/test.js +6 -0
- package/cjs/tgql.js +23 -8
- package/cjs/utils.js +141 -1
- package/cjs/weavedrive.js +86 -60
- package/esm/ao.js +30 -1
- package/esm/aoconnect.js +24 -15
- package/esm/ar.js +9 -3
- package/esm/armem.js +1 -0
- package/esm/gql.js +15 -6
- package/esm/helpers.js +50 -2
- package/esm/lua/process.wasm +0 -0
- package/esm/run.js +1 -1
- package/esm/server.js +30 -187
- package/esm/tao.js +7 -5
- package/esm/tar.js +125 -85
- package/esm/test.js +2 -1
- package/esm/tgql.js +12 -4
- package/esm/utils.js +227 -0
- package/esm/weavedrive.js +31 -25
- package/package.json +1 -1
package/esm/ar.js
CHANGED
|
@@ -2,7 +2,7 @@ import _Arweave from "arweave"
|
|
|
2
2
|
const Arweave = _Arweave.default ?? _Arweave
|
|
3
3
|
import { ArweaveSigner, bundleAndSignData, createData } from "arbundles"
|
|
4
4
|
import { buildTags, tag, isLocalhost } from "./utils.js"
|
|
5
|
-
import { is } from "ramda"
|
|
5
|
+
import { is, isNil } from "ramda"
|
|
6
6
|
import GQL from "./gql.js"
|
|
7
7
|
|
|
8
8
|
class AR {
|
|
@@ -258,9 +258,15 @@ class AR {
|
|
|
258
258
|
return (await this.gql.txs({ id: txid }))[0] ?? null
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
-
async data(txid,
|
|
261
|
+
async data(txid, _string = false) {
|
|
262
|
+
let decode = true
|
|
263
|
+
let string = _string
|
|
264
|
+
if (is(Object, _string)) {
|
|
265
|
+
if (!isNil(_string.decode)) decode = _string.decode
|
|
266
|
+
if (!isNil(_string.string)) string = _string.string
|
|
267
|
+
}
|
|
262
268
|
const _data = await this.arweave.transactions.getData(txid, {
|
|
263
|
-
decode
|
|
269
|
+
decode,
|
|
264
270
|
string,
|
|
265
271
|
})
|
|
266
272
|
return _data
|
package/esm/armem.js
CHANGED
package/esm/gql.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { includes, map, is, isNil, last, clone } from "ramda"
|
|
2
2
|
|
|
3
|
-
const full = `id anchor signature recipient owner { address key } fee { winston ar } quantity { winston ar } data { size type } tags { name value } block { id timestamp height previous } parent { id }`
|
|
3
|
+
const full = `id anchor signature recipient owner { address key } fee { winston ar } quantity { winston ar } data { size type } tags { name value } block { id timestamp height previous } parent { id } bundledIn { id }`
|
|
4
4
|
const full_blocks = `id timestamp height previous`
|
|
5
5
|
|
|
6
6
|
const subs = {
|
|
@@ -11,6 +11,7 @@ const subs = {
|
|
|
11
11
|
tags: ["name", "value"],
|
|
12
12
|
block: ["id", "timestamp", "height", "previous"],
|
|
13
13
|
parent: ["id"],
|
|
14
|
+
bundledIn: ["id"],
|
|
14
15
|
}
|
|
15
16
|
const field = (key, val = true) => {
|
|
16
17
|
if (includes(key, ["id", "anchor", "signature", "recipient"])) {
|
|
@@ -98,8 +99,11 @@ const query = (opt = {}) => {
|
|
|
98
99
|
}
|
|
99
100
|
if (opt.first) cond.push(`first: ${opt.first}`)
|
|
100
101
|
if (opt.after) cond.push(`after: "${opt.after}"`)
|
|
101
|
-
if (opt.asc)
|
|
102
|
-
|
|
102
|
+
if (opt.asc) {
|
|
103
|
+
cond.push(`sort: HEIGHT_ASC`)
|
|
104
|
+
} else {
|
|
105
|
+
cond.push(`sort: HEIGHT_DESC`)
|
|
106
|
+
}
|
|
103
107
|
let _cond = ""
|
|
104
108
|
if (cond.length > 0) _cond = `(${cond.join(", ")})`
|
|
105
109
|
let fields = []
|
|
@@ -124,6 +128,7 @@ const query = (opt = {}) => {
|
|
|
124
128
|
let _fields = fields.length > 0 ? fields.join(" ") : full
|
|
125
129
|
return `query {
|
|
126
130
|
transactions ${_cond}{
|
|
131
|
+
pageInfo { hasNextPage }
|
|
127
132
|
edges { cursor node { ${_fields} } }
|
|
128
133
|
}
|
|
129
134
|
}`
|
|
@@ -176,6 +181,7 @@ const query_blocks = (opt = {}) => {
|
|
|
176
181
|
let _fields = fields.length > 0 ? fields.join(" ") : full_blocks
|
|
177
182
|
return `query {
|
|
178
183
|
blocks ${_cond}{
|
|
184
|
+
pageInfo { hasNextPage }
|
|
179
185
|
edges { cursor node { ${_fields} } }
|
|
180
186
|
}
|
|
181
187
|
}`
|
|
@@ -191,13 +197,16 @@ export default class GQL {
|
|
|
191
197
|
headers: { "Content-Type": "application/json" },
|
|
192
198
|
body: JSON.stringify({ query }),
|
|
193
199
|
}).then(r => r.json())
|
|
194
|
-
return
|
|
200
|
+
return {
|
|
201
|
+
isNext: json.data[tar].pageInfo.hasNextPage,
|
|
202
|
+
data: map(v => ({ cursor: v.cursor, ...v.node }))(json.data[tar].edges),
|
|
203
|
+
}
|
|
195
204
|
}
|
|
196
205
|
async fetch(opt = {}, query, tar = "transactions") {
|
|
197
|
-
const data = await this._fetch(query, tar)
|
|
206
|
+
const { isNext, data } = await this._fetch(query, tar)
|
|
198
207
|
if (opt.next === true) {
|
|
199
208
|
let cursor = null
|
|
200
|
-
if (data.length > 0) cursor = last(data).cursor
|
|
209
|
+
if (isNext && data.length > 0) cursor = last(data).cursor
|
|
201
210
|
const next = !cursor
|
|
202
211
|
? null
|
|
203
212
|
: async () => {
|
package/esm/helpers.js
CHANGED
|
@@ -22,6 +22,13 @@ export class Src {
|
|
|
22
22
|
this.dir = dir
|
|
23
23
|
if (!dir) dirname().then(v => (this.dir = resolve(v, "lua")))
|
|
24
24
|
}
|
|
25
|
+
async init(dir) {
|
|
26
|
+
if (!this.dir) {
|
|
27
|
+
dir ??= await dirname()
|
|
28
|
+
this.dir = resolve(dir, "lua")
|
|
29
|
+
}
|
|
30
|
+
return this
|
|
31
|
+
}
|
|
25
32
|
data(file, ext = "lua") {
|
|
26
33
|
return readFileSync(
|
|
27
34
|
`${this.dir}/${file}.${ext}`,
|
|
@@ -34,6 +41,47 @@ export class Src {
|
|
|
34
41
|
}
|
|
35
42
|
}
|
|
36
43
|
|
|
44
|
+
export class Testnet {
|
|
45
|
+
constructor({ port = 4000, arweave, aoconnect, docker = false } = {}) {
|
|
46
|
+
this.docker = docker
|
|
47
|
+
this.arweave = arweave ?? { port }
|
|
48
|
+
this.aoconnect = aoconnect ?? {
|
|
49
|
+
MU_URL: `http://localhost:${port + 2}`,
|
|
50
|
+
SU_URL: `http://localhost:${port + 3}`,
|
|
51
|
+
CU_URL: `http://localhost:${port + 4}`,
|
|
52
|
+
GATEWAY_URL: `http://localhost:${port}`,
|
|
53
|
+
}
|
|
54
|
+
this.ar = new AR(this.arweave)
|
|
55
|
+
}
|
|
56
|
+
async init(jwk) {
|
|
57
|
+
this.authority = (
|
|
58
|
+
await fetch(this.aoconnect.SU_URL).then(r => r.json())
|
|
59
|
+
).address
|
|
60
|
+
this.src = await new Src({ ar: this.ar }).init()
|
|
61
|
+
await this.ar.init(jwk)
|
|
62
|
+
this.jwk = this.ar.jwk
|
|
63
|
+
this.addr = this.ar.a
|
|
64
|
+
this.gql = this.ar.gql
|
|
65
|
+
this.module_src = await this.src.upload("aos2_0_1", "wasm")
|
|
66
|
+
this.ao = await new AO({
|
|
67
|
+
ar: this.ar,
|
|
68
|
+
aoconnect: this.aoconnect,
|
|
69
|
+
authority: this.authority,
|
|
70
|
+
}).init(this.ar.jwk)
|
|
71
|
+
const { id } = await this.ao.postModule({
|
|
72
|
+
data: await this.ar.data(this.module_src),
|
|
73
|
+
overwrite: true,
|
|
74
|
+
})
|
|
75
|
+
this.module = id
|
|
76
|
+
const { scheduler } = await this.ao.postScheduler({
|
|
77
|
+
url: this.docker ? "http://su" : this.aoconnect.SU_URL,
|
|
78
|
+
overwrite: true,
|
|
79
|
+
})
|
|
80
|
+
this.scheduler = scheduler
|
|
81
|
+
return this
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
37
85
|
export const setup = async ({
|
|
38
86
|
aoconnect,
|
|
39
87
|
arweave,
|
|
@@ -61,7 +109,7 @@ export const setup = async ({
|
|
|
61
109
|
|
|
62
110
|
if (opt) {
|
|
63
111
|
const ar = await new AR(opt.ar).init(opt.jwk)
|
|
64
|
-
const src = new Src({ ar,
|
|
112
|
+
const src = new Src({ ar, dir })
|
|
65
113
|
const ao = await new AO(opt.ao).init(opt.jwk)
|
|
66
114
|
const ao2 = await new AO(opt.ao2).init(opt.jwk)
|
|
67
115
|
console.log("cache:\t", optPath)
|
|
@@ -78,7 +126,7 @@ export const setup = async ({
|
|
|
78
126
|
}
|
|
79
127
|
const ar = new AR(arweave)
|
|
80
128
|
await ar.gen("10")
|
|
81
|
-
const src = new Src({ ar,
|
|
129
|
+
const src = new Src({ ar, dir })
|
|
82
130
|
opt = { ar: { ...arweave }, jwk: ar.jwk }
|
|
83
131
|
if (!auth && /localhost/.test(aoconnect?.CU_URL ?? "")) {
|
|
84
132
|
auth = (await fetch(aoconnect.CU_URL).then(r => r.json())).address
|
|
Binary file
|
package/esm/run.js
CHANGED
package/esm/server.js
CHANGED
|
@@ -2,176 +2,21 @@ import express from "express"
|
|
|
2
2
|
import cors from "cors"
|
|
3
3
|
import base64url from "base64url"
|
|
4
4
|
import { DataItem } from "arbundles"
|
|
5
|
-
import { tags } from "./utils.js"
|
|
5
|
+
import { tags, toGraphObj } from "./utils.js"
|
|
6
6
|
import { connect } from "./aoconnect.js"
|
|
7
7
|
import { GQL, cu, su, mu } from "./test.js"
|
|
8
8
|
import bodyParser from "body-parser"
|
|
9
|
-
import { graphql, parse, validate, buildSchema } from "graphql"
|
|
10
9
|
import { keys, map, reverse } from "ramda"
|
|
11
|
-
const schema = buildSchema(`
|
|
12
|
-
schema {
|
|
13
|
-
query: Query
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
type Query {
|
|
17
|
-
transactions(
|
|
18
|
-
ids: [ID!]
|
|
19
|
-
tags: [TagFilter!]
|
|
20
|
-
block: BlockFilter
|
|
21
|
-
after: String
|
|
22
|
-
first: Int
|
|
23
|
-
): TransactionConnection!
|
|
24
|
-
|
|
25
|
-
block(id: ID, height: Int): Block
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
type TransactionConnection {
|
|
29
|
-
edges: [TransactionEdge!]!
|
|
30
|
-
pageInfo: PageInfo!
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
type TransactionEdge {
|
|
34
|
-
cursor: String!
|
|
35
|
-
node: Transaction!
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
type Transaction {
|
|
39
|
-
id: ID!
|
|
40
|
-
anchor: String
|
|
41
|
-
signature: String!
|
|
42
|
-
recipient: String
|
|
43
|
-
owner: Owner!
|
|
44
|
-
fee: Quantity!
|
|
45
|
-
quantity: Quantity!
|
|
46
|
-
data: Data!
|
|
47
|
-
tags: [Tag!]!
|
|
48
|
-
block: Block
|
|
49
|
-
parent: Transaction
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
type Owner {
|
|
53
|
-
address: String!
|
|
54
|
-
key: String!
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
type Quantity {
|
|
58
|
-
winston: String!
|
|
59
|
-
ar: String!
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
type Data {
|
|
63
|
-
size: String!
|
|
64
|
-
type: String
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
type Tag {
|
|
68
|
-
name: String!
|
|
69
|
-
value: String!
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
type Block {
|
|
73
|
-
id: ID!
|
|
74
|
-
timestamp: Int!
|
|
75
|
-
height: Int!
|
|
76
|
-
previous: String
|
|
77
|
-
transactions: [Transaction!]!
|
|
78
|
-
miner: String!
|
|
79
|
-
reward: String!
|
|
80
|
-
tags: [Tag!]!
|
|
81
|
-
indepHash: String!
|
|
82
|
-
nonce: String!
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
type PageInfo {
|
|
86
|
-
hasNextPage: Boolean!
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
input TagFilter {
|
|
90
|
-
name: String!
|
|
91
|
-
values: [String!]!
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
input BlockFilter {
|
|
95
|
-
min: Int
|
|
96
|
-
max: Int
|
|
97
|
-
}
|
|
98
|
-
`)
|
|
99
|
-
|
|
100
|
-
const root = {
|
|
101
|
-
transactions: ({ first }) => ({
|
|
102
|
-
edges: [],
|
|
103
|
-
pageInfo: {
|
|
104
|
-
hasNextPage: false,
|
|
105
|
-
},
|
|
106
|
-
}),
|
|
107
|
-
block: ({ id }) => ({
|
|
108
|
-
id,
|
|
109
|
-
timestamp: Date.now(),
|
|
110
|
-
height: 123456,
|
|
111
|
-
previous: "previous-block-id",
|
|
112
|
-
transactions: [],
|
|
113
|
-
miner: "example-miner",
|
|
114
|
-
reward: "1000",
|
|
115
|
-
tags: [],
|
|
116
|
-
indepHash: "example-indep-hash",
|
|
117
|
-
nonce: "000000",
|
|
118
|
-
}),
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const mapParsed = (parsedQuery, variables) => {
|
|
122
|
-
const operation = parsedQuery.definitions[0]
|
|
123
|
-
|
|
124
|
-
if (operation.operation !== "query") {
|
|
125
|
-
throw new Error("Only 'query' operations are supported.")
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const rootField = operation.selectionSet.selections[0]
|
|
129
|
-
const rootFieldName = rootField.name.value
|
|
130
|
-
|
|
131
|
-
const parseArgumentValue = argValue => {
|
|
132
|
-
if (argValue.kind === "Variable") {
|
|
133
|
-
return variables[argValue.name.value]
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (argValue.kind === "ListValue") {
|
|
137
|
-
return argValue.values.map(value => parseArgumentValue(value))
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
if (argValue.kind === "ObjectValue") {
|
|
141
|
-
return argValue.fields.reduce((obj, field) => {
|
|
142
|
-
obj[field.name.value] = parseArgumentValue(field.value)
|
|
143
|
-
return obj
|
|
144
|
-
}, {})
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return argValue.value
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const args = rootField.arguments.reduce((acc, arg) => {
|
|
151
|
-
acc[arg.name.value] = parseArgumentValue(arg.value)
|
|
152
|
-
return acc
|
|
153
|
-
}, {})
|
|
154
|
-
|
|
155
|
-
const extractFields = selectionSet => {
|
|
156
|
-
return selectionSet.selections.map(selection => {
|
|
157
|
-
const fieldName = selection.name.value
|
|
158
|
-
|
|
159
|
-
if (selection.selectionSet) {
|
|
160
|
-
return {
|
|
161
|
-
[fieldName]: extractFields(selection.selectionSet),
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
return fieldName
|
|
165
|
-
})
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const fields = extractFields(rootField.selectionSet)
|
|
169
|
-
|
|
170
|
-
return { rootFieldName, args, fields }
|
|
171
|
-
}
|
|
172
10
|
|
|
173
11
|
class Server {
|
|
174
|
-
constructor({
|
|
12
|
+
constructor({
|
|
13
|
+
ar = 4000,
|
|
14
|
+
mu = 4002,
|
|
15
|
+
su = 4003,
|
|
16
|
+
cu = 4004,
|
|
17
|
+
aoconnect,
|
|
18
|
+
log = false,
|
|
19
|
+
} = {}) {
|
|
175
20
|
const {
|
|
176
21
|
ar: _ar,
|
|
177
22
|
message,
|
|
@@ -182,7 +27,7 @@ class Server {
|
|
|
182
27
|
mem,
|
|
183
28
|
monitor,
|
|
184
29
|
unmonitor,
|
|
185
|
-
} = connect(aoconnect)
|
|
30
|
+
} = connect(aoconnect, log)
|
|
186
31
|
this.monitor = monitor
|
|
187
32
|
this.unmonitor = unmonitor
|
|
188
33
|
this.spawn = spawn
|
|
@@ -207,7 +52,7 @@ class Server {
|
|
|
207
52
|
app.get("/wallet/:id/balance", (req, res) => res.send("0"))
|
|
208
53
|
app.get("/mint/:id/:amount", (req, res) => res.json({ id: "0" }))
|
|
209
54
|
app.get("/tx/:id/offset", async (req, res) => {
|
|
210
|
-
res.status(
|
|
55
|
+
res.status(400)
|
|
211
56
|
res.send(null)
|
|
212
57
|
})
|
|
213
58
|
app.get("/tx_anchor", async (req, res) => {
|
|
@@ -229,26 +74,24 @@ class Server {
|
|
|
229
74
|
res.send("0")
|
|
230
75
|
})
|
|
231
76
|
app.post("/graphql", async (req, res) => {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
77
|
+
try {
|
|
78
|
+
const { query, variables } = req.body
|
|
79
|
+
const { tar, args } = toGraphObj({ query, variables })
|
|
80
|
+
let res2 = null
|
|
81
|
+
if (tar === "transactions") {
|
|
82
|
+
res2 = await this.gql.txs({ ...args })
|
|
83
|
+
} else if (tar === "blocks") {
|
|
84
|
+
res2 = await this.gql.blocks({ ...args })
|
|
85
|
+
}
|
|
86
|
+
const edges = map(v => ({ node: v, cursor: v.cursor }), res2)
|
|
87
|
+
res.json({
|
|
88
|
+
data: { transactions: { pageInfo: { hasNextPage: true }, edges } },
|
|
89
|
+
})
|
|
90
|
+
} catch (e) {
|
|
91
|
+
console.log(e)
|
|
92
|
+
res.status(400)
|
|
93
|
+
res.json({ error: "bad request" })
|
|
249
94
|
}
|
|
250
|
-
const edges = map(v => ({ node: v, cursor: v.cursor }), res2)
|
|
251
|
-
res.json({ data: { transactions: { edges } } })
|
|
252
95
|
})
|
|
253
96
|
let data = {}
|
|
254
97
|
app.post("/:id", async (req, res) => {
|
|
@@ -325,7 +168,7 @@ class Server {
|
|
|
325
168
|
err = true
|
|
326
169
|
}
|
|
327
170
|
if (err) {
|
|
328
|
-
res.status(
|
|
171
|
+
res.status(400)
|
|
329
172
|
res.send({ err })
|
|
330
173
|
} else {
|
|
331
174
|
res.send({ id: item.id })
|
|
@@ -407,7 +250,7 @@ class Server {
|
|
|
407
250
|
const { Id: id, Owner: owner, Tags: tags, Data: data } = req.body
|
|
408
251
|
const res2 = await this.dryrun({ id, owner, tags, data, process })
|
|
409
252
|
if (!res2) {
|
|
410
|
-
res.status(
|
|
253
|
+
res.status(400)
|
|
411
254
|
res.json({ err: true })
|
|
412
255
|
} else {
|
|
413
256
|
delete res2.Memory
|
package/esm/tao.js
CHANGED
|
@@ -77,7 +77,7 @@ class AO extends MAO {
|
|
|
77
77
|
this.message = message
|
|
78
78
|
this.spawn = async (...opt) => {
|
|
79
79
|
const res = await spawn(...opt)
|
|
80
|
-
|
|
80
|
+
await this.load({ data: log, pid: res })
|
|
81
81
|
return res
|
|
82
82
|
}
|
|
83
83
|
this.dryrun = async (...opt) => {
|
|
@@ -111,11 +111,13 @@ class AO extends MAO {
|
|
|
111
111
|
"Memory-Limit": "1-gb",
|
|
112
112
|
"Compute-Limit": "9000000000000",
|
|
113
113
|
})
|
|
114
|
-
|
|
115
|
-
const _tags = buildTags(null, t)
|
|
116
114
|
const signer = createDataItemSigner(jwk)
|
|
117
|
-
const { id, owner } = await this.ar.dataitem({
|
|
118
|
-
|
|
115
|
+
const { id, owner, item } = await this.ar.dataitem({
|
|
116
|
+
tags: t,
|
|
117
|
+
data,
|
|
118
|
+
signer,
|
|
119
|
+
})
|
|
120
|
+
await this.ar.postItems(item, jwk)
|
|
119
121
|
this.mem.wasms[id] = { data, format: t["Module-Format"] }
|
|
120
122
|
return { id }
|
|
121
123
|
}
|