|
// @ts-check |
|
// handwritten bundle, not usually done |
|
// See https://gist.github.com/zarutian/2c3b0789b71c7599ec9515f0d50da04f for explainer on ActiveCapCerts. |
|
const modules = new Map(); |
|
const moduleFuncs = new Map(); |
|
const { innerRequire, moduleExists } = (() => { |
|
const outerRequire = require; // capture require before it gets shadowed |
|
const innerRequire = async (moduleSpecifier) => { |
|
if (modules.has(moduleSpecifier)) { |
|
return modules.get(moduleSpecifier); |
|
} |
|
if (moduleFuncs.has(moduleSpecifier)) { |
|
const exports = await (moduleFuncs.get(moduleSpecifier))(); |
|
modules.set(moduleSpecifier, exports); |
|
return exports; |
|
} |
|
return outerRequire(moduleSpecifier); |
|
}; |
|
const moduleExists = (moduleSpecifier) => { |
|
const exports = outerRequire(moduleSpecifier); |
|
return (Object.entries(exports).length > 0); |
|
} |
|
return { innerRequire, moduleExists }; |
|
})(); |
|
const require = innerRequire; // shadow require in this scope |
|
moduleFuncs.set("@zarutian/SingleAssignMap", async () => { |
|
let exports = {}; |
|
const module = { exports }; |
|
const { harden } = await require("@agoric/harden"); |
|
exports.makeSingleAssignMap = (iterable) => { |
|
const backing = new Map(iterable); |
|
return harden({ |
|
has: (key) => backing.has(key), |
|
get: (key) => backing.get(key), |
|
set: (key, item) => { |
|
if (backing.has(key)) { |
|
throw new Error("key in SingleAssignMap has already been assigned a value"); |
|
} |
|
return backing.set(key, item); |
|
}, |
|
delete: (key) => { throw new Error("keys can not be removed from SingleAssignMap once asigned a value"); } |
|
[Symbol.iterator]: () => backing[Symbol.iterator](), |
|
keys: () => backing.keys(), |
|
values: () => backing.values(), |
|
entries: () => backing.entries(), |
|
}); |
|
} |
|
return module.exports; |
|
}); |
|
moduleFuncs.set("@zarutian/seqBlock", async () => { |
|
let exports = {}; |
|
const { makeSingleAssignMap } = await require("@zarutian/SingleAssignMap"); |
|
const { E, Far } = await require("@endo/eventual-send"); |
|
const makeSeqBlock = (sequenceBlock, environ = {}) => { |
|
return (...sb_args) => { |
|
const results = makeSingleAssignMap(); |
|
let lastQId = undefined; |
|
const i = (it) => { |
|
switch (it[0]) { |
|
case "@qid": return results.get(it[1]); |
|
case "@sba": return sb_args[it[1]]; |
|
case "@ref": // fallthrough |
|
case "@dat": return it[1]; |
|
case "@arr": return it.slice(1).map(i); |
|
case "@rec": return Object.fromEntries(i(it[1])); |
|
case "@env": |
|
if (it.length === 1) { |
|
return environ; |
|
} else { |
|
return it.slice(1).reduce((acc, idx) => acc[i(idx)], environ); |
|
} |
|
case "@sqb": return makeSeqBlock(i(it[1]), i(it[2])); |
|
default: throw new Error("i(): no such it[0] recognized"); |
|
} |
|
} |
|
Array.prototype.forEach.apply(sequenceBlock, (form) => { |
|
const [first, ...rest] = form; |
|
switch (first) { |
|
case "applyMethodSendOnly": { |
|
const [target, verb, args] = rest; |
|
E.sendOnly(i(target))[verb](i(args)); |
|
}; break; |
|
case "applyMethod": { |
|
const [qid, target, verb, args] = rest; |
|
const result = E(i(target))[verb](i(args)); |
|
results.set(qid, result); |
|
lastQId = qid; |
|
}; break; |
|
case "applyFunctionSendOnly": { |
|
const [target, args] = rest; |
|
(E.sendOnly(i(target)))(i(args)); |
|
}; break; |
|
case "applyFunction": { |
|
const [qid, target, args] = rest; |
|
const result = (E(i(target)))(i(args)); |
|
results.set(qid, result); |
|
lastQId = qid; |
|
}; break; |
|
case "get": { |
|
const [qid, target, prop] = rest; |
|
const result = E.get(i(target))[i(prop)]; |
|
results.set(qid, result); |
|
lastQId = qid; |
|
}; break; |
|
case "assignOnce": { |
|
const [qid, val] = rest; |
|
results.set(qid, i(val)); |
|
lastQId = qid; |
|
}; break; |
|
// 2022-05-24T02:08Z tbdecided #1 -byrjun- |
|
case "assignInEnv": { |
|
const [idxs, val] = rest; |
|
const it = i(idxs); |
|
if (it.length === 0) { |
|
environ = i(val); |
|
} else { |
|
it.reduce((acc, idx) => acc[i(idx)], environ) = i(val); |
|
} |
|
}; break; |
|
// -lok- |
|
default: throw new Error("unrecognizable form in seqBlock"); |
|
}; |
|
}); |
|
return results.get(lastQId); |
|
} |
|
} |
|
exports.makeSeqBlock = makeSeqBlock; |
|
return exports; |
|
}); |
|
moduleFuncs.set("@zarutian/seqBlock/cost-calculator", async () => { |
|
let exports = {}; |
|
const costCalculate = (sequenceBlock) => { |
|
let tally = BigInt(0); |
|
tally += BigInt(sequenceBlock.length); |
|
const i = (it) => { |
|
switch (it[0]) { |
|
case "@qid": |
|
case "@sba": |
|
case "@ref": // fallthrough |
|
case "@dat": tally += BigInt(1); break; |
|
case "@arr": tally += BigInt(1); it.slice(1).forEach(i); break; |
|
case "@rec": tally += BigInt(1); i(it[1]); break; |
|
case "@env": |
|
tally += BigInt(1); |
|
if (it.length === 1) { |
|
} else { |
|
it.slice(1).forEach(i); |
|
} |
|
break; |
|
case "@sqb": |
|
tally += BigInt(1); |
|
i(it[1]); i(it[2]); |
|
break; |
|
default: |
|
}; |
|
}; |
|
Array.prototype.forEach.apply(sequenceBlock, (form) => { |
|
const [first, ...rest] = form; |
|
switch (first) { |
|
case "applyMethodSendOnly": { |
|
const [target, verb, args] = rest; |
|
i(target); i(args); |
|
}; break; |
|
case "applyMethod": { |
|
const [qid, target, verb, args] = rest; |
|
i(target); i(args); |
|
}; break; |
|
case "applyFunctionSendOnly": { |
|
const [target, args] = rest; |
|
i(target); i(args); |
|
}; break; |
|
case "applyFunction": { |
|
const [qid, target, args] = rest; |
|
i(target); i(args); |
|
}; break; |
|
case "get": { |
|
const [qid, target, prop] = rest; |
|
i(target); i(prop); |
|
}; break; |
|
case "assignOnce": { |
|
const [qid, val] = rest; |
|
i(val); |
|
}; break; |
|
// 2022-05-24T02:08Z tbdecided #1 -byrjun- |
|
case "assignInEnv": { |
|
const [idxs, val] = rest; |
|
i(idxs); i(val); |
|
}; break; |
|
// -lok- |
|
} |
|
}); |
|
return tally; |
|
}; |
|
exports.costCalculate = costCalculate; |
|
return exports; |
|
}); |
|
moduleFuncs.set("@zarutian/handoff-tables", async () => { |
|
let exports = {}; |
|
const module = { exports }; |
|
const { harden } = await require("@agoric/harden"); |
|
const { makePromiseKit } = await require("@agoric/promise-kit"); |
|
const { E, Far } = await require("@endo/eventual-send"); |
|
exports.makeHandoffTable = () => { |
|
const recipiants = new Map(); |
|
const lookup = (g, r, n) => { |
|
if (!recipiants.has(r)) { return undefined; } |
|
const givers = recipiants.get(r); |
|
if (!givers.has(g)) { return undefined; } |
|
const gifts = givers.get(g); |
|
if (!gifts.has(n)) { return undefined; } |
|
return gifts.get(n); |
|
} |
|
const assign = (g, r, n, item) => { |
|
if (!recipiants.has(r)) { recipiants.set(r, (new Map())); } |
|
const givers = recipiants.get(r); |
|
if (!givers.has(g)) { givers.set(g, (new Map())); } |
|
const gifts = givers.get(g); |
|
gifts.set(n, item); |
|
} |
|
const remove = (g, r, n) => { |
|
if (!recipiants.has(r)) { return; } |
|
const givers = recipiants.get(r); |
|
if (!givers.has(g)) { return; } |
|
const gifts = givers.get(g); |
|
if (!gifts.has(n)) { return; } |
|
gifts.delete(n); |
|
if (gifts.size == 0) { |
|
givers.delete(g); |
|
if (givers.size == 0) { |
|
recipiants.delete(r); |
|
} |
|
} |
|
} |
|
return harden({ |
|
provideFor: (giver, recipiant, nynce, gift) => { |
|
const dufuhola = lookup(giver, recipiant, nynce); |
|
if (dufuhola === undefined) { |
|
assign(giver, recipiant, nynce, { kind: "gift", gift }); |
|
} else { |
|
if (dufuhola.kind === "gift") { |
|
if (dufuhola.gift !== gift) { |
|
throw new Error("ya kannea 'ssign same nynce for the same recipiant to two diffrent gifts"); |
|
} |
|
} else { |
|
if (dufuhola.kind == "promiseKit") { |
|
const { resolve } = dufuhola.promiseKit; |
|
resolve(harden({ getGift: () => gift })); |
|
remove(giver, recipiant, nynce); |
|
E.sendOnly(dufuhola.vine)._react(); |
|
return harden({ _react: () => {} }); |
|
} |
|
} |
|
} |
|
const vine = Far("Vine", { _react: () => { gift = undefined; } }); |
|
return vine; // might be pointless; |
|
}, |
|
acceptFrom: (giver, recipiant, nynce, vine) => { |
|
const dufuhola = lookup(giver, recipiant, nynce); |
|
if (dufuhola === undefined) { |
|
const promiseKit = makePromiseKit(); |
|
assign(giver, recipiant, nynce, { kind: "promiseKit", promiseKit, vine }); |
|
return promiseKit.promise; |
|
} else { |
|
if (dufuhola.kind === "promiseKit") { |
|
return dufuhola.promiseKit.promise; |
|
} |
|
if (dufuhola.kind === "gift") { |
|
const gift = dufuhola.gift; |
|
remove(giver, recipiant, nynce); |
|
E.sendOnly(vine)._react(); |
|
return Promise.resolve(harden({ getGift: () => gift })); |
|
} |
|
} |
|
}, |
|
isGiftWaiting: (giver, recipiant, nynce) => { |
|
const dufuhola = lookup(giver, recipiant, nynce); |
|
if (dufuhola === undefined) { return false; } |
|
if (dufuhola.kind === "gift") { return true; } |
|
return false; |
|
}, |
|
}); |
|
}; |
|
exports.makeHandoffFacet = (handoffTable, ident) => { |
|
return Far("HandoffTableFacet", { |
|
provideFor: (recipiant, nynce, gift) => handoffTable.provideFor(ident, recipiant, nynce, gift), |
|
acceptFrom: (giver, nynce, vine) => handoffTable.acceptFrom(giver, ident, nynce, vine), |
|
isGiftWaiting: (giver, nynce) => handoffTable.isGiftWaiting(giver, ident, nynce), |
|
}); |
|
}; |
|
return module.exports; |
|
}); |
|
moduleFuncs.set("@zarutian/ForwardingDelegatedPromise", async () => { |
|
// 2021-11-19T16:49Z todo: Þarf að breyta þessu í Promise.delegated() form |
|
// 2023-02-03T05:24Z byrjaður á því |
|
let exports = {}; |
|
const module = { exports }; |
|
const { harden } = await require("@agoric/harden"); |
|
const { E } = await require("@endo/eventual-send"); |
|
const forward = { |
|
applyMethod(result, promiseKit, verb, args) { |
|
E.when( |
|
(E(result)[verb])(...args), |
|
promiseKit.resolve, |
|
promiseKit.reject, |
|
); |
|
}, |
|
applyMethodOnly(result, verb, args) { |
|
(E.sendOnly(result)[verb])(...args); |
|
}, |
|
apply(result, promiseKit, args) { |
|
E.when( |
|
(E(result))(...args), |
|
promiseKit.resolve, |
|
promiseKit.reject, |
|
); |
|
}, |
|
applyOnly(result, args) { |
|
(E.sendOnly(result))(...args); |
|
}, |
|
get(result, promiseKit, property) { |
|
E.when( |
|
(E.get(result))[property], |
|
promiseKit.resolve, |
|
promiseKit.reject, |
|
); |
|
}, |
|
setOnly(result, property, newValue) { |
|
E.setOnly(result, property, newValue); |
|
}, |
|
}; |
|
const makeForwardingDelegatedPromise = (ERef, executor) => { |
|
let queue = []; // :FlexList |
|
const add2queue = (item) => { queue.push(item); }; |
|
const forwardingHandler = { |
|
applyMethod(target, verb, args) { |
|
// eventualSend |
|
const p1 = (E(ERef)[verb])(...args); |
|
const p2 = makeForwardingDelegatedPromiseKit(p1); |
|
add2queue(["applyMethod", p2, verb, args]) |
|
return p2.promise; |
|
}, |
|
applyMethodOnly(target, verb, args) { |
|
// eventualSendOnly |
|
(E.sendOnly(ERef)[verb])(...args); |
|
add2queue(["applyMethodOnly", verb, args]); |
|
}, |
|
apply(target, args) { |
|
// eventualApply |
|
const p1 = (E(ERef))(...args); |
|
const p2 = makeForwardingDelegatedPromiseKit(p1); |
|
add2queue(["apply", p2, args]); |
|
return p2.promise; |
|
}, |
|
applyOnly(target, args) { |
|
// eventualApplyOnly |
|
(E.sendOnly(ERef))(...args); |
|
add2queue(["applyOnly", args]); |
|
}, |
|
get(target, property) { |
|
// eventualGet |
|
const p1 = (E.get(ERef))[property]; |
|
const p2 = makeForwardingDelegatedPromiseKit(p1); |
|
add2queue(["get", p2, property]); |
|
return p2.promise; |
|
}, |
|
set(target, property, newValue): { |
|
// eventualSet, should actually never be invoked but does the default behaviour |
|
E.setOnly(ERef, property, newValue); |
|
add2queue(["setOnly", property, newValue]); |
|
return newValue; |
|
}, |
|
setOnly(target, property, newValue): { |
|
// eventualSetOnly |
|
E.setOnly(ERef, property, newValue); |
|
add2queue(["setOnly", property, newValue]); |
|
}, |
|
}; |
|
return Promise.delegated((resolve, reject, rWp) => { |
|
const resolveAndResend = (result) => { |
|
queue.forEach(pending => { |
|
forward[pending[0]](result, ...pending.slice(1)); |
|
}); |
|
queue = null; |
|
return resolve(result); |
|
}; |
|
const leysa = (result) => { queue = null; return resolve(result); }; |
|
const rWp2 = (...args) => { queue = null; return rWp(...args); }; |
|
return executor(leysa, reject, rWp2, resolveAndResend); |
|
}, forwardingHandler); |
|
}; |
|
const makeForwardingDelegatedPromiseKit = (ERef) => { |
|
let resolve = undefined; |
|
let reject = undefined; |
|
let resolveAndResend = undefined; |
|
let resolveWithPresence = undefined; |
|
const promise = makeForwardingDelegatedPromise(ERef, (leysa, hafna, rWp, leysaOgEndursenda) => { |
|
resolve = leysa; reject = hafna; |
|
resolveAndResend = leysaOgEndursenda; |
|
resolveWithPresence = rWp; |
|
}); |
|
return harden({ promise, resolve, reject, resolveAndResend, resolveWithPresence }); |
|
}; |
|
exports = { ...exports, makeForwardingDelegatedPromiseKit, makeForwardingDelegatedPromise }; |
|
return exports; |
|
}); |
|
moduleFuncs.set("@zarutian/async-ops", async () => { |
|
const { E } = await require("@endo/eventual-send"); |
|
const { makeForwardingDelegatedPromiseKit } = await require("@zarutian/ForwardingDelegatedPromise"); |
|
const someArgsAwaitForMethod = async (target, verb, args, which) => { |
|
const someSettled = await Promise.all(args.map((arg, idx) => (which[idx] ? arg : null ))); |
|
const newArgs = which.map((w, idx) => (w ? someSettled[idx] : args[idx])); |
|
return (E(target)[verb])(...newArgs); |
|
}; |
|
const someArgsAwaitForFunction = async (target, args, which) => { |
|
const someSettled = await Promise.all(args.map((arg, idx) => (which[idx] ? arg : null ))); |
|
const newArgs = which.map((w, idx) => (w ? someSettled[idx] : args[idx])); |
|
return (E(target))(...newArgs); |
|
}; |
|
const awaitForProperty = async (target, prop) => { |
|
const p = await prop; |
|
return (E.get(target))[p]; |
|
}; |
|
const async_listen = (promise, resolvementListener) => { |
|
return E.when( |
|
promise, |
|
(value) => E(resolvementListener).resolve(value), |
|
(err) => E(resolvementListener).reject(err), |
|
); |
|
}; |
|
const async_attempt = (opts) => { |
|
const {target, verb, args, awaitFor, fallback} = opts; |
|
const t1 = E(target)[verb](...args); |
|
const t2 = makeForwardingDelegatedPromiseKit(t1); |
|
E.when( |
|
t1, |
|
result => t2.resolve(result), |
|
err => { |
|
E.when( |
|
awaitFor, |
|
r => { t2.resolveAndResend(fallback(r, ...args)); }, |
|
t2.reject, |
|
); |
|
}, |
|
); |
|
return t2.promise; |
|
}; |
|
const async_arrayAt = (arr, idx) => { |
|
return async_attempt({ |
|
target: arr, |
|
verb: "at", |
|
args: [idx], |
|
awaitFor: Promise.all([idx]), |
|
fallback: ([i]) => E.get(arr)[i], |
|
}); |
|
}; |
|
exports.async_arrayAt = async_arrayAt; |
|
const async_pick = (selector, conseq, altern) => { |
|
return async_attempt({ |
|
target: selector, |
|
verb: "pick", |
|
args: [conseq, altern], |
|
awaitFor: selector, |
|
fallback: (theBool, conseq, altern) => (theBool ? conseq : altern), |
|
}); |
|
}; |
|
exports.async_pick = async_pick; |
|
exports.async_NOT = a => async_pick(a, false, true); |
|
exports.async_OR = (a, b) => { |
|
const c = async_pick(a, [true, true], [true, false]); |
|
return async_pick(b, E.get(c)[0], E.get(c)[1]); |
|
}; |
|
exports.async_AND = (a, b) => { |
|
const c = async_pick(a, [true, false], [false, false]); |
|
return async_pick(b, E.get(c)[0], E.get(c)[1]); |
|
}; |
|
exports.async_XOR = (a, b) => { |
|
const c = async_pick(a, [false, true], [true, false]); |
|
return async_pick(b, E.get(c)[0], E.get(c)[1]); |
|
}; |
|
// 2023-06-07T02:50 Added -begin- |
|
exports.async_If_v1 = (selector, conseqCallback, alternCallback) => { |
|
let used = false; |
|
const common = () => { |
|
if (used) { |
|
throw new Error("conseqCallback or alternCallback of an async_If already invoked"); |
|
} |
|
used = true; |
|
}; |
|
const ccb = () => { |
|
common(); |
|
(E(conseqCallback))(); |
|
}; |
|
const acb = () => { |
|
common(); |
|
(E(alternCallback))(); |
|
}; |
|
const t1 = async_pick(selector, ccb, acb); |
|
return (E(t1))(); |
|
}; |
|
exports.async_switch_v1 = (selector, cases, defaultCase) => { |
|
const t1 = (E(cases)[Symbol.asyncIterator])(); |
|
const t2 = () => { |
|
}; |
|
const t3 = () => { |
|
const t4 = E.get(E(t1).next()); |
|
const t5 = () => (E(defaultCase))(); |
|
const t6 = async_pick(t4.done, t5, t3); |
|
const t7 = E.get(t4.value); |
|
const t8 = exports.async_sameYet(t7[0], selector); |
|
const t9 = async_pick(t8, t7[1], t2); |
|
const tA = (E(t9))(); |
|
const tB = async_pick(t8, t2, t6); |
|
return (E(tB))(); |
|
} |
|
}; |
|
// -end- |
|
|
|
exports.async_add = (a, b) => { |
|
return async_attempt({ |
|
target: a, |
|
verb: "add", |
|
args: [b], |
|
awaitFor: Promise.all([a, b]), |
|
fallback: ([anum, bnum]) => (BigInt(anum) + BigInt(bnum)), |
|
}); |
|
} |
|
exports.async_subtract = (a, b) => { |
|
return async_attempt({ |
|
target: a, |
|
verb: "subtract", |
|
args: [b], |
|
awaitFor: Promise.all([a, b]), |
|
fallback: ([anum, bnum]) => (BigInt(anum) - BigInt(bnum)), |
|
}); |
|
}; |
|
exports.async_multiply = (a, b) => { |
|
return async_attempt({ |
|
target: a, |
|
verb: "multiply", |
|
args: [b], |
|
awaitFor: Promise.all([a, b]), |
|
fallback: ([anum, bnum]) => (BigInt(anum) * BigInt(bnum)), |
|
}); |
|
}; |
|
exports.async_divide = (a, b) => { |
|
return async_attempt({ |
|
target: a, |
|
verb: "divide", |
|
args: [b], |
|
awaitFor: Promise.all([a, b]), |
|
fallback: ([anum, bnum]) => (BigInt(anum) / BigInt(bnum)), |
|
}); |
|
}; |
|
exports.async_modulo = (a, b) => { |
|
return async_attempt({ |
|
target: a, |
|
verb: "modulo", |
|
args: [b], |
|
awaitFor: Promise.all([a, b]), |
|
fallback: ([anum, bnum]) => (BigInt(anum) % BigInt(bnum)), |
|
}); |
|
}; |
|
exports.async_negate = (a) => { |
|
return async_attempt({ |
|
target: a, |
|
verb: "negate", |
|
args: [], |
|
awaitFor: Promise.all([a]), |
|
fallback: ([anum]) => (-BigInt(anum)), |
|
}); |
|
}; |
|
exports.async_exponate = (a, b) => { |
|
return async_attempt({ |
|
target: a, |
|
verb: "exponate", |
|
args: [b], |
|
awaitFor: Promise.all([a, b]), |
|
fallback: ([anum, bnum]) => (BigInt(anum) ** BigInt(bnum)), |
|
}); |
|
}; |
|
exports.async_bitwiseNot = (a) => { |
|
return async_attempt({ |
|
target: a, |
|
verb: "bitwiseNot", |
|
args: [], |
|
awaitFor: Promise.all([a]), |
|
fallback: ([anum]) => (~BigInt(anum)), |
|
}); |
|
}; |
|
exports.async_bitwiseAnd = (a, b) => { |
|
return async_attempt({ |
|
target: a, |
|
verb: "bitwiseAnd", |
|
args: [b], |
|
awaitFor: Promise.all([a, b]), |
|
fallback: ([anum, bnum]) => (BigInt(anum) & BigInt(bnum)), |
|
}); |
|
}; |
|
exports.async_bitwiseOr = (a, b) => { |
|
return async_attempt({ |
|
target: a, |
|
verb: "bitwiseOr", |
|
args: [b], |
|
awaitFor: Promise.all([a, b]), |
|
fallback: ([anum, bnum]) => (BigInt(anum) | BigInt(bnum)), |
|
}); |
|
}; |
|
exports.async_bitwiseXor = (a, b) => { |
|
return async_attempt({ |
|
target: a, |
|
verb: "bitwiseXor", |
|
args: [b], |
|
awaitFor: Promise.all([a, b]), |
|
fallback: ([anum, bnum]) => (BigInt(anum) ^ BigInt(bnum)), |
|
}); |
|
}; |
|
const numToBoolArray = (num, nrOfBits = 32) => { |
|
var v = num; |
|
const r = []; |
|
while (nrOfBits > 0) { |
|
r.push(((v & 0x1) == 0x1)); |
|
v = v >> 1; |
|
nrOfBits--; |
|
} |
|
return r; |
|
}; |
|
const async_numToBoolArray = (num, nrOfBits = 32) => { |
|
return async_attempt({ |
|
target: num, |
|
verb: "toBoolArray", |
|
args: [nrOfBits], |
|
awaitFor: Promise.all([num]), |
|
fallback: ([n]) => (numToBoolArray(BigInt(n), nrOfBits)), |
|
}); |
|
}; |
|
/* |
|
const numFromBoolArray = (arr) => { |
|
var n = BigInt(0); |
|
while (arr.length > 0) { |
|
n = n << 1n; |
|
n = n + (arr.pop() ? BigInt(1) : BigInt(0)); |
|
} |
|
return n; |
|
}; |
|
*/ |
|
const numFromBoolArray = (arr) => { |
|
return arr.reduceRight((acc, item) => ((acc << 1n) + (item ? BigInt(1) : BigInt(0))), BigInt(0)); |
|
}; |
|
/* exports.async_numFromBoolArray = (arr) => { |
|
return E(arr).reduceRight(NakedNomad((acc, item) => ((acc << 1n) + (item ? BigInt(1) : BigInt(0)))), BigInt(0)); |
|
}; */ |
|
exports.async_numFromBoolArray = (arr) => { |
|
const K = (first, second) => second; |
|
const recurse = (idxP, numP) => { |
|
const contP = exports.async_numIsZero(idxP); |
|
const t2 = exports.async_pick(contP, BigInt(0), BigInt(1)); |
|
const idxP1 = exports.async_subtract(idxP, t2); |
|
const bitP = exports.async_arrayAt(arr, idxP); |
|
const bitnumP = exports.async_pick(bitP, BigInt(1), BigInt(0)); |
|
const numP1 = exports.async_multiply(numP, BigInt(2)); |
|
const numP2 = exports.async_add(numP1, bitnumP); |
|
const t3 = exports.async_pick(contP, K, recurse); |
|
return E(t3)(idxP1, numP2); |
|
} |
|
return recurse(E.get(arr).length, Promise.resolve(BigInt(0))); |
|
} |
|
exports.async_numIsZero = (num) => { |
|
return async_attempt({ |
|
target: num, |
|
verb: "isZero", |
|
args: [], |
|
awaitFor: Promise.all([num]), |
|
fallback: ([n]) => (BigInt(n) == BigInt(0)), |
|
}); |
|
}; |
|
exports.async_numIsGreaterThan = (a, b) => { |
|
return async_attempt({ |
|
target: a, |
|
verb: "isGreaterThan", |
|
args: [b], |
|
awaitFor: Promise.all([a, b]), |
|
fallback: ([anum, bnum]) => (BigInt(anum) > BigInt(bnum)), |
|
}); |
|
}; |
|
exports.async_numIsLessThan = (a, b) => { |
|
return async_attempt({ |
|
target: a, |
|
verb: "isLessThan", |
|
args: [b], |
|
awaitFor: Promise.all([a, b]), |
|
fallback: ([anum, bnum]) => (BigInt(anum) < BigInt(bnum)), |
|
}); |
|
}; |
|
exports.async_numIsEqual = function (a, b) { |
|
return async_attempt({ |
|
target: a, |
|
verb: "isEqual", |
|
args: [b], |
|
awaitFor: Promise.all([a, b]), |
|
fallback: ([anum, bnum]) => (BigInt(anum) == BigInt(bnum)), |
|
}); |
|
}; |
|
exports.pipe = (...funs) => |
|
(input) => Array.prototype.reduce.call(funs, (out, f) => f(out), input); |
|
exports.asyncPipeV1 = (...funs) => |
|
async (input) => await Array.prototype.reduce.call(funs, async (out, f) => await f(out), await input); |
|
/* |
|
const exports = { |
|
someArgsAwaitForMethod, |
|
someArgsAwaitForFunction, |
|
awaitForProperty, |
|
|
|
async_bitwiseOr, |
|
async_bitwiseXor, |
|
numToBoolArray, |
|
async_numToBoolArray, |
|
numFromBoolArray, |
|
async_numFromBoolArray, |
|
async_numIsZero, |
|
async_numIsGreaterThan, |
|
async_numIsLessThan, |
|
async_numIsEqual, |
|
}; |
|
*/ |
|
return exports; |
|
}); |
|
moduleFuncs.set("@zarutian/ActiveCapCert/0v1", async () => { |
|
let exports = {}; |
|
const { harden } = await require("@agoric/harden"); |
|
const { Far } = await require("@endo/eventual-send"); |
|
const { makeSeqBlock } = await require("@zarutian/seqBlock"); |
|
const { costCalculate } = await require("@zarutian/seqBlock/cost-calculator"); |
|
const async_ops = await require("@zarutian/async-ops"); |
|
const { JSON } = await require("JSON"); |
|
const parse = JSON.parse; // for now but still some tbd |
|
const { base64url_decode } = await require("base64"); |
|
const decode = base64url_decode; |
|
|
|
const openpgp = await require("openpgp"); |
|
const verifySignature = async (certBytes) => { |
|
const [accTag, issuerBytes, bodyBytes, signatureBytes] = certBytes.split("."); |
|
if (accTag !== "ActiveCapCert0v1") { |
|
throw new Error("certBytes did not start with reconized tag"); |
|
} |
|
const detachedSignature = decode(signatureBytes); |
|
const publicKeyArmored = decode(issuerBytes); |
|
const verified = await openpgp.verify({ |
|
message: openpgp.cleartext.fromText(bodyBytes), // CleartextMessage or Message object |
|
signature: await openpgp.signature.readArmored(detachedSignature), // parse detached signature |
|
publicKeys: (await openpgp.key.readArmored(publicKeyArmored)).keys // for verification |
|
}); |
|
if ( verified.signatures.length !== 1 ) { |
|
throw new Error("was only expecting one signiture"); |
|
} |
|
const { valid } = verified.signatures[0]; |
|
return valid; |
|
}; |
|
|
|
const makeActiveCapCertInstanceMaker = (opts) => { |
|
const getHandoffTableFacet = opts.getHandoffTableFacet; |
|
const makeActiveCapCertInstance = async (certBytes) => { |
|
const [accTag, issuerBytes, bodyBytes, signatureBytes] = certBytes.split("."); |
|
if (accTag !== "ActiveCapCert0v1") { |
|
throw new Error("certBytes did not start with reconized tag"); |
|
} |
|
if (! await verifySignature(certBytes) ) { |
|
throw new Error("signature verification failed"); |
|
} |
|
const envelope = parse(decode(bodyBytes)); |
|
const { seqBlock } = envelope; |
|
const environ = harden({ |
|
...(opts.endowments), |
|
makeActiveCapCertInstance, |
|
handoff: getHandoffTableFacet(issuerBytes), |
|
...async_ops, |
|
Far, |
|
}); |
|
return makeSeqBlock(seqBlock, environ); |
|
} |
|
} |
|
exports.makeActiveCapCertInstanceMaker = makeActiveCapCertInstanceMaker; |
|
exports.calculateCostOfACC = (certBytes) => { |
|
const [accTag, issuerBytes, bodyBytes, signatureBytes] = certBytes.split("."); |
|
if (accTag !== "ActiveCapCert0v1") { |
|
throw new Error("certBytes did not start with reconized tag"); |
|
} |
|
const envelope = parse(decode(bodyBytes)); |
|
const { seqBlock } = envelope; |
|
return costCalculate(seqBlock); |
|
}; |
|
return exports; |
|
}); |
|
moduleFuncs.set("@zarutian/certCheque/examples", async () => { |
|
let exports = {}; |
|
exports.makeSimplePaymentTransferV1 = (opts) => { |
|
const { AliceKeys, |
|
BobPublicKey, |
|
IssuerBoardId, |
|
PaymentNym } = opts; |
|
const seqBlock = [ |
|
["applyMethod", "issuerP", ["@env", "board"], "getValue", ["@arr", ["@dat", IssuerBoardId]]], |
|
["applyMethod", "paymentP1", ["@env", "handoff"], "acceptFrom", ["@arr", ["@dat", AliceKeys.publicKey], ["@dat", PaymentNym], ["@dat", null]]], |
|
["applyMethod", "paymentP2", ["@qid", "issuerP"], "claim", ["@arr", ["@qid", "paymentP1"]]], |
|
["applyMethod", "result", ["@env", "handoff"], "provideFor", ["@arr", ["@dat", BobPublicKey], ["@dat", PaymentNym], ["@qid", "paymentP2"]]], |
|
]; |
|
return cert; |
|
}; |
|
exports.makeSimplePaymentTransferV2 = (opts) => { |
|
const { AliceKeys, |
|
BobPublicKey, |
|
IssuerBoardId, |
|
PaymentNym } = opts; |
|
const seqBlock = [ |
|
["applyMethod", "issuerP", ["@env", "board"], "getValue", ["@arr", ["@dat", IssuerBoardId]]], |
|
["assignOnce", "AlicePK", ["@dat", AliceKeys.publicKey]], |
|
["assignOnce", "PaymentNym", ["@dat", PaymentNym]], |
|
["applyMethod", "bool1P", ["@env", "handoff"], "isGiftWaiting", ["@arr", ["@qid", "AlicePK"], ["@qid", "PaymentNym"]]], |
|
["assignOnce", "t", ["@sqb", |
|
["@dat", [ |
|
["applyMethod", "p1", ["@env", "handoff"], "acceptFrom", ["@arr", ["@env", "AlicePK"], ["@env", "PaymentNym"]]], |
|
["applyMethod", "p2", ["@env", "issuer"], "claim", ["@arr", ["@qid", "p1"]]], |
|
["applyMethod", "vine", ["@env", "handoff"], "provideFor", ["@arr", ["@dat", BobPublicKey], ["@env", "PaymentNym"]]], |
|
["assignOnce", "result", ["@dat", true]], |
|
]], |
|
["@rec", ["@arr", |
|
["@arr", ["@dat", "handoff"], ["@env", "handoff"]], |
|
["@arr", ["@dat", "issuer"], ["@qid", "issuerP"]], |
|
["@arr", ["@dat", "AlicePK"], ["@qid", "AlicePK"]], |
|
["@arr", ["@dat", "PaymentNym"], ["@qid", "PaymentNym"]], |
|
]], |
|
]], |
|
["assignOnce", "f", ["@sqb", ["@dat", |
|
[ |
|
["assignOnce", "result", ["@dat", false]], |
|
]], ["@rec" ["@arr"]]]], |
|
["applyMethod", "branchP", ["@qid", "bool1P"], "pick", ["@arr", ["@qid", "t"], ["@qid", "f"]]], |
|
["applyFunction", "result", ["@qid", "branchP"], ["@arr"]], |
|
]; |
|
return cert; |
|
}; |
|
return exports; |
|
}); |
|
function async getExports() { |
|
let exports = {}; |
|
const module = { exports }; |
|
|
|
const harden = await require("@agoric/harden"); |
|
const { E, Far } = await require("@agoric/eventual-send"); |
|
const { makeHandoffTable, makeHandoffFacet } = await require("@zarutian/handoff-tables"); |
|
// const { workerBundle } = await require("@zarutian/smart-contracts/certChequeExecutor/workerBundle"); |
|
const { makeActiveCapCertInstanceMaker, calculateCostOfACC } = await require("@zarutian/ActiveCapCert/0v1"); |
|
|
|
const start = (zcf, privateArgs) => { |
|
const Zoe = zcf.getZoeService(); |
|
// const workerInstallation = E(zoe).install(workerBundle); |
|
|
|
const handoffTable = makeHandoffTable(); |
|
const getHandoffTableFacet = (ident) => makeHandoffTableFacet(handoffTable, ident); |
|
let board = undefined; |
|
const makeActiveCapCertInstance = makeActiveCapCertInstanceMaker({ |
|
getHandoffTableFacet, |
|
endowments: { |
|
get board() { return board }, |
|
Zoe, |
|
}, |
|
}); |
|
let unit_price = zcf.getAmountMathFor(zcf.getTerms().issuers.Fuel).makeEmpty(); |
|
|
|
const creatorFacet = Far("creatorFacet", { |
|
setBoard: (newBoard) => { board = newBoard; }, |
|
setUnitPrice: (newPrice) => { unit_price = newPrice; }, |
|
}); |
|
const publicFacet = Far("publicFacet", { |
|
makeCertChequeInvitation: (certBytes, resultResolver) => { |
|
return zcf.makeInvitation(seat => { |
|
// do price calculation |
|
const cost = calculateCostOfACC(certBytes); // veikleiki hér? |
|
// todo: check if it is enough |
|
const certInstance = makeActiveCapCertInstance(certBytes); |
|
const result = harden({ certInstance }); |
|
if (resultResolver !== undefined) { |
|
E.sendOnly(resultResolver).resolve(result); |
|
} |
|
return result; |
|
}, "CertChequeInvitation"); |
|
}, |
|
}); |
|
return harden({ creatorFacet, publicFacet }); |
|
} |
|
exports.start = harden(start); |
|
|
|
return module.exports; |
|
} |
|
export { getExports, require }; |