HmacSHA1 with WebView but JavaScript execution returned a result of an unsupported type

Hi. I’m trying to calculate signature for Twitter API, so I wanna calculate HmacSHA1 without any libraries.
I wrote this function, calcHmacSHA1() with Web Crypto API.


// calcHmacSHA1
async function calcHmacSHA1(base, key){
  let wv = new WebView()
  let html = `
  <script>
  async function main(BASE, KEY, CALLBACK){
    const te = new TextEncoder('utf-8');
    const cryptoKey = await crypto.subtle.importKey(
      'raw',
      te.encode(KEY),
      {name: 'HMAC', hash: {name: 'SHA-1'}},
      false,
      ['sign']
    );
    const signature = await crypto.subtle.sign(
      'HMAC',
      cryptoKey,
      te.encode(BASE)
    );
    const buff = new Uint8Array(signature);
    const str = btoa(String.fromCharCode(...buff))
    return str;
  };
  </script>
  `;
  let js = `main('${base}', '${key}').then(completion);`;
  await wv.loadHTML(html);
  let result = await wv.evaluateJavaScript(js, true)
  return result;
};

let key = 'MyKey';
let base = 'MyMessage';
console.log(await calcHmacSHA1(base, key));

Log:

Error: Failed evaluating JavaScript with error: JavaScript execution returned a result of an unsupported type

Anyone know how to solve it?

It works for me when I change the line

let js = `main('${base}', '${key}').then(completion);`;

to

let js = `main('${base}', '${key}').then(completion); ""`;

I’ve added "" to the end of the line inside the string which is passed to wv.evaluateJavaScript(js, true);.

Apparently Scriptable tries to process the return value of the script somehow, even though it should wait for the call to the completion function. And because the app can’t convert a promise, it errors instantly.
With my modification, the app recieves a string, which it can process and then Scriptable waits correctly for the call to the completion function.

@simonbs Can you please have a look at this? It is quite unintuitive…

2 Likes