View difference between Paste ID: FithBYJi and CChWjRx6
SHOW: | | - or go back to the newest paste.
1
--[[-----------------------------------------------
2
|               KristWallet by 3d6                |
3
---------------------------------------------------
4
| This is the reference wallet for Krist.         |
5
| It is the basic definition of a functional      |
6
| Krist program, although it is not as old as the |
7
| network (we used to just use raw API calls).    |
8
---------------------------------------------------
9
 /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\  /\
10
/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/  \/
11
---------------------------------------------------
12
| Do whatever you want with this, but if you make |
13
| it interact with a currency or network other    |
14
| than Krist, please give me credit. Thanks <3    |
15
---------------------------------------------------
16
| This wallet will NEVER save passwords anywhere. |]]local
17
-----------------------------------------------]]--
18-
                   version = 14
18+
                   version = 16
19
local latest = 0
20
local balance = 0
21
local balance2 = 0
22
local balance3 = 0
23
local MOD = 2^32
24
local MODM = MOD-1
25
local gui = 0
26
local page = 0
27
local lastpage = 0
28
local scroll = 0
29
local masterkey = ""
30
local doublekey = ""
31
local address = ""
32
local addressv1 = ""
33
local addressdv = ""
34
local addresslv = ""
35
local subject = ""
36
local name = ""
37
local subbal = 0
38
local subtxs = ""
39
local stdate = {}
40
local stpeer = {}
41
local stval = {}
42
local blkpeer = {}
43
local pagespace = ""
44
local maxspace = ""
45
local ar = 0
46
local amt = 0
47
local availability = 0
48
local wallet, hud, update, settle, log, readconfig, checkdir, openwallet, makev2address
49
50
local function split(inputstr, sep)
51
        if sep == nil then
52
                sep = "%s"
53
        end
54
        local t={} ; i=1
55
        for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
56
                t[i] = str
57
                i = i + 1
58
        end
59
        return t
60
end
61
62
local function readURL(url)
63
  local resp = http.get(url)
64
  if not resp then
65
	log("Could not reach "..url)
66
    error("Error connecting to server")
67
	panic()
68
  end
69
  local content = resp.readAll():gsub("\n+$", "")
70
  resp.close()
71
  return content
72
end
73
74
local function boot()
75
  for i=1,2 do checkdir() end
76
  print("Starting KristWallet v"..tostring(version))
77
  log("Started KristWallet v"..tostring(version))
78
  update()
79
  if readconfig("enabled") and latest <= version then
80
    settle()
81
    openwallet()
82
    while page ~= 0 do
83
      wallet()
84
    end
85
    term.setBackgroundColor(32768)
86
    term.setTextColor(16)
87
    term.clear()
88
    term.setCursorPos(1,1)
89
    log("KristWallet closed safely")
90
  else
91
    if not readconfig("enabled") then print("KristWallet is disabled on this computer.") log("Disabled, shutting down") end
92
  end
93
  if readconfig("rebootonexit") then
94
    log("Rebooted computer")
95
    os.reboot()
96
  end
97
end
98
function update()
99
  latest = tonumber(readURL(readconfig("versionserver")))
100
  if latest > version then
101
    print("An update is available!")
102
    log("Discovered update")
103
    if readconfig("autoupdate") and not bench then
104
      local me = fs.open(fs.getName(shell.getRunningProgram()),"w")
105
      local nextversion = readURL(readconfig("updateserver"))
106
      print("Installed update. Run this program again to start v"..latest..".")
107
      me.write(nextversion)
108
      me.close()
109
      log("Installed update")
110
    else
111
      log("Ignored update")
112
      latest = -2
113
    end
114
  else
115
    log("No updates found")
116
  end
117
end
118
function log(text)
119
  local logfile = fs.open("kst/log_wallet","a")
120
  logfile.writeLine(tostring(os.day()).."-"..tostring(os.time()).."/"..text)
121
  logfile.close()
122
end
123
local function checkfile(path,default)
124
  if not fs.exists("kst/"..path) or path == "syncnode" then
125
    local file = fs.open("kst/"..path,"w")
126
    file.writeLine(default)
127
    file.close()
128
    log("Created file "..path)
129
    return false
130
  else
131
    return true
132
  end
133
end
134
function readconfig(path)
135
  if fs.exists("kst/"..path) then
136
    local file = fs.open("kst/"..path,"r")
137
    local context = file.readAll():gsub("\n+$", "")
138
    file.close()
139
    if context == "true" then return true end
140
    if context == "false" then return false end
141
    return context
142
  else
143
    print("An unknown error happened")
144
  end
145
end
146
function settle()
147
  if term.isColor() then gui = 1 end
148
  if term.isColor() and pocket then gui = 2 end
149
end
150
local function drawKrist()
151
  local posx, posy = term.getCursorPos()
152
  term.setBackgroundColor(1)
153
  term.setTextColor(32)
154
  term.write("/")
155
  term.setBackgroundColor(32)
156
  term.setTextColor(8192)
157
  term.write("\\")
158
  term.setCursorPos(posx,posy+1)
159
  term.setBackgroundColor(32)
160
  term.setTextColor(8192)
161
  term.write("\\")
162
  term.setBackgroundColor(8192)
163
  term.setTextColor(32)
164
  term.write("/")
165
  term.setCursorPos(posx+2,posy)
166
end
167
local function memoize(f)
168
  local mt = {}
169
  local t = setmetatable({}, mt)
170
  function mt:__index(k)
171
    local v = f(k)
172
    t[k] = v
173
    return v
174
  end
175
  return t
176
end
177
local function make_bitop_uncached(t, m)
178
  local function bitop(a, b)
179
    local res,p = 0,1
180
    while a ~= 0 and b ~= 0 do
181
      local am, bm = a % m, b % m
182
      res = res + t[am][bm] * p
183
      a = (a - am) / m
184
      b = (b - bm) / m
185
      p = p*m
186
    end
187
    res = res + (a + b) * p
188
    return res
189
  end
190
  return bitop
191
end
192
local function make_bitop(t)
193
  local op1 = make_bitop_uncached(t,2^1)
194
  local op2 = memoize(function(a) return memoize(function(b) return op1(a, b) end) end)
195
  return make_bitop_uncached(op2, 2 ^ (t.n or 1))
196
end
197
local bxor1 = make_bitop({[0] = {[0] = 0,[1] = 1}, [1] = {[0] = 1, [1] = 0}, n = 4})
198
local function bxor(a, b, c, ...)
199
  local z = nil
200
  if b then
201
    a = a % MOD
202
    b = b % MOD
203
    z = bxor1(a, b)
204
    if c then z = bxor(z, c, ...) end
205
    return z
206
  elseif a then return a % MOD
207
  else return 0 end
208
end
209
local function band(a, b, c, ...)
210
  local z
211
  if b then
212
    a = a % MOD
213
    b = b % MOD
214
    z = ((a + b) - bxor1(a,b)) / 2
215
    if c then z = bit32_band(z, c, ...) end
216
    return z
217
  elseif a then return a % MOD
218
  else return MODM end
219
end
220
local function bnot(x) return (-1 - x) % MOD end
221
local function rshift1(a, disp)
222
  if disp < 0 then return lshift(a,-disp) end
223
  return math.floor(a % 2 ^ 32 / 2 ^ disp)
224
end
225
local function rshift(x, disp)
226
  if disp > 31 or disp < -31 then return 0 end
227
  return rshift1(x % MOD, disp)
228
end
229
local function lshift(a, disp)
230
  if disp < 0 then return rshift(a,-disp) end
231
  return (a * 2 ^ disp) % 2 ^ 32
232
end
233
local function rrotate(x, disp)
234
  x = x % MOD
235
  disp = disp % 32
236
  local low = band(x, 2 ^ disp - 1)
237
  return rshift(x, disp) + lshift(low, 32 - disp)
238
end
239
local k = {
240
  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
241
  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
242
  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
243
  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
244
  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
245
  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
246
  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
247
  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
248
  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
249
  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
250
  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
251
  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
252
  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
253
  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
254
  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
255
  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
256
}
257
local function str2hexa(s)
258
  return (string.gsub(s, ".", function(c) return string.format("%02x", string.byte(c)) end))
259
end
260
local function num2s(l, n)
261
  local s = ""
262
  for i = 1, n do
263
    local rem = l % 256
264
    s = string.char(rem) .. s
265
    l = (l - rem) / 256
266
  end
267
  return s
268
end
269
local function s232num(s, i)
270
  local n = 0
271
  for i = i, i + 3 do n = n*256 + string.byte(s, i) end
272
  return n
273
end
274
local function preproc(msg, len)
275
  local extra = 64 - ((len + 9) % 64)
276
  len = num2s(8 * len, 8)
277
  msg = msg .. "\128" .. string.rep("\0", extra) .. len
