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.
- package/cjs/accounts.js +96 -0
- package/cjs/ao.js +1543 -0
- package/cjs/aoconnect.js +758 -0
- package/cjs/ar.js +794 -0
- package/cjs/dirname.js +7 -0
- package/cjs/helpers.js +381 -0
- package/cjs/index.js +20 -0
- package/cjs/utils.js +438 -0
- package/esm/.cache/opt.json +1 -0
- package/esm/accounts.js +91 -0
- package/esm/ao.js +737 -0
- package/esm/aoconnect.js +318 -0
- package/esm/ar.js +243 -0
- package/esm/dirname.js +1 -0
- package/esm/helpers.js +161 -0
- package/esm/index.js +4 -0
- package/esm/lua/aos-sqlite.wasm +0 -0
- package/esm/lua/aos.wasm +0 -0
- package/esm/lua/aos2.lua +33 -0
- package/esm/lua/aos2_0_1.wasm +0 -0
- package/esm/lua/atomic-asset.lua +238 -0
- package/esm/lua/atomic-note-library.lua +2274 -0
- package/esm/lua/atomic-note.lua +11 -0
- package/esm/lua/collection-registry.lua +202 -0
- package/esm/lua/collection.lua +173 -0
- package/esm/lua/notebook.lua +173 -0
- package/esm/lua/profile.lua +858 -0
- package/esm/lua/profile000.lua +666 -0
- package/esm/lua/proxy.lua +24 -0
- package/esm/lua/registry.lua +858 -0
- package/esm/lua/registry000.lua +636 -0
- package/esm/test.js +94 -0
- package/esm/utils.js +342 -0
- package/package.json +21 -0
- package/test/.cache/opt.json +1 -0
- package/test/accounts.js +91 -0
- package/test/ao.js +737 -0
- package/test/aoconnect.js +318 -0
- package/test/ar.js +243 -0
- package/test/dirname.js +1 -0
- package/test/helpers.js +161 -0
- package/test/index.js +4 -0
- package/test/lua/aos-sqlite.wasm +0 -0
- package/test/lua/aos.wasm +0 -0
- package/test/lua/aos2.lua +33 -0
- package/test/lua/aos2_0_1.wasm +0 -0
- package/test/lua/atomic-asset.lua +238 -0
- package/test/lua/atomic-note-library.lua +2274 -0
- package/test/lua/atomic-note.lua +11 -0
- package/test/lua/collection-registry.lua +202 -0
- package/test/lua/collection.lua +173 -0
- package/test/lua/notebook.lua +173 -0
- package/test/lua/profile.lua +858 -0
- package/test/lua/profile000.lua +666 -0
- package/test/lua/proxy.lua +24 -0
- package/test/lua/registry.lua +858 -0
- package/test/lua/registry000.lua +636 -0
- package/test/package.json +21 -0
- package/test/test.js +94 -0
- package/test/utils.js +342 -0
package/esm/aoconnect.js
ADDED
|
@@ -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/esm/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
|
package/esm/dirname.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default import.meta.dirname
|
package/esm/helpers.js
ADDED
|
@@ -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
|
+
}
|