@leofcoin/chain 1.4.20 → 1.4.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/CHANGELOG.md +14 -14
  2. package/LICENSE +88 -88
  3. package/README.md +4 -4
  4. package/demo/index.html +25 -25
  5. package/examples/contracts/token.js +7 -7
  6. package/package.json +71 -71
  7. package/plugins/bundle.js +18 -18
  8. package/src/chain.js +716 -716
  9. package/src/config/config.js +14 -14
  10. package/src/config/main.js +4 -4
  11. package/src/config/protocol.js +5 -5
  12. package/src/contract.js +51 -51
  13. package/src/fee/config.js +3 -3
  14. package/src/machine.js +215 -215
  15. package/src/node.js +24 -24
  16. package/src/protocol.js +3 -3
  17. package/src/state.js +31 -31
  18. package/src/transaction.js +233 -233
  19. package/src/type.index.d.ts +20 -20
  20. package/src/typer.js +19 -19
  21. package/test/chain.js +120 -109
  22. package/test/contracts/token.js +40 -40
  23. package/test/create-genesis.js +66 -66
  24. package/tsconfig.js +14 -14
  25. package/workers/block-worker.js +40 -40
  26. package/workers/machine-worker.js +218 -218
  27. package/workers/pool-worker.js +28 -28
  28. package/workers/transaction-worker.js +19 -19
  29. package/workers/workers.js +8 -8
  30. package/block-worker.js +0 -1
  31. package/demo/865.browser.js +0 -10
  32. package/demo/chain.browser.js +0 -66842
  33. package/demo/generate-account.browser.js +0 -50
  34. package/demo/messages.browser.js +0 -328
  35. package/demo/multi-wallet.browser.js +0 -15
  36. package/demo/node.browser.js +0 -9858
  37. package/demo/pako.browser.js +0 -6900
  38. package/demo/peernet-swarm.browser.js +0 -839
  39. package/demo/storage.browser.js +0 -3724
  40. package/demo/workers/865.js +0 -10
  41. package/demo/workers/block-worker.js +0 -13175
  42. package/demo/workers/machine-worker.js +0 -13385
  43. package/demo/workers/pool-worker.js +0 -8503
  44. package/demo/workers/transaction-worker.js +0 -8495
  45. package/demo/wrtc.browser.js +0 -28
  46. package/dist/browser/workers/865.js +0 -10
  47. package/dist/browser/workers/block-worker.js +0 -9460
  48. package/dist/browser/workers/machine-worker.js +0 -9670
  49. package/dist/browser/workers/pool-worker.js +0 -4608
  50. package/dist/browser/workers/transaction-worker.js +0 -4600
  51. package/dist/chain.js +0 -10128
  52. package/dist/client-80bc8156.js +0 -491
  53. package/dist/commonjs-7fe3c381.js +0 -270
  54. package/dist/contracts/factory.js +0 -1
  55. package/dist/contracts/name-service.js +0 -1
  56. package/dist/contracts/native-token.js +0 -1
  57. package/dist/contracts/validators.js +0 -1
  58. package/dist/generate-account-445db122.js +0 -46
  59. package/dist/index-57f93805.js +0 -718
  60. package/dist/messages-bce1b91d-81af3b00.js +0 -315
  61. package/dist/module/chain.js +0 -10091
  62. package/dist/module/client-8031ec88.js +0 -489
  63. package/dist/module/commonjs-9005d5c0.js +0 -268
  64. package/dist/module/generate-account-489552b6.js +0 -44
  65. package/dist/module/index-ac2285c4.js +0 -688
  66. package/dist/module/messages-bce1b91d-eaf75d83.js +0 -302
  67. package/dist/module/node.js +0 -7049
  68. package/dist/module/workers/block-worker.js +0 -94
  69. package/dist/module/workers/machine-worker.js +0 -304
  70. package/dist/module/workers/pool-worker.js +0 -55
  71. package/dist/module/workers/transaction-worker.js +0 -47
  72. package/dist/node.js +0 -7061
  73. package/dist/standards/token.js +0 -1
  74. package/dist/workers/machine-worker.js +0 -1
  75. package/dist/workers/pool-worker.js +0 -1
  76. package/dist/workers/transaction-worker.js +0 -1