278
  assert(#msg % 64 == 0)
279
  return msg
280
end
281
local function initH256(H)
282
  H[1] = 0x6a09e667
283
  H[2] = 0xbb67ae85
284
  H[3] = 0x3c6ef372
285
  H[4] = 0xa54ff53a
286
  H[5] = 0x510e527f
287
  H[6] = 0x9b05688c
288
  H[7] = 0x1f83d9ab
289
  H[8] = 0x5be0cd19
290
  return H
291
end
292
local function digestblock(msg, i, H)
293
  local w = {}
294
  for j = 1, 16 do w[j] = s232num(msg, i + (j - 1)*4) end
295
  for j = 17, 64 do
296
    local v = w[j - 15]
297
    local s0 = bxor(rrotate(v, 7), rrotate(v, 18), rshift(v, 3))
298
    v = w[j - 2]
299
    w[j] = w[j - 16] + s0 + w[j - 7] + bxor(rrotate(v, 17), rrotate(v, 19), rshift(v, 10))
300
  end
301
 
302
  local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]
303
  for i = 1, 64 do
304
    local s0 = bxor(rrotate(a, 2), rrotate(a, 13), rrotate(a, 22))
305
    local maj = bxor(band(a, b), band(a, c), band(b, c))
306
    local t2 = s0 + maj
307
    local s1 = bxor(rrotate(e, 6), rrotate(e, 11), rrotate(e, 25))
308
    local ch = bxor (band(e, f), band(bnot(e), g))
309
    local t1 = h + s1 + ch + k[i] + w[i]
310
    h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2
311
  end
312
 
313
  H[1] = band(H[1] + a)
314
  H[2] = band(H[2] + b)
315
  H[3] = band(H[3] + c)
316
  H[4] = band(H[4] + d)
317
  H[5] = band(H[5] + e)
318
  H[6] = band(H[6] + f)
319
  H[7] = band(H[7] + g)
320
  H[8] = band(H[8] + h)
