New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

edge-core-js

Package Overview
Dependencies
Maintainers
6
Versions
292
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

edge-core-js - npm Package Compare versions

Comparing version 1.1.0 to 1.2.0

7

CHANGELOG.md
# edge-core-js
## v1.2.0 (2023-06-15)
- added: Add an `EdgeCurrencyWallet.streamTransactions` method.
- deprecated: Pagination options for `getTransactions`. Use `streamTransactions` if you need pagination.
- fixed: Add the correct URI to `changeUsername`, so it works.
- fixed: Send a 'transactionsChanged' event when editing metadata.
## v1.1.0 (2023-06-08)

@@ -4,0 +11,0 @@

61

lib/client-side.js

@@ -1,2 +0,2 @@

import { shareData } from 'yaob'
import { close, shareData } from 'yaob'

@@ -9,2 +9,17 @@

/**

@@ -86,1 +101,45 @@ * Client-side EdgeAccount methods.

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')

150

lib/core/currency/wallet/currency-wallet-api.js

@@ -5,2 +5,7 @@ function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }import { add, div, lte, mul, sub } from 'biggystring'

import {
streamTransactions
} from '../../../client-side'
import { upgradeCurrencyCode } from '../../../types/type-helpers'

@@ -31,2 +36,3 @@

import { mergeDeeply } from '../../../util/util'

@@ -226,6 +232,19 @@ import { makeMetaTokens } from '../../account/custom-tokens'

},
async getTransactions(
opts = {}
async $internalStreamTransactions(
opts
) {
const { currencyCode = plugin.currencyInfo.currencyCode } = opts
const {
afterDate,
batchSize = 10,
beforeDate,
firstBatchSize = batchSize,
searchString,
tokenId,
unfilteredStart
} = opts
const { currencyCode } =
tokenId == null
? this.currencyInfo
: this.currencyConfig.allTokens[tokenId]

@@ -259,49 +278,98 @@ // Load transactions from the engine if necessary:

} = state
const { startIndex = 0, startEntries = sortedTxidHashes.length } = opts
// Iterate over the sorted transactions until we have enough output:
const out = []
for (
let i = startIndex, lastFile = startIndex;
i < sortedTxidHashes.length && out.length < startEntries;
++i
) {
// Load a batch of files if we need that:
if (i >= lastFile) {
const loadEnd = lastFile + startEntries
const missingTxIdHashes = sortedTxidHashes
.slice(lastFile, loadEnd)
.filter(txidHash => files[txidHash] == null)
const missingFiles = await loadTxFiles(input, missingTxIdHashes)
Object.assign(files, missingFiles)
lastFile = loadEnd
}
let i = _nullishCoalesce(unfilteredStart, () => ( 0))
let isFirst = true
let lastFile = 0
return bridgifyObject({
async next() {
const thisBatchSize = isFirst ? firstBatchSize : batchSize
const out = []
while (i < sortedTxidHashes.length && out.length < thisBatchSize) {
// Load a batch of files if we need that:
if (i >= lastFile) {
const missingTxIdHashes = sortedTxidHashes
.slice(lastFile, lastFile + thisBatchSize)
.filter(txidHash => files[txidHash] == null)
const missingFiles = await loadTxFiles(input, missingTxIdHashes)
Object.assign(files, missingFiles)
lastFile = lastFile + thisBatchSize
}
const txidHash = sortedTxidHashes[i]
const file = files[txidHash]
const txid = _nullishCoalesce(_optionalChain([file, 'optionalAccess', _ => _.txid]), () => ( _optionalChain([txidHashes, 'access', _2 => _2[txidHash], 'optionalAccess', _3 => _3.txid])))
if (txid == null) continue
const tx = txs[txid]
const txidHash = sortedTxidHashes[i++]
const file = files[txidHash]
const txid = _nullishCoalesce(_optionalChain([file, 'optionalAccess', _ => _.txid]), () => ( _optionalChain([txidHashes, 'access', _2 => _2[txidHash], 'optionalAccess', _3 => _3.txid])))
if (txid == null) continue
const tx = txs[txid]
// Filter transactions based on the currency code:
if (
tx == null ||
(tx.nativeAmount[currencyCode] == null &&
tx.networkFee[currencyCode] == null)
) {
continue
// Filter transactions based on the currency code:
if (
tx == null ||
(tx.nativeAmount[currencyCode] == null &&
tx.networkFee[currencyCode] == null)
) {
continue
}
// Filter transactions based on search criteria:
const edgeTx = combineTxWithFile(input, tx, file, currencyCode)
if (!searchStringFilter(ai, edgeTx, searchString)) continue
if (!dateFilter(edgeTx, afterDate, beforeDate)) continue
// Preserve the `getTransactions` hack if needed:
if (unfilteredStart != null) {
edgeTx.otherParams = { ...edgeTx.otherParams, unfilteredIndex: i }
}
out.push(edgeTx)
}
isFirst = false
return { done: out.length === 0, value: out }
}
})
},
// add this tx / file to the output
const edgeTx = combineTxWithFile(input, tx, file, currencyCode)
if (searchStringFilter(ai, edgeTx, opts) && dateFilter(edgeTx, opts)) {
out.push({
...edgeTx,
otherParams: { ...edgeTx.otherParams, unfilteredIndex: i }
})
async getTransactions(
opts = {}
) {
const {
currencyCode = plugin.currencyInfo.currencyCode,
endDate: beforeDate,
startDate: afterDate,
searchString,
startEntries,
startIndex = 0
} = opts
const { tokenId } = upgradeCurrencyCode({
allTokens: input.props.state.accounts[accountId].allTokens[pluginId],
currencyInfo: plugin.currencyInfo,
currencyCode
})
const stream = await out.$internalStreamTransactions({
unfilteredStart: startIndex,
batchSize: startEntries,
afterDate,
beforeDate,
searchString,
tokenId
})
// We have no length, so iterate to get everything:
if (startEntries == null) {
const out = []
while (true) {
const batch = await stream.next()
if (batch.done) return out
out.push(...batch.value)
}
}
return out
// We have a length, so the first batch is all we need:
const batch = await stream.next()
return batch.value
},
streamTransactions,
// Addresses:

@@ -308,0 +376,0 @@ async getReceiveAddress(

@@ -279,3 +279,3 @@ function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }import { lt } from 'biggystring'

const reduxTx = mergeTx(tx, defaultCurrency, reduxTxs[txid])
if (compare(reduxTx, reduxTxs[txid])) continue
if (compare(reduxTx, reduxTxs[txid]) && tx.metadata == null) continue

@@ -282,0 +282,0 @@ // Ensure the transaction has metadata:

export function dateFilter(
tx,
opts
afterDate = new Date(0),
beforeDate = new Date()
) {
const { startDate = new Date(0), endDate = new Date() } = opts
return (
tx.date * 1000 >= startDate.valueOf() && tx.date * 1000 < endDate.valueOf()
tx.date * 1000 >= afterDate.valueOf() &&
tx.date * 1000 < beforeDate.valueOf()
)

@@ -21,79 +18,74 @@ }

tx,
opts
searchString
) {
const currencyState = ai.props.state.currency
const { searchString } = opts
if (searchString != null && searchString !== '') {
// Sanitize search string
let cleanString = searchString
.toLowerCase()
.replace('.', '')
.replace(',', '')
// Remove leading zeroes
for (let i = 0; i < cleanString.length; i++) {
if (cleanString[i] !== '0') {
cleanString = cleanString.substring(i)
break
}
if (searchString == null || searchString === '') return true
// Sanitize search string
let cleanString = searchString.toLowerCase().replace('.', '').replace(',', '')
// Remove leading zeroes
for (let i = 0; i < cleanString.length; i++) {
if (cleanString[i] !== '0') {
cleanString = cleanString.substring(i)
break
}
}
function checkNullTypeAndIndex(value) {
if (
value == null ||
(typeof value !== 'string' && typeof value !== 'number')
)
return false
if (
!value
.toString()
.toLowerCase()
.replace('.', '')
.replace(',', '')
.includes(cleanString)
)
return false
function checkNullTypeAndIndex(value) {
if (
value == null ||
(typeof value !== 'string' && typeof value !== 'number')
)
return false
if (
!value
.toString()
.toLowerCase()
.replace('.', '')
.replace(',', '')
.includes(cleanString)
)
return false
return true
}
if (checkNullTypeAndIndex(tx.nativeAmount)) return true
if (tx.metadata != null) {
const {
category = '',
name = '',
notes = '',
exchangeAmount = {}
} = tx.metadata
const txCurrencyWalletState =
tx.walletId != null ? currencyState.wallets[tx.walletId] : undefined
if (
checkNullTypeAndIndex(category) ||
checkNullTypeAndIndex(name) ||
checkNullTypeAndIndex(notes) ||
(txCurrencyWalletState != null &&
checkNullTypeAndIndex(exchangeAmount[txCurrencyWalletState.fiat]))
)
return true
}
if (checkNullTypeAndIndex(tx.nativeAmount)) return true
if (tx.metadata != null) {
const {
category = '',
name = '',
notes = '',
exchangeAmount = {}
} = tx.metadata
const txCurrencyWalletState =
tx.walletId != null ? currencyState.wallets[tx.walletId] : undefined
if (
checkNullTypeAndIndex(category) ||
checkNullTypeAndIndex(name) ||
checkNullTypeAndIndex(notes) ||
(txCurrencyWalletState != null &&
checkNullTypeAndIndex(exchangeAmount[txCurrencyWalletState.fiat]))
)
}
if (tx.swapData != null) {
const { displayName = '', pluginId = '' } = tx.swapData.plugin
if (checkNullTypeAndIndex(displayName) || checkNullTypeAndIndex(pluginId))
return true
}
if (tx.spendTargets != null) {
for (const target of tx.spendTargets) {
const { publicAddress = '', memo = '' } = target
if (checkNullTypeAndIndex(publicAddress) || checkNullTypeAndIndex(memo))
return true
}
if (tx.swapData != null) {
const { displayName = '', pluginId = '' } = tx.swapData.plugin
if (checkNullTypeAndIndex(displayName) || checkNullTypeAndIndex(pluginId))
return true
}
if (tx.ourReceiveAddresses.length > 0) {
for (const address of tx.ourReceiveAddresses) {
if (checkNullTypeAndIndex(address)) return true
}
if (tx.spendTargets != null) {
for (const target of tx.spendTargets) {
const { publicAddress = '', memo = '' } = target
if (checkNullTypeAndIndex(publicAddress) || checkNullTypeAndIndex(memo))
return true
}
}
if (tx.ourReceiveAddresses.length > 0) {
for (const address of tx.ourReceiveAddresses) {
if (checkNullTypeAndIndex(address)) return true
}
}
if (checkNullTypeAndIndex(tx.txid)) return true
return false
}
return true
if (checkNullTypeAndIndex(tx.txid)) return true
return false
}

@@ -89,3 +89,3 @@ function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }import { uncleaner } from 'cleaners'

},
serverPath: '',
serverPath: '/v2/login/username',
stash: {

@@ -92,0 +92,0 @@ ..._optionalChain([passwordKit, 'optionalAccess', _9 => _9.stash]),

@@ -573,2 +573,3 @@ // @flow

* which can be used as the starting point for subsequent queries.
* @deprecated Use `streamTransactions` if you need pagination.
*/

