@polkadot/util#compactFromU8a TypeScript Examples

The following examples show how to use @polkadot/util#compactFromU8a. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: QrSigner.ts    From sdk with Apache License 2.0 4 votes vote down vote up
async function _constructDataFromBytes(bytes: Uint8Array, multipartComplete = false) {
  const frameInfo = hexStripPrefix(u8aToHex(bytes.slice(0, 5)));
  const frameCount = parseInt(frameInfo.substr(2, 4), 16);
  const isMultipart = frameCount > 1; // for simplicity, even single frame payloads are marked as multipart.
  const currentFrame = parseInt(frameInfo.substr(6, 4), 16);
  const uosAfterFrames = hexStripPrefix(u8aToHex(bytes.slice(5)));

  // UOS after frames can be metadata json
  if (isMultipart && !multipartComplete) {
    const partData = {
      currentFrame,
      frameCount,
      isMultipart,
      partData: uosAfterFrames,
    };
    return partData;
  }

  const zerothByte = uosAfterFrames.substr(0, 2);
  const firstByte = uosAfterFrames.substr(2, 2);
  const secondByte = uosAfterFrames.substr(4, 2);

  let action: string;

  try {
    // decode payload appropriately via UOS
    switch (zerothByte) {
      case "45": {
        // Ethereum UOS payload
        const data = {
          data: {}, // for consistency with legacy data format.
        };
        action = firstByte === "00" || firstByte === "01" ? "signData" : firstByte === "01" ? "signTransaction" : null;
        const address = uosAfterFrames.substr(4, 44);

        data["action"] = action;
        data.data["account"] = address;
        if (action === "signData") {
          data.data["rlp"] = uosAfterFrames[13];
        } else if (action === "signTransaction") {
          data.data["data"] = uosAfterFrames[13];
        } else {
          throw new Error("Could not determine action type.");
        }
        return data;
      }
      case "53": {
        // Substrate UOS payload
        const data = {
          data: {}, // for consistency with legacy data format.
        };
        try {
          data.data["crypto"] = firstByte === "00" ? "ed25519" : firstByte === "01" ? "sr25519" : null;
          const pubKeyHex = uosAfterFrames.substr(6, 64);
          const publicKeyAsBytes = hexToU8a("0x" + pubKeyHex);
          const hexEncodedData = "0x" + uosAfterFrames.slice(70);
          const hexPayload = hexEncodedData.slice(0, -64);
          const genesisHash = `0x${hexEncodedData.substr(-64)}`;
          const rawPayload = hexToU8a(hexPayload);
          data.data["genesisHash"] = genesisHash;
          const isOversized = rawPayload.length > 256;
          const network = SUBSTRATE_NETWORK_LIST[genesisHash];
          // if (!network) {
          //   throw new Error(`Signer does not currently support a chain with genesis hash: ${genesisHash}`);
          // }

          switch (secondByte) {
            case "00": // sign mortal extrinsic
            case "02": // sign immortal extrinsic
              data["action"] = isOversized ? "signData" : "signTransaction";
              data["oversized"] = isOversized;
              data["isHash"] = isOversized;
              const [offset] = compactFromU8a(rawPayload);
              const payload = rawPayload.subarray(offset);
              // data.data.data = isOversized
              // 	? await blake2b(u8aToHex(payload, -1, false))
              // 	: rawPayload;
              data.data["data"] = rawPayload; // ignore oversized data for now
              data.data["account"] = encodeAddress(publicKeyAsBytes, network?.prefix || 0); // encode to the prefix;

              break;
            case "01": // data is a hash
              data["action"] = "signData";
              data["oversized"] = false;
              data["isHash"] = true;
              data.data["data"] = hexPayload;
              data.data["account"] = encodeAddress(publicKeyAsBytes, network?.prefix || 0); // default to Kusama
              break;
          }
        } catch (e) {
          throw new Error("Error: something went wrong decoding the Substrate UOS payload: " + uosAfterFrames);
        }
        return data;
      }
      default:
        throw new Error("Error: Payload is not formatted correctly: " + bytes);
    }
  } catch (e) {
    throw new Error("we cannot handle the payload: " + bytes);
  }
}