wao 0.40.2 → 0.41.1
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-web.js +25 -0
- package/cjs/accounts.js +38 -0
- package/cjs/adaptor-base.js +504 -287
- package/cjs/adaptor-cf.js +42 -0
- package/cjs/ao-loader.js +1 -1
- package/cjs/ao.js +18 -6
- package/cjs/aoconnect-base.js +1017 -546
- package/cjs/aoconnect-cf.js +24 -0
- package/cjs/ar-remote.js +277 -0
- package/cjs/armem-base.js +822 -211
- package/cjs/armem-cf.js +128 -0
- package/cjs/armem.js +11 -5
- package/cjs/bar.js +511 -173
- package/cjs/car.js +37 -0
- package/cjs/cf-env.js +54 -0
- package/cjs/cf.js +76 -0
- package/cjs/cli.js +12 -6
- package/cjs/create.js +1 -1
- package/cjs/devs.js +53 -0
- package/cjs/dodb.js +116 -0
- package/cjs/hb.js +136 -53
- package/cjs/hyperbeam.js +85 -44
- package/cjs/keygen.js +94 -0
- package/cjs/run.js +4 -1
- package/cjs/server.js +40 -9
- package/cjs/storage-multi.js +525 -0
- package/cjs/tgql-d1.js +664 -0
- package/cjs/tgql.js +293 -172
- package/cjs/workspace/.claude/agents/tester.md +2 -2
- package/cjs/workspace/.claude/skills/build/SKILL.md +2 -2
- package/cjs/workspace/.claude/skills/test/SKILL.md +3 -2
- package/cjs/workspace/CLAUDE.md +2 -2
- package/cjs/workspace/README.md +1 -1
- package/cjs/workspace/docs/debug.md +9 -4
- package/cjs/workspace/docs/hyperbeam-devices.md +50 -1
- package/cjs/workspace/package.json +3 -3
- package/esm/accounts-web.js +14 -0
- package/esm/accounts.js +27 -0
- package/esm/adaptor-base.js +129 -31
- package/esm/adaptor-cf.js +11 -0
- package/esm/ao-loader.js +1 -1
- package/esm/ao.js +21 -2
- package/esm/aoconnect-base.js +255 -7
- package/esm/aoconnect-cf.js +9 -0
- package/esm/ar-remote.js +87 -0
- package/esm/armem-base.js +304 -53
- package/esm/armem-cf.js +67 -0
- package/esm/armem.js +7 -2
- package/esm/bar.js +126 -16
- package/esm/car.js +10 -0
- package/esm/cf-env.js +29 -0
- package/esm/cf.js +11 -0
- package/esm/cli.js +6 -2
- package/esm/create.js +1 -1
- package/esm/devs.js +15 -0
- package/esm/dodb.js +26 -0
- package/esm/hb.js +93 -16
- package/esm/hyperbeam.js +68 -30
- package/esm/keygen.js +47 -0
- package/esm/run.js +4 -1
- package/esm/server.js +29 -9
- package/esm/storage-multi.js +183 -0
- package/esm/tgql-d1.js +407 -0
- package/esm/tgql.js +29 -10
- package/esm/workspace/.claude/agents/tester.md +2 -2
- package/esm/workspace/.claude/skills/build/SKILL.md +2 -2
- package/esm/workspace/.claude/skills/test/SKILL.md +3 -2
- package/esm/workspace/CLAUDE.md +2 -2
- package/esm/workspace/README.md +1 -1
- package/esm/workspace/docs/debug.md +9 -4
- package/esm/workspace/docs/hyperbeam-devices.md +50 -1
- package/esm/workspace/package.json +3 -3
- package/package.json +10 -3
- package/postinstall.cjs +84 -0
- package/wao-0.41.1.tgz +0 -0
package/esm/aoconnect-base.js
CHANGED
|
@@ -37,12 +37,11 @@ let onRecovery = {}
|
|
|
37
37
|
let ongoing = {}
|
|
38
38
|
|
|
39
39
|
export default ({ AR, scheduler, mu, su, cu, acc, AoLoader, ArMem } = {}) => {
|
|
40
|
-
return (mem, { cache, log = false, extensions = {}, hb, variant } = {}) => {
|
|
40
|
+
return (mem, { cache, log = false, extensions = {}, hb, variant, storage, d1, r2, kv, ar_url } = {}) => {
|
|
41
41
|
const isMem = mem?.__type__ === "mem"
|
|
42
42
|
if (!isMem) {
|
|
43
|
-
let args = { cache }
|
|
43
|
+
let args = { cache, storage, scheduler, d1, r2, kv, ar_url }
|
|
44
44
|
if (mem?.SU_URL) {
|
|
45
|
-
args.scheduler = scheduler
|
|
46
45
|
args.variant = variant
|
|
47
46
|
args = mergeLeft(mem, args)
|
|
48
47
|
}
|
|
@@ -78,7 +77,9 @@ export default ({ AR, scheduler, mu, su, cu, acc, AoLoader, ArMem } = {}) => {
|
|
|
78
77
|
scheduler: "Scheduler",
|
|
79
78
|
module: "Module",
|
|
80
79
|
}
|
|
81
|
-
for (let v of __tags)
|
|
80
|
+
for (let v of __tags) {
|
|
81
|
+
v.name = cap[v.name] ?? v.name
|
|
82
|
+
}
|
|
82
83
|
return __tags
|
|
83
84
|
}
|
|
84
85
|
|
|
@@ -168,6 +169,50 @@ export default ({ AR, scheduler, mu, su, cu, acc, AoLoader, ArMem } = {}) => {
|
|
|
168
169
|
await ar.postItems(item, su.jwk)
|
|
169
170
|
}
|
|
170
171
|
|
|
172
|
+
// Remote CU — delegate WASM execution to satellite CU
|
|
173
|
+
if (opt._cu_url) {
|
|
174
|
+
const _tags = tags(opt.tags)
|
|
175
|
+
const ext = _tags.Extension || "WeaveDrive"
|
|
176
|
+
let p = {
|
|
177
|
+
_cu_url: opt._cu_url,
|
|
178
|
+
extension: ext,
|
|
179
|
+
format,
|
|
180
|
+
id,
|
|
181
|
+
epochs: [],
|
|
182
|
+
module: mod,
|
|
183
|
+
hash: id,
|
|
184
|
+
memory: null,
|
|
185
|
+
owner,
|
|
186
|
+
height: 0,
|
|
187
|
+
results: [id],
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
const cuResult = await fetch(`${opt._cu_url}/cu/evaluate`, {
|
|
191
|
+
method: "POST",
|
|
192
|
+
headers: { "Content-Type": "application/json" },
|
|
193
|
+
body: JSON.stringify({
|
|
194
|
+
message: id,
|
|
195
|
+
process: id,
|
|
196
|
+
data: opt.data ?? "",
|
|
197
|
+
tags: opt.tags,
|
|
198
|
+
from: owner,
|
|
199
|
+
is_spawn: true,
|
|
200
|
+
}),
|
|
201
|
+
}).then(r => r.json())
|
|
202
|
+
const _msg = {
|
|
203
|
+
...o(dissoc("signer"), dissoc("memory"))(opt),
|
|
204
|
+
res: cuResult,
|
|
205
|
+
msg: null,
|
|
206
|
+
}
|
|
207
|
+
await mem.set(_msg, "msgs", id)
|
|
208
|
+
} catch (e) {
|
|
209
|
+
console.log("Remote CU spawn error:", e)
|
|
210
|
+
}
|
|
211
|
+
await mem.set(p, "env", id)
|
|
212
|
+
delete ongoing[id]
|
|
213
|
+
return id
|
|
214
|
+
}
|
|
215
|
+
|
|
171
216
|
const now = Date.now
|
|
172
217
|
const t = tags(opt.tags)
|
|
173
218
|
const ext = t.Extension || "WeaveDrive"
|
|
@@ -316,6 +361,96 @@ export default ({ AR, scheduler, mu, su, cu, acc, AoLoader, ArMem } = {}) => {
|
|
|
316
361
|
} else {
|
|
317
362
|
await ar.postItems(item, su.jwk)
|
|
318
363
|
}
|
|
364
|
+
|
|
365
|
+
// Remote CU — delegate WASM execution to satellite CU
|
|
366
|
+
if (p._cu_url) {
|
|
367
|
+
try {
|
|
368
|
+
let evalData = _opt?.data ?? ""
|
|
369
|
+
let evalTags = _opt?.tags
|
|
370
|
+
let evalFrom = _opt?.from ?? opt.from
|
|
371
|
+
if (_opt?.item) {
|
|
372
|
+
const decoded = base64url.decode(_opt.item.data)
|
|
373
|
+
evalData = typeof decoded === "string" ? decoded : Buffer.from(decoded).toString("utf-8")
|
|
374
|
+
evalTags = _opt.item.tags
|
|
375
|
+
const t = tags(evalTags)
|
|
376
|
+
if (t["From-Process"]) evalFrom = t["From-Process"]
|
|
377
|
+
if (!evalFrom) {
|
|
378
|
+
evalFrom = await arweave.wallets.jwkToAddress({
|
|
379
|
+
kty: "RSA", n: _opt.item.owner, e: "AQAB",
|
|
380
|
+
})
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
// Cranked messages historically used MU addr as From. But AOS's
|
|
384
|
+
// msg.reply targets msg.From, so overwriting From to mu.addr
|
|
385
|
+
// breaks the X-Reference round-trip for Send().receive(). Only
|
|
386
|
+
// override when no explicit from is supplied by the caller.
|
|
387
|
+
if (_opt?.for && !_opt?.from) evalFrom = mu.addr
|
|
388
|
+
const cuResult = await fetch(`${p._cu_url}/cu/evaluate`, {
|
|
389
|
+
method: "POST",
|
|
390
|
+
headers: { "Content-Type": "application/json" },
|
|
391
|
+
body: JSON.stringify({
|
|
392
|
+
message: opt.message,
|
|
393
|
+
process: opt.process,
|
|
394
|
+
data: evalData,
|
|
395
|
+
tags: evalTags,
|
|
396
|
+
from: evalFrom,
|
|
397
|
+
}),
|
|
398
|
+
}).then(r => r.json())
|
|
399
|
+
p.results.push(opt.message)
|
|
400
|
+
await mem.set(p, "env", opt.process)
|
|
401
|
+
const _msg = { ...dissoc("signer", _opt), res: cuResult, msg: null }
|
|
402
|
+
await mem.set(_msg, "msgs", opt.message)
|
|
403
|
+
// Route outbox from CU response
|
|
404
|
+
for (const v of cuResult?.Messages ?? []) {
|
|
405
|
+
const envExists = await mem.get("env", v.Target)
|
|
406
|
+
if (envExists) {
|
|
407
|
+
await message({
|
|
408
|
+
for: opt.message,
|
|
409
|
+
process: v.Target,
|
|
410
|
+
tags: v.Tags,
|
|
411
|
+
data: v.Data,
|
|
412
|
+
signer: mu.signer,
|
|
413
|
+
from: opt.process,
|
|
414
|
+
target: v.Target,
|
|
415
|
+
})
|
|
416
|
+
} else if (mem._remote) {
|
|
417
|
+
// Forward to main AR's MU for routing
|
|
418
|
+
const fwdTags = buildTags(null, mergeLeft(tags(v.Tags), {
|
|
419
|
+
"Data-Protocol": "ao",
|
|
420
|
+
Variant: variant ?? "ao.TN.1",
|
|
421
|
+
Type: "Message",
|
|
422
|
+
"From-Process": opt.process,
|
|
423
|
+
"Pushed-For": opt.message,
|
|
424
|
+
}))
|
|
425
|
+
await record({
|
|
426
|
+
for: opt.message,
|
|
427
|
+
tags: fwdTags,
|
|
428
|
+
data: v.Data,
|
|
429
|
+
signer: mu.signer,
|
|
430
|
+
from: opt.process,
|
|
431
|
+
target: v.Target,
|
|
432
|
+
})
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
for (const v of cuResult?.Spawns ?? []) {
|
|
436
|
+
const __tags = tags(v.Tags)
|
|
437
|
+
await spawn({
|
|
438
|
+
for: opt.message,
|
|
439
|
+
module: __tags.Module,
|
|
440
|
+
scheduler,
|
|
441
|
+
tags: v.Tags,
|
|
442
|
+
data: v.Data,
|
|
443
|
+
from: __tags["From-Process"],
|
|
444
|
+
signer: mu.signer,
|
|
445
|
+
})
|
|
446
|
+
}
|
|
447
|
+
return id
|
|
448
|
+
} catch (e) {
|
|
449
|
+
console.log("Remote CU assign error:", e)
|
|
450
|
+
return null
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
|
|
319
454
|
try {
|
|
320
455
|
let data = _opt.data ?? ""
|
|
321
456
|
let _tags = _opt.tags
|
|
@@ -333,6 +468,13 @@ export default ({ AR, scheduler, mu, su, cu, acc, AoLoader, ArMem } = {}) => {
|
|
|
333
468
|
})
|
|
334
469
|
}
|
|
335
470
|
}
|
|
471
|
+
// Cranked messages (inter-process) historically used MU addr as
|
|
472
|
+
// From for AOS trust. But AOS's msg.reply uses msg.From as Target,
|
|
473
|
+
// so overwriting From to mu.addr breaks the X-Reference round-trip
|
|
474
|
+
// needed for Send().receive() coroutine resumption. Preserve the
|
|
475
|
+
// originating process (passed via _opt.from = opt.process from the
|
|
476
|
+
// outbox-dispatch loop) so replies land back on it.
|
|
477
|
+
if (_opt.for && !_opt.from) from = mu.addr
|
|
336
478
|
// check: is owner=mu.addr right?
|
|
337
479
|
const _owner = opt.message_item?.owner
|
|
338
480
|
? toAddr(opt.message_item.owner)
|
|
@@ -352,7 +494,7 @@ export default ({ AR, scheduler, mu, su, cu, acc, AoLoader, ArMem } = {}) => {
|
|
|
352
494
|
spawn: (await mem.getTx(p.id))?.item,
|
|
353
495
|
module: await mem.getTx(mod),
|
|
354
496
|
})
|
|
355
|
-
mem.env[opt.process].handle = p.handle
|
|
497
|
+
if (mem.env[opt.process]) mem.env[opt.process].handle = p.handle
|
|
356
498
|
}
|
|
357
499
|
if (p.compressed) {
|
|
358
500
|
const start = Date.now()
|
|
@@ -486,6 +628,25 @@ export default ({ AR, scheduler, mu, su, cu, acc, AoLoader, ArMem } = {}) => {
|
|
|
486
628
|
} catch (e) {
|
|
487
629
|
console.log(e)
|
|
488
630
|
}
|
|
631
|
+
} else if (mem._remote) {
|
|
632
|
+
// Remote mode: forward to main AR's MU for routing
|
|
633
|
+
try {
|
|
634
|
+
const di = await ar.dataitem({
|
|
635
|
+
data: v.Data ?? "",
|
|
636
|
+
signer: mu.signer,
|
|
637
|
+
tags: mergeLeft(tags(v.Tags), {
|
|
638
|
+
"Data-Protocol": "ao",
|
|
639
|
+
Variant: variant ?? "ao.TN.1",
|
|
640
|
+
Type: "Message",
|
|
641
|
+
"From-Process": opt.process,
|
|
642
|
+
"Pushed-For": opt.message,
|
|
643
|
+
}),
|
|
644
|
+
target: v.Target,
|
|
645
|
+
})
|
|
646
|
+
await mem._remote.postMU(di.item.getRaw())
|
|
647
|
+
} catch (e) {
|
|
648
|
+
console.log("Remote MU forward error:", e)
|
|
649
|
+
}
|
|
489
650
|
} else {
|
|
490
651
|
await record({
|
|
491
652
|
for: opt.message,
|
|
@@ -608,7 +769,7 @@ export default ({ AR, scheduler, mu, su, cu, acc, AoLoader, ArMem } = {}) => {
|
|
|
608
769
|
spawn: (await mem.getTx(p.id))?.item,
|
|
609
770
|
module: await mem.getTx(mod),
|
|
610
771
|
})
|
|
611
|
-
mem.env[opt.process].handle = p.handle
|
|
772
|
+
if (mem.env[opt.process]) mem.env[opt.process].handle = p.handle
|
|
612
773
|
}
|
|
613
774
|
if (p.compressed) {
|
|
614
775
|
const start = Date.now()
|
|
@@ -738,6 +899,92 @@ export default ({ AR, scheduler, mu, su, cu, acc, AoLoader, ArMem } = {}) => {
|
|
|
738
899
|
return { recovered: count, pid, success }
|
|
739
900
|
}
|
|
740
901
|
|
|
902
|
+
// Satellite CU evaluate: WASM execution only, no DataItem creation or AR posting.
|
|
903
|
+
// Used by cu_post_evaluate on remote CU workers.
|
|
904
|
+
const evaluate = async ({
|
|
905
|
+
message: msgId,
|
|
906
|
+
process: pid,
|
|
907
|
+
data,
|
|
908
|
+
tags: msgTags,
|
|
909
|
+
from,
|
|
910
|
+
is_spawn,
|
|
911
|
+
module: modId,
|
|
912
|
+
scheduler: sch,
|
|
913
|
+
}) => {
|
|
914
|
+
if (is_spawn) {
|
|
915
|
+
const mod = modId || tags(msgTags || []).Module
|
|
916
|
+
if (!mod) throw Error("module missing for evaluate spawn")
|
|
917
|
+
const { mod: resolvedMod, wasm, format } = await mem.getWasm(mod)
|
|
918
|
+
const _tags = tags(msgTags || [])
|
|
919
|
+
const ext = _tags.Extension || "WeaveDrive"
|
|
920
|
+
const wdrive = extensions[ext]
|
|
921
|
+
const spawnTx = await mem.getTx(pid)
|
|
922
|
+
const moduleTx = await mem.getTx(resolvedMod)
|
|
923
|
+
const handle = await AoLoader(wasm, {
|
|
924
|
+
format,
|
|
925
|
+
WeaveDrive: wdrive,
|
|
926
|
+
spawn: spawnTx?.item ?? spawnTx ?? null,
|
|
927
|
+
module: moduleTx,
|
|
928
|
+
})
|
|
929
|
+
const owner = from || mu.addr
|
|
930
|
+
let p = {
|
|
931
|
+
extension: ext,
|
|
932
|
+
format,
|
|
933
|
+
id: pid,
|
|
934
|
+
epochs: [],
|
|
935
|
+
handle,
|
|
936
|
+
module: resolvedMod,
|
|
937
|
+
hash: pid,
|
|
938
|
+
memory: null,
|
|
939
|
+
owner,
|
|
940
|
+
height: 0,
|
|
941
|
+
results: [pid],
|
|
942
|
+
}
|
|
943
|
+
let bootData = ""
|
|
944
|
+
if (_tags["On-Boot"] === "Data") bootData = data ?? ""
|
|
945
|
+
else bootData = data ?? ""
|
|
946
|
+
const msg = await genMsg(pid, p, bootData, msgTags || [], owner, owner, true)
|
|
947
|
+
const _env = await genEnv({ pid, owner, module: resolvedMod })
|
|
948
|
+
const res = await handle(null, msg, _env)
|
|
949
|
+
p.memory = res.Memory
|
|
950
|
+
delete res.Memory
|
|
951
|
+
await mem.set({ tags: msgTags, data, res, msg }, "msgs", pid)
|
|
952
|
+
await mem.set(p, "env", pid)
|
|
953
|
+
return res
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
// Message evaluation with state update
|
|
957
|
+
const p = await mem.get("env", pid)
|
|
958
|
+
if (!p) throw Error(`process ${pid} not found on satellite CU`)
|
|
959
|
+
if (!p.handle) {
|
|
960
|
+
const { format, mod, wasm } = await mem.getWasm(p.module)
|
|
961
|
+
const wdrive = extensions[p.extension]
|
|
962
|
+
const spawnTx = await mem.getTx(p.id)
|
|
963
|
+
const moduleTx = await mem.getTx(mod)
|
|
964
|
+
p.handle = await AoLoader(wasm, {
|
|
965
|
+
format,
|
|
966
|
+
WeaveDrive: wdrive,
|
|
967
|
+
spawn: spawnTx?.item ?? spawnTx ?? null,
|
|
968
|
+
module: moduleTx,
|
|
969
|
+
})
|
|
970
|
+
}
|
|
971
|
+
if (p.compressed) {
|
|
972
|
+
p.memory = mem.decompress(p.memory, p.original_size)
|
|
973
|
+
p.compressed = false
|
|
974
|
+
}
|
|
975
|
+
p.height += 1
|
|
976
|
+
const owner = from || mu.addr
|
|
977
|
+
const msg = await genMsg(msgId, p, data ?? "", msgTags || [], owner, owner)
|
|
978
|
+
const _env = await genEnv({ pid, owner: p.owner, module: p.module })
|
|
979
|
+
const res = await p.handle(p.memory, msg, _env)
|
|
980
|
+
p.memory = res.Memory
|
|
981
|
+
delete res.Memory
|
|
982
|
+
p.results.push(msgId)
|
|
983
|
+
await mem.set(p, "env", pid)
|
|
984
|
+
await mem.set({ tags: msgTags, data, from, res, msg }, "msgs", msgId)
|
|
985
|
+
return res
|
|
986
|
+
}
|
|
987
|
+
|
|
741
988
|
const result = async opt => {
|
|
742
989
|
return (await mem.get("msgs", opt.message))?.res
|
|
743
990
|
}
|
|
@@ -828,7 +1075,7 @@ export default ({ AR, scheduler, mu, su, cu, acc, AoLoader, ArMem } = {}) => {
|
|
|
828
1075
|
spawn: (await mem.getTx(p.id)).item,
|
|
829
1076
|
module: await mem.getTx(mod),
|
|
830
1077
|
})
|
|
831
|
-
mem.env[opt.process].handle = p.handle
|
|
1078
|
+
if (mem.env[opt.process]) mem.env[opt.process].handle = p.handle
|
|
832
1079
|
}
|
|
833
1080
|
if (p.compressed) {
|
|
834
1081
|
const start = Date.now()
|
|
@@ -844,6 +1091,7 @@ export default ({ AR, scheduler, mu, su, cu, acc, AoLoader, ArMem } = {}) => {
|
|
|
844
1091
|
return null
|
|
845
1092
|
},
|
|
846
1093
|
recover,
|
|
1094
|
+
evaluate,
|
|
847
1095
|
mem,
|
|
848
1096
|
}
|
|
849
1097
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import "./cf-env.js"
|
|
2
|
+
import base from "./aoconnect-base.js"
|
|
3
|
+
import AR from "./car.js"
|
|
4
|
+
import { mu, su, cu, acc } from "./cf.js"
|
|
5
|
+
import AoLoader from "./ao-loader.js"
|
|
6
|
+
import ArMem from "./armem-cf.js"
|
|
7
|
+
const scheduler = "_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA"
|
|
8
|
+
|
|
9
|
+
export const connect = base({ AR, scheduler, mu, su, cu, acc, AoLoader, ArMem })
|
package/esm/ar-remote.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
export default class RemoteAR {
|
|
2
|
+
constructor(ar_url) {
|
|
3
|
+
this.url = ar_url.replace(/\/$/, "")
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
async data(id) {
|
|
7
|
+
const res = await fetch(`${this.url}/ar/${id}`)
|
|
8
|
+
if (!res.ok) return null
|
|
9
|
+
return new Uint8Array(await res.arrayBuffer())
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async getTx(id) {
|
|
13
|
+
const query = `{ transactions(ids: ["${id}"]) {
|
|
14
|
+
edges { node { id owner { address key } recipient tags { name value }
|
|
15
|
+
anchor signature data { size type } block { id height timestamp } } }
|
|
16
|
+
} }`
|
|
17
|
+
const res = await fetch(`${this.url}/ar/graphql`, {
|
|
18
|
+
method: "POST",
|
|
19
|
+
headers: { "Content-Type": "application/json" },
|
|
20
|
+
body: JSON.stringify({ query }),
|
|
21
|
+
})
|
|
22
|
+
const json = await res.json()
|
|
23
|
+
const node = json?.data?.transactions?.edges?.[0]?.node
|
|
24
|
+
if (!node) return null
|
|
25
|
+
return {
|
|
26
|
+
id: node.id,
|
|
27
|
+
owner: node.owner?.address,
|
|
28
|
+
_owner_key: node.owner?.key,
|
|
29
|
+
recipient: node.recipient,
|
|
30
|
+
tags: node.tags,
|
|
31
|
+
anchor: node.anchor,
|
|
32
|
+
signature: node.signature,
|
|
33
|
+
_data: node.data,
|
|
34
|
+
block: node.block?.id,
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async postTx(tx) {
|
|
39
|
+
const res = await fetch(`${this.url}/ar/${tx.id || "tx"}`, {
|
|
40
|
+
method: "POST",
|
|
41
|
+
headers: { "Content-Type": "application/json" },
|
|
42
|
+
body: JSON.stringify(tx),
|
|
43
|
+
})
|
|
44
|
+
return await res.json()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async postMU(rawDataItem) {
|
|
48
|
+
const res = await fetch(`${this.url}/mu`, {
|
|
49
|
+
method: "POST",
|
|
50
|
+
headers: { "Content-Type": "application/octet-stream" },
|
|
51
|
+
body: rawDataItem,
|
|
52
|
+
})
|
|
53
|
+
return await res.json()
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
async getHeight() {
|
|
57
|
+
const res = await fetch(`${this.url}/ar/`)
|
|
58
|
+
const json = await res.json()
|
|
59
|
+
return json.height ?? 0
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async getAnchor() {
|
|
63
|
+
const res = await fetch(`${this.url}/ar/tx_anchor`)
|
|
64
|
+
return await res.text()
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async graphql(query, variables) {
|
|
68
|
+
const res = await fetch(`${this.url}/ar/graphql`, {
|
|
69
|
+
method: "POST",
|
|
70
|
+
headers: { "Content-Type": "application/json" },
|
|
71
|
+
body: JSON.stringify({ query, variables }),
|
|
72
|
+
})
|
|
73
|
+
return await res.json()
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async findSU(schedulerAddr) {
|
|
77
|
+
const query = `{ transactions(
|
|
78
|
+
owners: ["${schedulerAddr}"],
|
|
79
|
+
tags: [{ name: "Type", values: ["Scheduler-Location"] }],
|
|
80
|
+
first: 1, sort: HEIGHT_DESC
|
|
81
|
+
) { edges { node { tags { name value } } } } }`
|
|
82
|
+
const json = await this.graphql(query)
|
|
83
|
+
const tags = json?.data?.transactions?.edges?.[0]?.node?.tags ?? []
|
|
84
|
+
const urlTag = tags.find(t => t.name === "Url")
|
|
85
|
+
return urlTag?.value ?? null
|
|
86
|
+
}
|
|
87
|
+
}
|