wao 0.4.11 → 0.5.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 +4 -3
- package/cjs/aoconnect.js +223 -136
- package/cjs/ar.js +299 -211
- package/cjs/armem.js +102 -41
- package/cjs/run.js +26 -0
- package/cjs/server.js +632 -0
- package/cjs/tao.js +4 -8
- package/cjs/tar.js +161 -65
- package/cjs/test.js +8 -1
- package/esm/ao.js +1 -1
- package/esm/aoconnect.js +94 -35
- package/esm/ar.js +42 -2
- package/esm/armem.js +53 -8
- package/esm/run.js +7 -0
- package/esm/server.js +375 -0
- package/esm/tao.js +2 -2
- package/esm/tar.js +56 -31
- package/esm/test.js +4 -1
- package/esm/tgql.js +0 -1
- package/package.json +11 -1
package/esm/armem.js
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import Arweave from "arweave"
|
|
2
2
|
import { last } from "ramda"
|
|
3
|
-
|
|
3
|
+
import { buildTags } from "./utils.js"
|
|
4
4
|
export default class ArMem {
|
|
5
|
-
constructor() {
|
|
5
|
+
constructor({ MU_URL, CU_URL, SU_URL, GATEWAY_URL, scheduler } = {}) {
|
|
6
6
|
this.__type__ = "mem"
|
|
7
7
|
this.arweave = Arweave.init()
|
|
8
|
-
this.arweave.transactions.getTransactionAnchor = () =>
|
|
9
|
-
return this.blocks.length === 0
|
|
10
|
-
? ""
|
|
11
|
-
: last(this.blockmap[last(this.blocks)].txs)
|
|
12
|
-
}
|
|
8
|
+
this.arweave.transactions.getTransactionAnchor = () => this.getAnchor()
|
|
13
9
|
this.arweave.transactions.getPrice = () => 0
|
|
14
10
|
this.addrmap = {}
|
|
15
11
|
this.txs = {}
|
|
16
12
|
this.jwks = {}
|
|
17
|
-
this.height = 0
|
|
18
13
|
this.blocks = []
|
|
19
14
|
this.blockmap = {}
|
|
20
15
|
this.env = {}
|
|
@@ -39,5 +34,55 @@ export default class ArMem {
|
|
|
39
34
|
format: "wasm64-unknown-emscripten-draft_2024_02_15",
|
|
40
35
|
},
|
|
41
36
|
}
|
|
37
|
+
let txs = []
|
|
38
|
+
for (const k in this.modules) {
|
|
39
|
+
const key = this.modules[k]
|
|
40
|
+
txs.push(key)
|
|
41
|
+
this.txs[key] = {
|
|
42
|
+
id: key,
|
|
43
|
+
block: 0,
|
|
44
|
+
tags: buildTags(null, {
|
|
45
|
+
"Data-Protocol": "ao",
|
|
46
|
+
Variant: "ao.TN.1",
|
|
47
|
+
Type: "Module",
|
|
48
|
+
"Module-Format": "wasm64-unknown-emscripten-draft_2024_02_15",
|
|
49
|
+
"Input-Encoding": "JSON-V1",
|
|
50
|
+
"Output-Encoding": "JSON-V1",
|
|
51
|
+
"Memory-Limit": "1-gb",
|
|
52
|
+
"Compute-Limit": "9000000000000",
|
|
53
|
+
}),
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (scheduler && SU_URL) {
|
|
57
|
+
const key = scheduler
|
|
58
|
+
txs.push(key)
|
|
59
|
+
this.addrmap[scheduler] = { address: scheduler }
|
|
60
|
+
this.txs[key] = {
|
|
61
|
+
id: key,
|
|
62
|
+
block: 0,
|
|
63
|
+
owner: scheduler,
|
|
64
|
+
tags: buildTags(null, {
|
|
65
|
+
"Data-Protocol": "ao",
|
|
66
|
+
Variant: "ao.TN.1",
|
|
67
|
+
Type: "Scheduler-Location",
|
|
68
|
+
Url: SU_URL,
|
|
69
|
+
"Time-To-Live": 1000 * 60 * 60 * 24 * 365 * 10,
|
|
70
|
+
}),
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
this.blockmap["0"] = {
|
|
74
|
+
txs,
|
|
75
|
+
timestamp: Date.now(),
|
|
76
|
+
height: 0,
|
|
77
|
+
previous: "",
|
|
78
|
+
id: "0",
|
|
79
|
+
}
|
|
80
|
+
this.blocks.push("0")
|
|
81
|
+
this.height = 1
|
|
82
|
+
}
|
|
83
|
+
getAnchor() {
|
|
84
|
+
return this.blocks.length === 0
|
|
85
|
+
? "Do_Uc2Sju_ffp6Ev0AnLVdPtot15rvMjP-a9VVaA5fM"
|
|
86
|
+
: last(this.blockmap[last(this.blocks)].txs)
|
|
42
87
|
}
|
|
43
88
|
}
|
package/esm/run.js
ADDED
package/esm/server.js
ADDED
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
import express from "express"
|
|
2
|
+
import base64url from "base64url"
|
|
3
|
+
import { DataItem } from "arbundles"
|
|
4
|
+
import { tags } from "./utils.js"
|
|
5
|
+
import { connect } from "./aoconnect.js"
|
|
6
|
+
import { GQL, cu, su, mu } from "./test.js"
|
|
7
|
+
import bodyParser from "body-parser"
|
|
8
|
+
import { graphql, parse, validate, buildSchema } from "graphql"
|
|
9
|
+
import { map } from "ramda"
|
|
10
|
+
const schema = buildSchema(`
|
|
11
|
+
schema {
|
|
12
|
+
query: Query
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type Query {
|
|
16
|
+
transactions(
|
|
17
|
+
ids: [ID!]
|
|
18
|
+
tags: [TagFilter!]
|
|
19
|
+
block: BlockFilter
|
|
20
|
+
after: String
|
|
21
|
+
first: Int
|
|
22
|
+
): TransactionConnection!
|
|
23
|
+
|
|
24
|
+
block(id: ID, height: Int): Block
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type TransactionConnection {
|
|
28
|
+
edges: [TransactionEdge!]!
|
|
29
|
+
pageInfo: PageInfo!
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
type TransactionEdge {
|
|
33
|
+
cursor: String!
|
|
34
|
+
node: Transaction!
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
type Transaction {
|
|
38
|
+
id: ID!
|
|
39
|
+
anchor: String
|
|
40
|
+
signature: String!
|
|
41
|
+
recipient: String
|
|
42
|
+
owner: Owner!
|
|
43
|
+
fee: Quantity!
|
|
44
|
+
quantity: Quantity!
|
|
45
|
+
data: Data!
|
|
46
|
+
tags: [Tag!]!
|
|
47
|
+
block: Block
|
|
48
|
+
parent: Transaction
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
type Owner {
|
|
52
|
+
address: String!
|
|
53
|
+
key: String!
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
type Quantity {
|
|
57
|
+
winston: String!
|
|
58
|
+
ar: String!
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
type Data {
|
|
62
|
+
size: String!
|
|
63
|
+
type: String
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
type Tag {
|
|
67
|
+
name: String!
|
|
68
|
+
value: String!
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
type Block {
|
|
72
|
+
id: ID!
|
|
73
|
+
timestamp: Int!
|
|
74
|
+
height: Int!
|
|
75
|
+
previous: String
|
|
76
|
+
transactions: [Transaction!]!
|
|
77
|
+
miner: String!
|
|
78
|
+
reward: String!
|
|
79
|
+
tags: [Tag!]!
|
|
80
|
+
indepHash: String!
|
|
81
|
+
nonce: String!
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
type PageInfo {
|
|
85
|
+
hasNextPage: Boolean!
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
input TagFilter {
|
|
89
|
+
name: String!
|
|
90
|
+
values: [String!]!
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
input BlockFilter {
|
|
94
|
+
min: Int
|
|
95
|
+
max: Int
|
|
96
|
+
}
|
|
97
|
+
`)
|
|
98
|
+
|
|
99
|
+
const root = {
|
|
100
|
+
transactions: ({ first }) => ({
|
|
101
|
+
edges: [],
|
|
102
|
+
pageInfo: {
|
|
103
|
+
hasNextPage: false,
|
|
104
|
+
},
|
|
105
|
+
}),
|
|
106
|
+
block: ({ id }) => ({
|
|
107
|
+
id,
|
|
108
|
+
timestamp: Date.now(),
|
|
109
|
+
height: 123456,
|
|
110
|
+
previous: "previous-block-id",
|
|
111
|
+
transactions: [],
|
|
112
|
+
miner: "example-miner",
|
|
113
|
+
reward: "1000",
|
|
114
|
+
tags: [],
|
|
115
|
+
indepHash: "example-indep-hash",
|
|
116
|
+
nonce: "000000",
|
|
117
|
+
}),
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const mapParsed = (parsedQuery, variables) => {
|
|
121
|
+
const operation = parsedQuery.definitions[0]
|
|
122
|
+
|
|
123
|
+
if (operation.operation !== "query") {
|
|
124
|
+
throw new Error("Only 'query' operations are supported.")
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const rootField = operation.selectionSet.selections[0]
|
|
128
|
+
const rootFieldName = rootField.name.value
|
|
129
|
+
|
|
130
|
+
const parseArgumentValue = argValue => {
|
|
131
|
+
if (argValue.kind === "Variable") {
|
|
132
|
+
return variables[argValue.name.value]
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (argValue.kind === "ListValue") {
|
|
136
|
+
return argValue.values.map(value => parseArgumentValue(value))
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (argValue.kind === "ObjectValue") {
|
|
140
|
+
return argValue.fields.reduce((obj, field) => {
|
|
141
|
+
obj[field.name.value] = parseArgumentValue(field.value)
|
|
142
|
+
return obj
|
|
143
|
+
}, {})
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return argValue.value
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const args = rootField.arguments.reduce((acc, arg) => {
|
|
150
|
+
acc[arg.name.value] = parseArgumentValue(arg.value)
|
|
151
|
+
return acc
|
|
152
|
+
}, {})
|
|
153
|
+
|
|
154
|
+
const extractFields = selectionSet => {
|
|
155
|
+
return selectionSet.selections.map(selection => {
|
|
156
|
+
const fieldName = selection.name.value
|
|
157
|
+
|
|
158
|
+
if (selection.selectionSet) {
|
|
159
|
+
return {
|
|
160
|
+
[fieldName]: extractFields(selection.selectionSet),
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
return fieldName
|
|
164
|
+
})
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const fields = extractFields(rootField.selectionSet)
|
|
168
|
+
|
|
169
|
+
return { rootFieldName, args, fields }
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
class Server {
|
|
173
|
+
constructor({ ar = 4000, mu = 4002, su = 4003, cu = 4004, aoconnect } = {}) {
|
|
174
|
+
const {
|
|
175
|
+
ar: _ar,
|
|
176
|
+
message,
|
|
177
|
+
spawn,
|
|
178
|
+
dryrun,
|
|
179
|
+
result,
|
|
180
|
+
results,
|
|
181
|
+
mem,
|
|
182
|
+
monitor,
|
|
183
|
+
unmonitor,
|
|
184
|
+
} = connect(aoconnect)
|
|
185
|
+
this.monitor = monitor
|
|
186
|
+
this.unmonitor = unmonitor
|
|
187
|
+
this.spawn = spawn
|
|
188
|
+
this._ar = _ar
|
|
189
|
+
this.message = message
|
|
190
|
+
this.dryrun = dryrun
|
|
191
|
+
this.result = result
|
|
192
|
+
this.results = results
|
|
193
|
+
this.mem = mem
|
|
194
|
+
this.gql = new GQL({ mem })
|
|
195
|
+
this.ports = { ar, mu, su, cu }
|
|
196
|
+
this.servers = []
|
|
197
|
+
this.ar()
|
|
198
|
+
this.mu()
|
|
199
|
+
this.su()
|
|
200
|
+
this.cu()
|
|
201
|
+
}
|
|
202
|
+
ar() {
|
|
203
|
+
const app = express()
|
|
204
|
+
app.use(bodyParser.json({ limit: "100mb" }))
|
|
205
|
+
app.get("/tx/:id/offset", async (req, res) => {
|
|
206
|
+
res.status(500)
|
|
207
|
+
res.send(null)
|
|
208
|
+
})
|
|
209
|
+
app.get("/tx_anchor", async (req, res) => {
|
|
210
|
+
res.send(this.mem.getAnchor())
|
|
211
|
+
})
|
|
212
|
+
app.get("/mine", async (req, res) => {
|
|
213
|
+
res.json(req.params)
|
|
214
|
+
})
|
|
215
|
+
app.get("/:id", async (req, res) => {
|
|
216
|
+
const _data = await this._ar.data(req.params.id)
|
|
217
|
+
if (!_data) {
|
|
218
|
+
res.status(404)
|
|
219
|
+
res.send(null)
|
|
220
|
+
} else {
|
|
221
|
+
res.send(Buffer.from(_data, "base64"))
|
|
222
|
+
}
|
|
223
|
+
})
|
|
224
|
+
app.get("/price/:id", async (req, res) => {
|
|
225
|
+
res.send("0")
|
|
226
|
+
})
|
|
227
|
+
app.post("/graphql", async (req, res) => {
|
|
228
|
+
const { query, variables } = req.body
|
|
229
|
+
const parsedQuery = parse(query)
|
|
230
|
+
const errors = validate(schema, parsedQuery)
|
|
231
|
+
const parsed = mapParsed(parsedQuery, variables)
|
|
232
|
+
const tar = parsed.rootFieldName
|
|
233
|
+
const fields = parsed.fields[0].edges[0].node
|
|
234
|
+
const args = parsed.args
|
|
235
|
+
let res2 = null
|
|
236
|
+
if (tar === "transactions") {
|
|
237
|
+
res2 = await this.gql.txs({ ...args })
|
|
238
|
+
} else if (tar === "blocks") {
|
|
239
|
+
res2 = await this.gql.blocks()
|
|
240
|
+
}
|
|
241
|
+
const edges = map(v => ({ node: v, cursor: v.cursor }), res2)
|
|
242
|
+
res.json({ data: { transactions: { edges } } })
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
let data = {}
|
|
246
|
+
app.post("/:id", async (req, res) => {
|
|
247
|
+
if (req.body.chunk) {
|
|
248
|
+
if (data[req.body.data_root]) {
|
|
249
|
+
data[req.body.data_root].data += req.body.chunk
|
|
250
|
+
const buf = Buffer.from(req.body.chunk, "base64")
|
|
251
|
+
if (!data[req.body.data_root].chunks) {
|
|
252
|
+
data[req.body.data_root].chunks = buf
|
|
253
|
+
} else {
|
|
254
|
+
data[req.body.data_root].chunks = Buffer.concat([
|
|
255
|
+
data[req.body.data_root].chunks,
|
|
256
|
+
buf,
|
|
257
|
+
])
|
|
258
|
+
}
|
|
259
|
+
delete req.body.chunk
|
|
260
|
+
if (
|
|
261
|
+
data[req.body.data_root].data_size <=
|
|
262
|
+
data[req.body.data_root].chunks.length
|
|
263
|
+
) {
|
|
264
|
+
data[req.body.data_root].data =
|
|
265
|
+
data[req.body.data_root].chunks.toString("base64")
|
|
266
|
+
await this._ar.postTx(data[req.body.data_root])
|
|
267
|
+
delete data[req.body.data_root]
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
res.json({ id: req.body.id })
|
|
271
|
+
} else {
|
|
272
|
+
if (req.body.data_root && req.body.data === "") {
|
|
273
|
+
data[req.body.data_root] = req.body
|
|
274
|
+
} else {
|
|
275
|
+
await this._ar.postTx(req.body)
|
|
276
|
+
}
|
|
277
|
+
res.json({ id: req.body.id })
|
|
278
|
+
}
|
|
279
|
+
})
|
|
280
|
+
app.post("/tx", async (req, res) => {
|
|
281
|
+
await this._ar.postTx(req.body)
|
|
282
|
+
res.json({ id: req.body.id })
|
|
283
|
+
})
|
|
284
|
+
const server = app.listen(this.ports.ar, () => {
|
|
285
|
+
console.log(`AR on port ${this.ports.ar}`)
|
|
286
|
+
})
|
|
287
|
+
this.servers.push(server)
|
|
288
|
+
}
|
|
289
|
+
mu() {
|
|
290
|
+
const app = express()
|
|
291
|
+
app.use(express.raw({ type: "*/*" }))
|
|
292
|
+
app.get("/", (req, res) => res.send("ao messenger unit"))
|
|
293
|
+
app.post("/monitor/:id", async (req, res) => {
|
|
294
|
+
await this.monitor({ process: req.params.id })
|
|
295
|
+
res.json({ id: req.params.id, messag: "cron monitored!" })
|
|
296
|
+
})
|
|
297
|
+
app.delete("/monitor/:id", async (req, res) => {
|
|
298
|
+
await this.unmonitor({ process: req.params.id })
|
|
299
|
+
res.json({ id: req.params.id, message: "cron deleted!" })
|
|
300
|
+
})
|
|
301
|
+
app.post("/", async (req, res) => {
|
|
302
|
+
const binary = req.body
|
|
303
|
+
let valid = await DataItem.verify(binary)
|
|
304
|
+
let type = null
|
|
305
|
+
let item = null
|
|
306
|
+
if (valid) item = new DataItem(binary)
|
|
307
|
+
const _tags = tags(item.tags)
|
|
308
|
+
let err = null
|
|
309
|
+
if (_tags.Type === "Process") {
|
|
310
|
+
await this.spawn({
|
|
311
|
+
item,
|
|
312
|
+
module: _tags.Module,
|
|
313
|
+
scheduler: _tags.Scheduler,
|
|
314
|
+
})
|
|
315
|
+
} else if (_tags.Type === "Message") {
|
|
316
|
+
await this.message({ item, process: item.target })
|
|
317
|
+
} else {
|
|
318
|
+
err = true
|
|
319
|
+
}
|
|
320
|
+
if (err) res.status(500)
|
|
321
|
+
res.send({ id: item.id })
|
|
322
|
+
})
|
|
323
|
+
const server = app.listen(this.ports.mu, () =>
|
|
324
|
+
console.log(`MU on port ${this.ports.mu}`),
|
|
325
|
+
)
|
|
326
|
+
this.servers.push(server)
|
|
327
|
+
}
|
|
328
|
+
su() {
|
|
329
|
+
const app = express()
|
|
330
|
+
app.use(bodyParser.json())
|
|
331
|
+
app.get("/", (req, res) => res.json({ timestamp: Date.now() }))
|
|
332
|
+
const server = app.listen(this.ports.su, () =>
|
|
333
|
+
console.log(`SU on port ${this.ports.su}`),
|
|
334
|
+
)
|
|
335
|
+
this.servers.push(server)
|
|
336
|
+
}
|
|
337
|
+
cu() {
|
|
338
|
+
const app = express()
|
|
339
|
+
app.use(bodyParser.json())
|
|
340
|
+
app.get("/", (req, res) => res.json({ timestamp: Date.now() }))
|
|
341
|
+
app.get("/result/:mid", async (req, res) => {
|
|
342
|
+
const res2 = await this.result({
|
|
343
|
+
message: req.params.mid,
|
|
344
|
+
process: req.query["process-id"],
|
|
345
|
+
})
|
|
346
|
+
res.json(res2)
|
|
347
|
+
})
|
|
348
|
+
app.post("/dry-run", async (req, res) => {
|
|
349
|
+
const process = req.query["process-id"]
|
|
350
|
+
const { Id: id, Owner: owner, Tags: tags, Data: data } = req.body
|
|
351
|
+
const res2 = await this.dryrun({ id, owner, tags, data, process })
|
|
352
|
+
delete res2.Memory
|
|
353
|
+
res.json(res2)
|
|
354
|
+
})
|
|
355
|
+
const server = app.listen(this.ports.cu, () =>
|
|
356
|
+
console.log(`CU on port ${this.ports.cu}`),
|
|
357
|
+
)
|
|
358
|
+
this.servers.push(server)
|
|
359
|
+
}
|
|
360
|
+
end() {
|
|
361
|
+
return new Promise(res => {
|
|
362
|
+
let count = 0
|
|
363
|
+
for (const v of this.servers)
|
|
364
|
+
v.close(() => {
|
|
365
|
+
count += 1
|
|
366
|
+
if (count >= 4) {
|
|
367
|
+
console.log("servers closed!", count)
|
|
368
|
+
res()
|
|
369
|
+
}
|
|
370
|
+
})
|
|
371
|
+
})
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export default Server
|
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
|
-
await this.load({ data: log, pid: res })
|
|
80
|
+
//await this.load({ data: log, pid: res })
|
|
81
81
|
return res
|
|
82
82
|
}
|
|
83
83
|
this.dryrun = async (...opt) => {
|
|
@@ -117,7 +117,7 @@ class AO extends MAO {
|
|
|
117
117
|
const { id, owner } = await this.ar.dataitem({ tags: _tags, data, signer })
|
|
118
118
|
await this.ar.post({ data, tags: t, jwk })
|
|
119
119
|
this.mem.wasms[id] = { data, format: t["Module-Format"] }
|
|
120
|
-
return id
|
|
120
|
+
return { id }
|
|
121
121
|
}
|
|
122
122
|
}
|
|
123
123
|
|
package/esm/tar.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import MAR from "./ar.js"
|
|
2
|
-
import { buildTags } from "./utils.js"
|
|
2
|
+
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
|
|
@@ -17,16 +17,21 @@ class AR extends MAR {
|
|
|
17
17
|
this.arweave = this.mem.arweave
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
async dataitem({ target = "", data = "1984", tags = {}, signer }) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
async dataitem({ target = "", data = "1984", tags = {}, signer, item }) {
|
|
21
|
+
let di = item
|
|
22
|
+
if (!di) {
|
|
23
|
+
const _tags = buildTags(tags)
|
|
24
|
+
const _item = await signer({ data, tags: _tags, target })
|
|
25
|
+
di = new DataItem(_item.raw)
|
|
26
|
+
} else {
|
|
27
|
+
tags = t(di.tags)
|
|
28
|
+
}
|
|
24
29
|
const raw_owner = di.rawOwner
|
|
25
30
|
const hashBuffer = Buffer.from(
|
|
26
31
|
await crypto.subtle.digest("SHA-256", raw_owner),
|
|
27
32
|
)
|
|
28
33
|
const owner = base64url.encode(hashBuffer)
|
|
29
|
-
return { id:
|
|
34
|
+
return { id: await di.id, owner, item: di, tags }
|
|
30
35
|
}
|
|
31
36
|
|
|
32
37
|
async post({ data = "1984", tags = {}, jwk }) {
|
|
@@ -43,11 +48,13 @@ class AR extends MAR {
|
|
|
43
48
|
})
|
|
44
49
|
}
|
|
45
50
|
|
|
46
|
-
async postItem(
|
|
47
|
-
const tx = await this.mem.arweave.createTransaction(
|
|
51
|
+
async postItem(di, jwk) {
|
|
52
|
+
const tx = await this.mem.arweave.createTransaction(
|
|
53
|
+
{ data: di.binary },
|
|
54
|
+
jwk,
|
|
55
|
+
)
|
|
48
56
|
tx.addTag("Bundle-Format", "binary")
|
|
49
57
|
tx.addTag("Bundle-Version", "2.0.0")
|
|
50
|
-
const di = new DataItem(item.raw)
|
|
51
58
|
const data_size = Buffer.byteLength(di.rawData).toString()
|
|
52
59
|
let data_type = ""
|
|
53
60
|
for (const t of di.tags) if (t.name === "Content-Type") data_type = t.value
|
|
@@ -66,33 +73,33 @@ class AR extends MAR {
|
|
|
66
73
|
anchor: di.anchor,
|
|
67
74
|
signature: di.signature,
|
|
68
75
|
recipient: di.target,
|
|
69
|
-
id:
|
|
76
|
+
id: await di.id,
|
|
70
77
|
item: di,
|
|
71
78
|
owner,
|
|
72
79
|
tags: di.tags,
|
|
73
80
|
data,
|
|
74
81
|
}
|
|
75
|
-
this.mem.txs[
|
|
82
|
+
this.mem.txs[await di.id] = _item
|
|
76
83
|
return await this.postTx(tx, jwk, _item)
|
|
77
84
|
}
|
|
78
85
|
|
|
79
86
|
async postTx(tx, jwk, item) {
|
|
80
87
|
let [res, err] = [null, null]
|
|
81
|
-
await this.mem.arweave.transactions.sign(tx, jwk)
|
|
88
|
+
if (!tx.id) await this.mem.arweave.transactions.sign(tx, jwk)
|
|
89
|
+
this.mem.height += 1
|
|
90
|
+
let block = {
|
|
91
|
+
id: tx.id,
|
|
92
|
+
timestamp: Date.now(),
|
|
93
|
+
height: this.mem.height,
|
|
94
|
+
previous: last(this.mem.blocks) ?? "",
|
|
95
|
+
}
|
|
82
96
|
if (item) {
|
|
83
|
-
this.mem.height += 1
|
|
84
|
-
const block = {
|
|
85
|
-
id: tx.id,
|
|
86
|
-
timestamp: Date.now(),
|
|
87
|
-
height: this.mem.height,
|
|
88
|
-
previous: last(this.mem.blocks) ?? "",
|
|
89
|
-
}
|
|
90
97
|
if (!item.id) {
|
|
91
98
|
item.id = tx.id
|
|
92
|
-
this.mem.txs[
|
|
93
|
-
this.mem.txs[
|
|
94
|
-
this.mem.txs[
|
|
95
|
-
this.mem.txs[
|
|
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
|
|
96
103
|
let data_type = ""
|
|
97
104
|
for (const v of tx.tags) {
|
|
98
105
|
if (
|
|
@@ -101,27 +108,45 @@ class AR extends MAR {
|
|
|
101
108
|
data_type = v.get("value", { decode: true, string: true })
|
|
102
109
|
}
|
|
103
110
|
}
|
|
104
|
-
this.mem.txs[
|
|
111
|
+
this.mem.txs[tx.id]._data = { size: tx.data_size, type: data_type }
|
|
105
112
|
} else {
|
|
106
113
|
this.mem.txs[item.id].parent = { id: block.id }
|
|
107
114
|
}
|
|
108
115
|
block.txs = [item.id]
|
|
109
116
|
this.mem.txs[item.id].block = block.id
|
|
110
|
-
|
|
111
|
-
|
|
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
|
+
this.mem.txs[tx.id] = tx
|
|
127
|
+
block.txs = [tx.id]
|
|
128
|
+
this.mem.txs[tx.id].block = block.id
|
|
129
|
+
}
|
|
130
|
+
this.mem.blocks.push(block.id)
|
|
131
|
+
this.mem.blockmap[block.id] = block
|
|
132
|
+
|
|
133
|
+
if (jwk) {
|
|
134
|
+
const owner = await this.arweave.wallets.jwkToAddress(jwk)
|
|
135
|
+
this.mem.addrmap[owner] = jwk.n
|
|
112
136
|
}
|
|
113
137
|
res = { id: tx.id, status: 200, statusText: "200" }
|
|
114
|
-
const owner = await this.arweave.wallets.jwkToAddress(jwk)
|
|
115
|
-
this.mem.addrmap[owner] = jwk.n
|
|
116
138
|
return { res, err, id: tx.id }
|
|
117
139
|
}
|
|
118
140
|
|
|
119
|
-
tx(id) {
|
|
141
|
+
async tx(id) {
|
|
120
142
|
return this.mem.txs[id]
|
|
121
143
|
}
|
|
122
144
|
|
|
123
|
-
data(id) {
|
|
124
|
-
|
|
145
|
+
async data(id, string) {
|
|
146
|
+
let tx = this.mem.txs[id]
|
|
147
|
+
let _data = this.mem.txs[id]?.data ?? null
|
|
148
|
+
if (tx.format === 2 && _data && string) _data = base64url.decode(_data)
|
|
149
|
+
return _data
|
|
125
150
|
}
|
|
126
151
|
}
|
|
127
152
|
|
package/esm/test.js
CHANGED
|
@@ -8,12 +8,15 @@ import GQL from "./tgql.js"
|
|
|
8
8
|
import ArMem from "./armem.js"
|
|
9
9
|
import { dirname } from "./utils.js"
|
|
10
10
|
import { Src, setup, ok, fail } from "./helpers.js"
|
|
11
|
+
import Server from "./server.js"
|
|
12
|
+
|
|
11
13
|
const blueprint = async pkg => {
|
|
12
14
|
return readFileSync(resolve(await dirname(), `lua/${pkg}.lua`), "utf8")
|
|
13
15
|
}
|
|
14
|
-
const scheduler = "
|
|
16
|
+
const scheduler = "_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA"
|
|
15
17
|
|
|
16
18
|
export {
|
|
19
|
+
Server,
|
|
17
20
|
GQL,
|
|
18
21
|
ArMem,
|
|
19
22
|
AO,
|
package/esm/tgql.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wao",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "cjs/index.js",
|
|
6
6
|
"module": "esm/index.js",
|
|
@@ -27,6 +27,16 @@
|
|
|
27
27
|
"arbundles": "^0.11.1",
|
|
28
28
|
"arweave": "^1.15.1",
|
|
29
29
|
"base64url": "^3.0.1",
|
|
30
|
+
"body-parser": "^1.20.3",
|
|
31
|
+
"express": "^4.21.2",
|
|
32
|
+
"graphql": "^16.10.0",
|
|
30
33
|
"ramda": "^0.30.1"
|
|
34
|
+
},
|
|
35
|
+
"bin": {
|
|
36
|
+
"wao": "./cjs/run.js",
|
|
37
|
+
"wao-esm": "./esm/run.js"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"server": "node --experimental-wasm-memory64 cjs/run.js"
|
|
31
41
|
}
|
|
32
42
|
}
|