shop refactor

This commit is contained in:
kepler155c@gmail.com
2019-07-21 14:38:24 -06:00
parent e73ce3875b
commit e68c9e938f
7 changed files with 52 additions and 255 deletions

122
swshop/apis/jua.lua Normal file
View File

@@ -0,0 +1,122 @@
local juaVersion = "0.0"
juaRunning = false
eventRegistry = {}
timedRegistry = {}
local function registerEvent(event, callback)
if eventRegistry[event] == nil then
eventRegistry[event] = {}
end
table.insert(eventRegistry[event], callback)
end
local function registerTimed(time, repeating, callback)
if repeating then
callback(true)
end
table.insert(timedRegistry, {
time = time,
repeating = repeating,
callback = callback,
timer = os.startTimer(time)
})
end
local function discoverEvents(event)
local evs = {}
for k,v in pairs(eventRegistry) do
if k == event or string.match(k, event) or event == "*" then
for i,v2 in ipairs(v) do
table.insert(evs, v2)
end
end
end
return evs
end
function on(event, callback)
registerEvent(event, callback)
end
function setInterval(callback, time)
registerTimed(time, true, callback)
end
function setTimeout(callback, time)
registerTimed(time, false, callback)
end
function tick()
local eargs = {os.pullEventRaw()}
local event = eargs[1]
if eventRegistry[event] == nil then
eventRegistry[event] = {}
else
local evs = discoverEvents(event)
for i, v in ipairs(evs) do
v(unpack(eargs))
end
end
if event == "timer" then
local timer = eargs[2]
for i = #timedRegistry, 1, -1 do
local v = timedRegistry[i]
if v.timer == timer then
v.callback(not v.repeating or nil)
if v.repeating then
v.timer = os.startTimer(v.time)
else
table.remove(timedRegistry, i)
end
end
end
end
end
function run()
os.queueEvent("init")
juaRunning = true
while juaRunning do
tick()
end
end
function go(func)
on("init", func)
run()
end
function stop()
juaRunning = false
end
function await(func, ...)
local args = {...}
local out
local finished
func(function(...)
out = {...}
finished = true
end, unpack(args))
while not finished do tick() end
return unpack(out)
end
return {
on = on,
setInterval = setInterval,
setTimeout = setTimeout,
tick = tick,
run = run,
go = go,
stop = stop,
await = await
}

373
swshop/apis/k.lua Normal file
View File

@@ -0,0 +1,373 @@
local w
local r
local jua
local json
local await
local endpoint = "krist.ceriat.net"
local wsEndpoint = "ws://"..endpoint
local httpEndpoint = "http://"..endpoint
local function asserttype(var, name, vartype, optional)
if not (type(var) == vartype or optional and type(var) == "nil") then
error(name..": expected "..vartype.." got "..type(var), 3)
end
end
function init(juai, jsoni, wi, ri)
asserttype(juai, "jua", "table")
asserttype(jsoni, "json", "table")
asserttype(wi, "w", "table", true)
asserttype(ri, "r", "table")
jua = juai
await = juai.await
json = jsoni
w = wi
r = ri
end
local function prints(...)
local objs = {...}
for i, obj in ipairs(objs) do
print(textutils.serialize(obj))
end
end
local function url(call)
return httpEndpoint..call
end
local function api_request(cb, api, data)
local success, url, handle = await(r.request, url(api) .. (api:find("%%?") and "?cc" or "&cc"), {["Content-Type"]="application/json"}, data and json.encode(data))
if success then
cb(success, json.decode(handle.readAll()))
handle.close()
else
cb(success)
end
end
local function authorize_websocket(cb, privatekey)
asserttype(cb, "callback", "function")
asserttype(privatekey, "privatekey", "string", true)
api_request(function(success, data)
cb(success and data and data.ok, data.url and data.url:gsub("wss:", "ws:") or data)
end, "/ws/start", {
privatekey = privatekey
})
end
function address(cb, address)
asserttype(cb, "callback", "function")
asserttype(address, "address", "string")
api_request(function(success, data)
if data.address then
data.address.address = address
end
cb(success and data and data.ok, data.address or data)
end, "/addresses/"..address)
end
function addressTransactions(cb, address, limit, offset)
asserttype(cb, "callback", "function")
asserttype(address, "address", "string")
asserttype(limit, "limit", "number", true)
asserttype(offset, "offset", "number", true)
api_request(function(success, data)
cb(success and data and data.ok, data.transactions or data)
end, "/addresses/"..address.."/transactions?limit="..(limit or 50).."&offset="..(offset or 0))
end
function addressNames(cb, address)
asserttype(cb, "callback", "function")
asserttype(address, "address", "string")
api_request(function(success, data)
cb(success and data and data.ok, data.names or data)
end, "/addresses/"..address.."/names")
end
function addresses(cb, limit, offset)
asserttype(cb, "callback", "function")
asserttype(limit, "limit", "number", true)
asserttype(offset, "offset", "number", true)
api_request(function(success, data)
cb(success and data and data.ok, data.addresses or data)
end, "/addresses?limit="..(limit or 50).."&offset="..(offset or 0))
end
function rich(cb, limit, offset)
asserttype(cb, "callback", "function")
asserttype(limit, "limit", "number", true)
asserttype(offset, "offset", "number", true)
api_request(function(success, data)
cb(success and data and data.ok, data.addresses or data)
end, "/addresses/rich?limit="..(limit or 50).."&offset="..(offset or 0))
end
function transactions(cb, limit, offset)
asserttype(cb, "callback", "function")
asserttype(limit, "limit", "number", true)
asserttype(offset, "offset", "number", true)
api_request(function(success, data)
cb(success and data and data.ok, data.transactions or data)
end, "/transactions?limit="..(limit or 50).."&offset="..(offset or 0))
end
function latestTransactions(cb, limit, offset)
asserttype(cb, "callback", "function")
asserttype(limit, "limit", "number", true)
asserttype(offset, "offset", "number", true)
api_request(function(success, data)
cb(success and data and data.ok, data.transactions or data)
end, "/transactions/latest?limit="..(limit or 50).."&offset="..(offset or 0))
end
function transaction(cb, txid)
asserttype(cb, "callback", "function")
asserttype(txid, "txid", "number")
api_request(function(success, data)
cb(success and data and data.ok, data.transaction or data)
end, "/transactions/"..txid)
end
function makeTransaction(cb, privatekey, to, amount, metadata)
asserttype(cb, "callback", "function")
asserttype(privatekey, "privatekey", "string")
asserttype(to, "to", "string")
asserttype(amount, "amount", "number")
asserttype(metadata, "metadata", "string", true)
api_request(function(success, data)
cb(success and data and data.ok, data.transaction or data)
end, "/transactions", {
privatekey = privatekey,
to = to,
amount = amount,
metadata = metadata
})
end
local wsEventNameLookup = {
blocks = "block",
ownBlocks = "block",
transactions = "transaction",
ownTransactions = "transaction",
names = "name",
ownNames = "name",
ownWebhooks = "webhook",
motd = "motd"
}
local wsEvents = {}
local wsReqID = 0
local wsReqRegistry = {}
local wsEvtRegistry = {}
local wsHandleRegistry = {}
local function newWsID()
local id = wsReqID
wsReqID = wsReqID + 1
return id
end
local function registerEvent(id, event, callback)
if wsEvtRegistry[id] == nil then
wsEvtRegistry[id] = {}
end
if wsEvtRegistry[id][event] == nil then
wsEvtRegistry[id][event] = {}
end
table.insert(wsEvtRegistry[id][event], callback)
end
local function registerRequest(id, reqid, callback)
if wsReqRegistry[id] == nil then
wsReqRegistry[id] = {}
end
wsReqRegistry[id][reqid] = callback
end
local function discoverEvents(id, event)
local evs = {}
for k,v in pairs(wsEvtRegistry[id]) do
if k == event or string.match(k, event) or event == "*" then
for i,v2 in ipairs(v) do
table.insert(evs, v2)
end
end
end
return evs
end
wsEvents.success = function(id, handle)
-- fire success event
wsHandleRegistry[id] = handle
if wsEvtRegistry[id] then
local evs = discoverEvents(id, "success")
for i, v in ipairs(evs) do
v(id, handle)
end
end
end
wsEvents.failure = function(id)
-- fire failure event
if wsEvtRegistry[id] then
local evs = discoverEvents(id, "failure")
for i, v in ipairs(evs) do
v(id)
end
end
end
wsEvents.message = function(id, data)
local data = json.decode(data)
--print("msg:"..tostring(data.ok)..":"..tostring(data.type)..":"..tostring(data.id))
--prints(data)
-- handle events and responses
if wsReqRegistry[id] and wsReqRegistry[id][tonumber(data.id)] then
wsReqRegistry[id][tonumber(data.id)](data)
elseif wsEvtRegistry[id] then
local evs = discoverEvents(id, data.type)
for i, v in ipairs(evs) do
v(data)
end
if data.event then
local evs = discoverEvents(id, data.event)
for i, v in ipairs(evs) do
v(data)
end
end
local evs2 = discoverEvents(id, "message")
for i, v in ipairs(evs2) do
v(id, data)
end
end
end
wsEvents.closed = function(id)
-- fire closed event
if wsEvtRegistry[id] then
local evs = discoverEvents(id, "closed")
for i, v in ipairs(evs) do
v(id)
end
end
end
local function wsRequest(cb, id, type, data)
local reqID = newWsID()
registerRequest(id, reqID, function(data)
cb(data)
end)
data.id = tostring(reqID)
data.type = type
wsHandleRegistry[id].send(json.encode(data))
end
local function barebonesMixinHandle(id, handle)
handle.on = function(event, cb)
registerEvent(id, event, cb)
end
return handle
end
local function mixinHandle(id, handle)
handle.subscribe = function(cb, event, eventcb)
local data = await(wsRequest, id, "subscribe", {
event = event
})
registerEvent(id, wsEventNameLookup[event], eventcb)
cb(data.ok, data)
end
return barebonesMixinHandle(id, handle)
end
function connect(cb, privatekey, preconnect)
asserttype(cb, "callback", "function")
asserttype(privatekey, "privatekey", "string", true)
asserttype(preconnect, "preconnect", "function", true)
local url
if privatekey then
local success, auth = await(authorize_websocket, privatekey)
url = success and auth or wsEndpoint
end
local id = w.open(wsEvents, url)
if preconnect then
preconnect(id, barebonesMixinHandle(id, {}))
end
registerEvent(id, "success", function(id, handle)
cb(true, mixinHandle(id, handle))
end)
registerEvent(id, "failure", function(id)
cb(false)
end)
end
local domainMatch = "^([%l%d-_]*)@?([%l%d-]+).kst$"
local commonMetaMatch = "^(.+)=(.+)$"
function parseMeta(meta)
asserttype(meta, "meta", "string")
local tbl = {meta={}}
for m in meta:gmatch("[^;]+") do
if m:match(domainMatch) then
-- print("Matched domain")
local p1, p2 = m:match("([%l%d-_]*)@"), m:match("@?([%l%d-]+).kst")
tbl.name = p1
tbl.domain = p2
elseif m:match(commonMetaMatch) then
-- print("Matched common meta")
local p1, p2 = m:match(commonMetaMatch)
tbl.meta[p1] = p2
else
-- print("Unmatched standard meta")
table.insert(tbl.meta, m)
end
-- print(m)
end
-- print(textutils.serialize(tbl))
return tbl
end
return {
init = init,
address = address,
addressTransactions = addressTransactions,
addressNames = addressNames,
addresses = addresses,
rich = rich,
transactions = transactions,
latestTransactions = latestTransactions,
transaction = transaction,
makeTransaction = makeTransaction,
connect = connect,
parseMeta = parseMeta,
sha256 = sha256,
}

45
swshop/apis/krist.lua Normal file
View File

@@ -0,0 +1,45 @@
local sha2 = require('opus.crypto.sha2')
local Krist = { }
local function sha256(key)
return sha2:digest(key):toHex()
end
local function makeaddressbyte(byte)
byte = 48 + math.floor(byte / 7)
return string.char(byte + 39 > 122 and 101 or byte > 57 and byte + 39 or byte)
end
function Krist.makev2address(key)
local protein = {}
local stick = sha256(sha256(key))
local n = 0
local v2 = "k"
repeat
if n < 9 then
protein[n] = string.sub(stick,0,2)
stick = sha256(sha256(stick))
end
n = n + 1
until n == 9
n = 0
repeat
local link = tonumber(string.sub(stick,1+(2*n),2+(2*n)),16) % 9
if string.len(protein[link]) ~= 0 then
v2 = v2 .. makeaddressbyte(tonumber(protein[link],16))
protein[link] = ''
n = n + 1
else
stick = sha256(stick)
end
until n == 9
return v2
end
function Krist.toKristWalletFormat(passphrase)
return sha256('KRISTWALLET' .. passphrase) .. '-000'
end
return Krist

65
swshop/apis/r.lua Normal file
View File

@@ -0,0 +1,65 @@
local jua = nil
local idPatt = "#R%d+"
callbackRegistry = {}
local function gfind(str, patt)
local t = {}
for found in str:gmatch(patt) do
table.insert(t, found)
end
if #t > 0 then
return t
else
return nil
end
end
local function findID(url)
local found = gfind(url, idPatt)
if found then
return tonumber(found[#found]:sub(found[#found]:find("%d+")))
end
end
local function newID()
return #callbackRegistry + 1
end
local function trimID(url)
local found = gfind(url, idPatt)
local s, e = url:find(found[#found])
return url:sub(1, s-1)
end
function request(callback, url, headers, postData)
local id = newID()
local newUrl = url .. "#R" .. id
http.request(newUrl, postData, headers)
callbackRegistry[id] = callback
end
function init(jua)
jua = jua
jua.on("http_success", function(event, url, handle)
local id = findID(url)
if id and callbackRegistry[id] then
callbackRegistry[id](true, trimID(url), handle)
table.remove(callbackRegistry, id)
end
end)
jua.on("http_failure", function(event, url, handle)
local id = findID(url)
if id and callbackRegistry[id] then
callbackRegistry[id](false, trimID(url), handle)
table.remove(callbackRegistry, id)
end
end)
end
return {
request = request,
init = init
}

135
swshop/apis/w.lua Normal file
View File

@@ -0,0 +1,135 @@
local jua = nil
local idPatt = "#R%d+"
if not ((socket and socket.websocket) or http.websocketAsync) then
error("You do not have CC:Tweaked/CCTweaks installed or you are not on the latest version.")
end
local newws = socket and socket.websocket or http.websocketAsync
local async
if socket and socket.websocket then
async = false
else
async = true
end
callbackRegistry = {}
wsRegistry = {}
local function gfind(str, patt)
local t = {}
for found in str:gmatch(patt) do
table.insert(t, found)
end
if #t > 0 then
return t
else
return nil
end
end
local function findID(url)
local found = gfind(url, idPatt)
local id = tonumber(found[#found]:sub(found[#found]:find("%d+")))
return id
end
local function newID()
return #callbackRegistry + 1
end
local function trimID(url)
local found = gfind(url, idPatt)
local s, e = url:find(found[#found])
return url:sub(1, s-1)
end
function open(callback, url, headers)
local id
if async then
id = newID()
end
local newUrl
if async then
newUrl = url .. "#R" .. id
newws(newUrl, headers)
else
if headers then
error("Websocket headers not supported under CCTweaks")
end
local ws = newws(url)
ws.send = ws.write
id = ws.id()
wsRegistry[id] = ws
end
callbackRegistry[id] = callback
return id
end
function init(jua)
jua = jua
if async then
jua.on("websocket_success", function(event, url, handle)
local success, id = pcall(findID,url)
if success and id and callbackRegistry[id] and callbackRegistry[id].success then
callbackRegistry[id].success(id, handle)
end
end)
jua.on("websocket_failure", function(event, url)
local success, id = pcall(findID,url)
if success and id and callbackRegistry[id] and callbackRegistry[id].failure then
callbackRegistry[id].failure(id)
end
table.remove(callbackRegistry, id)
end)
jua.on("websocket_message", function(event, url, data)
local success, id = pcall(findID,url)
if success and id and callbackRegistry[id] and callbackRegistry[id].message then
callbackRegistry[id].message(id, data)
end
end)
jua.on("websocket_closed", function(event, url)
local success, id = pcall(findID,url)
if success and id and callbackRegistry[id] and callbackRegistry[id].closed then
callbackRegistry[id].closed(id)
end
table.remove(callbackRegistry, id)
end)
else
jua.on("socket_connect", function(event, id)
if id and callbackRegistry[id] and callbackRegistry[id].success then
callbackRegistry[id].success(id, wsRegistry[id])
end
end)
jua.on("socket_error", function(event, id, msg)
if id and callbackRegistry[id] and callbackRegistry[id].failure then
callbackRegistry[id].failure(id, msg)
end
table.remove(callbackRegistry, id)
end)
jua.on("socket_message", function(event, id)
if id and callbackRegistry[id] and callbackRegistry[id].message then
local data = wsRegistry[id].read()
callbackRegistry[id].message(id, data)
end
end)
jua.on("socket_closed", function(event, id)
if id and callbackRegistry[id] and callbackRegistry[id].closed then
callbackRegistry[id].closed(id)
end
table.remove(callbackRegistry, id)
end)
end
end
return {
open = open,
init = init
}