@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.
- package/CHANGELOG.md +14 -14
- package/LICENSE +88 -88
- package/README.md +4 -4
- package/demo/index.html +25 -25
- package/examples/contracts/token.js +7 -7
- package/package.json +71 -71
- package/plugins/bundle.js +18 -18
- package/src/chain.js +716 -716
- package/src/config/config.js +14 -14
- package/src/config/main.js +4 -4
- package/src/config/protocol.js +5 -5
- package/src/contract.js +51 -51
- package/src/fee/config.js +3 -3
- package/src/machine.js +215 -215
- package/src/node.js +24 -24
- package/src/protocol.js +3 -3
- package/src/state.js +31 -31
- package/src/transaction.js +233 -233
- package/src/type.index.d.ts +20 -20
- package/src/typer.js +19 -19
- package/test/chain.js +120 -109
- package/test/contracts/token.js +40 -40
- package/test/create-genesis.js +66 -66
- package/tsconfig.js +14 -14
- package/workers/block-worker.js +40 -40
- package/workers/machine-worker.js +218 -218
- package/workers/pool-worker.js +28 -28
- package/workers/transaction-worker.js +19 -19
- package/workers/workers.js +8 -8
- package/block-worker.js +0 -1
- package/demo/865.browser.js +0 -10
- package/demo/chain.browser.js +0 -66842
- package/demo/generate-account.browser.js +0 -50
- package/demo/messages.browser.js +0 -328
- package/demo/multi-wallet.browser.js +0 -15
- package/demo/node.browser.js +0 -9858
- package/demo/pako.browser.js +0 -6900
- package/demo/peernet-swarm.browser.js +0 -839
- package/demo/storage.browser.js +0 -3724
- package/demo/workers/865.js +0 -10
- package/demo/workers/block-worker.js +0 -13175
- package/demo/workers/machine-worker.js +0 -13385
- package/demo/workers/pool-worker.js +0 -8503
- package/demo/workers/transaction-worker.js +0 -8495
- package/demo/wrtc.browser.js +0 -28
- package/dist/browser/workers/865.js +0 -10
- package/dist/browser/workers/block-worker.js +0 -9460
- package/dist/browser/workers/machine-worker.js +0 -9670
- package/dist/browser/workers/pool-worker.js +0 -4608
- package/dist/browser/workers/transaction-worker.js +0 -4600
- package/dist/chain.js +0 -10128
- package/dist/client-80bc8156.js +0 -491
- package/dist/commonjs-7fe3c381.js +0 -270
- package/dist/contracts/factory.js +0 -1
- package/dist/contracts/name-service.js +0 -1
- package/dist/contracts/native-token.js +0 -1
- package/dist/contracts/validators.js +0 -1
- package/dist/generate-account-445db122.js +0 -46
- package/dist/index-57f93805.js +0 -718
- package/dist/messages-bce1b91d-81af3b00.js +0 -315
- package/dist/module/chain.js +0 -10091
- package/dist/module/client-8031ec88.js +0 -489
- package/dist/module/commonjs-9005d5c0.js +0 -268
- package/dist/module/generate-account-489552b6.js +0 -44
- package/dist/module/index-ac2285c4.js +0 -688
- package/dist/module/messages-bce1b91d-eaf75d83.js +0 -302
- package/dist/module/node.js +0 -7049
- package/dist/module/workers/block-worker.js +0 -94
- package/dist/module/workers/machine-worker.js +0 -304
- package/dist/module/workers/pool-worker.js +0 -55
- package/dist/module/workers/transaction-worker.js +0 -47
- package/dist/node.js +0 -7061
- package/dist/standards/token.js +0 -1
- package/dist/workers/machine-worker.js +0 -1
- package/dist/workers/pool-worker.js +0 -1
- 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 };
|