github.com/0chain/gosdk@v1.17.11/wasmsdk/demo/index.html (about)

     1  <!DOCTYPE html>
     2  
     3  <head>
     4    <!-- for zcn.wasm-->
     5    <script src="https://cdn.jsdelivr.net/gh/herumi/bls-wasm@v1.1.1/browser/bls.js"></script>
     6    <script src="https://cdn.jsdelivr.net/gh/golang/go@go1.21.5/misc/wasm/wasm_exec.js"></script>
     7    <script src="zcn.js"></script>
     8  
     9  
    10    <!-- for demo -->
    11    <script src="dom.js"></script>
    12  
    13    <!-- for player.js -->
    14    <script src="https://cdn.jsdelivr.net/npm/mux.js@6.3.0/dist/mux.js"></script>
    15    <script src="EBML.js"></script>
    16    <script src="player.js"></script>
    17  
    18  </head>
    19  
    20  <body>
    21  
    22    <h2>please download zcn.wasm from https://github.com/0chain/gosdk/releases/latest first</h2>
    23  
    24    <fieldset>
    25      <legend>logging</legend>
    26      <span>
    27        <button id="btnShowLogs">Show</button>
    28        <button id="btnHideLogs">Hide</button>
    29      </span>
    30      <br>
    31      <textarea id="logs" rows="10" cols="100">
    32  
    33    </textarea>
    34    </fieldset>
    35  
    36    <fieldset>
    37      <legend>Wallet</legend>
    38      <label for="clientId"> ClientID </label> <input id="clientId" name="clientId" style="width: 600px;"
    39        value="ab5b8ab19abe574d92238e0a5dc0c2abd53614cd12cab6b09576fab2a0f64a83" /><br>
    40      <label for="privateKey">PrivateKey</label> <input id="privateKey" name="privateKey" style="width: 600px;"
    41        value="0c2cb85c8c33b3cc35dc12b4754e61ae9488bba857982c382caa461ecac19d19" /><br>
    42      <label for="publicKey"> PublicKey</label> <input id="publicKey" name="publicKey" style="width: 600px;"
    43        value="d430b1b33eab43bd09886e6125e246600e36e3f88d658d00bf836aa564251e2364bccbfb18f1cb1b5fa4d96ba602b59bc009e6e0223b6a8ebdafc14822b78d23" /><br>
    44      <label for="mnemonic"> Mnemonic</label> <input id="mnemonic" name="mnemonic" style="width: 600px;"
    45        value="grace fiscal menu squeeze certain drum ostrich lunar ugly remember cousin observe oxygen brisk toward notable shoot cushion develop marble open aspect couch noise" /><br>
    46      <label for="peerPublicKey"> PeerPublicKey</label> <input id="peerPublicKey" name="peerPublicKey" style="width: 600px;"
    47        value="" /><br>
    48      <label for="isSplit"> IsSplit</label> <input id="isSplit" name="isSplit" style="width: 600px;"
    49        value="false" /><br>
    50  
    51      <button id="btnSetWallet">Change Wallet</button>
    52      <button id="btnSendMeTokens">Send Me Tokens</button>
    53      <button id="btnSendTokensToOtherWallet">Send Tokens to Other Wallet</button>
    54      <button id="btnGetBalance">Get Balance</button>
    55  
    56      <button id="btnGetUSDRate">Get USD Rate</button>
    57    </fieldset>
    58  
    59    <fieldset>
    60      <legend>Sharing</legend>
    61      <label for="authTicket"> AuthTicket </label> <input id="authTicket" name="authTicket" style="width: 600px;"
    62        value="eyJjbGllbnRfaWQiOiJhNGM1M2JmMjQ4YzYzNGVhNDgzYTk4Y2JhYTZiNzY3MjI2ZjUwNDUwNmIyOTkzODRiMzBmMmMwMGE1MmYwODUxIiwib3duZXJfaWQiOiIzMDc2NGJjYmE3MzIxNmI2N2MzNmIwNWExN2I0ZGQwNzZiZmRjNWJiMGVkODQ4NTZmMjc2MjIxODhjMzc3MjY5IiwiYWxsb2NhdGlvbl9pZCI6IjJmMjc3NDJlODYxN2YyY2U1MTk2OWFhNWQ1ZDAyY2MyZDg1NzQ1MzQ5MGVkZjBlODYzNmE0OTdjYjRmNTY3MWUiLCJmaWxlX3BhdGhfaGFzaCI6IjVhYTE2NzkyZDQ1YWMwMzI0ZTExZjc0Y2E5N2M0NDk3Zjc2ZmIxM2ZkN2ExMjIzMjc4NzQ4ZjY4OGIyNzU2OGUiLCJhY3R1YWxfZmlsZV9oYXNoIjoiYjQxZTFmZGI2YThlNzM0MmNkMzk5ZjY3MWFiYWRkM2MyN2QzZDQ0YjdmZGM0OGU3Mzc1ZTI4ZTM3MTI2NWY3YiIsImZpbGVfbmFtZSI6InJ0eDA5MDIwMDIxMnAucGRmIiwicmVmZXJlbmNlX3R5cGUiOiJmIiwiZXhwaXJhdGlvbiI6MTY4ODY4OTcyMTcxNCwidGltZXN0YW1wIjoxNjg3MDAyNzE2LCJlbmNyeXB0ZWQiOnRydWUsInNpZ25hdHVyZSI6IjIyOWUyY2FkNTU5YzEwMGU4MTVhNjk2ZTQ5YTU3ZTUyNGU5ZmQ1YmZmZTRjYjAyY2I0MDM1NGY0OTQ1YzY5MWYifQ==" /><br>
    63      <button id="decodeAuthticket">DecodeAuthTicket</button>
    64    </fieldset>
    65  
    66    <fieldset>
    67      <legend>Allocations</legend>
    68  
    69      <span>
    70        <button id="btnListAllocations">List</button>
    71        <button id="btnCreateAllocation">Create</button>
    72        <button id="btnGetAllocation">Get</button>
    73        <button id="btnCreateFreeAlloc">CreateFreeallocation</button>
    74        <button id="btnGetAllocationMinLock">AllocationMinLock</button>
    75        <button id="btnGetUpdateAllocationMinLock">UpdateAllocationMinLock</button>
    76        <button id="btnRemoteFileMap">RemoteFileMap</button>
    77        <button id="btnAddReplaceBlobber">AddReplaceBlobber</button>
    78        <button id="makeSCRestAPICall">makeSCRestAPICall</button>
    79      </span>
    80  
    81      <br>
    82  
    83      <div id="listAllocations">
    84      </div>
    85  
    86    </fieldset>
    87  
    88    <fieldset>
    89      <legend>Blobbers</legend>
    90  
    91      <span>
    92        <button id="btnListBlobbers">List</button>
    93        <button id="btnListBlobberSettings">Get</button>
    94        <button id="updateBlobberSettings">Update</button>
    95      </span>
    96  
    97      <br>
    98  
    99      <div id="listBlobbers">
   100      </div>
   101  
   102    </fieldset>
   103  
   104    <fieldset>
   105      <legend>Files</legend>
   106      <button id="btnListFiles">List</button>
   107      <span><input id="inputSelectedFile" type="file" multiple /> <button id="btnUploadFile">Upload</button> </span>
   108      <button id="btnUploadEncryptFile">EncryptedUpload</button> </span>
   109      [ <button id="btnDownloadFile">Download</button> | <button id="btnDownloadShared">Download with AuthTicket</button>
   110      | <button id="btnMultiDownload">MultiDownload</button>
   111      ]
   112      <button id="btnViewFile">View</button>
   113      <button id="btnGetFileStats">GetFileStats</button>
   114      <button id="btnDelete">Delete</button>
   115      <button id="btnShare">Share</button>
   116      <button id="btnGetContainers">getcontainers</button>
   117      <button id="btnUpdateContainer">updatecontainer</button>
   118      <button id="btnSearchContainer">searchcontainer</button>
   119      <button id="btnAllocationRepair">Repair</button>
   120      <button id="btnMultiOps">MultiOperation</button>
   121      <button id="createDir">createDir</button>
   122  
   123      <br>
   124  
   125      <div id="listFiles">
   126      </div>
   127  
   128    </fieldset>
   129  
   130  
   131    <fieldset>
   132      <legend>Output</legend>
   133      <pre id="txtOutput" style="font-size: 20px; font-weight: bold;">
   134      </pre>
   135    </fieldset>
   136  
   137  
   138    <fieldset>
   139      <legend>Media WebPlayer</legend>
   140  
   141      <div id="container">
   142        <video id='player' preload="metadata" controls></video>
   143      </div>
   144      <div className="controls">
   145        [ <button id="btnPlay">Play</button> | <button id="btnPlayShared">Play with auth ticket</button> ]
   146        <button id="btnPause">Pause</button>
   147        <button id="btnStop">Stop</button>
   148      </div>
   149    </fieldset>
   150  
   151  
   152    <fieldset>
   153      <legend>Image Viewer</legend>
   154      <img id="viewer" src="image.png" width="600" />
   155    </fieldset>
   156  
   157    <fieldset>
   158      <legend>Split Key</legend>
   159      <span>
   160        <button id="btnSetWalletInfo">SetWalletInfo</button>
   161        <button id="btnSetAuthUrl">SetAuthUrl</button>
   162        <button id="btnRegAuth">regAuth</button>
   163      </span>
   164      <br>
   165      <div id="splitKey">
   166      </div>
   167    </fieldset>
   168    <script>
   169      window.downloadCallback = function (totalBytes, completedBytes, error) {
   170        console.log("download: " + completedBytes + "/" + totalBytes + " err:" + error)
   171      }
   172  
   173      const getWallet = () => {
   174        const clientID = document.getElementById('clientId').value;
   175        const publicKey = document.getElementById('publicKey').value;
   176        const peerPublicKey = document.getElementById('peerPublicKey').value;
   177        const privateKey = document.getElementById('privateKey').value;
   178        const mnemonic = document.getElementById('mnemonic').value;
   179        const isSplit = document.getElementById('isSplit').value;
   180        return {
   181          clientID, peerPublicKey, publicKey, privateKey, mnemonic, isSplit
   182        }
   183      }
   184  
   185      // get active blobbers from network
   186      async function getBlobbersFromNetwork() {
   187        const GET_BLOBBERS = `/v1/screst/6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d7/getblobbers`
   188        const randomsharder = " https://dev1.zus.network/sharder01" // todo: get this randomly from network
   189        url = randomsharder + GET_BLOBBERS
   190        let response = await fetch(url);
   191        let data = await response.json();
   192        return data;
   193      }
   194  
   195      async function getBlobberDetails(blobberID) {
   196        const GET_BLOBBER = `/v1/screst/6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d7/getBlobber?blobber_id=`
   197        const randomsharder = " https://dev1.zus.network/sharder01" // todo: get this randomly from network
   198        url = randomsharder + GET_BLOBBER + blobberID
   199        let response = await fetch(url);
   200        let data = await response.json();
   201        return data;
   202      }
   203  
   204      const networkConfig = {
   205        chainId: '0afc093ffb509f059c55478bc1a60351cef7b4e9c008a53a6cc8241ca8617dfe',
   206        signatureScheme: 'bls0chain',
   207        minConfirmation: 10,
   208        minSubmit: 10,
   209        confirmationChainLength: 3,
   210      }
   211  
   212      const query = new URLSearchParams(window.location.search);
   213  
   214      let network = query.get('network')
   215      if (!network || network == 'undefined') {
   216        network = "dev.zus.network"
   217      }
   218  
   219      const blockWorker = 'https://' + network + '/dns';
   220      const config = [
   221        networkConfig.chainId,
   222        blockWorker,
   223        networkConfig.signatureScheme,
   224        networkConfig.minConfirmation,
   225        networkConfig.minSubmit,
   226        networkConfig.confirmationChainLength,
   227        'https://0box.' + network, //zboxHost
   228        'vult', //zboxAppType
   229        3,
   230        false,
   231      ]
   232  
   233      const bls = window.bls
   234      let goWasm;
   235      createWasm().then(async wasm => {
   236        await wasm.sdk.init(...config)
   237        await bls.init(bls.BN254)
   238  
   239        const { clientID, publicKey, privateKey, mnemonic } = getWallet();
   240  
   241        await wasm.setWallet(bls, clientID, publicKey, "", privateKey, publicKey, mnemonic, false);
   242  
   243        goWasm = wasm
   244      })
   245  
   246      onClick('btnSetWallet', async () => {
   247        const { clientID, publicKey, privateKey, peerPublicKey, mnemonic, isSplit } = getWallet();
   248  
   249        const isSplitRaw = isSplit == "true" ? true : false
   250  
   251        const newConfig = [
   252          networkConfig.chainId,
   253          blockWorker,
   254          networkConfig.signatureScheme,
   255          networkConfig.minConfirmation,
   256          networkConfig.minSubmit,
   257          networkConfig.confirmationChainLength,
   258          'https://0box.' + network, //zboxHost
   259          'vult', //zboxAppType
   260          3,
   261          isSplitRaw,
   262        ]
   263  
   264        await goWasm.sdk.init(...newConfig);
   265  
   266        await goWasm.setWallet(bls, clientID, publicKey, peerPublicKey, privateKey, publicKey, mnemonic, isSplitRaw);
   267      })
   268  
   269      onClick('btnSendMeTokens', async () => {
   270        await goWasm.sdk.faucet("pour", JSON.stringify("{Pay day}"), 10)
   271      })
   272  
   273      onClick('btnSendTokensToOtherWallet', async () => {
   274        try {
   275          const output = await goWasm.sdk.send(
   276            "5ad6e4d206d853833e96ff5c833369e567d2ef41ae1d5093141e1f90f1e8dcb0",
   277            10000000000,
   278            0
   279          )
   280          console.log("successfully sent with txn hash: ", output)
   281        } catch (e) {
   282          alert(e)
   283        }
   284      })
   285  
   286      onClick('btnGetBalance', async () => {
   287        const { clientID } = getWallet()
   288        const wallet = await goWasm.sdk.getWalletBalance(clientID)
   289        txtOutput.innerHTML = JSON.stringify(wallet, null, 2)
   290      })
   291  
   292      onClick('btnCreateFreeAlloc', async () => {
   293        var token = prompt("freeallocation token: ");
   294        try {
   295          const alloc = await goWasm.sdk.createfreeallocation(token)
   296          console.log("create freeallocation with ID: ", alloc)
   297        } catch (e) {
   298          alert(e)
   299        }
   300      })
   301  
   302      let allocations = []
   303      let blobbers = []
   304      let files = []
   305  
   306      const bindAllocations = () => setHtml("listAllocations", allocations.map(a => `<input type="radio"  name="selectedAllocation" value="${a.id}"><label for="${a.id}">${a.id}</label><br>`).join(""))
   307      const getSelectedAllocation = () => [...document.getElementsByName('selectedAllocation')].filter(it => it.checked).map(it => it.value).find(it => it != "");
   308  
   309      const bindFiles = () => setHtml('listFiles', files.map(f => `<input type="radio" name="selectedFile" value="${f.path}"><label for="${f.path}">[${f.type}]${f.path}</label><br>`).join(""))
   310      const getSelectedFile = () => [...document.getElementsByName('selectedFile')].filter(it => it.checked).map(it => it.value).find(it => it != "");
   311  
   312      const bindBlobbers = () => setHtml("listBlobbers", blobbers.map(a => `<input type="radio"  name="selectedBlobbers" value="${a.id}"><label for="${a.id}">${a.id}</label><br>`).join(""))
   313      const getSelectedBlobbers = () => [...document.getElementsByName('selectedBlobbers')].filter(it => it.checked).map(it => it.value).find(it => it != "");
   314  
   315      onClick('btnCreateAllocation', async () => {
   316  
   317        const expiry = new Date()
   318        expiry.setDate(expiry.getDate() + 300)
   319  
   320        //name string, datashards, parityshards int, size, expiry int64,minReadPrice, maxReadPrice, minWritePrice, maxWritePrice int64, lock int64,preferredBlobberIds []string
   321        const config = {
   322          datashards: 2,
   323          parityshards: 2,
   324          size: 2 * 1073741824,
   325          minReadPrice: 0,
   326          maxReadPrice: 184467440737095516,
   327          minWritePrice: 0,
   328          maxWritePrice: 184467440737095516,
   329          lock: 18800000000
   330        }
   331        try {
   332          const allocation = await goWasm.sdk.createAllocation(config.datashards, config.parityshards, config.size, config.minReadPrice, config.maxReadPrice, config.minWritePrice, config.maxWritePrice,
   333            config.lock, [], [], false)
   334  
   335          console.log(allocation)
   336          allocations = await goWasm.sdk.listAllocations()
   337          bindAllocations()
   338        } catch (e) {
   339          alert(e)
   340        }
   341  
   342      })
   343  
   344      onClick('btnListAllocations', async () => {
   345        allocations = await goWasm.sdk.listAllocations()
   346        bindAllocations()
   347      })
   348  
   349      onClick('btnRemoteFileMap', async () => {
   350        const allocationID = getSelectedAllocation()
   351        if (!allocationID) {
   352          alert("please select allocation")
   353          return
   354        }
   355        try {
   356          let resp = await goWasm.sdk.getRemoteFileMap(allocationID)
   357          console.log(resp)
   358          txtOutput.innerHTML = JSON.stringify(resp, null, 2)
   359        } catch (e) {
   360          alert(e)
   361        }
   362      })
   363  
   364      onClick('makeSCRestAPICall', async () => {
   365        const allocationID = getSelectedAllocation()
   366  
   367        try {
   368          params = {
   369            "allocation": allocationID
   370          }
   371          paramsJSON = JSON.stringify(params, null, 2)
   372          storagesc = "6dba10422e368813802877a85039d3985d96760ed844092319743fb3a76712d7"
   373          const resp = await goWasm.sdk.makeSCRestAPICall(storagesc, "/allocation", paramsJSON)
   374          txtOutput.innerHTML = resp
   375        } catch (e) {
   376          alert(e)
   377        }
   378      })
   379  
   380      onClick('createDir', async () => {
   381        const allocationId = getSelectedAllocation()
   382        goWasm.sdk.createDir(allocationId, "/dir2")
   383      })
   384  
   385      onClick('btnListBlobbers', async () => {
   386        // list active blobbers
   387        let blobbersResp = await getBlobbersFromNetwork()
   388        blobbers = blobbersResp.Nodes
   389        bindBlobbers()
   390      })
   391  
   392      onClick('btnGetAllocation', async () => {
   393        const allocationId = getSelectedAllocation()
   394        if (!allocationId) {
   395          alert("please select allocation")
   396          return
   397        }
   398        const alloc = await goWasm.sdk.getAllocation(allocationId)
   399        txtOutput.innerHTML = JSON.stringify(alloc, null, 2)
   400      })
   401  
   402      onClick('btnGetAllocationMinLock', async () => {
   403        let dataShards = 2
   404        let parityShards = 2
   405        let size = 100000
   406        let maxReadPrice = 10000000000
   407        let maxWritePrice = 1000000000
   408        try {
   409          const price = await goWasm.sdk.getAllocationMinLock(dataShards, parityShards, size, maxReadPrice, maxWritePrice)
   410          txtOutput.innerHTML = price
   411        } catch (e) {
   412          alert(e)
   413        }
   414      })
   415  
   416      onClick('btnGetUpdateAllocationMinLock', async () => {
   417        let size = 100000
   418        const allocationId = getSelectedAllocation()
   419        if (!allocationId) {
   420          alert("please selection allocationID")
   421          return
   422        } else {
   423          console.log("allocation:", allocationId)
   424        }
   425        try {
   426          const price = await goWasm.sdk.getUpdateAllocationMinLock(allocationId, size, true, false, "", "")
   427          txtOutput.innerHTML = price
   428        } catch (e) {
   429          alert(e)
   430        }
   431      })
   432  
   433      onClick('btnListBlobberSettings', async () => {
   434        const blobberID = getSelectedBlobbers()
   435        if (!blobberID) {
   436          alert("please select blobber")
   437          return
   438        }
   439        const details = await getBlobberDetails(blobberID)
   440        txtOutput.innerHTML = JSON.stringify(details, null, 2)
   441      })
   442  
   443      // increases readprice of blobber by 1 unit
   444      onClick('updateBlobberSettings', async () => {
   445        const blobberID = getSelectedBlobbers()
   446        if (!blobberID) {
   447          alert("please select blobber")
   448          return
   449        }
   450        let details = await getBlobberDetails(blobberID)
   451        details.terms.read_price += 1
   452        try {
   453          const txn = await goWasm.sdk.updateBlobberSettings(JSON.stringify(details))
   454        } catch (e) {
   455          alert(e)
   456        }
   457        // txtOutput.innerHTML = JSON.stringify(alloc, null, 2)
   458      })
   459  
   460      onClick('btnListFiles', async () => {
   461        const allocationId = getSelectedAllocation()
   462        if (!allocationId) {
   463          alert("please selection allocationID")
   464          return
   465        }
   466        const { list = [] } = await goWasm.sdk.listObjects(allocationId, '/',-1,50)
   467        files = list || []
   468        bindFiles()
   469      })
   470  
   471      onClick('btnUploadFile', async () => {
   472        const { files } = get('inputSelectedFile')
   473        if (files && files.length > 0) {
   474  
   475          const objects = []
   476          const allocationId = getSelectedAllocation()
   477          for (const file of files) {
   478            objects.push({
   479              allocationId: allocationId,
   480              remotePath: `/${file.name}`,
   481              file: file,
   482              // thumbnailBytes: await readBytes(file),//only for demo, don't upload original file as thumbnail in production
   483              encrypt: false,
   484              webstreaming: false,
   485              isUpdate: false,
   486              isRepair: false,
   487              numBlocks: 120,
   488              callback: function (totalBytes, completedBytes, error) {
   489                console.log(file.name + " " + completedBytes + "/" + totalBytes + " err:" + error)
   490              }
   491            })
   492          }
   493          const results = await goWasm.bulkUpload(objects)
   494          console.log(JSON.stringify(results))
   495        }
   496      })
   497  
   498      onClick('btnShare', async () => {
   499        // change these values according to your wallet (obtained from zbox `zbox getwallet`)
   500        let clientID = "a4c53bf248c634ea483a98cbaa6b767226f504506b299384b30f2c00a52f0851"
   501        let encryptionPublicKey = "SCxZlinUp+Z29jt8hXT623osEjALXVel6HdHgq1lXEY="
   502  
   503        const file = files.find(it => it.path == getSelectedFile())
   504        if (file) {
   505          const allocationId = getSelectedAllocation()
   506          if (!allocationId) {
   507            alert("please provide allocationId")
   508            return
   509          }
   510  
   511          console.log("sharing file", file?.path)
   512          let time = Date.now()
   513          let expiration = time += 3600 // after 1 hour
   514          let availableAfter = 0
   515          try {
   516            const result = await goWasm.sdk.share(allocationId, file?.path, "", "", expiration, false, availableAfter)
   517            console.log("output of share", result)
   518            txtOutput.innerHTML = JSON.stringify(result, null, 2)
   519          } catch (e) {
   520            alert(e)
   521          }
   522        }
   523  
   524      })
   525  
   526      onClick('btnUploadEncryptFile', async () => {
   527        const { files } = get('inputSelectedFile')
   528        if (files && files.length > 0) {
   529  
   530          const objects = []
   531          const allocationId = getSelectedAllocation()
   532          if (!allocationId) {
   533            alert("please provide allocationId")
   534          }
   535          for (const file of files) {
   536            objects.push({
   537              allocationId: allocationId,
   538              remotePath: `/${file.name}`,
   539              file: file,
   540              thumbnailBytes: await readBytes(file),//only for demo, don't upload original file as thumbnail in production
   541              encrypt: true,
   542              webstreaming: false,
   543              isUpdate: false,
   544              isRepair: false,
   545              numBlocks: 100,
   546              callback: function (totalBytes, completedBytes, error) {
   547                console.log(file.name + " " + completedBytes + "/" + totalBytes + " err:" + error)
   548              }
   549            })
   550          }
   551  
   552          const results = await goWasm.bulkUpload(objects)
   553  
   554          console.log(JSON.stringify(results))
   555        }
   556      })
   557  
   558      onClick('btnDownloadFile', async () => {
   559        const path = getSelectedFile()
   560        if (path) {
   561  
   562          const allocationId = getSelectedAllocation()
   563  
   564          //allocationID, remotePath, authTicket, lookupHash string, downloadThumbnailOnly bool, numBlocks int
   565          const file = await goWasm.sdk.download(allocationId, path, '', '', false, 10, "downloadCallback", true)
   566  
   567          const a = document.createElement('a')
   568          document.body.appendChild(a)
   569          a.style = 'display: none'
   570  
   571          a.href = file.url
   572          a.download = file.fileName
   573          a.click()
   574          window.URL.revokeObjectURL(file.url)
   575          document.body.removeChild(a)
   576  
   577        }
   578      })
   579  
   580      onClick('btnAddReplaceBlobber', async () => {
   581  
   582        var addremoveBlobberIDs = prompt("Add Blobber ID and remove blobberID (separated by a comma): ");
   583  
   584        var [addBlobberId, removeBlobberID] = addremoveBlobberIDs.split(",");
   585        // removeBlobberID = removeBlobberID !== undefined ? value : "";
   586  
   587        console.log("addBlobberId", addBlobberId)
   588        console.log("removeBlobberID", removeBlobberID)
   589        // addBlobberId = addBlobberId.trim()
   590        // removeBlobberID = removeBlobberID.trim()
   591        const allocationId = getSelectedAllocation()
   592        if (!allocationId) {
   593          alert("please provide allocationId")
   594        }
   595  
   596        try {
   597          const file = await goWasm.sdk.updateAllocationWithRepair(allocationId, 0, 0, 5000000000, false, addBlobberId, removeBlobberID)
   598  
   599        } catch (e) {
   600          alert(e)
   601        }
   602      })
   603  
   604      onClick('btnDownloadShared', async () => {
   605  
   606        const authTicket = get('authTicket').value
   607        if (authTicket) {
   608          try {
   609            const file = await goWasm.sdk.download('', '', authTicket, '', false, 10, "downloadCallback", true)
   610  
   611            console.log("downloaded file", file)
   612            const a = document.createElement('a')
   613            document.body.appendChild(a)
   614            a.style = 'display: none'
   615            a.href = file.url
   616            a.download = file.fileName
   617            a.click()
   618            window.URL.revokeObjectURL(file.url)
   619            document.body.removeChild(a)
   620          } catch (e) {
   621            alert(e)
   622          }
   623        }
   624      })
   625  
   626      onClick('decodeAuthticket', async () => {
   627        const authTicket = get('authTicket').value
   628        if (authTicket) {
   629          try {
   630            const output = await goWasm.sdk.decodeAuthTicket(authTicket);
   631            console.log(output)
   632            txtOutput.innerHTML = JSON.stringify(output, null, 2)
   633          } catch (e) {
   634            alert(e)
   635          }
   636        }
   637      })
   638  
   639      onClick('btnViewFile', async () => {
   640        const file = files.find(it => it.path == getSelectedFile())
   641        if (file && file.mimetype.startsWith('image')) {
   642          const allocationId = getSelectedAllocation()
   643          const { url } = await goWasm.sdk.download(allocationId, file.path, '', '', false, 10,)
   644          get('viewer').setAttribute('src', url)
   645        }
   646      })
   647  
   648      const player = get('player')
   649      let isPlayerReady = false
   650  
   651      onClick('btnPlay', async () => {
   652  
   653        if (isPlayerReady) {
   654          if (player.paused) {
   655            player.play()
   656          }
   657        } else {
   658  
   659          const file = files.find(it => it.path == getSelectedFile())
   660  
   661          const isLive = file.type == 'd'
   662  
   663          if (file) {
   664            const allocationId = getSelectedAllocation()
   665            startPlay({
   666              goWasm,
   667              allocationId,
   668              containerElement: get('container'),
   669              videoElement: player,
   670              remotePath: file?.path,
   671              authTicket: '',
   672              lookupHash: file?.lookup_hash,
   673              mimeType: file?.mimetype,
   674              isLive: isLive,
   675            })
   676            isPlayerReady = true
   677          }
   678        }
   679  
   680      })
   681  
   682      onClick('btnPlayShared', async () => {
   683  
   684        if (isPlayerReady) {
   685          if (player.paused) {
   686            player.play()
   687          }
   688        } else {
   689  
   690          const authTicket = get('authTicket').value
   691  
   692          const isLive = false
   693  
   694          if (authTicket) {
   695            const allocationId = getSelectedAllocation()
   696            startPlay({
   697              goWasm,
   698              allocationId,
   699              videoElement: player,
   700              remotePath: '',
   701              authTicket: authTicket,
   702              lookupHash: '',
   703              mimeType: '',
   704              isLive: isLive,
   705            })
   706            isPlayerReady = true
   707          }
   708        }
   709  
   710      })
   711  
   712      onClick('btnPause', async () => {
   713        player.pause();
   714      })
   715  
   716      onClick('btnStop', async () => {
   717        if (isPlayerReady) {
   718          stopPlay({ goWasm, videoElement: player })
   719          isPlayerReady = false
   720        }
   721      })
   722  
   723  
   724      const log = console.log
   725      const logs = get('logs')
   726      onClick('btnShowLogs', async () => {
   727        await goWasm.sdk.showLogs()
   728        console.log = s => {
   729          log(s)
   730          logs.value += s + "\n"
   731          logs.scrollLeft = 0;
   732          logs.scrollTop = logs.scrollHeight;
   733        }
   734      })
   735  
   736      onClick('btnHideLogs', async () => {
   737        await goWasm.sdk.hideLogs()
   738        console.log = log
   739      })
   740  
   741  
   742  
   743      onClick('btnGetFileStats', async () => {
   744        const file = files.find(it => it.path == getSelectedFile())
   745        if (file) {
   746          const allocationId = getSelectedAllocation()
   747          const stats = await goWasm.sdk.getFileStats(allocationId, file?.path)
   748          txtOutput.innerHTML = JSON.stringify(stats, null, 2)
   749        }
   750  
   751      })
   752  
   753      onClick('btnDelete', async () => {
   754        const file = files.find(it => it.path == getSelectedFile())
   755        if (file) {
   756          const allocationId = getSelectedAllocation()
   757          await goWasm.sdk.delete(allocationId, file?.path)
   758        }
   759      })
   760  
   761      onClick('btnGetUSDRate', async () => {
   762  
   763        const rate = await goWasm.sdk.getUSDRate("zcn")
   764        txtOutput.innerHTML = rate
   765      })
   766  
   767      onClick('btnGetContainers', async () => {
   768        const domain = "https://chimneyhwayr.zus.network"
   769        const username = "username1"
   770        const password = "password1"
   771  
   772        try {
   773          const stats = await goWasm.sdk.getcontainers(username, password, domain)
   774          txtOutput.innerHTML = JSON.stringify(stats, null, 2)
   775        } catch (e) {
   776          alert(e)
   777        }
   778      })
   779  
   780      onClick('btnUpdateContainer', async () => {
   781        const containerid = "3f9b21fcb9df9d6cc88b024357bf940284f749d4c30e13b7791d721def752498"
   782        const domain = "https://chimneyhwayr.zus.network"
   783        const username = "username1"
   784        const password = "password1"
   785        const image = "0chaindev/blobber:staging"
   786        try {
   787          const stats = await goWasm.sdk.updatecontainer(username, password, domain, containerid, image)
   788          txtOutput.innerHTML = JSON.stringify(stats, null, 2)
   789        } catch (e) {
   790          alert(e)
   791        }
   792      })
   793  
   794      onClick('btnSearchContainer', async () => {
   795        const domain = "https://chimneyhwayr.zus.network"
   796        const username = "username1"
   797        const password = "password1"
   798        const containername = "validator"
   799        try {
   800          const stats = await goWasm.sdk.searchcontainer(username, password, domain, containername)
   801          txtOutput.innerHTML = JSON.stringify(stats, null, 2)
   802        } catch (e) {
   803          alert(e)
   804        }
   805      })
   806  
   807      onClick('btnAllocationRepair', async () => {
   808        const allocationId = getSelectedAllocation()
   809        const output = await goWasm.sdk.allocationRepair(allocationId, "/")
   810        txtOutput.innerHTML = output
   811      })
   812  
   813      onClick('btnMultiDownload', async () => {
   814        console.log('multidownload')
   815        const path = getSelectedFile()
   816  
   817        const objects = []
   818        const allocationId = getSelectedAllocation()
   819        if (!allocationId) {
   820          alert("please provide allocationId")
   821        }
   822  
   823        objects.push({
   824          //remotePath: path,
   825          downloadOp: 1,
   826          numBlocks: 0,
   827          downloadToDisk: true,
   828        })
   829        let stringifiedArray = JSON.stringify(objects);
   830  
   831        try {
   832          const results = await goWasm.sdk.multiDownload('', stringifiedArray, 'eyJjbGllbnRfaWQiOiIiLCJvd25lcl9pZCI6IjI2ZTIzMjFhZWMxZmEyZDY1NGQ1MDQ5OWY3ZjhmYWJhNjNkYWMxYTExYTQwZDU3NDJkNDAzMWJmMzEzMzAxMTYiLCJhbGxvY2F0aW9uX2lkIjoiMDAwMzAzOTA1MGI3ZDdiM2FlNmI3MGEwZTVjMWU4ZjRhOTkxNzc1YWJiOTQ2NjljMDg4YzczNzJlMzYwMzkyYiIsImZpbGVfcGF0aF9oYXNoIjoiYWEzODE0NTM2ZWI2OWQwNjU4ZWM0OTgyZmE3ZTIwM2I2ZGI2ZWExYmU4ZmMxODRiMWJhOTZhMTk3NmMwM2JlOCIsImFjdHVhbF9maWxlX2hhc2giOiIxMjUwMjJhZGRiZTIwZDNhOWUzYjcxZTA0NjUzZjY3YiIsImZpbGVfbmFtZSI6InVidW50dS0yMi4wNC40LWxpdmUtc2VydmVyLWFtZDY0LmlzbyIsInJlZmVyZW5jZV90eXBlIjoiZiIsImV4cGlyYXRpb24iOjAsInRpbWVzdGFtcCI6MTcxNjM3ODIxNiwiZW5jcnlwdGVkIjpmYWxzZSwic2lnbmF0dXJlIjoiYmEzNzQ1NzlmZTczZDc1MWIwMTNiMjM2NjUzZDRiMGYyYzNjZDJlYTMyNTFkODg0MmRiNWQxNTlhNjBiN2ExMiJ9', '')
   833          console.log(JSON.stringify(results))
   834        } catch (e) {
   835          alert(e)
   836        }
   837  
   838      })
   839  
   840      onClick('btnMultiOps', async () => {
   841        const allocationId = getSelectedAllocation()
   842        if (!allocationId) {
   843          alert("please provide allocationId")
   844        }
   845        const objects = []
   846  
   847        objects.push(
   848          { // rename file
   849            operationType: `move`,
   850            remotePath: `/small2-182b.txt`,
   851            destPath: `/folder/small-182b.txt`,
   852          },
   853          { // todo: rename folder
   854            operationType: `move`,
   855            remotePath: `/folder`,
   856            destPath: `/folder2`,
   857          },
   858          { // move a file to an other folder
   859            operationType: `move`,
   860            remotePath: `/small-182b.txt`,
   861            destPath: `/folder/`,
   862          },
   863          { // copy a file to an other folder
   864            operationType: `copy`,
   865            remotePath: `/small2-182b.txt`,
   866            destPath: `/folder/`,
   867          },
   868        )
   869  
   870        let stringifiedArray = JSON.stringify(objects);
   871  
   872        try {
   873          console.log("executing MultiOps", objects[0])
   874          const output = await goWasm.sdk.multiOperation(allocationId, stringifiedArray)
   875        } catch (e) {
   876          alert(e)
   877        }
   878      })
   879  
   880      onClick('btnSetWalletInfo', async () => {
   881        const jsonWallet = {
   882          "client_id": "30764bcba73216b67c36b05a17b4dd076bfdc5bb0ed84856f27622188c377269",
   883          "client_key": "1f495df9605a4479a7dd6e5c7a78caf9f9d54e3a40f62a3dd68ed377115fe614d8acf0c238025f67a85163b9fbf31d10fbbb4a551d1cf00119897edf18b1841c",
   884          "keys": [
   885            { "public_key": "1f495df9605a4479a7dd6e5c7a78caf9f9d54e3a40f62a3dd68ed377115fe614d8acf0c238025f67a85163b9fbf31d10fbbb4a551d1cf00119897edf18b1841c", "private_key": "41729ed8d82f782646d2d30b9719acfd236842b9b6e47fee12b7bdbd05b35122" }
   886          ],
   887          "mnemonics": "glare mistake gun joke bid spare across diagram wrap cube swear cactus cave repeat you brave few best wild lion pitch pole original wasp",
   888          "version": "1.0",
   889          "date_created": "1662534022",
   890          "nonce": 0
   891        }
   892        const splitKeyWallet = true
   893        try {
   894          const jsonWalletString = JSON.stringify(jsonWallet);
   895          const isWalletInfoSet = await goWasm.sdk.setWalletInfo(jsonWalletString, splitKeyWallet)
   896          console.log("Set Wallet Info:", isWalletInfoSet)
   897        } catch (e) {
   898          alert(e)
   899        }
   900      })
   901  
   902      onClick('btnSetAuthUrl', async () => {
   903        // need to call setSplitKeyWallet to set wallet type to split key initially.
   904        const jsonWallet = {
   905          "client_id": "30764bcba73216b67c36b05a17b4dd076bfdc5bb0ed84856f27622188c377269",
   906          "client_key": "1f495df9605a4479a7dd6e5c7a78caf9f9d54e3a40f62a3dd68ed377115fe614d8acf0c238025f67a85163b9fbf31d10fbbb4a551d1cf00119897edf18b1841c",
   907          "keys": [
   908            { "public_key": "1f495df9605a4479a7dd6e5c7a78caf9f9d54e3a40f62a3dd68ed377115fe614d8acf0c238025f67a85163b9fbf31d10fbbb4a551d1cf00119897edf18b1841c", "private_key": "41729ed8d82f782646d2d30b9719acfd236842b9b6e47fee12b7bdbd05b35122" }
   909          ],
   910          "mnemonics": "glare mistake gun joke bid spare across diagram wrap cube swear cactus cave repeat you brave few best wild lion pitch pole original wasp",
   911          "version": "1.0",
   912          "date_created": "1662534022",
   913          "nonce": 0
   914        }
   915        const splitKeyWallet = true
   916        try {
   917          const jsonWalletString = JSON.stringify(jsonWallet);
   918          const isWalletInfoSet = await goWasm.sdk.setWalletInfo(jsonWalletString, splitKeyWallet)
   919          console.log("Set Wallet Info:", isWalletInfoSet)
   920        } catch (e) {
   921          alert(e)
   922        }
   923        // can add any string ,because just had string check while checking url
   924        const url = "Testing"
   925        try {
   926          const isAuthURLSet = await goWasm.sdk.setAuthUrl(url)
   927          console.log("Set Auth URL", isAuthURLSet);
   928        } catch (e) {
   929          alert(e)
   930        }
   931      })
   932  
   933      onClick('btnRegAuth', async () => {
   934        const authCallback = function (msg) {
   935          return `Authorized: ${msg}`;
   936        };
   937  
   938        const registerAuthorizer = goWasm.sdk.registerAuthorizer;
   939        registerAuthorizer(authCallback);
   940  
   941        // call the callAuth to see if the auth is set properly
   942        // Use the stored callback function from Go
   943        const message = "Hello, World!";
   944        const result = goWasm.sdk.callAuth(message);
   945        console.log(result); // Output: "Authorized: Hello, World!"
   946      })
   947  
   948    </script>
   949  </body>