@@ -1,688 +0,0 @@
1
- import bs58Check from 'bs58check';
2
- import * as bip32 from 'bip32';
3
- import randombytes from 'randombytes';
4
- import '@ethersproject/bignumber';
5
- import '@ethersproject/units';
6
- import secp256k1 from 'secp256k1';
7
- import { createKeccak } from 'hash-wasm';
8
- import base58 from '@vandeurenglenn/base58';
9
- import base32 from '@vandeurenglenn/base32';
10
- import varint from 'varint';
11
-
12
- var testnets = {
13
- 'leofcoin:olivia': {
14
- messagePrefix: '\u0019Leofcoin Signed Message:',
15
- pubKeyHash: 0x73, // o
16
- scriptHash: 0x76, // p
17
- multiTxHash: 0x8b4125, // omtx
18
- payments: {
19
- version: 0,
20
- unspent: 0x1fa443d7 // ounsp
21
- },
22
- wif: 0x7D, // s
23
- multiCodec: 0x7c4,
24
- bip32: { public: 0x13BBF2D5, private: 0x13BBCBC5 }
25
- },
26
- 'bitcoin:testnet': {
27
- messagePrefix: '\x18Bitcoin Signed Message:\n',
28
- bech32: 'tb',
29
- pubKeyHash: 0x6f,
30
- scriptHash: 0xc4,
31
- wif: 0xef,
32
- bip32: {
33
- public: 0x043587cf,
34
- private: 0x04358394
35
- }
36
- }
37
-
38
- };
39
-
40
- // https://en.bitcoin.it/wiki/List_of_address_prefixes
41
- /**
42
- * Main network
43
- * @return {messagePrefix, pubKeyHash, scriptHash, wif, bip32}
44
- */
45
- const leofcoin = {
46
- messagePrefix: '\u0019Leofcoin Signed Message:',
47
- pubKeyHash: 0x30, // L
48
- scriptHash: 0x37, // P
49
- multiTxHash: 0x3adeed, // Lmtx
50
- payments: {
51
- version: 0,
52
- unspent: 0x0d6e0327 // Lunsp
53
- },
54
- coin_type: 640,
55
- wif: 0x3F, // S
56
- multiCodec: 0x3c4,
57
- bip32: { public: 0x13BBF2D4, private: 0x13BBCBC4 },
58
- testnet: testnets['leofcoin:olivia']
59
- };
60
-
61
- const bitcoin = {
62
- messagePrefix: '\x18Bitcoin Signed Message:\n',
63
- bech32: 'bc',
64
- pubKeyHash: 0x00,
65
- multiCodec: 0x00,
66
- scriptHash: 0x05,
67
- wif: 0x80,
68
- coin_type: 0,
69
- bip32: {
70
- public: 0x0488b21e, private: 0x0488ade4
71
- },
72
- testnet: testnets['bitcoin:testnet']
73
- };
74
-
75
- const litecoin = {
76
- messagePrefix: '\x19Litecoin Signed Message:\n',
77
- pubKeyHash: 0x30,
78
- scriptHash: 0x32,
79
- wif: 0xb0,
80
- bip32: {
81
- public: 0x019da462,
82
- private: 0x019d9cfe
83
- }
84
- };
85
-
86
- const ethereum = {
87
- messagePrefix: '\x19Ethereum Signed Message:\n',
88
- pubKeyHash: 0x30,
89
- scriptHash: 0x32,
90
- bip32: {
91
- private: 0x0488ADE4, public: 0x0488B21E
92
- },
93
- coin_type: 60,
94
- wif: 0x45,//E
95
- multiCodec: 0x3c5
96
- };
97
-
98
- /**
99
- * Our & supported networks
100
- * @return {leofcoin, olivia}
101
- */
102
- var networks = {
103
- leofcoin,
104
- bitcoin,
105
- litecoin,
106
- ethereum
107
- };
108
-
109
- const fromNetworkString = network => {
110
- const parts = network.split(':');
111
- network = networks[parts[0]];
112
- if (parts[1]) {
113
- if (network[parts[1]]) network = network[parts[1]];
114
-
115
- network.coin_type = 1;
116
- }
117
- return network;
118
- };
119
-
120
- // see https://github.com/bitcoin/bips/blob/master/bip-0039/english.txt
121
-
122
- var wordlist = ["abandon","ability","able","about","above","absent","absorb","abstract","absurd","abuse","access","accident","account","accuse","achieve","acid","acoustic","acquire","across","act","action","actor","actress","actual","adapt","add","addict","address","adjust","admit","adult","advance","advice","aerobic","affair","afford","afraid","again","age","agent","agree","ahead","aim","air","airport","aisle","alarm","album","alcohol","alert","alien","all","alley","allow","almost","alone","alpha","already","also","alter","always","amateur","amazing","among","amount","amused","analyst","anchor","ancient","anger","angle","angry","animal","ankle","announce","annual","another","answer","antenna","antique","anxiety","any","apart","apology","appear","apple","approve","april","arch","arctic","area","arena","argue","arm","armed","armor","army","around","arrange","arrest","arrive","arrow","art","artefact","artist","artwork","ask","aspect","assault","asset","assist","assume","asthma","athlete","atom","attack","attend","attitude","attract","auction","audit","august","aunt","author","auto","autumn","average","avocado","avoid","awake","aware","away","awesome","awful","awkward","axis","baby","bachelor","bacon","badge","bag","balance","balcony","ball","bamboo","banana","banner","bar","barely","bargain","barrel","base","basic","basket","battle","beach","bean","beauty","because","become","beef","before","begin","behave","behind","believe","below","belt","bench","benefit","best","betray","better","between","beyond","bicycle","bid","bike","bind","biology","bird","birth","bitter","black","blade","blame","blanket","blast","bleak","bless","blind","blood","blossom","blouse","blue","blur","blush","board","boat","body","boil","bomb","bone","bonus","book","boost","border","boring","borrow","boss","bottom","bounce","box","boy","bracket","brain","brand","brass","brave","bread","breeze","brick","bridge","brief","bright","bring","brisk","broccoli","broken","bronze","broom","brother","brown","brush","bubble","buddy","budget","buffalo","build","bulb","bulk","bullet","bundle","bunker","burden","burger","burst","bus","business","busy","butter","buyer","buzz","cabbage","cabin","cable","cactus","cage","cake","call","calm","camera","camp","can","canal","cancel","candy","cannon","canoe","canvas","canyon","capable","capital","captain","car","carbon","card","cargo","carpet","carry","cart","case","cash","casino","castle","casual","cat","catalog","catch","category","cattle","caught","cause","caution","cave","ceiling","celery","cement","census","century","cereal","certain","chair","chalk","champion","change","chaos","chapter","charge","chase","chat","cheap","check","cheese","chef","cherry","chest","chicken","chief","child","chimney","choice","choose","chronic","chuckle","chunk","churn","cigar","cinnamon","circle","citizen","city","civil","claim","clap","clarify","claw","clay","clean","clerk","clever","click","client","cliff","climb","clinic","clip","clock","clog","close","cloth","cloud","clown","club","clump","cluster","clutch","coach","coast","coconut","code","coffee","coil","coin","collect","color","column","combine","come","comfort","comic","common","company","concert","conduct","confirm","congress","connect","consider","control","convince","cook","cool","copper","copy","coral","core","corn","correct","cost","cotton","couch","country","couple","course","cousin","cover","coyote","crack","cradle","craft","cram","crane","crash","crater","crawl","crazy","cream","credit","creek","crew","cricket","crime","crisp","critic","crop","cross","crouch","crowd","crucial","cruel","cruise","crumble","crunch","crush","cry","crystal","cube","culture","cup","cupboard","curious","current","curtain","curve","cushion","custom","cute","cycle","dad","damage","damp","dance","danger","daring","dash","daughter","dawn","day","deal","debate","debris","decade","december","decide","decline","decorate","decrease","deer","defense","define","defy","degree","delay","deliver","demand","demise","denial","dentist","deny","depart","depend","deposit","depth","deputy","derive","describe","desert","design","desk","despair","destroy","detail","detect","develop","device","devote","diagram","dial","diamond","diary","dice","diesel","diet","differ","digital","dignity","dilemma","dinner","dinosaur","direct","dirt","disagree","discover","disease","dish","dismiss","disorder","display","distance","divert","divide","divorce","dizzy","doctor","document","dog","doll","dolphin","domain","donate","donkey","donor","door","dose","double","dove","draft","dragon","drama","drastic","draw","dream","dress","drift","drill","drink","drip","drive","drop","drum","dry","duck","dumb","dune","during","dust","dutch","duty","dwarf","dynamic","eager","eagle","early","earn","earth","easily","east","easy","echo","ecology","economy","edge","edit","educate","effort","egg","eight","either","elbow","elder","electric","elegant","element","elephant","elevator","elite","else","embark","embody","embrace","emerge","emotion","employ","empower","empty","enable","enact","end","endless","endorse","enemy","energy","enforce","engage","engine","enhance","enjoy","enlist","enough","enrich","enroll","ensure","enter","entire","entry","envelope","episode","equal","equip","era","erase","erode","erosion","error","erupt","escape","essay","essence","estate","eternal","ethics","evidence","evil","evoke","evolve","exact","example","excess","exchange","excite","exclude","excuse","execute","exercise","exhaust","exhibit","exile","exist","exit","exotic","expand","expect","expire","explain","expose","express","extend","extra","eye","eyebrow","fabric","face","faculty","fade","faint","faith","fall","false","fame","family","famous","fan","fancy","fantasy","farm","fashion","fat","fatal","father","fatigue","fault","favorite","feature","february","federal","fee","feed","feel","female","fence","festival","fetch","fever","few","fiber","fiction","field","figure","file","film","filter","final","find","fine","finger","finish","fire","firm","first","fiscal","fish","fit","fitness","fix","flag","flame","flash","flat","flavor","flee","flight","flip","float","flock","floor","flower","fluid","flush","fly","foam","focus","fog","foil","fold","follow","food","foot","force","forest","forget","fork","fortune","forum","forward","fossil","foster","found","fox","fragile","frame","frequent","fresh","friend","fringe","frog","front","frost","frown","frozen","fruit","fuel","fun","funny","furnace","fury","future","gadget","gain","galaxy","gallery","game","gap","garage","garbage","garden","garlic","garment","gas","gasp","gate","gather","gauge","gaze","general","genius","genre","gentle","genuine","gesture","ghost","giant","gift","giggle","ginger","giraffe","girl","give","glad","glance","glare","glass","glide","glimpse","globe","gloom","glory","glove","glow","glue","goat","goddess","gold","good","goose","gorilla","gospel","gossip","govern","gown","grab","grace","grain","grant","grape","grass","gravity","great","green","grid","grief","grit","grocery","group","grow","grunt","guard","guess","guide","guilt","guitar","gun","gym","habit","hair","half","hammer","hamster","hand","happy","harbor","hard","harsh","harvest","hat","have","hawk","hazard","head","health","heart","heavy","hedgehog","height","hello","helmet","help","hen","hero","hidden","high","hill","hint","hip","hire","history","hobby","hockey","hold","hole","holiday","hollow","home","honey","hood","hope","horn","horror","horse","hospital","host","hotel","hour","hover","hub","huge","human","humble","humor","hundred","hungry","hunt","hurdle","hurry","hurt","husband","hybrid","ice","icon","idea","identify","idle","ignore","ill","illegal","illness","image","imitate","immense","immune","impact","impose","improve","impulse","inch","include","income","increase","index","indicate","indoor","industry","infant","inflict","inform","inhale","inherit","initial","inject","injury","inmate","inner","innocent","input","inquiry","insane","insect","inside","inspire","install","intact","interest","into","invest","invite","involve","iron","island","isolate","issue","item","ivory","jacket","jaguar","jar","jazz","jealous","jeans","jelly","jewel","job","join","joke","journey","joy","judge","juice","jump","jungle","junior","junk","just","kangaroo","keen","keep","ketchup","key","kick","kid","kidney","kind","kingdom","kiss","kit","kitchen","kite","kitten","kiwi","knee","knife","knock","know","lab","label","labor","ladder","lady","lake","lamp","language","laptop","large","later","latin","laugh","laundry","lava","law","lawn","lawsuit","layer","lazy","leader","leaf","learn","leave","lecture","left","leg","legal","legend","leisure","lemon","lend","length","lens","leopard","lesson","letter","level","liar","liberty","library","license","life","lift","light","like","limb","limit","link","lion","liquid","list","little","live","lizard","load","loan","lobster","local","lock","logic","lonely","long","loop","lottery","loud","lounge","love","loyal","lucky","luggage","lumber","lunar","lunch","luxury","lyrics","machine","mad","magic","magnet","maid","mail","main","major","make","mammal","man","manage","mandate","mango","mansion","manual","maple","marble","march","margin","marine","market","marriage","mask","mass","master","match","material","math","matrix","matter","maximum","maze","meadow","mean","measure","meat","mechanic","medal","media","melody","melt","member","memory","mention","menu","mercy","merge","merit","merry","mesh","message","metal","method","middle","midnight","milk","million","mimic","mind","minimum","minor","minute","miracle","mirror","misery","miss","mistake","mix","mixed","mixture","mobile","model","modify","mom","moment","monitor","monkey","monster","month","moon","moral","more","morning","mosquito","mother","motion","motor","mountain","mouse","move","movie","much","muffin","mule","multiply","muscle","museum","mushroom","music","must","mutual","myself","mystery","myth","naive","name","napkin","narrow","nasty","nation","nature","near","neck","need","negative","neglect","neither","nephew","nerve","nest","net","network","neutral","never","news","next","nice","night","noble","noise","nominee","noodle","normal","north","nose","notable","note","nothing","notice","novel","now","nuclear","number","nurse","nut","oak","obey","object","oblige","obscure","observe","obtain","obvious","occur","ocean","october","odor","off","offer","office","often","oil","okay","old","olive","olympic","omit","once","one","onion","online","only","open","opera","opinion","oppose","option","orange","orbit","orchard","order","ordinary","organ","orient","original","orphan","ostrich","other","outdoor","outer","output","outside","oval","oven","over","own","owner","oxygen","oyster","ozone","pact","paddle","page","pair","palace","palm","panda","panel","panic","panther","paper","parade","parent","park","parrot","party","pass","patch","path","patient","patrol","pattern","pause","pave","payment","peace","peanut","pear","peasant","pelican","pen","penalty","pencil","people","pepper","perfect","permit","person","pet","phone","photo","phrase","physical","piano","picnic","picture","piece","pig","pigeon","pill","pilot","pink","pioneer","pipe","pistol","pitch","pizza","place","planet","plastic","plate","play","please","pledge","pluck","plug","plunge","poem","poet","point","polar","pole","police","pond","pony","pool","popular","portion","position","possible","post","potato","pottery","poverty","powder","power","practice","praise","predict","prefer","prepare","present","pretty","prevent","price","pride","primary","print","priority","prison","private","prize","problem","process","produce","profit","program","project","promote","proof","property","prosper","protect","proud","provide","public","pudding","pull","pulp","pulse","pumpkin","punch","pupil","puppy","purchase","purity","purpose","purse","push","put","puzzle","pyramid","quality","quantum","quarter","question","quick","quit","quiz","quote","rabbit","raccoon","race","rack","radar","radio","rail","rain","raise","rally","ramp","ranch","random","range","rapid","rare","rate","rather","raven","raw","razor","ready","real","reason","rebel","rebuild","recall","receive","recipe","record","recycle","reduce","reflect","reform","refuse","region","regret","regular","reject","relax","release","relief","rely","remain","remember","remind","remove","render","renew","rent","reopen","repair","repeat","replace","report","require","rescue","resemble","resist","resource","response","result","retire","retreat","return","reunion","reveal","review","reward","rhythm","rib","ribbon","rice","rich","ride","ridge","rifle","right","rigid","ring","riot","ripple","risk","ritual","rival","river","road","roast","robot","robust","rocket","romance","roof","rookie","room","rose","rotate","rough","round","route","royal","rubber","rude","rug","rule","run","runway","rural","sad","saddle","sadness","safe","sail","salad","salmon","salon","salt","salute","same","sample","sand","satisfy","satoshi","sauce","sausage","save","say","scale","scan","scare","scatter","scene","scheme","school","science","scissors","scorpion","scout","scrap","screen","script","scrub","sea","search","season","seat","second","secret","section","security","seed","seek","segment","select","sell","seminar","senior","sense","sentence","series","service","session","settle","setup","seven","shadow","shaft","shallow","share","shed","shell","sheriff","shield","shift","shine","ship","shiver","shock","shoe","shoot","shop","short","shoulder","shove","shrimp","shrug","shuffle","shy","sibling","sick","side","siege","sight","sign","silent","silk","silly","silver","similar","simple","since","sing","siren","sister","situate","six","size","skate","sketch","ski","skill","skin","skirt","skull","slab","slam","sleep","slender","slice","slide","slight","slim","slogan","slot","slow","slush","small","smart","smile","smoke","smooth","snack","snake","snap","sniff","snow","soap","soccer","social","sock","soda","soft","solar","soldier","solid","solution","solve","someone","song","soon","sorry","sort","soul","sound","soup","source","south","space","spare","spatial","spawn","speak","special","speed","spell","spend","sphere","spice","spider","spike","spin","spirit","split","spoil","sponsor","spoon","sport","spot","spray","spread","spring","spy","square","squeeze","squirrel","stable","stadium","staff","stage","stairs","stamp","stand","start","state","stay","steak","steel","stem","step","stereo","stick","still","sting","stock","stomach","stone","stool","story","stove","strategy","street","strike","strong","struggle","student","stuff","stumble","style","subject","submit","subway","success","such","sudden","suffer","sugar","suggest","suit","summer","sun","sunny","sunset","super","supply","supreme","sure","surface","surge","surprise","surround","survey","suspect","sustain","swallow","swamp","swap","swarm","swear","sweet","swift","swim","swing","switch","sword","symbol","symptom","syrup","system","table","tackle","tag","tail","talent","talk","tank","tape","target","task","taste","tattoo","taxi","teach","team","tell","ten","tenant","tennis","tent","term","test","text","thank","that","theme","then","theory","there","they","thing","this","thought","three","thrive","throw","thumb","thunder","ticket","tide","tiger","tilt","timber","time","tiny","tip","tired","tissue","title","toast","tobacco","today","toddler","toe","together","toilet","token","tomato","tomorrow","tone","tongue","tonight","tool","tooth","top","topic","topple","torch","tornado","tortoise","toss","total","tourist","toward","tower","town","toy","track","trade","traffic","tragic","train","transfer","trap","trash","travel","tray","treat","tree","trend","trial","tribe","trick","trigger","trim","trip","trophy","trouble","truck","true","truly","trumpet","trust","truth","try","tube","tuition","tumble","tuna","tunnel","turkey","turn","turtle","twelve","twenty","twice","twin","twist","two","type","typical","ugly","umbrella","unable","unaware","uncle","uncover","under","undo","unfair","unfold","unhappy","uniform","unique","unit","universe","unknown","unlock","until","unusual","unveil","update","upgrade","uphold","upon","upper","upset","urban","urge","usage","use","used","useful","useless","usual","utility","vacant","vacuum","vague","valid","valley","valve","van","vanish","vapor","various","vast","vault","vehicle","velvet","vendor","venture","venue","verb","verify","version","very","vessel","veteran","viable","vibrant","vicious","victory","video","view","village","vintage","violin","virtual","virus","visa","visit","visual","vital","vivid","vocal","voice","void","volcano","volume","vote","voyage","wage","wagon","wait","walk","wall","walnut","want","warfare","warm","warrior","wash","wasp","waste","water","wave","way","wealth","weapon","wear","weasel","weather","web","wedding","weekend","weird","welcome","west","wet","whale","what","wheat","wheel","when","where","whip","whisper","wide","width","wife","wild","will","win","window","wine","wing","wink","winner","winter","wire","wisdom","wise","wish","witness","wolf","woman","wonder","wood","wool","word","work","world","worry","worth","wrap","wreck","wrestle","wrist","write","wrong","yard","year","yellow","you","young","youth","zebra","zero","zone","zoo"];
123
-
124
- const {subtle} = crypto;
125
-
126
- const uint8ArrayToHex = uint8Array =>
127
- [...uint8Array].map(x => x.toString(16).padStart(2, '0')).join('');
128
-
129
- const arrayBufferToHex = arrayBuffer =>
130
- uint8ArrayToHex(new Uint8Array(arrayBuffer));
131
-
132
- const hexToUint8Array = hex =>
133
- new Uint8Array(hex.match(/[\da-f]{2}/gi).map(x => parseInt(x, 16)));
134
-
135
- const generatePbkdf2 = async (password) => {
136
- return subtle.importKey(
137
- 'raw',
138
- password,
139
- 'PBKDF2',
140
- false,
141
- ['deriveBits']
142
- )
143
- };
144
-
145
- const pbkdf2 = async (password, salt, iterations = 4096, length = 64, hash = 'SHA-512') => {
146
- const key = await generatePbkdf2(password);
147
- const bits = await subtle.deriveBits({
148
- name: 'PBKDF2',
149
- hash,
150
- salt: salt,
151
- iterations,
152
- }, key, length);
153
- return bits;
154
- };
155
-
156
- const generateAesKey = async (length = 256) => {
157
- const key = await subtle.generateKey({
158
- name: 'AES-CBC',
159
- length
160
- }, true, ['encrypt', 'decrypt']);
161
-
162
- return key;
163
- };
164
-
165
- const importAesKey = async (exported, format = 'raw', length = 256) => {
166
- return await subtle.importKey(format, exported, {
167
- name: 'AES-CBC',
168
- length
169
- }, true, ['encrypt', 'decrypt'])
170
- };
171
-
172
- const exportAesKey = async (key, format = 'raw') => {
173
- return await subtle.exportKey(format, key)
174
- };
175
-
176
- const encryptAes = async (uint8Array, key, iv) => subtle.encrypt({
177
- name: 'AES-CBC',
178
- iv,
179
- }, key, uint8Array);
180
-
181
- const decryptAes = async (uint8Array, key, iv) => subtle.decrypt({
182
- name: 'AES-CBC',
183
- iv,
184
- }, key, uint8Array);
185
-
186
- const encrypt = async string => {
187
- const ec = new TextEncoder();
188
- const key = await generateAesKey();
189
- const iv = await randombytes(16);
190
- const ciphertext = await encryptAes(ec.encode(string), key, iv);
191
- const exported = await exportAesKey(key);
192
- return {
193
- key: arrayBufferToHex(exported),
194
- iv: iv.toString('hex'),
195
- cipher: arrayBufferToHex(ciphertext)
196
- }
197
- };
198
-
199
- const decrypt = async (cipher, key, iv) => {
200
- if (!key.type) key = await importAesKey(hexToUint8Array(key));
201
- cipher = new Uint8Array(hexToUint8Array(cipher));
202
- iv = new Uint8Array(hexToUint8Array(iv));
203
-
204
- const dec = new TextDecoder();
205
- const plaintext = await decryptAes(cipher, key, iv);
206
-
207
- return dec.decode(plaintext);
208
- };
209
-
210
- const createHash = async (data, algorithm = 'SHA-512') => {
211
- return await subtle.digest(algorithm, data)
212
- };
213
-
214
- class Mnemonic {
215
- constructor(options = {}) {
216
- if (!options.wordlist) this.wordlist = wordlist; // english always loaded, rest included by dev
217
- else this.wordlist = options.wordlist;
218
- }
219
-
220
- lpad(string, padString, length) {
221
- while (string.length < length) {
222
- string = padString + string;
223
- }
224
- return string;
225
- }
226
-
227
- normalize(string) {
228
- return (string || '').normalize('NFKD');
229
- }
230
-
231
- bytesToBinary(bytes) {
232
- return bytes.map(byte => this.lpad(byte.toString(2), '0', 8)).join('');
233
- }
234
-
235
- async deriveChecksumBits(entropyBuffer) {
236
- const entropy = entropyBuffer.length * 8;
237
- const cs = entropy / 32;
238
- const hash = await createHash(entropyBuffer, 'SHA-512');
239
- return this.bytesToBinary(Array.from(hash)).slice(0, cs);
240
- }
241
-
242
- async mnemonicFromEntropy(entropy) {
243
- if (!Buffer.isBuffer(entropy)) entropy = Buffer.from(entropy, 'hex');
244
- let checksum = await this.deriveChecksumBits(entropy);
245
- console.log(checksum);
246
- entropy = this.bytesToBinary(Array.from(entropy));
247
- let bits = entropy + checksum;
248
- bits = bits.match(/(.{1,11})/g);
249
- return bits.map(binary => {
250
- const index = parseInt(binary, 2);
251
- return this.wordlist[index]
252
- }).join(' ')
253
- }
254
-
255
- /**
256
- *
257
- * @param {Number} strength 256 / 8 = 32 = 24 words
258
- * @returns {String}
259
- */
260
- generate(strength = 256) {
261
- return this.mnemonicFromEntropy(randombytes(strength / 8))
262
- }
263
-
264
- salt(password) {
265
- return 'mnemonic' + this.normalize(password);
266
- }
267
-
268
- seedFromMnemonic(mnemonic, password) {
269
- const encoder =new TextEncoder();
270
- return pbkdf2(
271
- encoder.encode(this.normalize(mnemonic)),
272
- encoder.encode(this.salt(password)),
273
- 4096,
274
- 64,
275
- 'SHA-512')
276
- }
277
- }
278
-
279
- const { publicKeyConvert } = secp256k1;
280
-
281
- const publicKeyToEthereumAddress = async (publicKeyBuffer) => {
282
- let uncompressed = publicKeyConvert(publicKeyBuffer, false);
283
- const hasher = await createKeccak(256);
284
- hasher.update(uncompressed);
285
-
286
- const hash = hasher.digest();
287
- return `0x${hash.slice(-40).toString('hex')}`
288
- };
289
-
290
- class HDWallet {
291
-
292
- get chainCodeBuffer() {
293
- return this.ifNotLocked(() => this.hdnode.chainCode)
294
- }
295
-
296
- get chainCode() {
297
- return this.ifNotLocked(() => this.chainCodeBuffer.toString('hex'))
298
- }
299
-
300
- get privateKeyBuffer() {
301
- return this.ifNotLocked(() => this.hdnode.privateKey)
302
- }
303
-
304
- get privateKey() {
305
- return this.ifNotLocked(() => this.privateKeyBuffer.toString('hex'))
306
- }
307
-
308
- get publicKeyBuffer() {
309
- return this.ifNotLocked(() => this.hdnode.publicKey)
310
- }
311
-
312
- get publicKey() {
313
- return this.ifNotLocked(() => this.publicKeyBuffer.toString('hex'))
314
- }
315
-
316
- async ethereumAddress() {
317
- const address = await publicKeyToEthereumAddress(this.publicKeyBuffer);
318
- return address
319
- }
320
-
321
- get leofcoinAddress() {
322
- return bs58Check.encode(this.neutered.publicKeyBuffer)
323
- }
324
-
325
- get address() {
326
- return this.getAddressForCoin()
327
- }
328
-
329
- async getAddressForCoin(coin_type) {
330
- if (!coin_type) coin_type = this.hdnode.network.coin_type;
331
- if (coin_type === 1) {
332
- if (this.networkName?.split(':')[0] === 'ethereum') coin_type = 60;
333
- if (this.networkName?.split(':')[0] === 'leofcoin') coin_type = 640;
334
- }
335
- // if (coin_type === 0) return this.bitcoinAddress
336
- if (coin_type === 60) return this.ethereumAddress()
337
- if (coin_type === 640) return this.leofcoinAddress
338
- }
339
-
340
- get accountAddress() {
341
- return this.ifNotLocked(() => bs58Check.encode(this.hdnode.publicKeyBuffer))
342
- }
343
-
344
- get isTestnet() {
345
- if (typeof network === 'string')
346
- this.hdnode.network = fromNetworkString(network);
347
-
348
- return Boolean(this.hdnode.network.coin_type === 1)
349
- }
350
-
351
- constructor(network, hdnode) {
352
- if (typeof network === 'string') {
353
- this.networkName = network;
354
- this.network = fromNetworkString(network);
355
- } else if (typeof network === 'object')
356
- this.network = network;
357
-
358
- if (hdnode) this.defineHDNode(hdnode);
359
- }
360
-
361
- ifNotLocked(fn, params) {
362
- if (!this.locked) return fn(params);
363
- return null
364
- }
365
-
366
- defineHDNode(value) {
367
- Object.defineProperty(this, 'hdnode', {
368
- configurable: false,
369
- writable: false,
370
- value: value
371
- });
372
- }
373
-
374
- validateNetwork(network) {
375
- if (!network && !this.network) return console.error(`expected network to be defined`);
376
- if (!network && this.network) network = this.network;
377
- if (typeof network === 'string') network = fromNetworkString(network);
378
- if (typeof network !== 'object') return console.error('network not found');
379
- return network;
380
- }
381
-
382
- async generate(password, network) {
383
- network = this.validateNetwork(network);
384
- const mnemonic = await new Mnemonic().generate(512);
385
- const seed = await new Mnemonic().seedFromMnemonic(mnemonic, password, 512);
386
- this.defineHDNode(bip32.fromSeed(Buffer.from(seed, 'arrayBuffer'), network));
387
- return mnemonic;
388
- }
389
-
390
- /**
391
- * recover using mnemonic (recovery word list)
392
- */
393
- async recover(mnemonic, password, network) {
394
- network = this.validateNetwork(network, password);
395
- const seed = await new Mnemonic().seedFromMnemonic(mnemonic, password, 512);
396
- this.defineHDNode(bip32.fromSeed(Buffer.from(seed, 'arrayBuffer'), network));
397
- }
398
-
399
- load(base58, network) {
400
- network = this.validateNetwork(network);
401
- this.defineHDNode(bip32.fromBase58(base58, network));
402
- }
403
-
404
- save() {
405
- return this.hdnode.toBase58();
406
- }
407
-
408
- fromAddress(address, chainCode, network) {
409
- network = this.validateNetwork(network);
410
- // if (network.coin_type === 60) {
411
- // address = Buffer.from(address, 'hex')
412
- // } else {
413
- address = bs58Check.decode(address);
414
- // }
415
-
416
- if (!chainCode || chainCode && !Buffer.isBuffer(chainCode)) chainCode = address.slice(1);
417
- this.defineHDNode(bip32.fromPublicKey(address, chainCode, network));
418
- }
419
-
420
- fromPublicKey(hex, chainCode, network) {
421
- network = this.validateNetwork(network);
422
- if (!Buffer.isBuffer(hex)) hex = Buffer.from(hex, 'hex');
423
- if (!chainCode || chainCode && !Buffer.isBuffer(chainCode)) chainCode = hex.slice(1);
424
- this.defineHDNode(bip32.fromPublicKey(hex, chainCode, network));
425
- }
426
- }
427
-
428
- const { ecdsaSign, ecdsaVerify } = secp256k1;
429
- class MultiSignature {
430
- multiCodec;
431
- version;
432
- decoded;
433
- encoded;
434
- #multiSignature;
435
- constructor(version, multiCodec) {
436
- if (version === undefined)
437
- throw ReferenceError('version undefined');
438
- if (multiCodec === undefined)
439
- throw ReferenceError('multicodec undefined');
440
- this.multiCodec = multiCodec;
441
- this.version = version;
442
- }
443
- set multiSignature(value) {
444
- this.#multiSignature = value;
445
- }
446
- get signature() {
447
- return this.decoded.signature;
448
- }
449
- get multiSignature() {
450
- return this.#multiSignature || this.encoded || this.encode(this.signature);
451
- }
452
- export() {
453
- return base58.encode(this.multiSignature);
454
- }
455
- import(encoded) {
456
- return base58.decode(encoded);
457
- }
458
- sign(hash, privateKey) {
459
- if (!hash || !privateKey)
460
- throw ReferenceError(`${hash ? 'privateKey' : 'hash'} undefined`);
461
- const { signature } = ecdsaSign(hash, privateKey);
462
- this.decoded = {
463
- version: this.version,
464
- multiCodec: this.multiCodec,
465
- signature
466
- };
467
- return this.encode(signature);
468
- }
469
- /**
470
- * verify signature (multiSignature.signature)
471
- */
472
- verifySignature(signature, hash, publicKey) {
473
- return ecdsaVerify(signature, hash, publicKey);
474
- }
475
- /**
476
- * verify multiSignature
477
- */
478
- verify(multiSignature, hash, publicKey) {
479
- multiSignature = this.decode(multiSignature);
480
- return ecdsaVerify(multiSignature.signature, hash, publicKey);
481
- }
482
- encode(signature) {
483
- signature = signature || this.signature;
484
- if (!signature)
485
- throw ReferenceError('signature undefined');
486
- const encodedVersion = varint.encode(this.version);
487
- const encodedCodec = varint.encode(this.multiCodec);
488
- const uint8Array = new Uint8Array(encodedVersion.length + encodedCodec.length + signature.length);
489
- uint8Array.set(encodedVersion);
490
- uint8Array.set(encodedCodec, encodedVersion.length);
491
- uint8Array.set(signature, encodedVersion.length + encodedCodec.length);
492
- this.multiSignature = uint8Array;
493
- return this.multiSignature;
494
- }
495
- /**
496
- * decode exported multi signature to object
497
- * @param {multiSignature} multiSignature base58 encoded string
498
- * @return {decodedMultiSignature} { version, multiCodec, signature }
499
- */
500
- decode(multiSignature) {
501
- if (multiSignature)
502
- this.multiSignature = multiSignature;
503
- if (!this.multiSignature)
504
- throw ReferenceError('multiSignature undefined');
505
- let buffer = this.multiSignature;
506
- const version = varint.decode(buffer);
507
- buffer = buffer.slice(varint.decode.bytes);
508
- const codec = varint.decode(buffer);
509
- const signature = buffer.slice(varint.decode.bytes);
510
- if (version !== this.version)
511
- throw TypeError('Invalid version');
512
- if (this.multiCodec !== codec)
513
- throw TypeError('Invalid multiCodec');
514
- this.decoded = {
515
- version,
516
- multiCodec: codec,
517
- signature
518
- };
519
- return this.decoded;
520
- }
521
- toHex() {
522
- return this.multiSignature.toString('hex');
523
- }
524
- fromHex(hex) {
525
- return base58.decode(hex);
526
- }
527
- toBs58() {
528
- return base58.encode(this.multiSignature);
529
- }
530
- fromBs58(multiSignature) {
531
- return base58.decode(multiSignature);
532
- }
533
- toBs32() {
534
- return base32.encode(this.multiSignature);
535
- }
536
- fromBs32(multiSignature) {
537
- return base32.decode(multiSignature);
538
- }
539
- }
540
-
541
- // TODO: multihash addresses
542
- class HDAccount {
543
- /**
544
- * @param {number} depth - acount depth
545
- */
546
- constructor(node, depth = 0) {
547
- this.node = node;
548
- this.depth = depth;
549
- this._prefix = `m/44'/${node.network.coin_type}'/${depth}'/`;
550
- }
551
-
552
- /**
553
- * @param {number} index - address index
554
- */
555
- internal(index = 0) {
556
- return this.node.derivePath(`${this._prefix}1/${index}`)
557
- }
558
-
559
- /**
560
- * @param {number} index - address index
561
- */
562
- external(index = 0) {
563
- return this.node.derivePath(`${this._prefix}0/${index}`)
564
- }
565
- }
566
-
567
- class MultiWallet extends HDWallet {
568
- constructor(network, hdnode) {
569
- super(network, hdnode);
570
- this.multiCodec = this.network.multiCodec;
571
- this.version = 0x00;
572
- }
573
-
574
- get id() {
575
- const buffer = Buffer.concat([
576
- Buffer.from(varint.encode(this.multiCodec)),
577
- Buffer.from(this.account(0).node.neutered.publicKey, 'hex')
578
- ]);
579
- return bs58Check.encode(buffer)
580
- }
581
-
582
- get multiWIF() {
583
- return this.ifNotLocked(() => this.encode())
584
- }
585
-
586
- get neutered() {
587
- const neutered = this.ifNotLocked(() => new MultiWallet(this.networkName, this.hdnode.neutered()));
588
- if (neutered) this._neutered = neutered;
589
- return this._neutered
590
- }
591
-
592
- fromId(id) {
593
- let buffer = bs58Check.decode(id);
594
- varint.decode(buffer);
595
- buffer = buffer.slice(varint.decode.bytes);
596
- this.fromPublicKey(buffer, null, this.networkName);
597
- }
598
-
599
- async lock(multiWIF) {
600
- if (!multiWIF) multiWIF = this.multiWIF;
601
- this.encrypted = await encrypt(multiWIF.toString('hex'));
602
- this.locked = true;
603
- return this.encrypted
604
- }
605
-
606
- async unlock({key, iv, cipher}) {
607
- const decrypted = await decrypt(cipher, key, iv);
608
- this.import(decrypted);
609
- this.locked = false;
610
- }
611
-
612
- export() {
613
- return this.encode();
614
- }
615
-
616
- /**
617
- * encodes the multiWIF and loads wallet from bs58
618
- *
619
- * @param {multiWIF} multiWIF - note a multiWIF is not the same as a wif
620
- */
621
- import(multiWIF) {
622
- const { bs58, version, multiCodec } = this.decode(multiWIF);
623
- this.network = Object.values(networks).reduce((p, c) => {
624
- if (c.multiCodec===multiCodec) return c
625
- else if (c.testnet && c.testnet.multiCodec === multiCodec) return c.testnet
626
- else return p
627
- }, networks['leofcoin']);
628
- this.load(bs58, this.networkName);
629
- }
630
-
631
- /**
632
- * @return base58Check encoded string
633
- */
634
- encode() {
635
- const buffer = Buffer.concat([
636
- Buffer.from(varint.encode(this.version)),
637
- Buffer.from(varint.encode(this.multiCodec)),
638
- bs58Check.decode(this.save())
639
- ]);
640
- return bs58Check.encode(buffer);
641
- }
642
-
643
- decode(bs58) {
644
- let buffer = bs58Check.decode(bs58);
645
- const version = varint.decode(buffer);
646
- buffer = buffer.slice(varint.decode.bytes);
647
- const multiCodec = varint.decode(buffer);
648
- buffer = buffer.slice(varint.decode.bytes);
649
- bs58 = bs58Check.encode(buffer);
650
- if (version !== this.version) throw TypeError('Invalid version');
651
- if (this.multiCodec !== multiCodec) throw TypeError('Invalid multiCodec');
652
- return { version, multiCodec, bs58 };
653
- }
654
-
655
- sign(hash) {
656
- return new MultiSignature(this.version, this.network.multiCodec)
657
- .sign(hash, this.privateKeyBuffer);
658
-
659
- }
660
-
661
- verify(multiSignature, hash) {
662
- return new MultiSignature(this.version, this.network.multiCodec)
663
- .verify(multiSignature, hash, this.publicKeyBuffer)
664
- }
665
-
666
- /**
667
- * @param {number} account - account to return chain for
668
- * @return { internal(addressIndex), external(addressIndex) }
669
- */
670
- account(index) {
671
- return new HDAccount(new MultiWallet(this.networkName, this.hdnode), index);
672
- }
673
-
674
- /**
675
- * m / purpose' / coin_type' / account' / change / aadress_index
676
- *
677
- * see https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
678
- */
679
- derivePath(path) {
680
- return new MultiWallet(this.networkName, this.hdnode.derivePath(path))
681
- }
682
-
683
- derive(index) {
684
- return new MultiWallet(this.networkName, this.hdnode.derive(index));
685
- }
686
- }
687
-
688
- export { MultiWallet as default };