wao 0.1.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.
Files changed (60) hide show
  1. package/cjs/accounts.js +96 -0
  2. package/cjs/ao.js +1543 -0
  3. package/cjs/aoconnect.js +758 -0
  4. package/cjs/ar.js +794 -0
  5. package/cjs/dirname.js +7 -0
  6. package/cjs/helpers.js +381 -0
  7. package/cjs/index.js +20 -0
  8. package/cjs/utils.js +438 -0
  9. package/esm/.cache/opt.json +1 -0
  10. package/esm/accounts.js +91 -0
  11. package/esm/ao.js +737 -0
  12. package/esm/aoconnect.js +318 -0
  13. package/esm/ar.js +243 -0
  14. package/esm/dirname.js +1 -0
  15. package/esm/helpers.js +161 -0
  16. package/esm/index.js +4 -0
  17. package/esm/lua/aos-sqlite.wasm +0 -0
  18. package/esm/lua/aos.wasm +0 -0
  19. package/esm/lua/aos2.lua +33 -0
  20. package/esm/lua/aos2_0_1.wasm +0 -0
  21. package/esm/lua/atomic-asset.lua +238 -0
  22. package/esm/lua/atomic-note-library.lua +2274 -0
  23. package/esm/lua/atomic-note.lua +11 -0
  24. package/esm/lua/collection-registry.lua +202 -0
  25. package/esm/lua/collection.lua +173 -0
  26. package/esm/lua/notebook.lua +173 -0
  27. package/esm/lua/profile.lua +858 -0
  28. package/esm/lua/profile000.lua +666 -0
  29. package/esm/lua/proxy.lua +24 -0
  30. package/esm/lua/registry.lua +858 -0
  31. package/esm/lua/registry000.lua +636 -0
  32. package/esm/test.js +94 -0
  33. package/esm/utils.js +342 -0
  34. package/package.json +21 -0
  35. package/test/.cache/opt.json +1 -0
  36. package/test/accounts.js +91 -0
  37. package/test/ao.js +737 -0
  38. package/test/aoconnect.js +318 -0
  39. package/test/ar.js +243 -0
  40. package/test/dirname.js +1 -0
  41. package/test/helpers.js +161 -0
  42. package/test/index.js +4 -0
  43. package/test/lua/aos-sqlite.wasm +0 -0
  44. package/test/lua/aos.wasm +0 -0
  45. package/test/lua/aos2.lua +33 -0
  46. package/test/lua/aos2_0_1.wasm +0 -0
  47. package/test/lua/atomic-asset.lua +238 -0
  48. package/test/lua/atomic-note-library.lua +2274 -0
  49. package/test/lua/atomic-note.lua +11 -0
  50. package/test/lua/collection-registry.lua +202 -0
  51. package/test/lua/collection.lua +173 -0
  52. package/test/lua/notebook.lua +173 -0
  53. package/test/lua/profile.lua +858 -0
  54. package/test/lua/profile000.lua +666 -0
  55. package/test/lua/proxy.lua +24 -0
  56. package/test/lua/registry.lua +858 -0
  57. package/test/lua/registry000.lua +636 -0
  58. package/test/package.json +21 -0
  59. package/test/test.js +94 -0
  60. package/test/utils.js +342 -0
