wif.js 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. import { toBase58checkSync, fromBase58checkSync } from '@exodus/bytes/base58check.js'
  2. import { assertUint8 } from './assert.js'
  3. // Mostly matches npmjs.com/wif, but with extra checks + using our base58check
  4. // Also no inconsistent behavior on Buffer/Uint8Array input
  5. function from(arr, expectedVersion) {
  6. assertUint8(arr)
  7. if (arr.length !== 33 && arr.length !== 34) throw new Error('Invalid WIF length')
  8. const version = arr[0]
  9. if (expectedVersion !== undefined && version !== expectedVersion) {
  10. throw new Error('Invalid network version')
  11. }
  12. // Makes a copy, regardless of input being a Buffer or a Uint8Array (unlike .slice)
  13. const privateKey = Uint8Array.from(arr.subarray(1, 33))
  14. if (arr.length === 33) return { version, privateKey, compressed: false }
  15. if (arr[33] !== 1) throw new Error('Invalid compression flag')
  16. return { version, privateKey, compressed: true }
  17. }
  18. function to({ version: v, privateKey, compressed }) {
  19. if (!Number.isSafeInteger(v) || v < 0 || v > 0xff) throw new Error('Missing or invalid version')
  20. assertUint8(privateKey, { length: 32, name: 'privateKey' })
  21. const out = new Uint8Array(compressed ? 34 : 33)
  22. out[0] = v
  23. out.set(privateKey, 1)
  24. if (compressed) out[33] = 1
  25. return out
  26. }
  27. // Async performance is worse here, so expose the same internal methods as sync for now
  28. // ./base58check is sync internally anyway for now, so doesn't matter until that is changed
  29. export const fromWifStringSync = (string, version) => from(fromBase58checkSync(string), version)
  30. // export const fromWifString = async (string, version) => from(await fromBase58check(string), version)
  31. export const fromWifString = async (string, version) => from(fromBase58checkSync(string), version)
  32. export const toWifStringSync = (wif) => toBase58checkSync(to(wif))
  33. // export const toWifString = async (wif) => toBase58check(to(wif))
  34. export const toWifString = async (wif) => toBase58checkSync(to(wif))