[{"data":1,"prerenderedAt":2158},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fcore-tech\u002Fwallet-service":3,"docs-surround-\u002Fdocs\u002Fcore-tech\u002Fwallet-service":2147},{"id":4,"title":5,"body":6,"description":12,"extension":2139,"image":2140,"meta":2141,"navTitle":2140,"navigation":2142,"path":2143,"seo":2144,"stem":2145,"__hash__":2146},"docs\u002Fdocs\u002Fcore-tech\u002FWallet-Service.md","Wallet Service",{"type":7,"value":8,"toc":2117},"minimark",[9,13,18,21,184,188,191,240,244,247,253,256,268,272,275,288,296,301,304,330,333,347,349,352,481,496,556,565,567,570,572,575,584,591,598,601,607,614,628,632,635,679,687,689,692,778,786,832,837,839,842,925,939,985,990,992,995,1067,1072,1118,1123,1125,1128,1174,1177,1221,1225,1227,1230,1302,1307,1376,1388,1390,1393,1439,1441,1487,1492,1498,1506,1513,1520,1525,1653,1660,1693,1696,1970,2077,2081,2087,2091,2094,2113],[10,11,12],"p",{},"Beam wallet service allows to implement lightweight wallets using BEAM API.",[14,15,17],"h2",{"id":16},"how-to-build","How to build",[10,19,20],{},"Wallet service and related projects are supposed to be run on Linux only. It is possible to build everything for Windows and using Windows but it is not oficially supported. Releases are also provided only for Linux.",[22,23,24,49,62,75,96,105,156],"ol",{},[25,26,27,28,35,36,40,41,44,45,48],"li",{},"Install required tools to build the generic BEAM project. Refer ",[29,30,34],"a",{"href":31,"rel":32},"https:\u002F\u002Fgithub.com\u002FBeamMW\u002Fbeam\u002Fwiki\u002FHow-to-build",[33],"nofollow","BEAM build instructions"," for detals. For example if you're using Ubuntu 18.04 Desktop you need to execute steps ",[37,38,39],"code",{},"1. Install dependencies"," & ",[37,42,43],{},"2. Install cmake"," from the ",[37,46,47],{},"Ubuntu 18.04 Desktop"," section.",[25,50,51,52,55,56,61],{},"Install golang. You need at least v1.13.0 to build the project. If the relevant package is provided with your OS it is better to use it. For example ",[37,53,54],{},"sudo dnf install golang"," on Fedora. If your OS doesn't not provide recent golang packages (like Ubuntu 18.04) use instructions ",[29,57,60],{"href":58,"rel":59},"https:\u002F\u002Fgolang.org\u002Fdoc\u002Finstall",[33],"from the official website",".",[25,63,64,65],{},"Clone the repository",[66,67,72],"pre",{"className":68,"code":70,"language":71},[69],"language-text","git clone https:\u002F\u002Fgithub.com\u002FBeamMW\u002Fwallet-service.git\n","text",[37,73,70],{"__ignoreMap":74},"",[25,76,77,78,81,82,85,86,89,90],{},"Checkout the necessary branch. We use the ",[37,79,80],{},"master"," branch for development. To be able to connect to the testnet you have to checkout the ",[37,83,84],{},"testnet"," branch. To be able to connect to the mainnet you have to checkout the ",[37,87,88],{},"mainnet"," branch.",[66,91,94],{"className":92,"code":93,"language":71},[69],"cd wallet-service\ngit checkout testnet\n",[37,95,93],{"__ignoreMap":74},[25,97,98,99],{},"Init submodules",[66,100,103],{"className":101,"code":102,"language":71},[69],"git submodule update --init --recursive\n",[37,104,102],{"__ignoreMap":74},[25,106,107,108,40,111,114,115,118,119,122,123,129,131,132,138,140,141,40,144,147,148,151,152,155],{},"Build ",[37,109,110],{},"wallet-service",[37,112,113],{},"sbbs-monitor",". Use build commands from the ",[29,116,34],{"href":31,"rel":117},[33]," according to your OS.",[120,121],"br",{},"For example for Fedora",[66,124,127],{"className":125,"code":126,"language":71},[69],"cmake -DCMAKE_BUILD_TYPE=Release . && make -j4\n",[37,128,126],{"__ignoreMap":74},[120,130],{},"For Ububtu 18.04 Desktop",[66,133,136],{"className":134,"code":135,"language":71},[69],"export CC=gcc-8 && export CXX=g++-8\ncmake -DCMAKE_BUILD_TYPE=Release && make -j4\n",[37,137,135],{"__ignoreMap":74},[120,139],{},"After the build process completes you would have ",[37,142,143],{},"wallet-service(-testnet\u002F-masternet)",[37,145,146],{},"sbbs-monitor(-testnet\u002F-masternet)"," binaries in the ",[37,149,150],{},"wallet-service\u002Fservice"," folder. Mainnet binaries do not have the ",[37,153,154],{},"-BRANCHNAME"," postfix.",[25,157,107,158,161,167,169,170,172,173,176,177,180,181,183],{},[37,159,160],{},"service-balancer",[66,162,165],{"className":163,"code":164,"language":71},[69],"cd service-balancer && go build && cd ..\n",[37,166,164],{"__ignoreMap":74},[120,168],{},"After the build process completes you would have the ",[37,171,160],{}," binary in the ",[37,174,175],{},"wallet-service\u002Fservice-balancer"," folder. N.B. At the moment manual builds do not add ",[37,178,179],{},"-masternet\u002F-testnet"," postfix to the ",[37,182,160],{}," executable.",[14,185,187],{"id":186},"prebuilt-binaries","Prebuilt binaries",[10,189,190],{},"You can get the latest prebuilt wallet service binaries here.",[22,192,193,217],{},[25,194,195,196],{},"Testnet",[197,198,199,205,211],"ul",{},[25,200,201],{},[29,202,203],{"href":203,"rel":204},"https:\u002F\u002Fbuilds.beam-mw.com\u002Ffiles\u002Ftestnet\u002Flatest\u002FRelease\u002Flinux\u002Fservice-balancer-testnet.tar.gz",[33],[25,206,207],{},[29,208,209],{"href":209,"rel":210},"https:\u002F\u002Fbuilds.beam-mw.com\u002Ffiles\u002Ftestnet\u002Flatest\u002FRelease\u002Flinux\u002Fwallet-service-testnet.tar.gz",[33],[25,212,213],{},[29,214,215],{"href":215,"rel":216},"https:\u002F\u002Fbuilds.beam-mw.com\u002Ffiles\u002Ftestnet\u002Flatest\u002FRelease\u002Flinux\u002Fsbbs-monitor-testnet.tar.gz",[33],[25,218,219,220],{},"Masternet",[197,221,222,228,234],{},[25,223,224],{},[29,225,226],{"href":226,"rel":227},"https:\u002F\u002Fbuilds.beam-mw.com\u002Ffiles\u002Fmasternet\u002Flatest\u002FRelease\u002Flinux\u002Fservice-balancer-masternet.tar.gz",[33],[25,229,230],{},[29,231,232],{"href":232,"rel":233},"https:\u002F\u002Fbuilds.beam-mw.com\u002Ffiles\u002Fmasternet\u002Flatest\u002FRelease\u002Flinux\u002Fwallet-service-masternet.tar.gz",[33],[25,235,236],{},[29,237,238],{"href":238,"rel":239},"https:\u002F\u002Fbuilds.beam-mw.com\u002Ffiles\u002Fmasternet\u002Flatest\u002FRelease\u002Flinux\u002Fsbbs-monitor-masternet.tar.gz",[33],[14,241,243],{"id":242},"deployment","Deployment",[10,245,246],{},"At the moment it is advised to use our public API enpoints until the deployment procedure is stabilized and made public. Docker would be available as well as the detailed deployment guide.",[14,248,250],{"id":249},"how-to-try",[29,251,252],{"name":249},"How to try",[10,254,255],{},"Currently the Wallet Service is deployed for masternet & testnet and provides the following public Service Balancer endpoints",[22,257,258,263],{},[25,259,195,260,262],{},[120,261],{},"wss:\u002F\u002Fweb-wallet-testnet.beam.mw\u002Fws",[25,264,219,265,267],{},[120,266],{},"wss:\u002F\u002Fweb-wallet-masternet.beam.mw\u002Fws",[14,269,271],{"id":270},"api-guide","API Guide",[10,273,274],{},"Wallet service exposes its API only via JSONRpc v2.0 over WebSockets. To access the API you should",[22,276,277,285],{},[25,278,279,280,284],{},"Login to the balancer and get the API enpoint. Check the ",[29,281,283],{"href":282},"#how-to-try","how to try section"," for the list of our public balancer endpoints.",[25,286,287],{},"Communicate with the API enpoint using the Wallet Service API.",[10,289,290,291,295],{},"Too keep user 'secrets' at the user's side Wallet Service doesn't ask for the seed phrase. Instead it expects the client to implement a set of methods that deal with secrets\u002Foutputs creation\u002Fsigning, i.e. user-side keykeeper. We provide default WebAssembly implementation of the keykeeper for JS\u002FWeb usage. Check the ",[29,292,294],{"href":293},"#wasm-key-keeper","key keeper"," section for details.",[297,298,300],"h3",{"id":299},"service-balancer-api","Service Balancer API",[10,302,303],{},"Service Balancer API provides the following methods:",[197,305,306,312,318,324],{},[25,307,308],{},[29,309,311],{"href":310},"#login","login",[25,313,314],{},[29,315,317],{"href":316},"#logout","logout",[25,319,320],{},[29,321,323],{"href":322},"#subscribe","subscribe",[25,325,326],{},[29,327,329],{"href":328},"#unsubscribe","unsubscribe",[10,331,332],{},"In addition to the Web Sockets API Service Balancer provides the following HTTP(S) endpoints:",[197,334,335,341],{},[25,336,337],{},[29,338,340],{"href":339},"#balancer-hello","\u002F",[25,342,343],{},[29,344,346],{"href":345},"#balancer-status","\u002Fstatus",[297,348,311],{"id":311},[10,350,351],{},"Login to the service balancer and get the wallet service endpoint",[66,353,357],{"className":354,"code":355,"language":356,"meta":74,"style":74},"language-json shiki shiki-themes github-dark","\u003C--\n{\n    \"jsonrpc\": \"2.0\",\n    \"id\": \"123\",\n    \"method\": \"login\",\n    \"params\":\n    {\n        \"WalletID\": \"wallet id\",\n        \"SbbsAddress\": \"\",\n        \"SbbsAddressPrivate\": \"\"\n    }\n}\n","json",[37,358,359,368,374,391,404,417,426,432,445,458,469,475],{"__ignoreMap":74},[360,361,364],"span",{"class":362,"line":363},"line",1,[360,365,367],{"class":366},"s95oV","\u003C--\n",[360,369,371],{"class":362,"line":370},2,[360,372,373],{"class":366},"{\n",[360,375,377,381,384,388],{"class":362,"line":376},3,[360,378,380],{"class":379},"sDLfK","    \"jsonrpc\"",[360,382,383],{"class":366},": ",[360,385,387],{"class":386},"sU2Wk","\"2.0\"",[360,389,390],{"class":366},",\n",[360,392,394,397,399,402],{"class":362,"line":393},4,[360,395,396],{"class":379},"    \"id\"",[360,398,383],{"class":366},[360,400,401],{"class":386},"\"123\"",[360,403,390],{"class":366},[360,405,407,410,412,415],{"class":362,"line":406},5,[360,408,409],{"class":379},"    \"method\"",[360,411,383],{"class":366},[360,413,414],{"class":386},"\"login\"",[360,416,390],{"class":366},[360,418,420,423],{"class":362,"line":419},6,[360,421,422],{"class":379},"    \"params\"",[360,424,425],{"class":366},":\n",[360,427,429],{"class":362,"line":428},7,[360,430,431],{"class":366},"    {\n",[360,433,435,438,440,443],{"class":362,"line":434},8,[360,436,437],{"class":379},"        \"WalletID\"",[360,439,383],{"class":366},[360,441,442],{"class":386},"\"wallet id\"",[360,444,390],{"class":366},[360,446,448,451,453,456],{"class":362,"line":447},9,[360,449,450],{"class":379},"        \"SbbsAddress\"",[360,452,383],{"class":366},[360,454,455],{"class":386},"\"\"",[360,457,390],{"class":366},[360,459,461,464,466],{"class":362,"line":460},10,[360,462,463],{"class":379},"        \"SbbsAddressPrivate\"",[360,465,383],{"class":366},[360,467,468],{"class":386},"\"\"\n",[360,470,472],{"class":362,"line":471},11,[360,473,474],{"class":366},"    }\n",[360,476,478],{"class":362,"line":477},12,[360,479,480],{"class":366},"}\n",[197,482,483,490,493],{},[25,484,485,486,489],{},"WalletID - wallet id, get it from ",[37,487,488],{},"keykeeper.getWalletID"," method based on the generated seed",[25,491,492],{},"SbbsAddress - reserved for future use, leave empty for now",[25,494,495],{},"SbbsAddressPrivate - reserved for future use, leave empty for now",[66,497,499],{"className":354,"code":498,"language":356,"meta":74,"style":74},"-->\n{\n    \"jsonrpc\": \"2.0\",\n    \"id\": \"123\",\n    \"result\": {\n        \"endpoint\": \"web-wallet-testnet.beam.mw?service=30000\"\n    }\n}\n",[37,500,501,506,510,520,530,538,548,552],{"__ignoreMap":74},[360,502,503],{"class":362,"line":363},[360,504,505],{"class":366},"-->\n",[360,507,508],{"class":362,"line":370},[360,509,373],{"class":366},[360,511,512,514,516,518],{"class":362,"line":376},[360,513,380],{"class":379},[360,515,383],{"class":366},[360,517,387],{"class":386},[360,519,390],{"class":366},[360,521,522,524,526,528],{"class":362,"line":393},[360,523,396],{"class":379},[360,525,383],{"class":366},[360,527,401],{"class":386},[360,529,390],{"class":366},[360,531,532,535],{"class":362,"line":406},[360,533,534],{"class":379},"    \"result\"",[360,536,537],{"class":366},": {\n",[360,539,540,543,545],{"class":362,"line":419},[360,541,542],{"class":379},"        \"endpoint\"",[360,544,383],{"class":366},[360,546,547],{"class":386},"\"web-wallet-testnet.beam.mw?service=30000\"\n",[360,549,550],{"class":362,"line":428},[360,551,474],{"class":366},[360,553,554],{"class":362,"line":434},[360,555,480],{"class":366},[197,557,558],{},[25,559,560,561,564],{},"endpoint - returns wallet service endpoint used to access Walet Service API & Beam Wallet API. You should manually append the web socket protocol prefix ",[37,562,563],{},"wss:\u002F\u002F"," in front of it.",[297,566,323],{"id":323},[10,568,569],{},"Subscribe to the BBS address notifications to be notified about incoming transaction. Reserved for future use",[297,571,329],{"id":329},[10,573,574],{},"Unsubsribe from the BBS address notifications. Reserved for future use",[10,576,577],{},[578,579,580],"strong",{},[29,581,583],{"name":582},"balancer-hello","balancer root (\u002F)",[10,585,586,587,590],{},"Just a 'hello world' endpoint. Returns the ",[37,588,589],{},"Hello! This is the wallet service balancer"," string. It is intended to be used for alive checks.",[10,592,593],{},[578,594,595],{},[29,596,346],{"name":597},"balancer-status",[10,599,600],{},"Status endpoint. Returns json with the internal service balancer methods.",[66,602,605],{"className":603,"code":604,"language":71},[69],"\u002Fstatus?secret=secret\n",[37,606,604],{"__ignoreMap":74},[10,608,609,610,613],{},"Expects secret (password) to be provided. Secret is configured in the balancer's ",[37,611,612],{},"config.json"," file. For testent & masternet this endpoint is public and can be accessed by anyone:",[197,615,616,622],{},[25,617,618],{},[29,619,620],{"href":620,"rel":621},"https:\u002F\u002Fweb-wallet-testnet.beam.mw\u002Fstatus?secret=secret",[33],[25,623,624],{},[29,625,626],{"href":626,"rel":627},"https:\u002F\u002Fweb-wallet-masternet.beam.mw\u002Fstatus?secret=secret",[33],[297,629,631],{"id":630},"wallet-service-api","Wallet Service API",[10,633,634],{},"Wallet Service API provides the following methods:",[197,636,637,643,649,655,661,667,673],{},[25,638,639],{},[29,640,642],{"href":641},"#create_wallet","create_wallet",[25,644,645],{},[29,646,648],{"href":647},"#open_wallet","open_wallet",[25,650,651],{},[29,652,654],{"href":653},"#change_password","change_password",[25,656,657],{},[29,658,660],{"href":659},"#calc_change","calc_change",[25,662,663],{},[29,664,666],{"href":665},"#release","release",[25,668,669],{},[29,670,672],{"href":671},"#ping","ping",[25,674,675],{},[29,676,678],{"href":677},"#wallet-api-methods","Wallet API methdos",[10,680,681,682,686],{},"Wallet service expect a set of keykeper-related methods to be implemented by the client. Check the ",[29,683,685],{"href":684},"#keykeeper-client-metods","Wallet Service Client keykeeper methods"," for details.",[297,688,642],{"id":642},[10,690,691],{},"Create new wallet",[66,693,695],{"className":354,"code":694,"language":356,"meta":74,"style":74},"\u003C--\n{\n    \"jsonrpc\": \"2.0\",\n    \"id\": \"123\",\n    \"method\": \"create_wallet\",\n    \"params\":\n    {\n        \"pass\": \"wallet password\",\n        \"ownerkey\": \"wallet owner key\",\n    }\n}\n",[37,696,697,701,705,715,725,736,742,746,758,770,774],{"__ignoreMap":74},[360,698,699],{"class":362,"line":363},[360,700,367],{"class":366},[360,702,703],{"class":362,"line":370},[360,704,373],{"class":366},[360,706,707,709,711,713],{"class":362,"line":376},[360,708,380],{"class":379},[360,710,383],{"class":366},[360,712,387],{"class":386},[360,714,390],{"class":366},[360,716,717,719,721,723],{"class":362,"line":393},[360,718,396],{"class":379},[360,720,383],{"class":366},[360,722,401],{"class":386},[360,724,390],{"class":366},[360,726,727,729,731,734],{"class":362,"line":406},[360,728,409],{"class":379},[360,730,383],{"class":366},[360,732,733],{"class":386},"\"create_wallet\"",[360,735,390],{"class":366},[360,737,738,740],{"class":362,"line":419},[360,739,422],{"class":379},[360,741,425],{"class":366},[360,743,744],{"class":362,"line":428},[360,745,431],{"class":366},[360,747,748,751,753,756],{"class":362,"line":434},[360,749,750],{"class":379},"        \"pass\"",[360,752,383],{"class":366},[360,754,755],{"class":386},"\"wallet password\"",[360,757,390],{"class":366},[360,759,760,763,765,768],{"class":362,"line":447},[360,761,762],{"class":379},"        \"ownerkey\"",[360,764,383],{"class":366},[360,766,767],{"class":386},"\"wallet owner key\"",[360,769,390],{"class":366},[360,771,772],{"class":362,"line":460},[360,773,474],{"class":366},[360,775,776],{"class":362,"line":471},[360,777,480],{"class":366},[197,779,780,783],{},[25,781,782],{},"pass - initial wallet password",[25,784,785],{},"ownerkey - wallet owner key, get it from key keeper",[66,787,789],{"className":354,"code":788,"language":356,"meta":74,"style":74},"-->\n{\n    \"jsonrpc\": \"2.0\",\n    \"id\": \"123\",\n    \"result\": \"wallet id\"\n}\n",[37,790,791,795,799,809,819,828],{"__ignoreMap":74},[360,792,793],{"class":362,"line":363},[360,794,505],{"class":366},[360,796,797],{"class":362,"line":370},[360,798,373],{"class":366},[360,800,801,803,805,807],{"class":362,"line":376},[360,802,380],{"class":379},[360,804,383],{"class":366},[360,806,387],{"class":386},[360,808,390],{"class":366},[360,810,811,813,815,817],{"class":362,"line":393},[360,812,396],{"class":379},[360,814,383],{"class":366},[360,816,401],{"class":386},[360,818,390],{"class":366},[360,820,821,823,825],{"class":362,"line":406},[360,822,534],{"class":379},[360,824,383],{"class":366},[360,826,827],{"class":386},"\"wallet id\"\n",[360,829,830],{"class":362,"line":419},[360,831,480],{"class":366},[197,833,834],{},[25,835,836],{},"result - returns wallet id used to identify the wallet in other API calls",[297,838,648],{"id":648},[10,840,841],{},"Open wallet with the given ID and password.",[66,843,845],{"className":354,"code":844,"language":356,"meta":74,"style":74},"\u003C--\n{\n    \"jsonrpc\": \"2.0\",\n    \"id\": \"123\",\n    \"method\": \"open_wallet\",\n    \"params\":\n    {\n        \"id\": \"\u003Cwallet ID>\",\n        \"pass\": \"\u003Cwallet password>\"\n    }\n}\n",[37,846,847,851,855,865,875,886,892,896,908,917,921],{"__ignoreMap":74},[360,848,849],{"class":362,"line":363},[360,850,367],{"class":366},[360,852,853],{"class":362,"line":370},[360,854,373],{"class":366},[360,856,857,859,861,863],{"class":362,"line":376},[360,858,380],{"class":379},[360,860,383],{"class":366},[360,862,387],{"class":386},[360,864,390],{"class":366},[360,866,867,869,871,873],{"class":362,"line":393},[360,868,396],{"class":379},[360,870,383],{"class":366},[360,872,401],{"class":386},[360,874,390],{"class":366},[360,876,877,879,881,884],{"class":362,"line":406},[360,878,409],{"class":379},[360,880,383],{"class":366},[360,882,883],{"class":386},"\"open_wallet\"",[360,885,390],{"class":366},[360,887,888,890],{"class":362,"line":419},[360,889,422],{"class":379},[360,891,425],{"class":366},[360,893,894],{"class":362,"line":428},[360,895,431],{"class":366},[360,897,898,901,903,906],{"class":362,"line":434},[360,899,900],{"class":379},"        \"id\"",[360,902,383],{"class":366},[360,904,905],{"class":386},"\"\u003Cwallet ID>\"",[360,907,390],{"class":366},[360,909,910,912,914],{"class":362,"line":447},[360,911,750],{"class":379},[360,913,383],{"class":366},[360,915,916],{"class":386},"\"\u003Cwallet password>\"\n",[360,918,919],{"class":362,"line":460},[360,920,474],{"class":366},[360,922,923],{"class":362,"line":471},[360,924,480],{"class":366},[197,926,927,936],{},[25,928,929,930,932,933,935],{},"id - wallet id returned by the ",[29,931,642],{"href":641}," method or by the ",[37,934,488],{}," method",[25,937,938],{},"pass - wallet password used to create wallet",[66,940,942],{"className":354,"code":941,"language":356,"meta":74,"style":74},"-->\n{\n    \"jsonrpc\": \"2.0\",\n    \"id\": \"123\",\n    \"result\": \"adc18c1afbb74674b5853fb4350df70a\"\n}\n",[37,943,944,948,952,962,972,981],{"__ignoreMap":74},[360,945,946],{"class":362,"line":363},[360,947,505],{"class":366},[360,949,950],{"class":362,"line":370},[360,951,373],{"class":366},[360,953,954,956,958,960],{"class":362,"line":376},[360,955,380],{"class":379},[360,957,383],{"class":366},[360,959,387],{"class":386},[360,961,390],{"class":366},[360,963,964,966,968,970],{"class":362,"line":393},[360,965,396],{"class":379},[360,967,383],{"class":366},[360,969,401],{"class":386},[360,971,390],{"class":366},[360,973,974,976,978],{"class":362,"line":406},[360,975,534],{"class":379},[360,977,383],{"class":366},[360,979,980],{"class":386},"\"adc18c1afbb74674b5853fb4350df70a\"\n",[360,982,983],{"class":362,"line":419},[360,984,480],{"class":366},[197,986,987],{},[25,988,989],{},"result - unique session id. Reserved for the future use",[297,991,654],{"id":654},[10,993,994],{},"Change wallet password. Wallet must be already opened when this method is called.",[66,996,998],{"className":354,"code":997,"language":356,"meta":74,"style":74},"\u003C--\n{\n    \"jsonrpc\": \"2.0\",\n    \"id\": \"123\",\n    \"method\": \"change_password\",\n    \"params\":\n    {\n        \"new_pass\": \"new password\"\n    }\n}\n",[37,999,1000,1004,1008,1018,1028,1039,1045,1049,1059,1063],{"__ignoreMap":74},[360,1001,1002],{"class":362,"line":363},[360,1003,367],{"class":366},[360,1005,1006],{"class":362,"line":370},[360,1007,373],{"class":366},[360,1009,1010,1012,1014,1016],{"class":362,"line":376},[360,1011,380],{"class":379},[360,1013,383],{"class":366},[360,1015,387],{"class":386},[360,1017,390],{"class":366},[360,1019,1020,1022,1024,1026],{"class":362,"line":393},[360,1021,396],{"class":379},[360,1023,383],{"class":366},[360,1025,401],{"class":386},[360,1027,390],{"class":366},[360,1029,1030,1032,1034,1037],{"class":362,"line":406},[360,1031,409],{"class":379},[360,1033,383],{"class":366},[360,1035,1036],{"class":386},"\"change_password\"",[360,1038,390],{"class":366},[360,1040,1041,1043],{"class":362,"line":419},[360,1042,422],{"class":379},[360,1044,425],{"class":366},[360,1046,1047],{"class":362,"line":428},[360,1048,431],{"class":366},[360,1050,1051,1054,1056],{"class":362,"line":434},[360,1052,1053],{"class":379},"        \"new_pass\"",[360,1055,383],{"class":366},[360,1057,1058],{"class":386},"\"new password\"\n",[360,1060,1061],{"class":362,"line":447},[360,1062,474],{"class":366},[360,1064,1065],{"class":362,"line":460},[360,1066,480],{"class":366},[197,1068,1069],{},[25,1070,1071],{},"new_pass - new wallet password",[66,1073,1075],{"className":354,"code":1074,"language":356,"meta":74,"style":74},"-->\n{\n    \"jsonrpc\": \"2.0\",\n    \"id\": \"123\",\n    \"result\": \"done\"\n}\n",[37,1076,1077,1081,1085,1095,1105,1114],{"__ignoreMap":74},[360,1078,1079],{"class":362,"line":363},[360,1080,505],{"class":366},[360,1082,1083],{"class":362,"line":370},[360,1084,373],{"class":366},[360,1086,1087,1089,1091,1093],{"class":362,"line":376},[360,1088,380],{"class":379},[360,1090,383],{"class":366},[360,1092,387],{"class":386},[360,1094,390],{"class":366},[360,1096,1097,1099,1101,1103],{"class":362,"line":393},[360,1098,396],{"class":379},[360,1100,383],{"class":366},[360,1102,401],{"class":386},[360,1104,390],{"class":366},[360,1106,1107,1109,1111],{"class":362,"line":406},[360,1108,534],{"class":379},[360,1110,383],{"class":366},[360,1112,1113],{"class":386},"\"done\"\n",[360,1115,1116],{"class":362,"line":419},[360,1117,480],{"class":366},[197,1119,1120],{},[25,1121,1122],{},"result - \"done\" on success",[297,1124,666],{"id":666},[10,1126,1127],{},"Close (release) the currently opened wallet. Usually it is not necessary to call this method. Wallet would be automatically closed as soon as the web socket connection is released.",[66,1129,1131],{"className":354,"code":1130,"language":356,"meta":74,"style":74},"\u003C--\n{\n    \"jsonrpc\": \"2.0\",\n    \"id\": \"123\",\n    \"method\": \"release\"\n}\n\n",[37,1132,1133,1137,1141,1151,1161,1170],{"__ignoreMap":74},[360,1134,1135],{"class":362,"line":363},[360,1136,367],{"class":366},[360,1138,1139],{"class":362,"line":370},[360,1140,373],{"class":366},[360,1142,1143,1145,1147,1149],{"class":362,"line":376},[360,1144,380],{"class":379},[360,1146,383],{"class":366},[360,1148,387],{"class":386},[360,1150,390],{"class":366},[360,1152,1153,1155,1157,1159],{"class":362,"line":393},[360,1154,396],{"class":379},[360,1156,383],{"class":366},[360,1158,401],{"class":386},[360,1160,390],{"class":366},[360,1162,1163,1165,1167],{"class":362,"line":406},[360,1164,409],{"class":379},[360,1166,383],{"class":366},[360,1168,1169],{"class":386},"\"release\"\n",[360,1171,1172],{"class":362,"line":419},[360,1173,480],{"class":366},[10,1175,1176],{},"This method does not have any parameters.",[66,1178,1179],{"className":354,"code":1074,"language":356,"meta":74,"style":74},[37,1180,1181,1185,1189,1199,1209,1217],{"__ignoreMap":74},[360,1182,1183],{"class":362,"line":363},[360,1184,505],{"class":366},[360,1186,1187],{"class":362,"line":370},[360,1188,373],{"class":366},[360,1190,1191,1193,1195,1197],{"class":362,"line":376},[360,1192,380],{"class":379},[360,1194,383],{"class":366},[360,1196,387],{"class":386},[360,1198,390],{"class":366},[360,1200,1201,1203,1205,1207],{"class":362,"line":393},[360,1202,396],{"class":379},[360,1204,383],{"class":366},[360,1206,401],{"class":386},[360,1208,390],{"class":366},[360,1210,1211,1213,1215],{"class":362,"line":406},[360,1212,534],{"class":379},[360,1214,383],{"class":366},[360,1216,1113],{"class":386},[360,1218,1219],{"class":362,"line":419},[360,1220,480],{"class":366},[197,1222,1223],{},[25,1224,1122],{},[297,1226,660],{"id":660},[10,1228,1229],{},"Service method used to calculate change for the given transaction amount",[66,1231,1233],{"className":354,"code":1232,"language":356,"meta":74,"style":74},"\u003C--\n{\n    \"jsonrpc\": \"2.0\",\n    \"id\": \"123\",\n    \"method\": \"calc_change\",\n    \"params\":\n    {\n        \"amount\": 100\n    }\n}\n",[37,1234,1235,1239,1243,1253,1263,1274,1280,1284,1294,1298],{"__ignoreMap":74},[360,1236,1237],{"class":362,"line":363},[360,1238,367],{"class":366},[360,1240,1241],{"class":362,"line":370},[360,1242,373],{"class":366},[360,1244,1245,1247,1249,1251],{"class":362,"line":376},[360,1246,380],{"class":379},[360,1248,383],{"class":366},[360,1250,387],{"class":386},[360,1252,390],{"class":366},[360,1254,1255,1257,1259,1261],{"class":362,"line":393},[360,1256,396],{"class":379},[360,1258,383],{"class":366},[360,1260,401],{"class":386},[360,1262,390],{"class":366},[360,1264,1265,1267,1269,1272],{"class":362,"line":406},[360,1266,409],{"class":379},[360,1268,383],{"class":366},[360,1270,1271],{"class":386},"\"calc_change\"",[360,1273,390],{"class":366},[360,1275,1276,1278],{"class":362,"line":419},[360,1277,422],{"class":379},[360,1279,425],{"class":366},[360,1281,1282],{"class":362,"line":428},[360,1283,431],{"class":366},[360,1285,1286,1289,1291],{"class":362,"line":434},[360,1287,1288],{"class":379},"        \"amount\"",[360,1290,383],{"class":366},[360,1292,1293],{"class":379},"100\n",[360,1295,1296],{"class":362,"line":447},[360,1297,474],{"class":366},[360,1299,1300],{"class":362,"line":460},[360,1301,480],{"class":366},[197,1303,1304],{},[25,1305,1306],{},"amount - transaction amount in groth",[66,1308,1310],{"className":354,"code":1309,"language":356,"meta":74,"style":74},"-->\n{\n    \"jsonrpc\": \"2.0\",\n    \"id\": \"123\",\n    \"result\": {\n        \"change\": 499999900,\n        \"change_str\": \"499999900\"\n    }\n}\n",[37,1311,1312,1316,1320,1330,1340,1346,1358,1368,1372],{"__ignoreMap":74},[360,1313,1314],{"class":362,"line":363},[360,1315,505],{"class":366},[360,1317,1318],{"class":362,"line":370},[360,1319,373],{"class":366},[360,1321,1322,1324,1326,1328],{"class":362,"line":376},[360,1323,380],{"class":379},[360,1325,383],{"class":366},[360,1327,387],{"class":386},[360,1329,390],{"class":366},[360,1331,1332,1334,1336,1338],{"class":362,"line":393},[360,1333,396],{"class":379},[360,1335,383],{"class":366},[360,1337,401],{"class":386},[360,1339,390],{"class":366},[360,1341,1342,1344],{"class":362,"line":406},[360,1343,534],{"class":379},[360,1345,537],{"class":366},[360,1347,1348,1351,1353,1356],{"class":362,"line":419},[360,1349,1350],{"class":379},"        \"change\"",[360,1352,383],{"class":366},[360,1354,1355],{"class":379},"499999900",[360,1357,390],{"class":366},[360,1359,1360,1363,1365],{"class":362,"line":428},[360,1361,1362],{"class":379},"        \"change_str\"",[360,1364,383],{"class":366},[360,1366,1367],{"class":386},"\"499999900\"\n",[360,1369,1370],{"class":362,"line":434},[360,1371,474],{"class":366},[360,1373,1374],{"class":362,"line":447},[360,1375,480],{"class":366},[197,1377,1378,1381],{},[25,1379,1380],{},"change - transaction change in groth",[25,1382,1383,1384,1387],{},"change_str - string representation of the ",[37,1385,1386],{},"change"," parameter",[297,1389,672],{"id":672},[10,1391,1392],{},"Just a convenience ping (are you alive?) method. It is recommended not to use this method but to rely on the underlying websocket infrastructure which already implements ping-pong control frames.",[66,1394,1396],{"className":354,"code":1395,"language":356,"meta":74,"style":74},"\u003C--\n{\n    \"jsonrpc\": \"2.0\",\n    \"id\": \"123\",\n    \"method\": \"ping\"\n}\n\n",[37,1397,1398,1402,1406,1416,1426,1435],{"__ignoreMap":74},[360,1399,1400],{"class":362,"line":363},[360,1401,367],{"class":366},[360,1403,1404],{"class":362,"line":370},[360,1405,373],{"class":366},[360,1407,1408,1410,1412,1414],{"class":362,"line":376},[360,1409,380],{"class":379},[360,1411,383],{"class":366},[360,1413,387],{"class":386},[360,1415,390],{"class":366},[360,1417,1418,1420,1422,1424],{"class":362,"line":393},[360,1419,396],{"class":379},[360,1421,383],{"class":366},[360,1423,401],{"class":386},[360,1425,390],{"class":366},[360,1427,1428,1430,1432],{"class":362,"line":406},[360,1429,409],{"class":379},[360,1431,383],{"class":366},[360,1433,1434],{"class":386},"\"ping\"\n",[360,1436,1437],{"class":362,"line":419},[360,1438,480],{"class":366},[10,1440,1176],{},[66,1442,1444],{"className":354,"code":1443,"language":356,"meta":74,"style":74},"-->\n{\n    \"jsonrpc\": \"2.0\",\n    \"id\": \"123\",\n    \"result\": \"pong\"\n}\n",[37,1445,1446,1450,1454,1464,1474,1483],{"__ignoreMap":74},[360,1447,1448],{"class":362,"line":363},[360,1449,505],{"class":366},[360,1451,1452],{"class":362,"line":370},[360,1453,373],{"class":366},[360,1455,1456,1458,1460,1462],{"class":362,"line":376},[360,1457,380],{"class":379},[360,1459,383],{"class":366},[360,1461,387],{"class":386},[360,1463,390],{"class":366},[360,1465,1466,1468,1470,1472],{"class":362,"line":393},[360,1467,396],{"class":379},[360,1469,383],{"class":366},[360,1471,401],{"class":386},[360,1473,390],{"class":366},[360,1475,1476,1478,1480],{"class":362,"line":406},[360,1477,534],{"class":379},[360,1479,383],{"class":366},[360,1481,1482],{"class":386},"\"pong\"\n",[360,1484,1485],{"class":362,"line":419},[360,1486,480],{"class":366},[197,1488,1489],{},[25,1490,1491],{},"result - \"pong\" on success",[297,1493,1495],{"id":1494},"wallet-api-methods",[29,1496,1497],{"name":1494},"wallet API methods",[10,1499,1500,1501,295],{},"Wallet service also implements all the BEAM Wallet Protocol API methods. Please consult the ",[29,1502,1505],{"href":1503,"rel":1504},"https:\u002F\u002Fgithub.com\u002FBeamMW\u002Fbeam\u002Fwiki\u002FBeam-wallet-protocol-API",[33],"Beam wallet protocol API",[297,1507,1509],{"id":1508},"webassembly-keykeeper",[29,1510,1512],{"name":1511},"wasm-key-keeper","WebAssembly Keykeeper",[10,1514,1515],{},[29,1516,1519],{"href":1517,"rel":1518},"https:\u002F\u002Fbuilds.beam.mw\u002Ftestnet\u002F2020.06.16\u002FMinSizeRel\u002Fwasm\u002Fwasm-key-keeper.tar.gz",[33],"Get latest testnet version",[1521,1522,1524],"h4",{"id":1523},"keykeeper-initialization-example","Keykeeper initialization example:",[66,1526,1530],{"className":1527,"code":1528,"language":1529,"meta":74,"style":74},"language-html shiki shiki-themes github-dark","\u003C!DOCTYPE html>\n\u003Chtml>\n\u003Cscript src='wasm-key-keeper.js'>\u003C\u002Fscript>\n\u003Cscript type=\"text\u002Fjavascript\">\n    Module().then((Module) => console.log(`Key Keeper module successfully loaded.`))\n\u003C\u002Fscript>\n\u003C\u002Fhtml>\n","html",[37,1531,1532,1548,1557,1580,1596,1636,1645],{"__ignoreMap":74},[360,1533,1534,1537,1541,1545],{"class":362,"line":363},[360,1535,1536],{"class":366},"\u003C!",[360,1538,1540],{"class":1539},"s4JwU","DOCTYPE",[360,1542,1544],{"class":1543},"svObZ"," html",[360,1546,1547],{"class":366},">\n",[360,1549,1550,1553,1555],{"class":362,"line":370},[360,1551,1552],{"class":366},"\u003C",[360,1554,1529],{"class":1539},[360,1556,1547],{"class":366},[360,1558,1559,1561,1564,1567,1570,1573,1576,1578],{"class":362,"line":376},[360,1560,1552],{"class":366},[360,1562,1563],{"class":1539},"script",[360,1565,1566],{"class":1543}," src",[360,1568,1569],{"class":366},"=",[360,1571,1572],{"class":386},"'wasm-key-keeper.js'",[360,1574,1575],{"class":366},">\u003C\u002F",[360,1577,1563],{"class":1539},[360,1579,1547],{"class":366},[360,1581,1582,1584,1586,1589,1591,1594],{"class":362,"line":393},[360,1583,1552],{"class":366},[360,1585,1563],{"class":1539},[360,1587,1588],{"class":1543}," type",[360,1590,1569],{"class":366},[360,1592,1593],{"class":386},"\"text\u002Fjavascript\"",[360,1595,1547],{"class":366},[360,1597,1598,1601,1604,1607,1610,1614,1617,1621,1624,1627,1630,1633],{"class":362,"line":406},[360,1599,1600],{"class":1543},"    Module",[360,1602,1603],{"class":366},"().",[360,1605,1606],{"class":1543},"then",[360,1608,1609],{"class":366},"((",[360,1611,1613],{"class":1612},"s9osk","Module",[360,1615,1616],{"class":366},") ",[360,1618,1620],{"class":1619},"snl16","=>",[360,1622,1623],{"class":366}," console.",[360,1625,1626],{"class":1543},"log",[360,1628,1629],{"class":366},"(",[360,1631,1632],{"class":386},"`Key Keeper module successfully loaded.`",[360,1634,1635],{"class":366},"))\n",[360,1637,1638,1641,1643],{"class":362,"line":419},[360,1639,1640],{"class":366},"\u003C\u002F",[360,1642,1563],{"class":1539},[360,1644,1547],{"class":366},[360,1646,1647,1649,1651],{"class":362,"line":428},[360,1648,1640],{"class":366},[360,1650,1529],{"class":1539},[360,1652,1547],{"class":366},[1521,1654,1656],{"id":1655},"wallet-service-client-keykeeper-methods",[29,1657,1659],{"name":1658},"keykeeper-client-metods","Wallet Service client keykeeper methods",[197,1661,1662,1668,1673,1678,1683,1688],{},[25,1663,1664],{},[29,1665,1667],{"href":1666},"#keykeeper-methods","get_kdf",[25,1669,1670],{},[29,1671,1672],{"href":1666},"get_slots",[25,1674,1675],{},[29,1676,1677],{"href":1666},"create_output",[25,1679,1680],{},[29,1681,1682],{"href":1666},"sign_receiver",[25,1684,1685],{},[29,1686,1687],{"href":1666},"sign_sender",[25,1689,1690],{},[29,1691,1692],{"href":1666},"sign_split",[10,1694,1695],{},"These methods are supported by the default WASM keykeeper. Wallet Service Client should just implement a simple proxy:",[66,1697,1699],{"className":1527,"code":1698,"language":1529,"meta":74,"style":74},"\u003C!DOCTYPE html>\n\u003Chtml>\n\u003Cscript src='wasm-key-keeper.js'>\u003C\u002Fscript>\n\u003Cscript type=\"text\u002Fjavascript\">\n    Module().then((Module) => {\n        var connection = null;\n        var endpoint = 'ws:\u002F\u002Furl-to-service';\n        var seed = Module.KeyKeeper.GeneratePhrase();\n    var keykeeper = new Module.KeyKeeper(seed);\n        connection = new WebSocket(endpoint);\n        connection.onmessage = e =>  {\n        var data = JSON.parse(e.data);\n            if(data.method) {\n            var res = keykeeper.invokeServiceMethod(e.data);\n        connection.send(res);\n        }\n       }\n    })\n\u003C\u002Fscript>\n\u003C\u002Fhtml>\n",[37,1700,1701,1711,1719,1737,1751,1770,1786,1800,1818,1840,1855,1875,1895,1904,1923,1934,1940,1946,1952,1961],{"__ignoreMap":74},[360,1702,1703,1705,1707,1709],{"class":362,"line":363},[360,1704,1536],{"class":366},[360,1706,1540],{"class":1539},[360,1708,1544],{"class":1543},[360,1710,1547],{"class":366},[360,1712,1713,1715,1717],{"class":362,"line":370},[360,1714,1552],{"class":366},[360,1716,1529],{"class":1539},[360,1718,1547],{"class":366},[360,1720,1721,1723,1725,1727,1729,1731,1733,1735],{"class":362,"line":376},[360,1722,1552],{"class":366},[360,1724,1563],{"class":1539},[360,1726,1566],{"class":1543},[360,1728,1569],{"class":366},[360,1730,1572],{"class":386},[360,1732,1575],{"class":366},[360,1734,1563],{"class":1539},[360,1736,1547],{"class":366},[360,1738,1739,1741,1743,1745,1747,1749],{"class":362,"line":393},[360,1740,1552],{"class":366},[360,1742,1563],{"class":1539},[360,1744,1588],{"class":1543},[360,1746,1569],{"class":366},[360,1748,1593],{"class":386},[360,1750,1547],{"class":366},[360,1752,1753,1755,1757,1759,1761,1763,1765,1767],{"class":362,"line":406},[360,1754,1600],{"class":1543},[360,1756,1603],{"class":366},[360,1758,1606],{"class":1543},[360,1760,1609],{"class":366},[360,1762,1613],{"class":1612},[360,1764,1616],{"class":366},[360,1766,1620],{"class":1619},[360,1768,1769],{"class":366}," {\n",[360,1771,1772,1775,1778,1780,1783],{"class":362,"line":419},[360,1773,1774],{"class":1619},"        var",[360,1776,1777],{"class":366}," connection ",[360,1779,1569],{"class":1619},[360,1781,1782],{"class":379}," null",[360,1784,1785],{"class":366},";\n",[360,1787,1788,1790,1793,1795,1798],{"class":362,"line":428},[360,1789,1774],{"class":1619},[360,1791,1792],{"class":366}," endpoint ",[360,1794,1569],{"class":1619},[360,1796,1797],{"class":386}," 'ws:\u002F\u002Furl-to-service'",[360,1799,1785],{"class":366},[360,1801,1802,1804,1807,1809,1812,1815],{"class":362,"line":434},[360,1803,1774],{"class":1619},[360,1805,1806],{"class":366}," seed ",[360,1808,1569],{"class":1619},[360,1810,1811],{"class":366}," Module.KeyKeeper.",[360,1813,1814],{"class":1543},"GeneratePhrase",[360,1816,1817],{"class":366},"();\n",[360,1819,1820,1823,1826,1828,1831,1834,1837],{"class":362,"line":447},[360,1821,1822],{"class":1619},"    var",[360,1824,1825],{"class":366}," keykeeper ",[360,1827,1569],{"class":1619},[360,1829,1830],{"class":1619}," new",[360,1832,1833],{"class":366}," Module.",[360,1835,1836],{"class":1543},"KeyKeeper",[360,1838,1839],{"class":366},"(seed);\n",[360,1841,1842,1845,1847,1849,1852],{"class":362,"line":460},[360,1843,1844],{"class":366},"        connection ",[360,1846,1569],{"class":1619},[360,1848,1830],{"class":1619},[360,1850,1851],{"class":1543}," WebSocket",[360,1853,1854],{"class":366},"(endpoint);\n",[360,1856,1857,1860,1863,1866,1869,1872],{"class":362,"line":471},[360,1858,1859],{"class":366},"        connection.",[360,1861,1862],{"class":1543},"onmessage",[360,1864,1865],{"class":1619}," =",[360,1867,1868],{"class":1612}," e",[360,1870,1871],{"class":1619}," =>",[360,1873,1874],{"class":366},"  {\n",[360,1876,1877,1879,1882,1884,1887,1889,1892],{"class":362,"line":477},[360,1878,1774],{"class":1619},[360,1880,1881],{"class":366}," data ",[360,1883,1569],{"class":1619},[360,1885,1886],{"class":379}," JSON",[360,1888,61],{"class":366},[360,1890,1891],{"class":1543},"parse",[360,1893,1894],{"class":366},"(e.data);\n",[360,1896,1898,1901],{"class":362,"line":1897},13,[360,1899,1900],{"class":1619},"            if",[360,1902,1903],{"class":366},"(data.method) {\n",[360,1905,1907,1910,1913,1915,1918,1921],{"class":362,"line":1906},14,[360,1908,1909],{"class":1619},"            var",[360,1911,1912],{"class":366}," res ",[360,1914,1569],{"class":1619},[360,1916,1917],{"class":366}," keykeeper.",[360,1919,1920],{"class":1543},"invokeServiceMethod",[360,1922,1894],{"class":366},[360,1924,1926,1928,1931],{"class":362,"line":1925},15,[360,1927,1859],{"class":366},[360,1929,1930],{"class":1543},"send",[360,1932,1933],{"class":366},"(res);\n",[360,1935,1937],{"class":362,"line":1936},16,[360,1938,1939],{"class":366},"        }\n",[360,1941,1943],{"class":362,"line":1942},17,[360,1944,1945],{"class":366},"       }\n",[360,1947,1949],{"class":362,"line":1948},18,[360,1950,1951],{"class":366},"    })\n",[360,1953,1955,1957,1959],{"class":362,"line":1954},19,[360,1956,1640],{"class":366},[360,1958,1563],{"class":1539},[360,1960,1547],{"class":366},[360,1962,1964,1966,1968],{"class":362,"line":1963},20,[360,1965,1640],{"class":366},[360,1967,1529],{"class":1539},[360,1969,1547],{"class":366},[1971,1972,1973,1992],"table",{},[1974,1975,1976],"thead",{},[1977,1978,1979,1983,1986,1989],"tr",{},[1980,1981,1982],"th",{},"Method",[1980,1984,1985],{},"Description",[1980,1987,1988],{},"Arguments",[1980,1990,1991],{},"Return",[1993,1994,1995,2010,2024,2038,2052,2064],"tbody",{},[1977,1996,1997,2001,2004,2007],{},[1998,1999,2000],"td",{},"getOwnerKey",[1998,2002,2003],{},"get owner key from password",[1998,2005,2006],{},"wallet password (string)",[1998,2008,2009],{},"owner key (string)",[1977,2011,2012,2015,2018,2021],{},[1998,2013,2014],{},"ConvertTokenToJson",[1998,2016,2017],{},"get token data",[1998,2019,2020],{},"token (string)",[1998,2022,2023],{},"PeerID (string), PeerWalletIdentity (string), TransactionType (number), tx_id (number)",[1977,2025,2026,2029,2032,2035],{},[1998,2027,2028],{},"getSendToken",[1998,2030,2031],{},"generate token",[1998,2033,2034],{},"sbbsAddressHex (string), identityStrHex (string), amountBase64 (string)",[1998,2036,2037],{},"key (string)",[1977,2039,2040,2043,2046,2049],{},[1998,2041,2042],{},"getWalletID",[1998,2044,2045],{},"get wallet id",[1998,2047,2048],{},"-",[1998,2050,2051],{},"wallet id (string)",[1977,2053,2054,2056,2059,2061],{},[1998,2055,1814],{},[1998,2057,2058],{},"generate seed phrase",[1998,2060,2048],{},[1998,2062,2063],{},"seed phrase (string)",[1977,2065,2066,2069,2072,2074],{},[1998,2067,2068],{},"IsValidPhrase",[1998,2070,2071],{},"seed phrase validation",[1998,2073,2048],{},[1998,2075,2076],{},"is seed valid (boolean)",[1521,2078,2080],{"id":2079},"minimal-wallet-implementation-example","Minimal Wallet implementation example:",[66,2082,2085],{"className":2083,"code":2084,"language":71},[69],"﻿\u003C!doctype html>\n\u003Chtml lang=\"en\">\n\u003Chead>\n    \u003Ctitle>Beam Wallet Client\u003C\u002Ftitle>\n\n    \u003Cmeta charset=\"utf-8\">\n    \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">\n\n    \u003Clink rel=\"stylesheet\" href=\"https:\u002F\u002Fstackpath.bootstrapcdn.com\u002Fbootstrap\u002F4.3.1\u002Fcss\u002Fbootstrap.min.css\" integrity=\"sha384-ggOyR0iXCbMQv3Xipma34MD+dH\u002F1fQ784\u002Fj6cY\u002FiJTQUOhcWr7x9JvoRxT2MZw1T\" crossorigin=\"anonymous\">\n\u003C\u002Fhead>\n\n\u003Cbody>\n    \u003Cdiv class=\"container\">\n        \u003Ch1 class=\"text-center\">Beam Wallet Client\u003C\u002Fh1>\n        \u003Chr>\n\n        \u003Chr>\n        \u003Cdiv id=\"login-panel\">\n          \u003Cspan class=\"badge badge-danger\">status: logging in, please wait...\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n\n        \u003Cdiv id=\"connecting-panel\" style=\"display: none;\">\n            \u003Cspan class=\"badge badge-danger\">status: connecting to the Wallet Service, please wait...\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n\n        \u003Cform id=\"create-wallet-panel\" style=\"display: none;\">\n            \u003Cdiv class=\"form-group\">\n                \u003Cspan class=\"badge badge-success\">status: connected to the Wallet Service\u003C\u002Fspan>\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"form-group\">\n                \u003Clabel for=\"seed-phrase-input\">Generated seed phrase:\u003C\u002Flabel>\n                \u003Cinput disabled type=\"text\" class=\"seed-phrase-input form-control\" placeholder=\"Enter seed phrase\">\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"form-group\">\n                \u003Clabel for=\"wallet-pass-input\">Enter wallet password:\u003C\u002Flabel>\n                \u003Cinput type=\"password\" class=\"wallet-pass-input form-control\" placeholder=\"Enter wallet password\" value=\"456\">\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"form-group\">\n                \u003Cbutton type=\"button\" class=\"create-wallet-button btn btn-primary\">\n                    \u003Cspan class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\" style=\"display: none;\">\u003C\u002Fspan>\n                    Create new wallet\n                \u003C\u002Fbutton>\n            \u003C\u002Fdiv>\n        \u003C\u002Fform>\n\n        \u003Cform id=\"open-wallet-panel\" style=\"display: none;\">\n            \u003Cdiv class=\"form-group\">\n                \u003Cspan class=\"badge badge-success\">status: connected to the Wallet Service\u003C\u002Fspan>\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"form-group\">\n                \u003Clabel for=\"wallet-pass-input\">Enter wallet password:\u003C\u002Flabel>\n                \u003Cinput type=\"password\" class=\"wallet-pass-input form-control\" placeholder=\"Enter wallet password\" value=\"456\">\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"form-group\">\n                \u003Cbutton type=\"button\" class=\"open-wallet-button btn btn-primary\">\n                    \u003Cspan class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\" style=\"display: none;\">\u003C\u002Fspan>\n                    Open wallet\n                \u003C\u002Fbutton>\n                or\n                \u003Cbutton type=\"button\" class=\"delete-wallet-button btn btn-danger\">\n                        \u003Cspan class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\" style=\"display: none;\">\u003C\u002Fspan>\n                        Delete wallet\n                \u003C\u002Fbutton>\n            \u003C\u002Fdiv>\n        \u003C\u002Fform>\n\n        \u003Cform id=\"wallet-panel\" style=\"display: none;\">\n            \u003Cdiv class=\"form-group\">\n                \u003Cspan class=\"badge badge-success\">status: connected to the Wallet Service\u003C\u002Fspan>\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"form-group\">\n                \u003Cdiv>Available: \u003Cspan class=\"available\">\u003C\u002Fspan>\u003C\u002Fdiv>\n                \u003Cdiv>Sending: \u003Cspan class=\"sending\">\u003C\u002Fspan>\u003C\u002Fdiv>\n                \u003Cdiv>Receiving: \u003Cspan class=\"receiving\">\u003C\u002Fspan>\u003C\u002Fdiv>\n            \u003C\u002Fdiv>\n            \u003Cdiv class=\"form-group\">\n                Current height: \u003Cspan class=\"current_height\">\u003C\u002Fspan>\n            \u003C\u002Fdiv>\n            \u003Chr>\n            \u003Ch3>Send\u003C\u002Fh3>\n                \u003Cdiv class=\"form-group\">\n                    \u003Clabel for=\"receiver-address-input\">Enter receiver address:\u003C\u002Flabel>\n                    \u003Cinput type=\"text\" class=\"receiver-address-input form-control\" placeholder=\"Enter receiver address\" value=\"19f3b39d925ce49f19f67c3787b54bfe4414d490f0acf42b58527a23608427bbb34\">\n                \u003C\u002Fdiv>\n                \u003Cdiv class=\"form-group\">\n                    \u003Clabel for=\"amount-input\">Enter amount (GROTH):\u003C\u002Flabel>\n                    \u003Cinput type=\"text\" class=\"amount-input form-control\" placeholder=\"Enter amount\">\n                \u003C\u002Fdiv>\n                \u003Cbutton type=\"button\" class=\"send-button btn btn-danger\">\n                    Send\n                \u003C\u002Fbutton>               \n            \u003Chr>\n            \u003Ch3>Transactions\u003C\u002Fh3>\n            \u003Ctable class=\"table transactions\">\n                \u003Cthead>\n                    \u003Ctr>\n                        \u003Cth>#\u003C\u002Fth>\n                        \u003Cth>created\u003C\u002Fth>\n                        \u003Cth>receiver\u003C\u002Fth>\n                        \u003Cth>sender\u003C\u002Fth>\n                        \u003Cth>amount\u003C\u002Fth>\n                        \u003Cth>status\u003C\u002Fth>\n                    \u003C\u002Ftr>\n                \u003C\u002Fthead>\n                \u003Ctbody>\u003C\u002Ftbody>\n            \u003C\u002Ftable>\n            \u003Chr>\n            \u003Ch3>Addresses\u003C\u002Fh3>\n            \u003Ctable class=\"table addresses\">\n                \u003Cthead>\n                    \u003Ctr>\n                        \u003Cth>#\u003C\u002Fth>\n                        \u003Cth>address\u003C\u002Fth>\n                        \u003Cth>comment\u003C\u002Fth>\n                        \u003Cth>create time\u003C\u002Fth>\n                        \u003Cth>duration\u003C\u002Fth>\n                        \u003Cth>expired\u003C\u002Fth>\n                        \u003Cth>own\u003C\u002Fth>\n                    \u003C\u002Ftr>\n                \u003C\u002Fthead>\n                \u003Ctbody>\u003C\u002Ftbody>\n            \u003C\u002Ftable>\n            \u003Cdiv id=\"push-panel\" style=\"display:none\">\n            \u003Cbutton class=\"btn btn-secondary\" id=\"push-enable\" style=\"display:none\">Enable Push Notifications\u003C\u002Fbutton>\n            \u003Cbutton class=\"btn btn-secondary\" id=\"push-disable\" style=\"display:none\">Disable Push Notifications\u003C\u002Fbutton>\n            \u003Cspan id=\"push-blocked\" style=\"display:none\">Push notifications are blocked by user\u003C\u002Fspan>\n            \u003C\u002Fdiv>\n            \u003Chr>\n            \u003Ch3>UTXO\u003C\u002Fh3>\n            \u003Ctable class=\"table utxo\">\n                \u003Cthead>\n                    \u003Ctr>\n                        \u003Cth>#\u003C\u002Fth>\n                        \u003Cth>amount\u003C\u002Fth>\n                        \u003Cth>id\u003C\u002Fth>\n                        \u003Cth>maturity\u003C\u002Fth>\n                        \u003Cth>status\u003C\u002Fth>\n                        \u003Cth>type\u003C\u002Fth>\n                    \u003C\u002Ftr>\n                \u003C\u002Fthead>\n                \u003Ctbody>\u003C\u002Ftbody>\n            \u003C\u002Ftable>\n            \u003Chr>\n            \u003Cbutton type=\"button\" class=\"close-wallet-button btn btn-secondary\">\n                Close wallet\n            \u003C\u002Fbutton>\n        \u003C\u002Fform>     \n    \n    \u003C\u002Fdiv>\n\u003C\u002Fbody>\n    \u003Cscript src='wasm-key-keeper.js'>\u003C\u002Fscript>\n    \u003Cscript src=\"https:\u002F\u002Fcode.jquery.com\u002Fjquery-3.3.1.slim.min.js\" integrity=\"sha384-q8i\u002FX+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo\" crossorigin=\"anonymous\">\u003C\u002Fscript>\n    \u003Cscript src=\"https:\u002F\u002Fcdnjs.cloudflare.com\u002Fajax\u002Flibs\u002Fpopper.js\u002F1.14.7\u002Fumd\u002Fpopper.min.js\" integrity=\"sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1\" crossorigin=\"anonymous\">\u003C\u002Fscript>\n    \u003Cscript src=\"https:\u002F\u002Fstackpath.bootstrapcdn.com\u002Fbootstrap\u002F4.3.1\u002Fjs\u002Fbootstrap.min.js\" integrity=\"sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf\u002FnJGzIxFDsf4x0xIM+B07jRM\" crossorigin=\"anonymous\">\u003C\u002Fscript>\n    \u003Cscript type=\"module\">\n    import WebPush from '.\u002Fwebpush.js'\n    Module().then(function(Module) {\n        let keykeeper = null\n        var loginConnection = null\n        var connection = null\n        var webpush = null\n        var defaddr = null\n\n        login()\n\n        \u002F\u002F If you change walletID\u002Fseed you should ALWAYS relogin\n        \u002F\u002F If you lose loginConnection or connection, ALWAYS relogin\n        \u002F\u002F Both loginConnection & connection should be active\n        function login() {\n            \u002F\u002Fkeykeeper = initKeyKeeper(\"giraffe usage sad arrest sound chimney file select monster head clown ask\")\n            \u002F\u002FlocalStorage.seed = \"giraffe usage sad arrest sound chimney file select monster head clown ask\"\n            \u002F\u002FlocalStorage.id = keykeeper.getWalletID()\n\n            if (localStorage.id && localStorage.seed) {\n                console.log(`Stored WalletID:${localStorage.id}`)\n                console.log(`Stored Seed: ${localStorage.seed}`)\n                keykeeper = initKeyKeeper(localStorage.seed)\n                console.log(`Keykeeper created`);\n            } else {\n                let seed = Module.KeyKeeper.GeneratePhrase()\n                console.log(`New Seed: ${seed}`)\n                keykeeper = initKeyKeeper(seed)\n                console.log(`New WalletID: ${keykeeper.getWalletID()}`)\n                $('#create-wallet-panel .seed-phrase-input').val(seed)\n            }\n\n            console.log(\"Logging in...\")\n            loginConnection = new WebSocket('ws:\u002F\u002F127.0.0.1:20000\u002Fws')\n\n            loginConnection.onclose = () => {\n                console.log('login_ws: connection lost')\n                loginConnection = null\n                relogin()\n            }\n\n            loginConnection.onerror = error => {\n                console.log(`login_ws: connection error: ${JSON.stringify(error)}`)\n            }\n\n            loginConnection.onopen = () => {\n                console.log('login_ws: connected...')\n\n                let loginParams = {\n                    WalletID: keykeeper.getWalletID()\n                }\n\n                loginConnection.send(JSON.stringify({\n                    jsonrpc: \"2.0\",\n                    id: 123,\n                    method: \"login\",\n                    params: loginParams\n                }))\n            }\n\n            loginConnection.onmessage = e => {\n                let data = JSON.parse(e.data)\n\n                if (data.result) {\n                    console.log(`login_ws: result is ${JSON.stringify(data.result)}`)\n                    if (data.id === 123) {\n                        console.log(\"login_ws: OK, endpoint is \", data.result.endpoint)\n                        let endpoint = ['ws:\u002F\u002F', data.result.endpoint].join('');\n                        start(endpoint)\n                    }\n                } else {\n                    console.log(\"login_ws: failed\")\n                    if (data.error) {\n                        console.log(`login_ws: error code:${data.error.code} text:${data.error.data}`)\n                    }\n                }\n            }\n        }\n\n        function relogin () {\n            console.log('relogin in 5 seconds...')\n            setTimeout(() => login(), 5000)\n            showPanel('#connecting-panel')\n        }\n\n        function start(url) {\n            console.log(\"STARTING...\")\n            showPanel('#connecting-panel')\n            connection = new WebSocket(url)\n\n            connection.onerror = error => {\n                console.log(`connection error: ${JSON.stringify(error)}`)\n            }\n\n            connection.onopen = () => {\n                console.log('Connected to the Wallet Servce...')\n                if (localStorage.id) {\n                    showPanel('#open-wallet-panel')\n                } else {\n                    showPanel('#create-wallet-panel')\n                }\n            }\n\n            connection.onclose = () =>\n            {\n                console.log('connection lost...')\n                connection = null\n                loginConnection.close()\n            }\n        }\n\n        function showPanel(id) {\n            ['#login-panel', '#connecting-panel', '#create-wallet-panel', '#open-wallet-panel', '#wallet-panel'].forEach(name => $(name).hide())\n            $(id).show()\n        }\n\n        function initKeyKeeper(seed) {\n            return new Module.KeyKeeper(seed);\n        }\n\n        function onkeykeeper(data) {\n            console.log(`\u003C\u003C\u003C keykeeper request: ${data}`)\n            let res = keykeeper.invokeServiceMethod(data)\n            console.log(`>>> keykeeper response: ${res}`)\n            connection.send(res);\n        }\n\n        \u002F*function refresh()\n        {\n            if(localStorage.id) {\n                showPanel('#open-wallet-panel')\n            }\n            else\n            {\n                $('#create-wallet-panel .seed-phrase-input').val(Module.KeyKeeper.GeneratePhrase())\n                showPanel('#create-wallet-panel')\n            }\n        }*\u002F\n\n        $('#create-wallet-panel .create-wallet-button').click(() =>\n        {\n            let seed = $('#create-wallet-panel .seed-phrase-input').val()\n            console.log(`Creating new wallet with seed phrase: ${seed}`)\n\n            var walletPass = $('#create-wallet-panel .wallet-pass-input').val()\n            var ownerKey = keykeeper.getOwnerKey(walletPass)\n            console.log('ownerKey is: data:application\u002Foctet-stream;base64,' + ownerKey)\n\n            $('#create-wallet-panel .create-wallet-button')\n                .attr('disabled', true)\n                .find('.spinner-border').show()\n\n            connection.onmessage = e =>  {\n                console.log(`got response: ${e.data}`)\n\n                var data = JSON.parse(e.data)\n\n                if(data.result && data.result.length)\n                {\n                    console.log(`result is: ${data.result}`)\n\n                    localStorage.clear()\n                    localStorage.seed = seed\n                    localStorage.id = data.result\n\n                    $('#create-wallet-panel .create-wallet-button')\n                        .attr('disabled', false)\n                        .find('.spinner-border').hide()\n\n                    showPanel('#open-wallet-panel')\n                }\n                else if(data.error)\n                    console.log(`error occured, code:${data.error.code} text:${data.error.data}`)\n                else if(data.method)\n                    onkeykeeper(e.data)\n            }\n\n            connection.send(JSON.stringify(\n            {\n                jsonrpc:'2.0',\n                id: 0,\n                method: 'create_wallet',\n                params:\n                {\n                    pass: walletPass,\n                    ownerkey: ownerKey\n                }\n            }))\n        })\n\n        $('#open-wallet-panel .delete-wallet-button').click(() => {\n            if (confirm('Are you sure want do delete current wallet data?')) {\n                pushNotifyUnsub(defaddr)\n                localStorage.clear()\n                connection.close()\n            }\n        })\n\n        $('#wallet-panel .close-wallet-button').click(() => {\n            if (confirm('Are you sure want do close the wallet?')) {\n                connection.close()\n            }\n        })\n\n        $('#open-wallet-panel .open-wallet-button').click(() => {\n            console.log(`Opening wallet with seed phrase: ${localStorage.seed}`)\n            let walletPass = $('#open-wallet-panel .wallet-pass-input').val()\n            let walletID = keykeeper.getWalletID()\n\n            console.log(`walletID: ${walletID}`)\n            connection.onmessage = e => {\n                console.log(`open wallet got response: ${e.data}`)\n                let data = JSON.parse(e.data)\n                if (data.result && data.result.length) {\n                    console.log(`wallet session: ${data.result}`)\n                    showPanel('#wallet-panel')\n                    showWalletStatus()\n                } else if (data.error)\n                    console.log(`error occured, code:${data.error.code} text:${data.error.data}`)\n                else if (data.method)\n                    onkeykeeper(e.data)\n            }\n\n            connection.send(JSON.stringify({\n                jsonrpc: '2.0',\n                id: 0,\n                method: 'open_wallet',\n                params: {\n                    id: localStorage.id,\n                    pass: walletPass\n                }\n            }))\n        })\n\n        function showWalletStatus() {\n            \u002F\u002F unsubscribe if any\n            pushNotifyUnsub(defaddr)\n\n            connection.onmessage = e => {\n                let data = JSON.parse(e.data)\n                if (data.result) {\n                    $(\"#wallet-panel .available\").text(data.result.available)\n                    $(\"#wallet-panel .sending\").text(data.result.sending)\n                    $(\"#wallet-panel .receiving\").text(data.result.receiving)\n                    $(\"#wallet-panel .current_height\").text(data.result.current_height)\n                    showAddresses()\n                } else if (data.error)\n                    console.log(`error occured, code:${data.error.code} text:${data.error.data}`)\n                else if (data.method)\n                    onkeykeeper(e.data)\n            }\n            connection.send(JSON.stringify({\n                jsonrpc: '2.0',\n                id: 0,\n                method: 'wallet_status'\n            }))\n        }\n\n        function showAddresses() {\n            connection.onmessage = e => {\n                let data = JSON.parse(e.data)\n                if(data.result) {\n                    let body = $('#wallet-panel .addresses > tbody').empty()\n                    data.result.forEach && data.result.forEach((item, index) => {\n                        if (index === 0) defaddr = item\n                        console.log(JSON.stringify(item))\n                        body.append(`\u003Ctr>\n                                        \u003Ctd>${index+1}\u003C\u002Ftd>\n                                        \u003Ctd>${item.address}\u003C\u002Ftd>\n                                        \u003Ctd>${item.comment}\u003C\u002Ftd>\n                                        \u003Ctd>${item.create_time}\u003C\u002Ftd>\n                                        \u003Ctd>${item.duration}\u003C\u002Ftd>\n                                        \u003Ctd>${item.expired}\u003C\u002Ftd>\n                                        \u003Ctd>${item.own}\u003C\u002Ftd>\n                                    \u003C\u002Ftr>`)\n                    })\n                    if (defaddr) {\n                        showPush()\n                    }\n                    showUtxo()\n                }\n                else if(data.error)\n                    console.log(`error occured, code:${data.error.code} text:${data.error.data}`)\n                else if(data.method)\n                    onkeykeeper(e.data)\n            }\n\n            connection.send(JSON.stringify({\n                jsonrpc: '2.0',\n                id: 0,\n                method: 'addr_list',\n                params: {\n                    own: true\n                }\n            }))\n        }\n        \n        async function pushNotifySub(addr) {\n            return new Promise((resolve, reject) => {\n                if (!addr) reject()\n                return webpush.notifyServer(true, loginConnection, {\n                    SbbsAddress: keykeeper.getSbbsAddress(addr.own_id_str),\n                    SbbsAddressPrivate: keykeeper.getSbbsAddressPrivate(addr.own_id_str),\n                    ExpiresAt: addr.create_time + addr.duration\n                })\n            })\n        }\n\n        async function pushNotifyUnsub(addr) {\n            return new Promise((resolve, reject) => {\n                if (!addr) reject()\n\n                if (!webpush.userSubscribed) {\n                    console.log('unsub: no previous subscription')\n                    reject()\n                    return\n                }\n                return webpush.notifyServer(false, loginConnection, {\n                    SbbsAddress: keykeeper.getSbbsAddress(addr.own_id_str),\n                    SbbsAddressPrivate: keykeeper.getSbbsAddressPrivate(addr.own_id_str)\n                })\n            })\n        }\n\n        function showPush() {\n            webpush = new Proxy(new WebPush(), {\n                set: function(obj, prop, value) {\n                    if (prop === \"subscription\") {\n                        if (value) {\n                            $(\"#push-enable\").hide()\n                            $(\"#push-disable\").show()\n                        } else {\n                            $(\"#push-enable\").show()\n                            $(\"#push-disable\").hide()\n                        }\n                        $(\"#push-panel\").show()\n                    }\n                    obj[prop] = value\n                    return true\n                }\n            })\n\n            if (webpush.blockedByUser) {\n                console.log(\"notifications blocked by user\")\n                $(\"#push-blocked\").show()\n                $(\"#push-panel\").show()\n                \u002F\u002F may be push was disabled in settings\n                \u002F\u002F remove any previous subscriptions\n                \u002F\u002F TODO: check the same on service worker start (if possible)\n                pushNotifyUnsub(defaddr)\n            } else {\n                console.log(\"notifications enabled, notifying server\");\n                (async () => {\n                    if (await webpush.register(loginConnection)) {\n                        await pushNotifySub(defaddr)\n                        console.log(\"Push notification - OK\")\n                    }\n                })()\n            }\n\n            $(\"#push-enable\").click(() => {\n                (async () => {\n                    if (await webpush.subscribe()) {\n                        await pushNotifySub(defaddr)\n                    }\n                })()\n                return true\n            })\n\n            $(\"#push-disable\").click(() => {\n                (async () => {\n                    await pushNotifyUnsub()\n                    await webpush.unsubscribe()\n                })()\n                return true\n            })\n        }\n\n        function showUtxo() {\n            connection.onmessage = e => {\n                let data = JSON.parse(e.data)\n                if (data.result) {\n                    let body = $('#wallet-panel .utxo > tbody').empty()\n                    data.result.forEach && data.result.forEach((item, index) => body.append(`\u003Ctr>\n                            \u003Ctd>${index + 1}\u003C\u002Ftd>\n                            \u003Ctd>${item.amount}\u003C\u002Ftd>\n                            \u003Ctd>${item.id}\u003C\u002Ftd>\n                            \u003Ctd>${item.maturity}\u003C\u002Ftd>\n                            \u003Ctd>${item.status_string}\u003C\u002Ftd>\n                            \u003Ctd>${item.type}\u003C\u002Ftd>\n                            \u003C\u002Ftr>`))\n                    showTransactions()\n                } else if (data.error)\n                    console.log(`error occured, code:${data.error.code} text:${data.error.data}`)\n                else if (data.method)\n                    onkeykeeper(e.data)\n            }\n\n            connection.send(JSON.stringify({\n                jsonrpc: '2.0',\n                id: 0,\n                method: 'get_utxo'\n            }))\n        }\n\n        function showTransactions() {\n            connection.onmessage = e => {\n                let data = JSON.parse(e.data)\n                if (data.result) {\n                    let body = $('#wallet-panel .transactions > tbody').empty()\n                    data.result.forEach && data.result.forEach((item, index) => {\n                        body.append(`\u003Ctr>\n                            \u003Ctd>${index + 1}\u003C\u002Ftd>\n                            \u003Ctd>${new Date(item.create_time * 1000).toLocaleString()}\u003C\u002Ftd>\n                            \u003Ctd>${item.receiver.slice(0, 32)}...\u003C\u002Ftd>\n                            \u003Ctd>${item.sender.slice(0, 32)}...\u003C\u002Ftd>\n                            \u003Ctd>${item.value}\u003C\u002Ftd>\n                            \u003Ctd>${item.status_string}\u003C\u002Ftd>\n                            \u003C\u002Ftr>`)\n                    })\n                } else onkeykeeper(e.data)\n                if ($('#wallet-panel').is(\":visible\"))\n                    setTimeout(showWalletStatus, 5000)\n            }\n\n            connection.send(JSON.stringify({\n                jsonrpc: '2.0',\n                id: 0,\n                method: 'tx_list'\n            }))\n        }\n\n        $('#wallet-panel .send-button').click(() => {\n            let addr = $('#wallet-panel .receiver-address-input').val()\n            if (addr.length === 0) {\n                alert('Please, enter valid address.')\n                return\n            }\n\n            let amount = $('#wallet-panel .amount-input').val()\n            if (isNaN(parseInt(amount))) {\n                alert('Please, enter valid amount.')\n                return\n            }\n\n            if (confirm(`Are you sure want send ${amount} groth to ${addr}?`)) {\n                $('#wallet-panel .amount-input').val('')\n                send(parseInt(amount), addr)\n            }\n        })\n\n        function send(amount, address) {\n            console.log(`!!! sending ${amount} groth to ${address}...`)\n            connection.onmessage = (e) => {\n                let data = JSON.parse(e.data)\n                if (data.result)\n                    console.log(`result is ${data.result}`)\n                else if (data.error)\n                    console.log(`error occured, code:${data.error.code} text:${data.error.data}`)\n                else if (data.method)\n                    onkeykeeper(e.data)\n            }\n            connection.send(JSON.stringify({\n                jsonrpc: \"2.0\",\n                id: 123,\n                method: \"tx_send\",\n                params: {\n                    value: amount,\n                    fee: 100,\n                    address: address,\n                    comment: \"thank you!\"\n                }\n            }))\n        }\n\n        function createNewTestAddr() {\n            connection.send(JSON.stringify({\n                jsonrpc: '2.0',\n                id: 123,\n                method: 'create_address',\n                params:\n                        {\n                            expiration: '24h',\n                            comment: 'John Smith'\n                        }\n            }))\n        }\n    })\n    \u003C\u002Fscript>\n\u003C\u002Fhtml>\n",[37,2086,2084],{"__ignoreMap":74},[14,2088,2090],{"id":2089},"reference-wallet-implementation","Reference Wallet Implementation",[10,2092,2093],{},"We provide the reference web wallet implementation that combines all the described APIs together and yields the working chrome extension.",[197,2095,2096,2105],{},[25,2097,2098,2099,2104],{},"Check out the ",[29,2100,2103],{"href":2101,"rel":2102},"https:\u002F\u002Fgithub.com\u002FBeamMW\u002Fweb-wallet",[33],"web-wallet repository"," for the source code",[25,2106,2107,2108],{},"Install the testnet ",[29,2109,2112],{"href":2110,"rel":2111},"https:\u002F\u002Fchrome.google.com\u002Fwebstore\u002Fdetail\u002Fbeam-web-wallet-testnet\u002Filhaljfiglknggcoegeknjghdgampffk?hl=en",[33],"chrome extension",[2114,2115,2116],"style",{},"html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s4JwU, html code.shiki .s4JwU{--shiki-default:#85E89D}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}",{"title":74,"searchDepth":370,"depth":370,"links":2118},[2119,2120,2121,2122,2123,2138],{"id":16,"depth":370,"text":17},{"id":186,"depth":370,"text":187},{"id":242,"depth":370,"text":243},{"id":249,"depth":370,"text":252},{"id":270,"depth":370,"text":271,"children":2124},[2125,2126,2127,2128,2129,2130,2131,2132,2133,2134,2135,2136,2137],{"id":299,"depth":376,"text":300},{"id":311,"depth":376,"text":311},{"id":323,"depth":376,"text":323},{"id":329,"depth":376,"text":329},{"id":630,"depth":376,"text":631},{"id":642,"depth":376,"text":642},{"id":648,"depth":376,"text":648},{"id":654,"depth":376,"text":654},{"id":666,"depth":376,"text":666},{"id":660,"depth":376,"text":660},{"id":672,"depth":376,"text":672},{"id":1494,"depth":376,"text":1497},{"id":1508,"depth":376,"text":1512},{"id":2089,"depth":370,"text":2090},"md",null,{},true,"\u002Fdocs\u002Fcore-tech\u002Fwallet-service",{"description":12},"docs\u002Fcore-tech\u002FWallet-Service","chp-p_MqrWC6l4hIUaSSVvms5pwxsZVMaG72lQd8zxo",[2148,2153],{"title":2149,"path":2150,"stem":2151,"description":2152,"children":-1},"Overview","\u002Fdocs\u002Fcore-tech\u002Fwasm-wallet-client","docs\u002Fcore-tech\u002FWASM-wallet-client","WASM wallet client is a thin wrapper around Beam client library build into WASM using Emscripten toolchain. This wrapper allows to run BEAM wallet inside any browser supporting WebAssembly and it provides the regular BEAM wallet API to communicated with it from external(javascript) code. It's available via npm for different network types:",{"title":2154,"path":2155,"stem":2156,"description":2157,"children":-1},"Wallet Audit","\u002Fdocs\u002Fcore-tech\u002Fwallet-audit","docs\u002Fcore-tech\u002FWallet-audit","Crypto-currencies are often criticized for being used by \"gray market\" and virtually inappropriate for compliant businesses due to their inherent non-transparency.",1783006090247]