321
end
322
local function sha256(msg)
323
  msg = preproc(msg, #msg)
324
  local H = initH256({})
325
  for i = 1, #msg, 64 do digestblock(msg, i, H) end
326
  return str2hexa(num2s(H[1], 4) .. num2s(H[2], 4) .. num2s(H[3], 4) .. num2s(H[4], 4) ..
327
          num2s(H[5], 4) .. num2s(H[6], 4) .. num2s(H[7], 4) .. num2s(H[8], 4))
328
end
329
local function panic()
330
  page = 0
331
  log("Panicking! Shutting down KristWallet.")
332
end
333
local function makeaddressbyte(j)
334
  if j <= 6 then return "0"
335
  elseif j <= 13 then return "1"
336
  elseif j <= 20 then return "2"
337
  elseif j <= 27 then return "3"
338
  elseif j <= 34 then return "4"
339
  elseif j <= 41 then return "5"
340
  elseif j <= 48 then return "6"
341
  elseif j <= 55 then return "7"
342
  elseif j <= 62 then return "8"
343
  elseif j <= 69 then return "9"
344
  elseif j <= 76 then return "a"
345
  elseif j <= 83 then return "b"
346
  elseif j <= 90 then return "c"
347
  elseif j <= 97 then return "d"
348
  elseif j <= 104 then return "e"
349
  elseif j <= 111 then return "f"
350
  elseif j <= 118 then return "g"
351
  elseif j <= 125 then return "h"
352
  elseif j <= 132 then return "i"
353
  elseif j <= 139 then return "j"
354
  elseif j <= 146 then return "k"
355
  elseif j <= 153 then return "l"
356
  elseif j <= 160 then return "m"
357
  elseif j <= 167 then return "n"
358
  elseif j <= 174 then return "o"
359
  elseif j <= 181 then return "p"
360
  elseif j <= 188 then return "q"
361
  elseif j <= 195 then return "r"
362
  elseif j <= 202 then return "s"
363
  elseif j <= 209 then return "t"
364
  elseif j <= 216 then return "u"
365
  elseif j <= 223 then return "v"
366
  elseif j <= 230 then return "w"
367
  elseif j <= 237 then return "x"
368
  elseif j <= 244 then return "y"
369
  elseif j <= 251 then return "z"
370
  else return "e"
371
  end
372
end
373
function checkdir()
374
  if fs.isDir("kst") then
375
    math.randomseed(os.time()) 
376
    checkfile("log_wallet","-----KRISTWALLET LOG FILE-----")
377
    checkfile("enabled","true") --Disabling this just makes KristWallet refuse to start.
378
    checkfile("sweepv1","true")
379
    checkfile("appendhashes","true") --Disabling this makes it possible to use KristWallet with extremely old addresses.
380
    checkfile("autoupdate","true")
381
    checkfile("whitelisted","false")
382
    checkfile("rebootonexit","false")
383
    checkfile("autologin","false")
384
    checkfile("keyAL",sha256(""))
385
    checkfile("keyLV",sha256(math.random(1000000)..os.time())) --This is where the local vault's krist is stored. DO NOT DESTROY!
386
    checkfile("versionserver","https://raw.githubusercontent.com/BTCTaras/kristwallet/master/staticapi/version")
387
    checkfile("updateserver","https://raw.githubusercontent.com/BTCTaras/kristwallet/master/kristwallet")
388-
    checkfile("syncnode","http://krist.ceriat.net/")
388+
    checkfile("syncnode","http://unequaled-metal-guanaco.glitch.me/")
389
    checkfile("whitelist","")
390
    checkfile("blacklist","")
391
  else
392
    fs.makeDir("kst")
393
  end
394
end
395
function openwallet()
396
  term.setBackgroundColor(8)
397
  term.clear()
398
  local krists = 0
399
  repeat
400
    term.setCursorPos(3+(3*krists),3)
401
    drawKrist()
402
    krists = krists + 1
403
  until krists == 16
404
  krists = 0
405
  repeat
406
    term.setCursorPos(3+(3*krists),16)
407
    drawKrist()
408
    krists = krists + 1
409
  until krists == 16
410
  term.setBackgroundColor(8)
411
  term.setTextColor(32768)
412
  term.setCursorPos(6,6)
413
  term.write("Password:")
414
  term.setCursorPos(6,8)
415
         -----|---+---------+---------+---------+-----|---+-
416
  term.write("Please enter your secret password to")
417
  term.setCursorPos(6,9)
418
  term.write("use Krist. If this is your first time")
419
  term.setCursorPos(6,10)
420
  term.write("using Krist, type your desired password.")
421
  term.setCursorPos(6,11)
422
  term.write("You will be able to access your Krist")
423
  term.setCursorPos(6,12)
424
  term.write("on any computer on any server as long")
425
  term.setCursorPos(6,13)
426
  term.write("as you type in the same password! It will")
427
  term.setCursorPos(6,14)
428
  term.write("not be saved or shared with anyone.")
429
  term.setCursorPos(16,6)
430
  local password = ""
431
  if readconfig("autologin") then
432
    password = readconfig("keyAL")
433
  else
434
    password = read("*")
435
	if password == "" then term.setCursorPos(16,6) password = read("*") end
436
    if readconfig("appendhashes") then password = sha256("KRISTWALLET"..password) end
437
  end
438
  term.clear()
439
  term.setCursorPos(1,1)
440
  page = 1+gui*(10*(gui-1))
441
  if readconfig("appendhashes") then masterkey = password.."-000" else masterkey = password end
442
  log("Read password")
443
  addressv1 = string.sub(sha256(masterkey),0,10)
444
  log("Derived address: "..addressv1)
445
  address = makev2address(masterkey)
446
  log("Derived address: "..address)
447
  balance = tonumber(readURL(readconfig("syncnode").."?getbalance="..addressv1))
448
  if balance > 0 and readconfig("sweepv1") then local transaction = readURL(readconfig("syncnode").."?pushtx&q="..address.."&pkey="..masterkey.."&amt="..balance); log("Swept hex address") end
449
  balance = tonumber(readURL(readconfig("syncnode").."?getbalance="..address))
450
	if balance >= 100000 then log("Woah! There's a small fortune here!") elseif balance > 0 then log("There is some krist here!") end
451
  if readconfig("whitelisted") then
452
    local whitelist = readconfig("whitelist")
453
    if string.find(whitelist, address) == nil then
454
      log(address.." is not on the whitelist!")
455
      print("Sorry, this wallet is not on the whitelist for this computer!")
456
      page = 0
457
      os.sleep(3)
458
    end
459
  else
460
    local blacklist = readconfig("blacklist")
461
    if string.find(blacklist, addressv1) ~= nil then
462
      log(addressv1.." is on the blacklist!")
463
      print("Your wallet is blocked from this computer!")
464
      page = 0
465
      os.sleep(3)
466
    elseif string.find(blacklist, address) ~= nil then
467
      log(address.." is on the blacklist!")
468
      print("Your wallet is blocked from this computer!")
469
      page = 0
470
      os.sleep(3)
471
    end
472
  end
473
  addresslv = makev2address(readconfig("keyLV"))
474
  log("Loaded local vault")
475
  os.sleep()
476
  http.post(readconfig("syncnode") .. "/login", "privatekey=" .. textutils.urlEncode(masterkey) .. "&v=2")
477
  log("Sent pkey hash to auth server")
478
end
479
function makev2address(key)
480
  local protein = {}
481
  local stick = sha256(sha256(key))
482
  local n = 0
483
  local link = 0
484
  local v2 = "k"
485
  repeat
486
    if n < 9 then protein[n] = string.sub(stick,0,2)
487
    stick = sha256(sha256(stick)) end
488
    n = n + 1
489
  until n == 9
490
  n = 0
491
  repeat
492
    link = tonumber(string.sub(stick,1+(2*n),2+(2*n)),16) % 9
493
    if string.len(protein[link]) ~= 0 then
494
      v2 = v2 .. makeaddressbyte(tonumber(protein[link],16))
495
      protein[link] = ''
496
      n = n + 1
497
    else
498
      stick = sha256(stick)
499
    end
500
  until n == 9
501
  return v2
502
end
503
local function postgraphic(px,py,id)
504
  term.setCursorPos(px,py)
505
  if id == 0 then drawKrist()
506
  elseif id == 1 then
507
    --Mined Krist
508
    term.setCursorPos(px+1,py)
509
    term.setBackgroundColor(256)
510
    term.setTextColor(128)
511
    term.write("/T\\")
512
    term.setCursorPos(px,py+1)
513
    term.write("/")
514
    term.setCursorPos(px+2,py+1)
515
    term.write("|")
516
    term.setCursorPos(px+4,py+1)
517
    term.write("\\")
518
    term.setCursorPos(px+2,py+2)
519
    term.write("|")
520
    term.setCursorPos(px+2,py+3)
521
    term.write("|")
522
    term.setCursorPos(px+4,py+2)
523
    drawKrist()
524
  elseif id == 2 then
525
    --Sent Krist
526
    term.setCursorPos(px,py+2)
527
    term.setBackgroundColor(256)
528
    term.setTextColor(16384)
529
    term.write(" ")
530
    term.setCursorPos(px+1,py+3)
531
    term.write("    ")
532
    term.setCursorPos(px+5,py+2)
533
    term.write(" ")
534
    term.setBackgroundColor(1)
535
    term.setCursorPos(px+2,py)
536
    term.write("/\\")
537
    term.setCursorPos(px+2,py+1)
538
    term.write("||")
539
  elseif id == 3 then
540
    --Received Krist
541
    term.setCursorPos(px,py+2)
542
    term.setBackgroundColor(256)
543
    term.setTextColor(8192)
544
    term.write(" ")
545
    term.setCursorPos(px+1,py+3)
546
    term.write("    ")
547
    term.setCursorPos(px+5,py+2)
548
    term.write(" ")
549
    term.setBackgroundColor(1)
550
    term.setCursorPos(px+2,py)
551
    term.write("||")
552
    term.setCursorPos(px+2,py+1)
553
    term.write("\\/")
554
  elseif id == 4 then
555
    --Sent to yourself
556
    term.setCursorPos(px,py+2)
557
    term.setBackgroundColor(256)
558
    term.setTextColor(16)
559
    term.write(" ")
560
    term.setCursorPos(px+1,py+3)
561
    term.write("    ")
562
    term.setCursorPos(px+5,py+2)
563
    term.write(" ")
564
    term.setBackgroundColor(1)
565
    term.setCursorPos(px+1,py)
566
    term.write("/\\||")
567
    term.setCursorPos(px+1,py+1)
568
    term.write("||\\/")
569
  elseif id == 5 then
570
    --Swept from v1 address
571
    term.setCursorPos(px+1,py)
572
    term.setBackgroundColor(256)
573
    term.setTextColor(128)
574
    term.write(" v1 ")
575
    term.setCursorPos(px+2,py+1)
576
    term.setBackgroundColor(1)
577
    term.setTextColor(2048)
578
    term.write("||")
579
    term.setCursorPos(px+2,py+2)
580
    term.write("\\/")
581
    term.setCursorPos(px+1,py+3)
582
    term.setBackgroundColor(16)
583
    term.setTextColor(32768)
584
    term.write(" v2 ")
585
  elseif id == 6 then
586
    --Name registered
587
    term.setBackgroundColor(32)
588
    term.setTextColor(8192)
589
    term.setCursorPos(px+4,py)
590
    term.write("/")
591
    term.setCursorPos(px+1,py+1)
592
    term.write("\\")
593
    term.setCursorPos(px+3,py+1)
594
    term.write("/")
595
    term.setCursorPos(px+2,py+2)
596
    term.write("V")
597
    term.setCursorPos(px+1,py+3)
598
    term.setBackgroundColor(16384)
599
    term.setTextColor(4)
600
    term.write(".kst")
601
  elseif id == 7 then
602
    --Name operation
603
    term.setBackgroundColor(8)
604
    term.setTextColor(512)
605
    term.setCursorPos(px+1,py)
606
    term.write(" a ")
607
    term.setBackgroundColor(1)
608
    term.write("\\")
609
    term.setBackgroundColor(8)
610
    term.setCursorPos(px+1,py+1)
611
    term.write("====")
612
    term.setCursorPos(px+1,py+2)
613
    term.write("====")
614
    term.setCursorPos(px+1,py+3)
615
    term.setBackgroundColor(16384)
616
    term.setTextColor(4)
617
    term.write(".kst")
618
  elseif id == 8 then
619
    --Name sent
620
    term.setCursorPos(px+1,py+3)
621
    term.setBackgroundColor(16384)
622
    term.setTextColor(4)
623
    term.write(".kst")
624
    term.setTextColor(16384)
625
    term.setBackgroundColor(1)
626
    term.setCursorPos(px+2,py)
627
    term.write("/\\")
628
    term.setCursorPos(px+2,py+1)
629
    term.write("||")
630
  elseif id == 9 then
631
    --Name received
632
    term.setCursorPos(px+1,py+3)
633
    term.setBackgroundColor(16384)
634
    term.setTextColor(4)
635
    term.write(".kst")
636
    term.setTextColor(8192)
637
    term.setBackgroundColor(1)
638
    term.setCursorPos(px+1,py)
639
    term.write("||")
640
    term.setCursorPos(px+1,py+1)
641
    term.write("\\/")
642
    term.setTextColor(16384)
643
    term.setCursorPos(px+3,py)
644
    term.write("/\\")
645
    term.setCursorPos(px+3,py+1)
646
    term.write("||")
647
  end
648
end
649
function wallet()
650
  hud()
651
  local pagebefore = page
652
  local event, button, xPos, yPos = os.pullEvent("mouse_click")
653
  if gui == 1 and xPos >= 3 and xPos <= 14 then
654
    if yPos == 5 then
655
      page = 1
656
      balance = tonumber(readURL(readconfig("syncnode").."?getbalance="..address))
657
    end
658
    if yPos == 7 then
659
      page = 2
660
      subject = address
661
      scroll = 0
662
    end
663
    if yPos == 9 then
664
      page = 3
665
      balance = tonumber(readURL(readconfig("syncnode").."?getbalance="..address))
666
    end
667
    if yPos == 11 then
668
      page = 8
669
    end
670
    if yPos == 13 then
671
      page = 4
672
    end
673
    if yPos == 15 then
674
      page = 15
675
    end
676
    if yPos == 17 then
677
      page = 0
678
    end
679
  elseif gui == 2 then
680
    if yPos == 2 and xPos >= 19 and xPos <= 24 then
681
      page = 0
682
    end
683
  end
684
  local lexm = http.get(readconfig("syncnode").."?listnames="..address)
685
  local lem = false
686
  local lexmm
687
  if lexm.readAll then
688
	lem = true
689
	lexmm = lexm.readAll():gsub("\n+$", "")
690
  end
691
	
692
  if page == 1 then
693
    balance = tonumber(readURL(readconfig("syncnode").."?getbalance="..address))
694
    if (yPos-7)%5 == 0 and yPos >= 7 and xPos >= 26 and xPos <= 35 then
695
      subject = string.sub(readURL(readconfig("syncnode").."?listtx="..address.."&overview"),13+(31*((yPos-7)/5)),22+(31*((yPos-7)/5)))
696
      if string.len(subject) == 10 and subject ~= "N/A(Mined)" and subject ~= "N/A(Names)" then
697
        page = 2
698
      end
699
    end
700
  elseif page == 2 then
701
    if yPos > 2 and yPos <= 2+ar-(16*(scroll)) and xPos >= 31 and xPos < 41 then
702
      if stpeer[(yPos-2)+(16*(scroll))] == "N/A(Mined)" then
703
        --possibly link to a block later?
704
      elseif stpeer[(yPos-2)+(16*(scroll))] == "N/A(Names)" then
705
        --possibly link to a name later??
706
      else
707
        subject = stpeer[(yPos-2)+(16*(scroll))]
708
        scroll = 0
709
      end
710
    end
711
    if yPos == 19 and xPos >= 32 and xPos <= 36 then
712
      scroll = 0
713
    end
714
    if yPos == 19 and xPos >= 38 and xPos <= 41 then
715
      scroll = math.max(0,scroll-1)
716
    end
717
    if yPos == 19 and xPos >= 43 and xPos <= 46 then
718
      scroll = math.min(lastpage,scroll+1)
719
    end
720
    if yPos == 19 and xPos >= 48 then
721
      scroll = lastpage
722
    end
723
    if yPos == 1 and xPos >= 17 then
724
      page = 6
725
    end
726
    log("Page index is "..scroll)
727
  elseif page == 3 then
728
    if xPos >= 17 then
729
      term.setCursorPos(33,5)
730
      local recipient = read()
731
      term.setCursorPos(33,6)
732
      log("Read recipient for transfer")
733
      local amount = read()
734
      log("Read amount for transfer")
735
      local transaction = readURL(readconfig("syncnode").."?pushtx2&q="..recipient.."&pkey="..masterkey.."&amt="..amount)
736
      balance = tonumber(readURL(readconfig("syncnode").."?getbalance="..address))
737
      log("Attempting to send "..amount.." KST to "..recipient)
738
      term.setCursorPos(19,8)
739
      if transaction == "Success" then
740
        term.setTextColor(8192)
741
        term.write("Transfer successful")
742
        log("Transfer successful")
743
        term.setTextColor(32768)
744
      elseif string.sub(transaction,0,5) == "Error" then
745
        local problem = "An unknown error happened"
746
        local code = tonumber(string.sub(transaction,6,10))
747
        if code == 1 then problem = "Insufficient funds available" end
748
        if code == 2 then problem = "Not enough KST in transaction" end
749
        if code == 3 then problem = "Can't comprehend amount to send" end
750
        if code == 4 then problem = "Invalid recipient address" end
751
        term.setTextColor(16384)
752
        term.write(problem)
753
        log(problem)
754
        term.setTextColor(32768)
755
      else
756
        term.setTextColor(16384)
757
        term.write(transaction)
758
        term.setTextColor(32768)
759
      end
760
      os.sleep(2.5) --lower this if you do tons of transfers
761
      log("Unfroze display")
762
    end
763
  elseif page == 4 then
764
    if yPos == 3 and xPos >= 19 and xPos <= 31 then
765
      page = 5
766
      scroll = 0
767
    end
768
    if yPos == 4 and xPos >= 19 and xPos <= 31 then
769
      page = 10
770
    end
771
    if yPos == 3 and xPos >= 35 and xPos <= 48 then
772
      page = 6
773
    end
774
    if yPos == 4 and xPos >= 35 and xPos <= 46 then
775
      page = 7
776
    end
777
  elseif page == 5 then
778
    if yPos > 2 and xPos >= 27 and xPos <= 36 then
779
      page = 2
780
      subject = blkpeer[(yPos-2)]
781
      scroll = 0
782
    end
783
  elseif page == 6 then
784
    term.setCursorPos(18,1)
785
    term.write("                       ")
786
    term.setCursorPos(18,1)
787
    term.write("ADDRESS ")
788
    subject = read()
789
    if string.len(subject) == 10 then
790
      page = 2
791
      scroll = 0
792
    else
793
      page = 6
794
    end
795
  elseif page == 7 then
796
    if yPos > 2 and yPos <= 18 and xPos >= 20 and xPos < 30 then
797
      if blkpeer[(yPos-2)] ~= "N/A(Burnt)" then
798
        page = 2
799
        subject = blkpeer[(yPos-2)]
800
        scroll = 0
801
      end
802
    end
803
  elseif page == 15 then
804
	
805
	local function isEdit(xpo)
806
		return xpo >= 39 and xpo <= 42
807
	end
808
	local function isSend(xpo)
809
		return xpo >= 44 and xpo <= 47
810
	end
811
	
812
	if xPos and yPos then
813
		local listofnames = split(lexmm, ";")
814
		if yPos == 1 and xPos >= 46 then
815
			page = 16
816
		elseif lem and yPos >= 3 and isEdit(xPos) then
817
			if listofnames[yPos - 3] then
818
				page = 17
819
				local nameclicked = yPos - 3
820
				subject = listofnames[nameclicked]
821
			end
822
		elseif lem and yPos >= 3 and isSend(xPos) then
823
			if listofnames[yPos - 3] then
824
				page = 18
825
				local nameclicked = yPos - 3
826
				subject = listofnames[nameclicked]
827
			end
828
		end
829
	end
830
  elseif page == 8 then
831
    if yPos == 3 and xPos >= 19 and xPos <= 30 then
832
      page = 9
833
    end
834
    if yPos == 3 and xPos >= 35 and xPos <= 47 then
835
      page = 16
836
    end
837
    if yPos == 4 and xPos >= 35 and xPos <= 47 then
838
      --page = 18
839
    end
840
    if yPos == 4 and xPos >= 19 and xPos <= 29 then
841
      page = 13
842
    end
843
  elseif page == 18 then
844
		if yPos == 5 and xPos >= 30 then
845
      term.setCursorPos(30,5)
846
      term.write("                           ")
847
      term.setCursorPos(30,5)
848
      maxspace = read():lower()
849
      term.setCursorPos(19,7)
850
      pagespace = readURL(readconfig("syncnode").."?name_transfer&pkey="..masterkey.."&name="..subject.."&q="..maxspace)
851
			if pagespace == "Success" then
852
			end
853
				term.write("Name transferred")
854
				log("Tried sending a name to "..maxspace)
855
				os.sleep(3)
856
				page = 15
857
		end
858
  elseif page == 16 then
859
    if yPos == 4 and xPos >= 25 then
860
      term.setCursorPos(25,4)
861
      term.write("                           ")
862
      term.setCursorPos(25,4)
863
      name = read():lower():gsub(".kst",""):gsub(" ","")
864
      term.setCursorPos(25,4)
865
      term.write("Please wait...             ")
866
      if string.len(name) > 0 then
867
        if name == "a" or name == "name" or name == "id" or name == "owner" or name == "registered" or name == "updated" or name == "expires" or name == "unpaid" then
868
          availability = 0
869
        else
870
          availability = tonumber(readURL(readconfig("syncnode").."?name_check="..name))
871
          log("Checked "..name..".kst for availability ("..availability..")")
872
          term.setCursorPos(19,7)
873
          if availability then
874
            term.setTextColor(colors.green)
875
            term.write("Available!")
876
          else
877
            term.setTextColor(colors.red)
878
            term.write("Not available!")
879
          end
880
        end
881
      else
882
        name = ""
883
      end
884
    elseif yPos == 7 and xPos >= 30 and xPos <= 39 and availability == 1 and balance >= 500 then
885
      availability = 2
886
      local k = readURL(readconfig("syncnode").."?name_new&pkey="..masterkey.."&name="..name)
887
    end
888
  elseif page == 17 then
889
    if yPos == 5 and xPos >= 25 then
890
      term.setCursorPos(25,5)
891
      term.write("                           ")
892
      term.setCursorPos(25,5)
893
      zone = read():gsub("http://","")
894
      term.setCursorPos(25,5)
895
      term.write("Please wait...             ")
896
      local sevenminutesleftuntilmaystartsfuckihavetoreleasethisnow = readURL(readconfig("syncnode").."?name_update&pkey="..masterkey.."&name="..subject.."&ar="..zone)
897
    elseif yPos == 7 and xPos >= 30 and xPos <= 39 and availability == 1 and balance >= 500 then
898
      availability = 2
899
      local k = readURL(readconfig("syncnode").."?name_new&pkey="..masterkey.."&name="..name)
900
    end
901
  elseif page == 9 then
902
    if yPos == 4 and xPos >= 30 then
903
      term.setCursorPos(30,4)
904
      term.write("                      ")
905
      term.setCursorPos(30,4)
906
      doublekey = read("*")
907
      term.setCursorPos(30,4)
908
      term.write("Please wait...        ")
909
      if string.len(doublekey) > 0 then
910
        doublekey = sha256(masterkey.."-"..sha256(doublekey))
911
        addressdv = makev2address(doublekey)
912
        balance2 = tonumber(readURL(readconfig("syncnode").."?getbalance="..addressdv))
913
        log("Derived double vault "..addressdv)
914
      else
915
        addressdv = ""
916
        balance2 = 0
917
      end
918
    end
919
    if yPos == 5 and xPos >= 33 then
920
      term.setCursorPos(33,5)
921
      term.write("                      ")
922
      term.setCursorPos(33,5)
923
      amt = read()
924
      if tonumber(amt) == nil then
925
        amt = 0
926
      elseif tonumber(amt) % 1 ~= 0 then
927
        amt = 0
928
      elseif tonumber(amt) <= 0 then
929
        amt = 0
930
      end
931
    end
932
    if yPos == 6 and xPos >= 25 and xPos <= 33 then
933
      if tonumber(amt) > 0 and string.len(doublekey) > 0 then
934
        if tonumber(amt) <= balance then
935
          local transaction = readURL(readconfig("syncnode").."?pushtx2&q="..addressdv.."&pkey="..masterkey.."&amt="..tonumber(amt))
936
          balance = tonumber(readURL(readconfig("syncnode").."?getbalance="..address))
937
          balance2 = tonumber(readURL(readconfig("syncnode").."?getbalance="..addressdv))
938
          log("Put "..amt.." KST in a double vault")
939
        end
940
      end
941
    end
942
    if yPos == 6 and xPos >= 35 and xPos <= 44 then
943
      if tonumber(amt) > 0 and string.len(doublekey) > 0 then
944
        if tonumber(amt) <= balance2 then
945
          local transaction = readURL(readconfig("syncnode").."?pushtx2&q="..address.."&pkey="..doublekey.."&amt="..tonumber(amt))
946
          balance = tonumber(readURL(readconfig("syncnode").."?getbalance="..address))
947
          balance2 = tonumber(readURL(readconfig("syncnode").."?getbalance="..addressdv))
948
          log("Took "..amt.." KST from a double vault")
949
        end
950
      end
951
    end
952
  elseif page == 13 then
953
    if yPos == 5 and xPos >= 33 then
954
      term.setCursorPos(33,5)
955
      term.write("                      ")
956
      term.setCursorPos(33,5)
957
      term.setTextColor(32768)
958
      amt = read()
959
      if tonumber(amt) == nil then
960
        amt = 0
961
      elseif tonumber(amt) % 1 ~= 0 then
962
        amt = 0
963
      elseif tonumber(amt) <= 0 then
964
        amt = 0
965
      end
966
    end
967
    if yPos == 6 and xPos >= 25 and xPos <= 33 then
968
      if tonumber(amt) > 0 then
969
        if tonumber(amt) <= balance then
970
          local transaction = readURL(readconfig("syncnode").."?pushtx2&q="..addresslv.."&pkey="..masterkey.."&amt="..tonumber(amt))
971
          balance = tonumber(readURL(readconfig("syncnode").."?getbalance="..address))
972
          log("Put "..amt.." KST in a local vault")
973
        end
974
      end
975
    end
976
    if yPos == 6 and xPos >= 35 and xPos <= 44 then
977
      if tonumber(amt) > 0 then
978
        if tonumber(amt) <= balance3 then
979
          local transaction = readURL(readconfig("syncnode").."?pushtx2&q="..address.."&pkey="..readconfig("keyLV").."&amt="..tonumber(amt))
980
          balance = tonumber(readURL(readconfig("syncnode").."?getbalance="..address))
981
          log("Took "..amt.." KST from a local vault")
982
        end
983
      end
984
    end
985
  end
986
  if pagebefore ~= page then log("Switched to page "..page) end
987
end
988
local function drawTab(text)
989
  term.setBackgroundColor(512)
990
  term.write(text)
991
end
992
local function drawBtn(text)
993
  term.setBackgroundColor(32)
994
  term.write(text)
995
end
996
function hud()
997
  term.setBackgroundColor(1)
998
  term.setTextColor(32768)
999
  term.clear()
1000
  if gui == 1 then
1001
    local sidebar = 1
1002
    while sidebar < 51 do
1003
      term.setCursorPos(1,sidebar)
1004
      term.setBackgroundColor(8)
1005
      term.write("                ")
1006
      sidebar = sidebar + 1
1007
    end
1008
    term.setCursorPos(2,2)
1009
    drawKrist()
1010
    term.setBackgroundColor(8)
1011
    term.setTextColor(32768)
1012
    term.write(" KristWallet")
1013
    term.setCursorPos(5,3)
1014
    term.setTextColor(2048)
1015
    term.write("release "..version.."")
1016
    term.setCursorPos(2,19)
1017
    term.write("    by 3d6")
1018
    term.setTextColor(32768)
1019
    term.setCursorPos(3,5)
1020
    drawTab("  Overview  ")
1021
    term.setCursorPos(3,7)
1022
    drawTab("Transactions")
1023
    term.setCursorPos(3,9)
1024
    drawTab(" Send Krist ")
1025
    term.setCursorPos(3,11)
1026
    drawTab(" Special TX ")
1027
    term.setCursorPos(3,13)
1028
    drawTab(" Economicon ")
1029
    term.setCursorPos(3,15)
1030
    drawTab("Name Manager")
1031
    term.setCursorPos(3,17)
1032
    drawTab("    Exit    ")
1033
    term.setBackgroundColor(1)
1034
  elseif gui == 2 then
1035
    term.setCursorPos(1,1)
1036
    term.setBackgroundColor(8)
1037
    term.write("                          ")
1038
    term.setCursorPos(1,2)
1039
    term.write("                          ")
1040
    term.setCursorPos(1,3)
1041
    term.write("                          ")
1042
    term.setCursorPos(1,4)
1043
    term.write("                          ")
1044
    term.setCursorPos(2,2)
1045
    drawKrist()
1046
    term.setBackgroundColor(8)
1047
    term.setTextColor(32768)
1048
    term.write(" KristWallet")
1049
    term.setCursorPos(5,3)
1050
    term.setTextColor(2048)
1051
    term.write("release "..version.."")
1052
    term.setCursorPos(19,2)
1053
    term.setBackgroundColor(16384)
1054
    term.setTextColor(32768)
1055
    term.write(" Exit ")
1056
  end
1057
  if page == 1 then
1058
    term.setCursorPos(19,2)
1059
    term.write("Your address: ")
1060
    term.setTextColor(16384)
1061
    term.write(address)
1062
    term.setTextColor(32768)
1063
    term.setCursorPos(19,5)
1064
    local recenttransactions = ""
1065
    if tostring(balance) ~= 'nil' then recenttransactions = readURL(readconfig("syncnode").."?listtx="..address.."&overview") end
1066
    local txtype = 0
1067
    local graphics = 0
1068
    if string.len(recenttransactions) > 25 then
1069
      repeat
1070
        if string.sub(recenttransactions,13+(31*graphics),22+(31*graphics)) == "N/A(Mined)" then txtype = 1
1071
        elseif string.sub(recenttransactions,13+(31*graphics),22+(31*graphics)) == "N/A(Names)" and tonumber(string.sub(recenttransactions,23+(31*graphics),31+(31*graphics))) == 0 then txtype = 7
1072
        elseif tonumber(string.sub(recenttransactions,23+(31*graphics),31+(31*graphics))) == 0 then txtype = 9
1073
        elseif string.sub(recenttransactions,13+(31*graphics),22+(31*graphics)) == "N/A(Names)" then txtype = 6
1074
        elseif string.sub(recenttransactions,13+(31*graphics),22+(31*graphics)) == address then txtype = 4
1075
        elseif string.sub(recenttransactions,13+(31*graphics),22+(31*graphics)) == addressv1 then txtype = 5
1076
        elseif tonumber(string.sub(recenttransactions,23+(31*graphics),31+(31*graphics))) < 0 then txtype = 2
1077
        elseif tonumber(string.sub(recenttransactions,23+(31*graphics),31+(31*graphics))) > 0 then txtype = 3
1078
		else txtype = 8
1079
        end
1080
        postgraphic(19,5+(5*graphics),txtype)
1081
        term.setCursorPos(26,5+(5*graphics))
1082
        term.setBackgroundColor(1)
1083
        term.setTextColor(32768)
1084
        if txtype == 1 then term.write("Mined")
1085
        elseif txtype == 2 then term.write("Sent")
1086
        elseif txtype == 3 then term.write("Received")
1087
        elseif txtype == 4 then term.write("Sent to yourself")
1088
        elseif txtype == 5 then term.write("Imported")
1089
        elseif txtype == 6 then term.write("Name registered")
1090
        elseif txtype == 7 then term.write("Name operation")
1091
        elseif txtype == 8 then term.write("Unknown")
1092
        elseif txtype == 9 then term.write("Name transfer")
1093
        end
1094
        term.setCursorPos(26,6+(5*graphics))
1095
        if txtype == 4 then
1096
          term.setTextColor(32768)
1097
        elseif tonumber(string.sub(recenttransactions,23+(31*graphics),31+(31*graphics))) > 0 then
1098
          term.setTextColor(8192)
1099
          term.write("+")
1100
        elseif tonumber(string.sub(recenttransactions,23+(31*graphics),31+(31*graphics))) == 0 then
1101
          term.setTextColor(16)
1102
        else
1103
          term.setTextColor(16384)
1104
        end
1105
        if txtype < 7 then term.write(tostring(tonumber(string.sub(recenttransactions,23+(31*graphics),31+(31*graphics)))).." KST") end
1106
        term.setCursorPos(26,7+(5*graphics))
1107
        term.setTextColor(32768)
1108
        if txtype ~= 6 then term.setTextColor(512) end
1109
        if txtype == 9 or (txtype > 1 and txtype < 6) then term.write(string.sub(recenttransactions,13+(31*graphics),22+(31*graphics))) end
1110
        --if txtype == 6 then term.write(".kst") end
1111
        term.setCursorPos(26,8+(5*graphics))
1112
        term.setTextColor(128)
1113
        term.write(string.sub(recenttransactions,1+(31*graphics),12+(31*graphics)))
1114
        graphics = graphics + 1
1115
      until graphics >= math.floor(string.len(recenttransactions)/32)
1116
    end
1117
    term.setTextColor(32768)
1118
    term.setCursorPos(19,3)
1119
    term.write("Your balance: ")
1120
    term.setTextColor(1024)
1121
    if tostring(balance) == 'nil' then balance = 0 end
1122
    term.write(tostring(balance).." KST ")
1123-
    if address == "ke3kjplzsz" or address == "767fc628a4" or address == "e3b0c44298" then
1123+
1124
    local names = tonumber(readURL(readconfig("syncnode").."?getnames="..address))
1125
    if names > 0 then term.write("["..tostring(names).."]") end
1126
    local alert = http.get(readconfig("syncnode").."?alert="..masterkey).readAll()
1127
    if #(alert:gsub("^%s*(.-)%s*$", "%1")) > 0 then
1128-
      term.write("You are currently using a blank string password.")
1128+
1129
      term.setBackgroundColor(16384)
1130
      term.setTextColor(16)
1131
      term.clearLine()
1132
      term.write(alert)
1133
    end
1134
  elseif page == 2 then
1135
    term.setCursorPos(18,1)
1136
    term.write("Please wait...")
1137
    os.sleep(0)
1138
    subbal = readURL(readconfig("syncnode").."?getbalance="..subject)
1139
    subtxs = readURL(readconfig("syncnode").."?listtx="..subject)
1140
    log("Loaded transactions for address "..subject)
1141
    log("Page index is "..scroll)
1142
    term.setCursorPos(18,1)
1143
    if subtxs == "end" then subbal = 0 end
1144
    term.write("ADDRESS "..subject.." - "..subbal.." KST")
1145
    term.setCursorPos(17,2)
1146
    term.setBackgroundColor(256)
1147
    term.write(" Time         Peer           Value ")
1148
    term.setBackgroundColor(1)
1149
    if subtxs ~= "end" then
1150
      local tx = 0
1151
      local s = 0
1152
      ar = 16*scroll
1153
      repeat
1154
        tx = tx + 1
1155
        stdate[tx] = string.sub(subtxs,1,12)
1156
        subtxs = string.sub(subtxs,13)
1157
        stpeer[tx] = string.sub(subtxs,1,10)
1158
        subtxs = string.sub(subtxs,11)
1159
        stval[tx] = tonumber(string.sub(subtxs,1,9))
1160
        subtxs = string.sub(subtxs,10)
1161
        if stpeer[tx] == subject then stval[tx] = 0 end
1162
      until string.len(subtxs) == 3
1163
      repeat
1164
        ar = ar + 1
1165
        term.setTextColor(32768)
1166
        term.setCursorPos(18,2+ar-(16*(scroll)))
1167
        term.write(stdate[ar])
1168
        if stpeer[ar] ~= "N/A(Mined)" then term.setTextColor(512) end
1169
        if stpeer[ar] == subject then term.setTextColor(32768) end
1170
        if stpeer[ar] == "N/A(Names)" then term.setTextColor(32768) end
1171
        term.setCursorPos(31,2+ar-(16*(scroll)))
1172
        term.write(stpeer[ar])
1173
        term.setCursorPos(50-string.len(tostring(math.abs(stval[ar]))),2+ar-(16*(scroll)))
1174
        if stval[ar] > 0 then
1175
          term.setTextColor(8192)
1176
          term.write("+")
1177
        elseif stval[ar] < 0 then
1178
          term.setTextColor(16384)
1179
        else
1180
          term.setTextColor(32768)
1181
          term.write(" ")
1182
        end
1183
        term.write(tostring(stval[ar]))
1184
      until ar == math.min(tx,16*(scroll+1))
1185
      term.setBackgroundColor(256)
1186
      term.setCursorPos(17,19)
1187
      term.write("                                   ")
1188
      term.setCursorPos(17,19)
1189
      term.setTextColor(32768)
1190
      lastpage = math.floor((tx-1)/16)
1191
      if (1+lastpage) < 100 then maxspace = maxspace.." " end
1192
      if (1+lastpage) < 10 then maxspace = maxspace.." " end
1193
      if (1+scroll) < 100 then pagespace = pagespace.." " end
1194
      if (1+scroll) < 10 then pagespace = pagespace.." " end
1195
      term.write(" Page "..pagespace..(1+scroll).."/"..maxspace..(1+lastpage))
1196
      pagespace = ""
1197
      maxspace = ""
1198
      term.setCursorPos(32,19)
1199
      term.setTextColor(128)
1200
      term.write("First Prev Next Last")
1201
      if (scroll > 0) then
1202
        term.setCursorPos(32,19)
1203
        term.setTextColor(2048)
1204
        term.write("First Prev")
1205
      end
1206
      if (scroll < lastpage and tx > 16) then
1207
        term.setCursorPos(43,19)
1208
        term.setTextColor(2048)
1209
        term.write("Next Last")
1210
      end
1211
    else
1212
      term.write("No transactions to display!")
1213
      term.setBackgroundColor(256)
1214
      term.setCursorPos(17,19)
1215
      term.write("                                   ")
1216
      term.setCursorPos(17,19)
1217
      term.setTextColor(32768)
1218
      term.write(" Page   1/  1")
1219
      term.setCursorPos(32,19)
1220
      term.setTextColor(128)
1221
      term.write("First Prev Next Last")
1222
    end
1223
  elseif page == 3 then
1224
    term.setCursorPos(19,2)
1225
    term.write("Your address: ")
1226
    term.setTextColor(16384)
1227
    term.write(address)
1228
    term.setTextColor(32768)
1229
    term.setCursorPos(19,3)
1230
    term.write("Your balance: ")
1231
    term.setTextColor(1024)
1232
    if tostring(balance) == 'nil' then balance = 0 end
1233
    term.write(tostring(balance).." KST")
1234
    term.setTextColor(32768)
1235
    term.setCursorPos(19,5)
1236
    term.write("Recipient:    ")
1237
    term.write("                   ")
1238
    term.setCursorPos(19,6)
1239
    term.write("Amount (KST): ")
1240
    term.write("                   ")
1241
  elseif page == 4 then
1242
    term.setCursorPos(19,2)
1243
    term.write("Mining          Addresses")
1244
    term.setTextColor(512)
1245
    term.setCursorPos(19,3)
1246
    term.write("Latest blocks   Address lookup")
1247
    term.setCursorPos(19,4)
1248
    term.write("Lowest hashes   Top balances")
1249
    term.setCursorPos(19,5)
1250
    --term.write("Lowest nonces   ")
1251
    term.setTextColor(32768)
1252
    term.setCursorPos(19,7)
1253
    --term.write("Economy         Transactions")
1254
    term.setTextColor(512)
1255
    term.setCursorPos(19,8)
1256
    --term.write("KST issuance    Latest transfers")
1257
    term.setCursorPos(19,9)
1258
    --term.write("KST distrib.    Largest transfers")
1259
  elseif page == 5 then
1260
    local blocks = readURL(readconfig("syncnode").."?blocks")
1261
    local tx = 0
1262
    ar = 0
1263
    local height = string.sub(blocks,1,8)
1264
    local blktime = {}
1265
    blkpeer = {}
1266
    local blkhash = {}
1267
    height = tonumber(string.sub(blocks,1,8))
1268
    blocks = string.sub(blocks,9)
1269
    local today = string.sub(blocks,1,10)
1270
    blocks = string.sub(blocks,11)
1271
    repeat
1272
      tx = tx + 1
1273
      blktime[tx] = string.sub(blocks,1,8)
1274
      blocks = string.sub(blocks,9)
1275
      blkpeer[tx] = string.sub(blocks,1,10)
1276
      blocks = string.sub(blocks,11)
1277
      blkhash[tx] = string.sub(blocks,1,12)
1278
      blocks = string.sub(blocks,13)
1279
      if stpeer[tx] == subject then stval[tx] = 0 end
1280
    until string.len(blocks) == 0
1281
    term.setCursorPos(18,1)
1282
    term.write("Height: "..tostring(height))
1283
    term.setCursorPos(36,1)
1284
    term.write("Date: "..today)
1285
    term.setCursorPos(17,2)
1286
    term.setBackgroundColor(256)
1287
    term.write(" Time     Miner      Hash          ")
1288
    ----------(" 00:00:00 0000000000 000000000000 ")
1289
    term.setBackgroundColor(1)
1290
    repeat
1291
      ar = ar + 1
1292
      term.setCursorPos(18,2+ar)
1293
      term.write(blktime[ar])
1294
      if blkpeer[ar] ~= "N/A(Burnt)" then term.setTextColor(512) end
1295
      term.setCursorPos(27,2+ar)
1296
      term.write(blkpeer[ar])
1297
      term.setTextColor(32768)
1298
      term.setCursorPos(38,2+ar)
1299
      term.write(blkhash[ar])
1300
    until ar == math.min(tx,17*(scroll+1))
1301
  elseif page == 6 then
1302
    term.setCursorPos(17,2)
1303
    term.setBackgroundColor(256)
1304
    term.write(" Time         Peer           Value ")
1305
    term.setBackgroundColor(256)
1306
    term.setCursorPos(17,19)
1307
    term.write("                                   ")
1308
    term.setCursorPos(17,19)
1309
    term.setTextColor(32768)
1310
    term.write(" Page    /")
1311
    term.setCursorPos(32,19)
1312
    term.setTextColor(128)
1313
    term.write("First Prev Next Last")
1314
    term.setBackgroundColor(1)
1315
    term.setCursorPos(18,1)
1316
    term.write("ADDRESS (click to edit)")
1317
  elseif page == 7 then
1318
    local blocks = readURL(readconfig("syncnode").."?richapi")
1319
    local tx = 0
1320
    ar = 0
1321
    local height = string.sub(blocks,1,8)
1322
    local blktime = {}
1323
    blkpeer = {}
1324
    local blkhash = {}
1325
    repeat
1326
      tx = tx + 1
1327
      blkpeer[tx] = string.sub(blocks,1,10)
1328
      blocks = string.sub(blocks,11)
1329
      blktime[tx] = tonumber(string.sub(blocks,1,8))
1330
      blocks = string.sub(blocks,9)
1331
      blkhash[tx] = string.sub(blocks,1,11)
1332
      blocks = string.sub(blocks,12)
1333
    until string.len(blocks) == 0
1334
    term.setCursorPos(18,1)
1335
    term.write("Krist address rich list")
1336
    term.setCursorPos(17,2)
1337
    term.setBackgroundColor(256)
1338
    term.write("R# Address     Balance First seen  ")
1339
    term.setBackgroundColor(1)
1340
    repeat
1341
      ar = ar + 1
1342
      term.setCursorPos(17,2+ar)
1343
      if ar < 10 then term.write(" ") end
1344
      term.write(ar)
1345
      term.setCursorPos(20,2+ar)
1346
      if blkpeer[ar] ~= "N/A(Burnt)" then term.setTextColor(512) end
1347
      term.write(blkpeer[ar])
1348
      term.setTextColor(32768)
1349
      term.setCursorPos(39-string.len(tostring(math.abs(blktime[ar]))),2+ar)
1350
      term.write(blktime[ar])
1351
      term.setCursorPos(40,2+ar)
1352
      term.write(blkhash[ar])
1353
    until ar == 16
1354
  elseif page == 8 then
1355
    term.setCursorPos(19,2)
1356
    term.write("Storage         Names")
1357
    term.setTextColor(512)
1358
    term.setCursorPos(19,3)
1359
    term.write("Double vault    Register name")
1360
    term.setCursorPos(19,4)
1361
    term.write("Local vault")
1362
    term.setCursorPos(19,5)
1363
    --term.write("Disk vault      v1 SHA vault")
1364
    term.setCursorPos(19,6)
1365
    --term.write("SHA vault       v1 wallet")
1366
  elseif page == 9 then
1367
    term.setCursorPos(25,2)
1368
    term.write("Double vault manager")
1369
    term.setCursorPos(19,8)
1370
    term.write("Using double vaults is a way to")
1371
    term.setCursorPos(19,9)
1372
    term.write("store your Krist under an extra")
1373
    term.setCursorPos(19,10)
1374
    term.write("layer of security. You can only")
1375
    term.setCursorPos(19,11)
1376
    term.write("access a double vault from your")
1377
    term.setCursorPos(19,12)
1378
    term.write("wallet (on any server) and then")
1379
    term.setCursorPos(19,13)
1380
    term.write("only after typing an extra pass")
1381
    term.setCursorPos(19,14)
1382
    term.write("code. Double wallets are wholly")
1383
    term.setCursorPos(19,15)
1384
    term.write("invisible to unauthorized users")
1385
    term.setCursorPos(19,16)
1386
    term.write("of your wallet; they can not be")
1387
    term.setCursorPos(19,17)
1388
    term.write("seen or opened without the pass")
1389
    term.setCursorPos(19,18)
1390
    term.write("code set by you.")
1391
    term.setCursorPos(19,4)
1392
    term.write("Pass code: ")
1393
    term.setCursorPos(19,5)
1394
    term.write("Amount (KST): ")
1395
    term.setCursorPos(30,4)
1396
    if string.len(doublekey) == 0 then
1397
      term.setTextColor(256)
1398
      term.write("(click to set)")
1399
    else
1400
      term.setTextColor(8192)
1401
      term.write("Ready: "..balance2.." KST")
1402
      if tonumber(amt) > 0 then
1403
        term.setCursorPos(25,6)
1404
        term.setTextColor(32768)
1405
        term.setBackgroundColor(128)
1406
        if tonumber(amt) <= balance then
1407
          term.setBackgroundColor(2)
1408
        end
1409
        term.write(" Deposit ")
1410
        term.setBackgroundColor(1)
1411
        term.write(" ")
1412
        term.setBackgroundColor(128)
1413
        if tonumber(amt) <= balance2 then
1414
          term.setBackgroundColor(2)
1415
        end
1416
        term.write(" Withdraw ")
1417
        term.setBackgroundColor(1)
1418
      end
1419
    end
1420
    term.setCursorPos(33,5)
1421
    if amt == 0 then
1422
      term.setTextColor(256)
1423
      term.write("(click to set)")
1424
    else
1425
      term.setTextColor(32768)
1426
      term.write(amt)
1427
    end
1428
    term.setTextColor(32768)
1429
  elseif page == 10 then
1430
    local blocks = readURL(readconfig("syncnode").."?blocks&low")
1431
    local tx = 0
1432
    ar = 0
1433
    local blktime = {}
1434
    blkpeer = {}
1435
    local blkhash = {}
1436
    repeat
1437
      tx = tx + 1
1438
      blktime[tx] = string.sub(blocks,1,6)
1439
      blocks = string.sub(blocks,7)
1440
      blkpeer[tx] = string.sub(blocks,1,6)
1441
      blocks = string.sub(blocks,7)
1442
      blkhash[tx] = string.sub(blocks,1,20)
1443
      blocks = string.sub(blocks,21)
1444
    until string.len(blocks) == 0
1445
    term.setCursorPos(17,1)
1446
    term.setBackgroundColor(256)
1447
    term.write(" Date   Block# Hash                ")
1448
    ----------(" Feb 28 000000 000000000000oooooooo")
1449
    term.setBackgroundColor(1)
1450
    repeat
1451
      ar = ar + 1
1452
      term.setCursorPos(18,1+ar)
1453
      term.write(blktime[ar])
1454
      term.setCursorPos(31-string.len(tostring(math.abs(tonumber(blkpeer[ar])))),1+ar)
1455
      term.write(tonumber(blkpeer[ar]))
1456
      term.setTextColor(256)
1457
      term.setCursorPos(32,1+ar)
1458
      term.write(blkhash[ar])
1459
      term.setTextColor(32768)
1460
      term.setCursorPos(32,1+ar)
1461
      term.write(string.sub(blkhash[ar],1,12))
1462
    until ar == math.min(tx,18)
1463
  elseif page == 11 then
1464
    local blocks = readURL(readconfig("syncnode").."?blocks&low&lownonce")
1465
    local tx = 0
1466
    ar = 0
1467
    local blktime = {}
1468
    blkpeer = {}
1469
    local blkhash = {}
1470
    repeat
1471
      tx = tx + 1
1472
      blktime[tx] = string.sub(blocks,1,6)
1473
      blocks = string.sub(blocks,7)
1474
      blkpeer[tx] = string.sub(blocks,1,6)
1475
      blocks = string.sub(blocks,7)
1476
      blkhash[tx] = string.sub(blocks,1,12)
1477
      blocks = string.sub(blocks,13)
1478
    until string.len(blocks) == 0
1479
    term.setCursorPos(17,1)
1480
    term.setBackgroundColor(256)
1481
    term.write(" Date   Block# Nonce               ")
1482
    ----------(" Feb 28 000000 000000000000")
1483
    term.setBackgroundColor(1)
1484
    repeat
1485
      ar = ar + 1
1486
      term.setCursorPos(18,1+ar)
1487
      term.write(blktime[ar])
1488
      term.setCursorPos(31-string.len(tostring(math.abs(tonumber(blkpeer[ar])))),1+ar)
1489
      term.write(tonumber(blkpeer[ar]))
1490
      term.setTextColor(32768)
1491
      term.setCursorPos(32,1+ar)
1492
      term.write(tonumber(blkhash[ar]))
1493
    until ar == math.min(tx,18)
1494
  elseif page == 12 then
1495
    local blocks = readURL(readconfig("syncnode").."?blocks&low&highnonce")
1496
    local tx = 0
1497
    ar = 0
1498
    local blktime = {}
1499
    blkpeer = {}
1500
    local blkhash = {}
1501
    repeat
1502
      tx = tx + 1
1503
      blktime[tx] = string.sub(blocks,1,6)
1504
      blocks = string.sub(blocks,7)
1505
      blkpeer[tx] = string.sub(blocks,1,6)
1506
      blocks = string.sub(blocks,7)
1507
      blkhash[tx] = string.sub(blocks,1,12)
1508
      blocks = string.sub(blocks,13)
1509
    until string.len(blocks) == 0
1510
    term.setCursorPos(17,1)
1511
    term.setBackgroundColor(256)
1512
    term.write(" Date   Block# Nonce               ")
1513
    ----------(" Feb 28 000000 000000000000")
1514
    term.setBackgroundColor(1)
1515
    repeat
1516
      ar = ar + 1
1517
      term.setCursorPos(18,1+ar)
1518
      term.write(blktime[ar])
1519
      term.setCursorPos(31-string.len(tostring(math.abs(tonumber(blkpeer[ar])))),1+ar)
1520
      term.write(tonumber(blkpeer[ar]))
1521
      term.setTextColor(32768)
1522
      term.setCursorPos(32,1+ar)
1523
      term.write(tonumber(blkhash[ar]))
1524
    until ar == math.min(tx,18)
1525
  elseif page == 13 then
1526
    balance3 = tonumber(readURL(readconfig("syncnode").."?getbalance="..addresslv))
1527
    term.setCursorPos(25,2)
1528
    term.write("Local vault manager")
1529
    term.setCursorPos(19,8)
1530
    term.write("Local vaults are a place to put")
1531
    term.setCursorPos(19,9)
1532
    term.write("Krist in the form of a file on")
1533
    term.setCursorPos(19,10)
1534
    term.write("a computer. Unlike traditional")
1535
    term.setCursorPos(19,11)
1536
    term.write("wallets, local vaults can only")
1537
    term.setCursorPos(19,12)
1538
    term.write("be accessed on the computer")
1539
    term.setCursorPos(19,13)
1540
    term.write("they were initially created on.")
1541
    term.setCursorPos(19,14)
1542
    term.write("If you do this, please ensure")
1543
    term.setCursorPos(19,15)
1544
    term.write("that this computer is never")
1545
    term.setCursorPos(19,16)
1546
    term.write("stolen or broken, as your money")
1547
    term.setCursorPos(19,17)
1548
    term.write("may be lost if you don't have a")
1549
    term.setCursorPos(19,18)
1550
    term.write("backup.")
1551
    term.setCursorPos(19,4)
1552
    term.write("KST put here: "..balance3)
1553
    term.setCursorPos(19,5)
1554
    term.write("Amount (KST): ")
1555
    term.setCursorPos(33,5)
1556
    if amt == 0 then
1557
      term.setTextColor(256)
1558
      term.write("(click to set)")
1559
    else
1560
      term.setTextColor(32768)
1561
      term.write(amt)
1562
    end
1563
    if tonumber(amt) > 0 then
1564
      term.setCursorPos(25,6)
1565
      term.setTextColor(32768)
1566
      term.setBackgroundColor(128)
1567
      if tonumber(amt) <= balance then
1568
        term.setBackgroundColor(2)
1569
      end
1570
      term.write(" Deposit ")
1571
      term.setBackgroundColor(1)
1572
      term.write(" ")
1573
      term.setBackgroundColor(128)
1574
      if tonumber(amt) <= balance3 then
1575
        term.setBackgroundColor(2)
1576
      end
1577
      term.write(" Withdraw ")
1578
      term.setBackgroundColor(1)
1579
    end
1580
  elseif page == 14 then
1581
    term.setBackgroundColor(1)
1582
    term.setCursorPos(19,2)
1583
    term.write("Local settings")
1584
    --deprecated for now
1585
  elseif page == 15 then
1586
    term.setBackgroundColor(1)
1587
    term.setCursorPos(18,1)
1588
    term.write(".KST domain name manager     [New]")
1589
    term.setCursorPos(46,1)
1590
    term.setBackgroundColor(32)
1591
    term.setTextColor(1)
1592
    term.write(" + NEW")
1593
    term.setCursorPos(17,2)
1594
    term.setBackgroundColor(256)
1595
    term.setTextColor(32768)
1596
    term.write(" Name                 Actions      ")
1597
    term.setBackgroundColor(1)
1598
    term.setCursorPos(18,3)
1599
    local namelist = readURL(readconfig("syncnode").."?listnames="..address)
1600
	local splitname = split(namelist, ";")
1601
	
1602
1603
    if #splitname == 0 then
1604
      term.setTextColor(256)
1605
      term.write("No names to display!")
1606
    else
1607
      local namecount = 1
1608
      repeat
1609
				local thisname = splitname[namecount]
1610
				--namelist:sub(0,namelist:find(";")-1)
1611
        term.setTextColor(32768)
1612
        term.setCursorPos(18,3+namecount)
1613
        term.write(splitname[namecount]..".kst")
1614
        term.setCursorPos(39,3+namecount)
1615
        term.setTextColor(512)
1616
        if thisname == "a" or thisname == "name" or thisname == "owner" or thisname == "updated" or thisname == "registered" or thisname == "expires" or thisname == "id" or thisname == "unpaid" then term.setTextColor(256) end
1617
        term.write("Edit Send ")
1618
        term.setTextColor(256)
1619
        term.write("Go")
1620
        namecount = namecount + 1
1621
      until namecount == #splitname+1
1622
    end
1623
    --term.write("a.kst                Edit Send Go")
1624
    term.setBackgroundColor(1)
1625
  elseif page == 16 then
1626
    term.setBackgroundColor(1)
1627
    term.setCursorPos(20,2)
1628
    term.write(".KST domain name registration")
1629
    term.setCursorPos(19,4)
1630
    term.write("Name: ")
1631
    if name == "" then
1632
      term.setTextColor(colors.lightGray)
1633
      term.write("(click to set)")
1634
    else
1635
      term.write(name)
1636
      term.setTextColor(colors.lightGray)
1637
      term.write(".kst")
1638
    end
1639
    term.setTextColor(colors.black)
1640
    term.setCursorPos(19,5)
1641
    term.write("Cost: 500 KST")
1642
    term.setCursorPos(19,7)
1643
    --term.write("Available! [Register]")
1644
    if name == "" then
1645
      term.setTextColor(colors.blue)
1646
      term.write("Please select a name!")
1647
    elseif availability == 1 then
1648
      term.setTextColor(colors.green)
1649
      term.write("Available! ")
1650
      --if balance >= 500 then
1651
        term.setBackgroundColor(colors.green)
1652
        term.setTextColor(colors.lime)
1653
        term.write(" Register ")
1654
        term.setBackgroundColor(colors.white)
1655
      --end
1656
    elseif availability == 2 then
1657
      term.setTextColor(colors.yellow)
1658
      term.write("Name registered!")
1659
    else
1660
      term.setTextColor(colors.red)
1661
      term.write("Not available!")
1662
    end
1663
    term.setTextColor(colors.black)
1664
    term.setCursorPos(19,9)
1665
    term.write(".KST domain names are used on")
1666
    term.setCursorPos(19,10)
1667
    term.write("the KristScape browser. For")
1668
    term.setCursorPos(19,11)
1669
    term.write("more information, please see")
1670
    term.setCursorPos(19,12)
1671
    term.write("the Krist thread.")
1672
    term.setCursorPos(19,14)
1673
    term.write("All Krist spent on names will")
1674
    term.setCursorPos(19,15)
1675
    term.write("be added to the value of")
1676
    term.setCursorPos(19,16)
1677
    term.write("future blocks; essentially")
1678
    term.setCursorPos(19,17)
1679
    term.write("being \"re-mined.\"")
1680
  elseif page == 17 then
1681
    term.setBackgroundColor(1)
1682
    term.setCursorPos(28,2)
1683
    term.write(".KST zone file")
1684
    term.setCursorPos(19,4)
1685
    term.write("Name: "..subject)
1686
    term.setTextColor(colors.lightGray)
1687
    term.write(".kst")
1688
    term.setTextColor(colors.black)
1689
    term.setCursorPos(19,7)
1690
    term.write("Your name's zone file is the")
1691
    term.setCursorPos(19,8)
1692
    term.write("URL of the site it is pointing")
1693
    term.setCursorPos(19,9)
1694
    term.write("to. When KristScape navigates")
1695
    term.setCursorPos(19,10)
1696
    term.write("to a name, it will make an HTTP")
1697
    term.setCursorPos(19,11)
1698
    term.write("get request to the above URL.")
1699
    term.setCursorPos(19,12)
1700
    term.write("The zone record should not")
1701
    term.setCursorPos(19,13)
1702
    term.write("include a protocol (http://)")
1703
    term.setCursorPos(19,14)
1704
    term.write("and shouldn't end with a")
1705
    term.setCursorPos(19,15)
1706
    term.write("slash. You can redirect a name")
1707
    term.setCursorPos(19,16)
1708
    term.write("to another name by making the")
1709
    term.setCursorPos(19,17)
1710
    term.write("first character of the record")
1711
    term.setCursorPos(19,18)
1712
    term.write("a dollar sign; e.g. $krist.kst")
1713
    term.setTextColor(colors.black)
1714
    term.setCursorPos(19,5)
1715
    term.write("Zone: ")
1716
    zone = readURL(readconfig("syncnode").."?a="..subject)
1717
    if zone == "" then
1718
      term.setTextColor(colors.lightGray)
1719
      term.write("(click to set)")
1720
    else
1721
      term.write(zone)
1722
    end
1723
  elseif page == 18 then
1724
    term.setBackgroundColor(1)
1725
    term.setCursorPos(28,2)
1726
    term.write("Name transfer")
1727
    term.setCursorPos(19,4)
1728
    term.write("Name: "..subject)
1729
    term.setTextColor(colors.lightGray)
1730
    term.write(".kst")
1731
    term.setTextColor(colors.black)
1732
    term.setCursorPos(19,5)
1733
    term.write("Recipient: ")
1734
  elseif page == 21 then
1735
    term.setBackgroundColor(1)
1736
    term.setCursorPos(4,6)
1737
    term.write("Address - ")
1738
    term.setTextColor(16384)
1739
    term.write(address)
1740
    term.setTextColor(32768)
1741
    term.setCursorPos(4,7)
1742
    term.write("Balance - ")
1743
    term.setTextColor(1024)
1744
    if tostring(balance) == 'nil' then balance = 0 end
1745
    term.write(tostring(balance).." KST")
1746
    term.setTextColor(32768)
1747
    term.setCursorPos(3,9)
1748
  end
1749
end
1750
boot()