@@ -0,0 +1,318 @@
1
+ import { DataItem } from "warp-arbundles"
2
+ import base64url from "base64url"
3
+ import AoLoader from "@permaweb/ao-loader"
4
+ import { readFileSync } from "fs"
5
+ import { resolve } from "path"
6
+ import { is, clone, fromPairs, map, mergeLeft } from "ramda"
7
+ import accounts from "./accounts.js"
8
+
9
+ function isJSON(obj) {
10
+ if (obj === null || obj === undefined) return false
11
+ if (
12
+ typeof obj !== "object" ||
13
+ obj instanceof Buffer ||
14
+ obj instanceof ArrayBuffer ||
15
+ Array.isArray(obj)
16
+ ) {
17
+ return false
18
+ }
19
+
20
+ try {
21
+ const str = JSON.stringify(obj)
22
+ const parsed = JSON.parse(str)
23
+ const isjson = typeof parsed === "object" && parsed !== null
24
+ return isjson ? str : false
25
+ } catch (e) {
26
+ return false
27
+ }
28
+ }
29
+
30
+ const jsonToStr = obj =>
31
+ isJSON(obj) || (is(Number, obj) ? Number(obj).toString() : obj)
32
+
33
+ const dirname = async () =>
34
+ typeof __dirname != "undefined"
35
+ ? __dirname
36
+ : (await import("./dirname.js")).default
37
+
38
+ const tags = tags => fromPairs(map(v => [v.name, v.value])(tags))
39
+ const action = value => tag("Action", value)
40
+ const tag = (name, value) => ({ name, value: jsonToStr(value) })
41
+
42
+ const buildTags = (act, tags) => {
43
+ let _tags = []
44
+ if (act) _tags.push(action(act))
45
+ for (const k in tags) {
46
+ if (is(Array)(tags[k])) for (const v of tags[k]) _tags.push(tag(k, v))
47
+ else _tags.push(tag(k, tags[k]))
48
+ }
49
+ return _tags
50
+ }
51
+
52
+ export const connect = () => {
53
+ let wasms = {
54
+ T9W7AieZu7VZgv4NsjIGSPZSxGDWlTCixeLuFYo4WCM: {
55
+ file: "aos2_0_1",
56
+ format: "wasm64-unknown-emscripten-draft_2024_02_15",
57
+ },
58
+ }
59
+ let modules = {
60
+ aos_2_0_1: "T9W7AieZu7VZgv4NsjIGSPZSxGDWlTCixeLuFYo4WCM",
61
+ }
62
+ let modmap = {}
63
+ let env = { msgs: {} }
64
+ let mu = accounts.mu
65
+ const transform = input => {
66
+ const output = { Tags: [] }
67
+ if (input.Data) output.Data = input.Data
68
+ Object.entries(input).forEach(([key, value]) => {
69
+ if (key !== "Data" && key !== "Tags" && typeof value === "string") {
70
+ output.Tags.push({ name: key, value })
71
+ }
72
+ })
73
+ input.Tags?.forEach(tag => {
74
+ const tagKey = Object.keys(tag)[0]
75
+ const tagValue = tag[tagKey]
76
+ if (typeof tagValue === "string") {
77
+ output.Tags.push({ name: tagKey, value: tagValue })
78
+ }
79
+ })
80
+
81
+ return output
82
+ }
83
+
84
+ const genMsg = (p, data, Tags, from, owner, dry = false) => {
85
+ if (!dry) p.height += 1
86
+ return {
87
+ Id: p.height,
88
+ Target: p.id,
89
+ Owner: owner,
90
+ Data: data?.length ? data : "",
91
+ "Block-Height": p.height.toString(),
92
+ Timestamp: Date.now().toString(),
93
+ Module: p.module,
94
+ From: from,
95
+ Cron: false,
96
+ Tags: Tags?.length ? Tags : [],
97
+ }
98
+ }
99
+
100
+ const genEnv = ({ pid, owner = "", module = "", auth = "" }) => {
101
+ return {
102
+ Process: {
103
+ Id: pid,
104
+ Tags: [
105
+ { name: "Data-Protocol", value: "ao" },
106
+ { name: "Variant", value: "ao.TN.1" },
107
+ { name: "Type", value: "Process" },
108
+ { name: "Authority", value: auth },
109
+ ],
110
+ Owner: owner,
111
+ },
112
+ Module: {
113
+ Id: module,
114
+ Tags: [
115
+ { name: "Data-Protocol", value: "ao" },
116
+ { name: "Variant", value: "ao.TN.1" },
117
+ { name: "Type", value: "Module" },
118
+ ],
119
+ },
120
+ }
121
+ }
122
+
123
+ const parse = async opt => {
124
+ const item = await opt.signer({ data: opt.data ?? "", tags: opt.tags })
125
+ const rowner = new DataItem(item.raw).rawOwner
126
+ const hashBuffer = Buffer.from(
127
+ await crypto.subtle.digest("SHA-256", rowner),
128
+ )
129
+ const owner = base64url.encode(hashBuffer)
130
+ return { id: item.id, owner }
131
+ }
132
+
133
+ const postModule = async ({ data, tags = {}, signer }) => {
134
+ const t = mergeLeft(tags, {
135
+ "Data-Protocol": "ao",
136
+ Variant: "ao.TN.1",
137
+ Type: "Module",
138
+ "Module-Format": "wasm64-unknown-emscripten-draft_2024_02_15",
139
+ "Input-Encoding": "JSON-V1",
140
+ "Output-Encoding": "JSON-V1",
141
+ "Memory-Limit": "1-gb",
142
+ "Compute-Limit": "9000000000000",
143
+ })
144
+ const _tags = buildTags(t)
145
+ const { id, owner } = await parse({ tags: _tags, data, signer })
146
+ const handle = await AoLoader(data, { format: t["Module-Format"] })
147
+ modmap[id] = { handle, id }
148
+ return id
149
+ }
150
+
151
+ const message = async opt => {
152
+ const p = env[opt.process]
153
+ let ex = false
154
+ for (let v of opt.tags) {
155
+ if (v.name === "Type") ex = true
156
+ }
157
+ if (!ex) opt.tags.push({ name: "Type", value: "Message" })
158
+ const { id, owner } = await parse(opt)
159
+ try {
160
+ const msg = genMsg(
161
+ p,
162
+ opt.data ?? "",
163
+ opt.tags,
164
+ opt.from ?? owner,
165
+ mu.addr,
166
+ )
167
+ const _env = genEnv({
168
+ pid: p.id,
169
+ owner: p.owner,
170
+ module: p.module,
171
+ auth: mu.addr,
172
+ })
173
+ const res = await p.handle(p.memory, msg, _env)
174
+ p.memory = res.Memory
175
+ delete res.Memory
176
+ p.res[id] = res
177
+ p.results.push(id)
178
+ p.txs.unshift({ id: id, ...opt })
179
+ env.msgs[id] = opt
180
+ for (const v of res.Messages ?? []) {
181
+ if (env[v.Target]) {
182
+ await message({
183
+ process: v.Target,
184
+ tags: v.Tags,
185
+ data: v.Data,
186
+ signer: mu.signer,
187
+ from: opt.process,
188
+ })
189
+ }
190
+ }
191
+ return id
192
+ } catch (e) {
193
+ console.log(e)
194
+ }
195
+ return null
196
+ }
197
+
198
+ return {
199
+ modules,
200
+ accounts: accounts.users,
201
+ message,
202
+ txs: async pid => {
203
+ let _txs = []
204
+ for (let v of env[pid].txs) _txs.push({ tags: v.tags, id: v.id })
205
+ return _txs
206
+ },
207
+ spawn: async (opt = {}) => {
208
+ let mod = opt.module ?? modules["aos_2_0_1"]
209
+ if (!modmap[mod] && wasms[mod]) {
210
+ const __dirname = await dirname()
211
+ const wasm = readFileSync(
212
+ resolve(__dirname, `lua/${wasms[mod].file}.wasm`),
213
+ )
214
+ const handle = await AoLoader(wasm, { format: wasms[mod].format })
215
+ modmap[mod] = { handle, id: mod }
216
+ }
217
+ if (!mod) throw Error("module not found")
218
+ const _module = modmap[mod]
219
+ let ex = false
220
+ opt.tags ??= []
221
+ for (let v of opt.tags) if (v.name === "Type") ex = true
222
+ if (!ex) opt.tags.push({ name: "Type", value: "Process" })
223
+ const { id, owner } = await parse(opt)
224
+ env.msgs[id] = opt
225
+ env[id] = {
226
+ id: id,
227
+ handle: _module.handle,
228
+ module: _module.id,
229
+ memory: null,
230
+ owner,
231
+ height: 1,
232
+ res: { id: null },
233
+ results: [id],
234
+ txs: [],
235
+ }
236
+ return id
237
+ },
238
+ assign: async opt => {
239
+ const p = env[opt.process]
240
+ let _opt = clone(env.msgs[opt.message])
241
+ const { id, owner } = await parse(_opt)
242
+ try {
243
+ const msg = genMsg(
244
+ p,
245
+ _opt.data ?? "",
246
+ _opt.tags,
247
+ _opt.from ?? owner,
248
+ mu.addr,
249
+ )
250
+ const _env = genEnv({
251
+ pid: p.id,
252
+ owner: p.owner,
253
+ module: p.module,
254
+ auth: mu.addr,
255
+ })
256
+ const res = await p.handle(p.memory, msg, _env)
257
+ p.memory = res.Memory
258
+ delete res.Memory
259
+ p.res[id] = res
260
+ p.results.push(id)
261
+ p.txs.unshift({ id: id, ..._opt })
262
+ env.msgs[id] = _opt
263
+ for (const v of res.Messages ?? []) {
264
+ if (env[v.Target]) {
265
+ await message({
266
+ process: v.Target,
267
+ tags: v.Tags,
268
+ data: v.Data,
269
+ signer: mu.signer,
270
+ from: opt.process,
271
+ })
272
+ }
273
+ }
274
+ return id
275
+ } catch (e) {
276
+ console.log(e)
277
+ }
278
+ return null
279
+ },
280
+ result: async opt => env[opt.process].res[opt.message],
281
+ results: async opt => {
282
+ const p = env[opt.process]
283
+ let results = []
284
+ const limit = opt.limit ?? 25
285
+ if (opt.sort === "DESC") {
286
+ for (let i = p.results.length - 1; 0 < i; i--) {
287
+ results.push({ cursor: p.results[i], node: p.res[p.results[i]] })
288
+ if (results.length >= limit) break
289
+ }
290
+ } else {
291
+ for (let i = 0; i < p.results.length; i++) {
292
+ results.push({ node: p.res[p.results[i]] })
293
+ if (results.length >= limit) break
294
+ }
295
+ }
296
+ return { edges: results }
297
+ },
298
+
299
+ dryrun: async opt => {
300
+ const p = env[opt.process]
301
+ const { id, owner } = await parse(opt)
302
+ try {
303
+ const msg = genMsg(p, opt.data ?? "", opt.tags, owner, mu.addr, true)
304
+ const _env = genEnv({
305
+ pid: p.id,
306
+ owner: p.owner,
307
+ module: p.module,
308
+ auth: mu.addr,
309
+ })
310
+ const res = await p.handle(p.memory, msg, _env)
311
+ return res
312
+ } catch (e) {
313
+ console.log(e)
314
+ }
315
+ return null
316
+ },
317
+ }
318
+ }
package/test/ar.js ADDED
@@ -0,0 +1,243 @@
1
+ import Arweave from "arweave"
2
+ import { ArweaveSigner, bundleAndSignData, createData } from "arbundles"
3
+ import { buildTags, tag, query, queries, isLocalhost } from "./utils.js"
4
+ import { is } from "ramda"
5
+
6
+ class AR {
7
+ constructor({ host, port = 443, protocol } = {}) {
8
+ this.__type__ = "ar"
9
+ let _arweave = { host, port, protocol }
10
+ if (!_arweave.host)
11
+ _arweave.host = port === 443 ? "arweave.net" : "127.0.0.1"
12
+ if (!_arweave.protocol)
13
+ _arweave.protocol = isLocalhost(_arweave.host) ? "http" : "https"
14
+ if (!_arweave.port) _arweave.port = isLocalhost(_arweave.host) ? 1984 : 443
15
+ this.port = _arweave.port
16
+ this.arweave = Arweave.init(_arweave)
17
+ this.host = _arweave.host
18
+ this.protocol = _arweave.protocol
19
+ }
20
+
21
+ isArConnect(jwk) {
22
+ return this.jwk?.id || this.jwk?.walletName === "ArConnect"
23
+ }
24
+
25
+ async init(jwk) {
26
+ let isGen = false
27
+ if (!jwk && typeof window === "object") jwk = window.arweaveWallet
28
+ if (!jwk) isGen = true
29
+ else {
30
+ this.jwk = jwk
31
+ const isWallet = this.isArConnect(this.jwk)
32
+ if (isWallet) {
33
+ try {
34
+ await this.jwk.connect([
35
+ "ACCESS_ADDRESS",
36
+ "ACCESS_PUBLIC_KEY",
37
+ "SIGN_TRANSACTION",
38
+ ])
39
+ this.addr = await this.jwk.getActiveAddress()
40
+ this.pub = await this.jwk.getActivePublicKey()
41
+ this.isWallet = true
42
+ } catch (e) {
43
+ isGen = true
44
+ }
45
+ } else {
46
+ this.addr = await this.toAddr(jwk)
47
+ this.pub = jwk.n
48
+ }
49
+ }
50
+ if (isGen) {
51
+ this.isWallet = false
52
+ this.addr = this.pub = this.jwk = null
53
+ await this.gen("100")
54
+ }
55
+ return this
56
+ }
57
+
58
+ async mine() {
59
+ await this.arweave.api.get(`/mine`)
60
+ }
61
+
62
+ async checkWallet({ jwk } = {}) {
63
+ if (jwk) return { err: null, jwk }
64
+ let [err, addr, pub] = [null, null, null]
65
+ let existWallet = typeof window === "object" && window.arweaveWallet
66
+ let isJwkWallet = this.isArConnect(this.jwk)
67
+ if (!this.jwk) {
68
+ if (this._jwk) {
69
+ jwk = this._jwk
70
+ pub = this._jwk.n
71
+ addr = await this.toAddr(jwk)
72
+ } else {
73
+ ;({ jwk, addr, pub } = await this.gen("100", false))
74
+ }
75
+ } else if (this.jwk && !isJwkWallet) {
76
+ jwk = this.jwk
77
+ addr = this.addr
78
+ pub = this.pub
79
+ } else if (existWallet) {
80
+ await arweaveWallet.connect([
81
+ "ACCESS_ADDRESS",
82
+ "ACCESS_PUBLIC_KEY",
83
+ "SIGN_TRANSACTION",
84
+ ])
85
+ const _addr = await arweaveWallet.getActiveAddress()
86
+ if (_addr) {
87
+ if (this.addr && this.addr !== _addr) err = "the wrong wallet"
88
+ else {
89
+ addr = _addr
90
+ pub = await arweaveWallet.getActivePublicKey()
91
+ jwk = arweaveWallet
92
+ }
93
+ } else {
94
+ err = "no wallet found"
95
+ }
96
+ } else {
97
+ err = "no wallet found"
98
+ }
99
+ return { addr, jwk, pub, err }
100
+ }
101
+
102
+ async balance(addr = this.addr) {
103
+ if (!addr) {
104
+ ;({ addr } = await this.checkWallet())
105
+ }
106
+ return this.toAR(await this.arweave.wallets.getBalance(addr))
107
+ }
108
+
109
+ async mint(addr, amount = "1.0") {
110
+ await this.arweave.api.get(`/mint/${addr}/${this.toWinston(amount)}`)
111
+ await this.mine()
112
+ return await this.balance(addr)
113
+ }
114
+
115
+ toWinston(ar) {
116
+ return this.arweave.ar.arToWinston(ar)
117
+ }
118
+
119
+ toAR(w) {
120
+ return this.arweave.ar.winstonToAr(w)
121
+ }
122
+
123
+ async toAddr(jwk) {
124
+ ;({ jwk } = await this.checkWallet({ jwk }))
125
+ if (this.isArConnect(jwk)) return await jwk.getActiveAddress()
126
+ else {
127
+ return await this.arweave.wallets.jwkToAddress(jwk)
128
+ }
129
+ }
130
+
131
+ async gen(amount, overwrite) {
132
+ const jwk = await this.arweave.wallets.generate()
133
+ const addr = await this.toAddr(jwk)
134
+ if (overwrite === false) {
135
+ this._jwk = jwk
136
+ } else if (!this.jwk || overwrite) {
137
+ this.jwk = jwk
138
+ this.pub = jwk.n
139
+ this.addr = addr
140
+ this.isWallet = false
141
+ }
142
+ let bal = "0"
143
+ if (amount && isLocalhost(this.host)) bal = await this.mint(addr, amount)
144
+ return { jwk, addr, pub: jwk.n, bal }
145
+ }
146
+
147
+ async transfer(ar, target, jwk) {
148
+ let err = null
149
+ ;({ jwk, err } = await this.checkWallet({ jwk }))
150
+ if (err) return { err }
151
+ else {
152
+ let tx = await this.arweave.createTransaction({
153
+ target,
154
+ quantity: this.toWinston(ar),
155
+ })
156
+ return await this.postTx(tx, jwk)
157
+ }
158
+ }
159
+
160
+ async bundle(_items, jwk) {
161
+ let err = null
162
+ ;({ jwk, err } = await this.checkWallet({ jwk }))
163
+ if (err) return { err }
164
+ else {
165
+ const signer = new ArweaveSigner(jwk)
166
+ const items = _items.map(v => {
167
+ let tags = []
168
+ for (const k in v[1] && {}) {
169
+ if (is(Array)(v[1][k])) {
170
+ for (const v of v[1][k]) tags.push(tag(k, v))
171
+ } else {
172
+ tags.push(tag(k, v[1][k]))
173
+ }
174
+ }
175
+ return createData(v[0], signer, { tags, ...(v[2] ?? {}) })
176
+ })
177
+ const bundle = await bundleAndSignData(items, signer)
178
+ const tx = await bundle.toTransaction({}, this.arweave, jwk)
179
+ await this.postTx(tx, jwk)
180
+ return { err, items, tx, id: tx.id }
181
+ }
182
+ }
183
+
184
+ async post({ data = "1984", tags = {}, jwk }) {
185
+ let err = null
186
+ ;({ err, jwk } = await this.checkWallet({ jwk }))
187
+ if (err) return { err }
188
+ else {
189
+ let tx = await this.arweave.createTransaction({ data: data })
190
+ let _tags = buildTags(null, tags)
191
+ for (const v of _tags) tx.addTag(v.name, v.value)
192
+ return this.postTx(tx, jwk)
193
+ }
194
+ }
195
+
196
+ async postTx(tx, jwk) {
197
+ let [res, err] = [null, null]
198
+ ;({ err, jwk } = await this.checkWallet({ jwk }))
199
+ if (!err) {
200
+ if (this.isArConnect(jwk)) tx = await jwk.sign(tx)
201
+ else {
202
+ await this.arweave.transactions.sign(tx, jwk)
203
+ }
204
+ res = await this.arweave.transactions.post(tx)
205
+ if (res.status !== 200) err = res.statusText
206
+ if (isLocalhost(this.host)) await this.mine()
207
+ }
208
+ return { res, err, id: tx.id }
209
+ }
210
+
211
+ async tx(txid) {
212
+ const json = await fetch(
213
+ `${this.protocol}://${this.host}:${this.port}/graphql`,
214
+ {
215
+ method: "POST",
216
+ headers: { "Content-Type": "application/json" },
217
+ body: JSON.stringify({ query: query(txid) }),
218
+ },
219
+ ).then(r => r.json())
220
+ return json.data.transactions.edges.map(v => v.node)[0] ?? null
221
+ }
222
+
223
+ async txs(to) {
224
+ const json = await fetch(
225
+ `${this.protocol}://${this.host}:${this.port}/graphql`,
226
+ {
227
+ method: "POST",
228
+ headers: { "Content-Type": "application/json" },
229
+ body: JSON.stringify({ query: queries(to) }),
230
+ },
231
+ ).then(r => r.json())
232
+ return json.data.transactions.edges.map(v => v.node)
233
+ }
234
+
235
+ async data(txid, string = false) {
236
+ return await this.arweave.transactions.getData(txid, {
237
+ decode: true,
238
+ string,
239
+ })
240
+ }
241
+ }
242
+
243
+ export default AR
@@ -0,0 +1 @@
1
+ export default import.meta.dirname
@@ -0,0 +1,161 @@
1
+ import { AR, AO } from "./index.js"
2
+ import assert from "assert"
3
+ import { createDataItemSigner, connect } from "@permaweb/aoconnect"
4
+ import { dirname as _dirname, resolve } from "path"
5
+ import { mkdirSync, existsSync, writeFileSync, readFileSync } from "fs"
6
+ import yargs from "yargs"
7
+
8
+ let {
9
+ reset = false,
10
+ cache = false,
11
+ auth = null,
12
+ } = yargs(process.argv.slice(2)).argv
13
+
14
+ const dirname = async () =>
15
+ typeof __dirname != "undefined"
16
+ ? __dirname
17
+ : (await import("./dirname.js")).default
18
+
19
+ export class Src {
20
+ constructor({ ar, dir } = {}) {
21
+ this.ar = ar
22
+ this.dir = dir
23
+ if (!dir) dirname().then(v => (this.dir = v))
24
+ }
25
+ data(file, ext = "lua") {
26
+ return readFileSync(
27
+ `${this.dir}/${file}.${ext}`,
28
+ ext === "wasm" ? null : "utf8",
29
+ )
30
+ }
31
+ async upload(file, ext = "lua") {
32
+ const res = await this.ar.post({ data: this.data(file, ext) })
33
+ return res.err ? null : res.id
34
+ }
35
+ }
36
+
37
+ export const setup = async ({
38
+ aoconnect,
39
+ arweave,
40
+ cacheDir = ".cache",
41
+ targets = { profile: false, note: false, asset: false },
42
+ } = {}) => {
43
+ if (targets.asset || targets.note) targets.profile = true
44
+ let opt = null
45
+ console.error = () => {}
46
+ console.warn = () => {}
47
+ const dir = resolve(await dirname(), "lua")
48
+ const _cacheDir = resolve(await dirname(), cacheDir)
49
+ const optPath = `${_cacheDir}/opt.json`
50
+ if (cache && !reset) {
51
+ try {
52
+ if (existsSync(optPath)) {
53
+ opt = JSON.parse(readFileSync(optPath, "utf8"))
54
+ } else {
55
+ console.log("cache doesn't exist:", optPath)
56
+ }
57
+ } catch (e) {
58
+ console.log(e)
59
+ }
60
+ }
61
+
62
+ if (opt) {
63
+ const ar = await new AR(opt.ar).init(opt.jwk)
64
+ const src = new Src({ ar, readFileSync, dir })
65
+ const ao = await new AO(opt.ao).init(opt.jwk)
66
+ const ao2 = await new AO(opt.ao2).init(opt.jwk)
67
+ console.log("cache:\t", optPath)
68
+ console.log("addr:\t", ar.addr)
69
+ return { opt, ar, ao2, ao, src }
70
+ }
71
+
72
+ // ar
73
+ arweave ??= { port: 4000 }
74
+ aoconnect ??= {
75
+ MU_URL: "http://localhost:4002",
76
+ CU_URL: "http://localhost:4004",
77
+ GATEWAY_URL: "http://localhost:4000",
78
+ }
79
+ const ar = new AR(arweave)
80
+ await ar.gen("10")
81
+ const src = new Src({ ar, readFileSync, dir })
82
+ opt = { ar: { ...arweave }, jwk: ar.jwk }
83
+ if (!auth && /localhost/.test(aoconnect?.CU_URL ?? "")) {
84
+ auth = (await fetch(aoconnect.CU_URL).then(r => r.json())).address
85
+ }
86
+
87
+ // ao
88
+ const wasm = await src.upload("aos-sqlite", "wasm")
89
+ const wasm2 = await src.upload("aos", "wasm")
90
+ const wasm_aos2 = await src.upload("aos2_0_1", "wasm")
91
+
92
+ const ao = new AO({ aoconnect, ar, authority: auth })
93
+ const { id: module_aos2 } = await ao.postModule({
94
+ data: await ar.data(wasm_aos2),
95
+ })
96
+
97
+ const { id: module_sqlite } = await ao.postModule({
98
+ data: await ar.data(wasm),
99
+ overwrite: true,
100
+ })
101
+
102
+ const { id: module } = await ao.postModule({
103
+ data: await ar.data(wasm2),
104
+ overwrite: true,
105
+ })
106
+
107
+ const { scheduler } = await ao.postScheduler({
108
+ url: "http://su",
109
+ overwrite: true,
110
+ })
111
+ opt.ao = {
112
+ module: module_sqlite,
113
+ scheduler,
114
+ aoconnect,
115
+ ar: opt.ar,
116
+ authority: auth,
117
+ }
118
+
119
+ // ao2
120
+ const ao2 = await new AO({
121
+ aoconnect,
122
+ ar,
123
+ authority: auth,
124
+ module: module_aos2,
125
+ scheduler,
126
+ }).init(ar.jwk)
127
+
128
+ opt.ao2 = {
129
+ module: module_aos2,
130
+ scheduler,
131
+ aoconnect,
132
+ ar: opt.ar,
133
+ authority: auth,
134
+ }
135
+
136
+ if (auth) opt.ao.authority = auth
137
+ opt.authority = auth
138
+ opt.targets = targets
139
+ opt.modules = {
140
+ aos2: module_aos2,
141
+ aos1: module,
142
+ sqlite: module_sqlite,
143
+ }
144
+ if (cache) {
145
+ if (!existsSync(_cacheDir)) mkdirSync(_cacheDir)
146
+ writeFileSync(optPath, JSON.stringify(opt))
147
+ }
148
+ return { opt, ao, ar, src, ao2 }
149
+ }
150
+
151
+ export const ok = obj => {
152
+ if (obj.err) console.log(obj.err)
153
+ assert.equal(obj.err, null)
154
+ return obj
155
+ }
156
+
157
+ export const fail = obj => {
158
+ if (!obj.err) console.log(obj.res)
159
+ assert.notEqual(obj.err, null)
160
+ return obj
161
+ }