edge-core-js
Version:
Edge account & wallet management library
137 lines (101 loc) • 2.91 kB
JavaScript
import { close, shareData } from 'yaob'
/**
* Client-side EdgeAccount methods.
*/
export class AccountSync {
getFirstWalletInfo(type) {
return this.allKeys.find(info => info.type === type)
}
getWalletInfo(id) {
return this.allKeys.find(info => info.id === id)
}
listWalletIds() {
return this.allKeys.map(info => info.id)
}
}
shareData(AccountSync.prototype, 'AccountSync')
/**
* Verifies that a password meets our suggested rules.
*/
export function checkPasswordRules(password) {
const tooShort = password.length < 10
const noNumber = !/[0-9]/.test(password)
const noLowerCase = !/[a-z]/.test(password)
const noUpperCase = !/[A-Z]/.test(password)
// Quick & dirty password strength estimation:
const charset =
(/[0-9]/.test(password) ? 10 : 0) +
(/[A-Z]/.test(password) ? 26 : 0) +
(/[a-z]/.test(password) ? 26 : 0) +
(/[^0-9A-Za-z]/.test(password) ? 30 : 0)
const secondsToCrack = Math.pow(charset, password.length) / 1e6
return {
secondsToCrack,
tooShort,
noNumber,
noLowerCase,
noUpperCase,
passed:
password.length >= 16 ||
!(tooShort || noNumber || noUpperCase || noLowerCase)
}
}
shareData({ checkPasswordRules })
/**
* Normalizes a username, and checks for invalid characters.
* TODO: Support a wider character range via Unicode normalization.
*/
export function fixUsername(username) {
const out = username
.toLowerCase()
.replace(/[ \f\r\n\t\v]+/g, ' ')
.replace(/ $/, '')
.replace(/^ /, '')
for (let i = 0; i < out.length; ++i) {
const c = out.charCodeAt(i)
if (c < 0x20 || c > 0x7e) {
throw new Error('Bad characters in username')
}
}
return out
}
shareData({ fixUsername })
/**
* Synchronously constructs a transaction stream.
* This method creates a secret internal stream,
* which differs slightly from the AsyncIterableIterator protocol
* because of YAOB limitations.
* It then wraps the internal stream object with the correct API.
*/
export function streamTransactions(
opts
) {
let stream
let streamClosed = false
const out = {
next: async () => {
if (stream == null) stream = await this.$internalStreamTransactions(opts)
if (!streamClosed) {
const out = await stream.next()
if (!out.done) return out
close(stream)
streamClosed = true
}
return { done: true, value: undefined }
},
/**
* Closes the iterator early if the client doesn't want all the results.
* This is necessary to prevent memory leaks over the bridge.
*/
return: async () => {
if (stream != null && !streamClosed) {
close(stream)
streamClosed = true
}
return { done: true, value: undefined }
},
[Symbol.asyncIterator]: () => out
}
return out
}
shareData({ streamTransactions }, 'CurrencyWalletSync')