@@ -581,2 +582,3 @@ startIndex?: number;

* We may return less than this when we reach the end.
* @deprecated Use `streamTransactions` if you need pagination.
*/

@@ -592,2 +594,28 @@ startEntries?: number;

export type EdgeStreamTransactionOptions = {
/**
* The number of entries to return in each batch.
* Defaults to something reasonable, like 10.
*/
batchSize?: number;
/**
* The number entries to return on the first batch.
* Defaults to `batchSize`.
*/
firstBatchSize?: number;
/** Only return transactions newer than this date */
afterDate?: Date;
/** Only return transactions older than this date */
beforeDate?: Date;
/** Only return transactions matching this string */
searchString?: string;
/** The token to query, or undefined for the main currency */
tokenId?: string;
}
export type EdgeGetReceiveAddressOptions = EdgeCurrencyCodeOptions & {

@@ -940,2 +968,5 @@ forceIndex?: number;

) => Promise<EdgeTransaction[]>;
+streamTransactions: (
opts?: EdgeStreamTransactionOptions
) => AsyncGenerator<EdgeTransaction[]>;

@@ -942,0 +973,0 @@ // Addresses:

@@ -1674,1 +1674,32 @@

{
"name": "edge-core-js",
"version": "1.1.0",
"version": "1.2.0",
"description": "Edge account & wallet management library",

@@ -5,0 +5,0 @@ "keywords": [

@@ -571,2 +571,3 @@ import type { Disklet } from 'disklet'

* which can be used as the starting point for subsequent queries.
* @deprecated Use `streamTransactions` if you need pagination.
*/

@@ -579,2 +580,3 @@ startIndex?: number

* We may return less than this when we reach the end.
* @deprecated Use `streamTransactions` if you need pagination.
*/

@@ -590,2 +592,28 @@ startEntries?: number

export interface EdgeStreamTransactionOptions {
/**
* The number of entries to return in each batch.
* Defaults to something reasonable, like 10.
*/
batchSize?: number
/**
* The number entries to return on the first batch.
* Defaults to `batchSize`.
*/
firstBatchSize?: number
/** Only return transactions newer than this date */
afterDate?: Date
/** Only return transactions older than this date */
beforeDate?: Date
/** Only return transactions matching this string */
searchString?: string
/** The token to query, or undefined for the main currency */
tokenId?: string
}
export type EdgeGetReceiveAddressOptions = EdgeCurrencyCodeOptions & {

@@ -934,2 +962,5 @@ forceIndex?: number

) => Promise<EdgeTransaction[]>
readonly streamTransactions: (
opts?: EdgeStreamTransactionOptions
) => AsyncIterableIterator<EdgeTransaction[]>

@@ -936,0 +967,0 @@ // Addresses:

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc