local M = {} local modem = peripheral.wrap("back") local SERVER_CHANNEL = 43 local function sendRequestAndWaitForReply(messageTable, replyHandler, timeout) timeout = timeout or 5 local replyChannel = math.random(1000, 9999) modem.open(replyChannel) messageTable.replyChannel = replyChannel local jsonMessage = textutils.serialiseJSON(messageTable) modem.transmit(SERVER_CHANNEL, replyChannel, jsonMessage) local startTime = os.clock() local replyReceived = false while os.clock() - startTime < timeout do local event, side, channel, receivedReplyChannel, message, distance = os.pullEvent("modem_message") if event == "modem_message" and channel == replyChannel then local success, parsedReply = pcall(textutils.unserialiseJSON, message) if success and type(parsedReply) == "table" then replyHandler(parsedReply) replyReceived = true break end end end modem.close(replyChannel) return replyReceived end function M.getCredit(username, callback) local message = { type = "getCredit", user = username } return sendRequestAndWaitForReply(message, function(reply) if reply.type == "creditResponse" and reply.user == username then callback(reply.credit) else callback(nil) end end) end function M.addTransaction(username, amount, vendor, vendor_account, callback, timeout) if type(amount) ~= "number" or amount <= 0 then error("Amount must be a positive number.", 2) end if type(username) ~= "string" or #username == 0 then error("Username must be a non-empty string.", 2) end if type(vendor) ~= "string" or #vendor == 0 then error("Vendor must be a non-empty string.", 2) end if type(vendor_account) ~= "string" or #vendor_account == 0 then error("Vendor account must be a non-empty string.", 2) end if type(callback) ~= "function" then error("Callback must be a function.", 2) end if timeout and (type(timeout) ~= "number" or timeout <= 0) then error("Timeout must be a positive number if provided.", 2) end local message = { type = "addTransaction", user = username, amount = amount, vendor = vendor, vendor_account = vendor_account } return sendRequestAndWaitForReply(message, function(reply) if reply.type == "transactionCompleted" and reply.transaction_id then if reply.status == "success" then callback(true, reply.newCredit) elseif reply.status == "failed" then callback(false, reply.reason) elseif reply.status == "cancelled" then callback(false, "cancelled") else callback(false, "unknown_status") end else callback(false, "unexpected_reply") end end, timeout) end return M