jshuo / hw-app-avalanche

SecuX JS bindings for Avalanche

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Using SecuX JS for Avalanche

Here is example of our source code

//@flow

import createHash from 'create-hash'
import { buildPathBuffer } from '@secux/utility'
import { ITransport, StatusCode, TransportStatusError } from '@secux/transport'

function buildTxBuffer(paths: Array<string>, txs: Buffer, tp: TransactionType, chainId: number) {
  const head = [],
    data = []
  for (let i = 0; i < paths.length; i++) {
    const headerBuffer = Buffer.alloc(4)
    headerBuffer.writeUInt16LE(tp, 0)
    headerBuffer.writeUInt16LE(chainId, 2)

    const path = paths[i]
    const { pathNum, pathBuffer } = buildPathBuffer(path)
    // generic prepare can use 3 or 5 path level key to sign
    if (pathNum !== 5 && pathNum !== 3) throw Error('Invalid Path for Signing Transaction')

    head.push(Buffer.concat([Buffer.from([pathNum * 4 + 4]), headerBuffer, pathBuffer]))
  }
  // fixed 2 byte length
  const preparedTxLenBuf = Buffer.alloc(2)
  preparedTxLenBuf.writeUInt16BE(txs.length, 0)
  data.push(Buffer.concat([preparedTxLenBuf, txs]))
  return Buffer.concat([Buffer.from([paths.length]), ...head, ...data])
}

export default class Avalanche {
  constructor(transport) {
    this.transport = transport
  }
  async signTransaction(prefixPath, paths, changePath, txn: Buffer): Promise<{ hash: Buffer, signatures: Map<string, Buffer> }> {
    const SIGNATURE_LENGTH = 65
    let bip32path = []
    let resultMap: Map<string, Buffer> = new Map()
    for (let i = 0; i < paths.length; i++) {
      let suffix = paths[i]
      bip32path.push(`${prefixPath}/${suffix}`)
    }
    const P1 = changePath !== null ? 0x1 : 0x0
    if (changePath !== null) bip32path.push(changePath)
    const txBuffer = buildTxBuffer(bip32path, Buffer.from(txn))
    const rsp = await this.transport.Send(0x70, 0xa7, P1, 0, Buffer.concat([txBuffer]))
    // if (rsp.status !== StatusCode.SUCCESS) throw new TransportStatusError(rsp.status)
    if (rsp.dataLength !== SIGNATURE_LENGTH * paths.length) throw Error('Invalid length Signature')

    let signature = []
    let offset = 0
    while (offset < rsp.dataLength) {
      const sig = rsp.data.slice(offset, offset + SIGNATURE_LENGTH)
      offset = offset + SIGNATURE_LENGTH
      signature.push(sig)
    }

    for (let i = 0; i < paths.length; i++) {
      resultMap.set(paths[i].toString(true), signature[i])
    }
    return {
      hash: '',
      signatures: resultMap
    }
  }
}

About

SecuX JS bindings for Avalanche

License:Other


Languages

Language:JavaScript 93.0%Language:Shell 7.0%