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

bnc-assist

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bnc-assist - npm Package Compare versions

Comparing version 0.6.2 to 0.7.0

multidep.json

6

internals/jestSetup.js

@@ -6,1 +6,7 @@ // eslint-disable-next-line import/no-extraneous-dependencies

MockDate.set('1/1/2010')
// Set a single userAgent to use across all development environments
Object.defineProperty(window.navigator, 'userAgent', {
value:
'Mozilla/ 5.0(linux) AppleWebKit / 537.36(KHTML, like Gecko) jsdom / 11.12.0'
})

6

package.json
{
"name": "bnc-assist",
"version": "0.6.2",
"version": "0.7.0",
"description": "Blocknative Assist js library for Dapp developers",

@@ -10,2 +10,3 @@ "main": "lib/assist.min.js",

"lint": "eslint src/ --fix",
"pretest": "multidep multidep.json",
"test": "TZ=Europe/Paris jest"

@@ -66,2 +67,3 @@ },

"mockdate": "^2.0.2",
"multidep": "^2.0.2",
"prettier": "^1.15.2",

@@ -82,2 +84,2 @@ "regenerator-runtime": "^0.13.1",

]
}
}

@@ -46,3 +46,3 @@ # Assist.js

The library uses [semantic versioning](https://semver.org/spec/v2.0.0.html).
The current version is 0.6.2.
The current version is 0.7.0.
There are minified and non-minified versions.

@@ -52,7 +52,7 @@ Put this script at the top of your `<head>`

```html
<script src="https://assist.blocknative.com/0-6-2/assist.js"></script>
<script src="https://assist.blocknative.com/0-7-0/assist.js"></script>
<!-- OR... -->
<script src="https://assist.blocknative.com/0-6-2/assist.min.js"></script>
<script src="https://assist.blocknative.com/0-7-0/assist.min.js"></script>
```

@@ -416,2 +416,75 @@

### `updateStyle(style)`
#### Parameters
`style` - `Object`: Object containing new style information (**Required**)
```javascript
const style = {
darkMode: Boolean, // Set Assist UI to dark mode
css: String, // Custom css string to overide Assist default styles
notificationsPosition: String, // Defines which corner transaction notifications will be positioned. Options: 'topLeft', 'topRight', 'bottomRight', 'bottomLeft'. ['bottomRight']
}
```
#### Examples
```javascript
// Enable dark mode
const style = {
darkMode: true
}
assistInstance.updateStyle(style)
// Disable dark mode and set notification background to black
const style = {
darkMode: false,
css: `.bn-notification { background: black }`
}
assistInstance.updateStyle(style)
```
### `notify(type, message, options)`
Trigger a custom UI notification
#### Parameters
`type` - `String`: One of: ['success', 'pending', 'error'] (**Required**)
`message` - `String`: The message to display in the notification. HTML can be embedded in the string. (**Required**)
`options` - `Object`: Further customize the notification
```javascript
options = {
customTimeout: Number, // Specify how many ms the notification should exist. Set to -1 for no timeout.
customCode: String // An identifier for this notify call
}
```
options.customTimeout defaults: { success: 2000, pending: 5000, error: 5000 }
#### Returns
`Function`
- a function that when called will dismiss the notification
#### Examples
```javascript
// Display a success notification with an embedded link for 5000ms
assistInstance.notify('success', 'Operation was a success! Click <a href="https://example.com" target="_blank">here</a> to view more', { customTimeout: 5000 });
// Display a pending notification, load data from an imaginary backend
// and dismiss the pending notification only when the data is loaded
const dismiss = assistInstance.notify('pending', 'Loading data...', { customTimeout: -1 });
myEventEmitter.emit('fetch-data-from-backend')
myEventEmitter.on('data-from-backend-loaded', () => {
dismiss()
})
```
## Contribute

@@ -418,0 +491,0 @@

@@ -35,2 +35,21 @@ import { initialState } from './index.test'

export default {
success: {
categories: ['userInitiatedNotify'],
customStates: [
{ config: { messages: { success: () => 'success custom msg' } } }
]
},
pending: {
categories: ['userInitiatedNotify'],
params: { transaction: mockTxFactory({ startTime: true }) },
customStates: [
{ config: { messages: { pending: () => 'pending custom msg' } } }
]
},
error: {
categories: ['userInitiatedNotify'],
customStates: [
{ config: { messages: { error: () => 'error custom msg' } } }
]
},
browserFail: {

@@ -37,0 +56,0 @@ categories: ['onboard'],

import 'jest-dom/extend-expect'
import assist from '~/js'
import { createIframe } from '~/js/helpers/iframe'
import styles from '~/css/styles.css'
import { updateState } from '~/js/helpers/state'
import { updateState, initialState } from '~/js/helpers/state'
import { handleEvent } from '~/js/helpers/events'

@@ -15,1 +17,54 @@ test('iframe gets rendered to document', () => {

})
// Check that updating notificationsPosition doesn't throw any errors
describe('when the initial notification position is bottomRight', () => {
let notificationsPosition
let config
beforeEach(() => {
notificationsPosition = 'bottomRight'
config = { dappId: '123', style: { notificationsPosition } }
})
describe('and there are no notifications in the DOM', () => {
test(`changing the notification position to topLeft doesn't throw`, () => {
const da = assist.init(config)
da.updateStyle({ notificationsPosition: 'topLeft' })
})
})
describe('and there are notifications in the DOM', () => {
test(`changing the notification position to topLeft doesn't throw`, () => {
const da = assist.init(config)
handleEvent({ eventCode: 'txPending', categoryCode: 'activeTransaction' })
handleEvent({ eventCode: 'txSent', categoryCode: 'activeTransaction' })
handleEvent({ eventCode: 'txFailed', categoryCode: 'activeTransaction' })
da.updateStyle({ notificationsPosition: 'topLeft' })
})
})
})
describe('when the initial notification position is topLeft', () => {
let notificationsPosition
let config
beforeEach(() => {
notificationsPosition = 'topLeft'
config = { dappId: '123', style: { notificationsPosition } }
})
describe('and there are no notifications in the DOM', () => {
test(`changing the notification position to bottomRight doesn't throw`, () => {
const da = assist.init(config)
da.updateStyle({ notificationsPosition: 'bottomRight' })
})
})
describe('and there are notifications in the DOM', () => {
test(`changing the notification position to bottomRight doesn't throw`, () => {
const da = assist.init(config)
handleEvent({ eventCode: 'txPending', categoryCode: 'activeTransaction' })
handleEvent({ eventCode: 'txSent', categoryCode: 'activeTransaction' })
handleEvent({ eventCode: 'txFailed', categoryCode: 'activeTransaction' })
da.updateStyle({ notificationsPosition: 'bottomRight' })
})
})
})
afterEach(() => {
updateState(initialState)
})

@@ -11,3 +11,2 @@ import Web3 from 'web3'

jest.mock('../../js/helpers/browser')
jest.mock('../../js/helpers/state')
jest.mock('../../js/helpers/iframe')

@@ -18,3 +17,5 @@

// this is a little hacky but it's easier than creating a __mocks__ directory just for this case
websocket.openWebsocketConnection = jest.fn(() => ({ then: jest.fn() }))
websocket.openWebsocketConnection = jest.fn(() => {
jest.fn()
})

@@ -54,2 +55,3 @@ const assist = da.init({ dappId: 'something' })

)
try {

@@ -107,3 +109,3 @@ assist.Contract(contract)

const web3 = new Web3('ws://example.com')
stateMock.state.validApiKey = true
stateMock.state = { validApiKey: true, accessToAccounts: true }
da.init({ dappId: 'something', web3, headlessMode: true })

@@ -115,3 +117,4 @@ expect(iframeMock.createIframe).toHaveBeenCalledTimes(0)

beforeEach(() => {
stateMock.updateState(stateMock.initialState)
events.handleEvent.mockClear()
})

@@ -18,5 +18,17 @@ import eventToUI from '~/js/views/event-to-ui'

// If not a server event then log it
!serverEvent && lib.logEvent(eventObj)
let eventToLog = { ...eventObj }
// If dealing with a custom notification the logged event
// should have it's event and category code changed
if (categoryCode === 'userInitiatedNotify') {
eventToLog = {
...eventToLog,
categoryCode: 'custom',
eventCode: 'notification'
}
}
// Log everything that isn't a server event
!serverEvent && lib.logEvent(eventToLog)
// If tx status is 'completed', UI has been already handled

@@ -23,0 +35,0 @@ if (eventCode === 'txConfirmed' || eventCode === 'txConfirmedClient') {

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

import { positionElement } from '~/js/views/dom'
import { positionElement, updateNotificationsPosition } from '~/js/views/dom'
import darkModeStyles from '~/css/dark-mode.css'

@@ -6,5 +6,52 @@

export function updateStyle({ darkMode, css, notificationsPosition }) {
const { iframeDocument } = state
const darkModeStyleElement = iframeDocument.getElementById('dark-mode-style')
const customCssStyleElement = iframeDocument.getElementById(
'custom-css-style'
)
// update darkMode
if (typeof darkMode === 'boolean') {
const newConfig = {
...state.config,
style: {
...state.config.style,
darkMode
}
}
darkModeStyleElement.innerHTML = darkMode ? darkModeStyles : ''
updateState({ config: newConfig })
}
// update custom css
if (css) {
const newConfig = {
...state.config,
style: {
...state.config.style,
css
}
}
customCssStyleElement.innerHTML = css
updateState({ config: newConfig })
}
// update notifications position
if (notificationsPosition) {
const newConfig = {
...state.config,
style: {
...state.config.style,
notificationsPosition
}
}
updateState({
config: newConfig
})
updateNotificationsPosition()
}
}
export function createIframe(browserDocument, assistStyles, style = {}) {
const { darkMode, css } = style
const initialIframeContent = `

@@ -16,8 +63,4 @@ <html>

</style>
<style>
${darkMode ? darkModeStyles : ''}
</style>
<style>
${css || ''}
</style>
<style id="dark-mode-style"></style>
<style id="custom-css-style"></style>
</head>

@@ -43,2 +86,3 @@ <body></body>

updateState({ iframe, iframeDocument: iDocument, iframeWindow: iWindow })
updateStyle(style)
}

@@ -45,0 +89,0 @@

@@ -43,1 +43,33 @@ export const initialState = {

}
export function filteredState() {
const {
mobileDevice,
validBrowser,
currentProvider,
web3Wallet,
accessToAccounts,
walletLoggedIn,
walletEnabled,
accountAddress,
accountBalance,
minimumBalance,
userCurrentNetworkId,
correctNetwork
} = state
return {
mobileDevice,
validBrowser,
currentProvider,
web3Wallet,
accessToAccounts,
walletLoggedIn,
walletEnabled,
accountAddress,
accountBalance,
minimumBalance,
userCurrentNetworkId,
correctNetwork
}
}

@@ -109,2 +109,3 @@ import uuid from 'uuid/v4'

case 'txCancel':
case 'pending':
return 'progress'

@@ -118,5 +119,7 @@ case 'txSendFail':

case 'txConfirmReminder':
case 'error':
return 'failed'
case 'txConfirmed':
case 'txConfirmedClient':
case 'success':
return 'complete'

@@ -123,0 +126,0 @@ default:

@@ -5,4 +5,5 @@ import '@babel/polyfill'

import { state, updateState } from './helpers/state'
import { state, updateState, filteredState } from './helpers/state'
import { handleEvent } from './helpers/events'
import notify from './logic/user-initiated-notify'
import {

@@ -20,3 +21,3 @@ legacyCall,

import { getOverloadedMethodKeys } from './helpers/utilities'
import { createIframe } from './helpers/iframe'
import { createIframe, updateStyle } from './helpers/iframe'
import {

@@ -101,3 +102,5 @@ getTransactionQueueFromStorage,

Transaction,
getState
getState,
updateStyle,
notify
}

@@ -198,3 +201,3 @@

resolve('User is ready to transact')
resolve(filteredState())
})

@@ -236,3 +239,3 @@ }

const ready = await prepareForTransaction('onboard').catch(error => {
await prepareForTransaction('onboard').catch(error => {
removeItem('onboarding')

@@ -243,3 +246,3 @@ reject(error)

removeItem('onboarding')
resolve(ready)
resolve(filteredState())
})

@@ -286,5 +289,6 @@ }

contractObj._jsonInterface ||
Object.keys(contractObj.abiModel.abi.methods).map(
key => contractObj.abiModel.abi.methods[key].abiItem
)
Object.keys(contractObj.abiModel.abi.methods)
// remove any arrays from the ABI, they contain redundant information
.filter(key => !Array.isArray(contractObj.abiModel.abi.methods[key]))
.map(key => contractObj.abiModel.abi.methods[key].abiItem)

@@ -371,42 +375,40 @@ const contractClone = Object.create(Object.getPrototypeOf(contractObj))

const methodsKeys = Object.keys(contractObj[key])
// go through all the methods in the contract ABI and derive
// the 'methods' key of the delegated contract from them
newContractObj.methods = abi.reduce((methodsObj, methodAbi) => {
const { name, type, constant, inputs } = methodAbi
newContractObj.methods = abi.reduce((obj, methodAbi) => {
const { name, type, constant } = methodAbi
// if not function, do nothing with it
if (type !== 'function') {
return obj
return methodsObj
}
// if we have seen this key, then we have already dealt with it
if (seenMethods.includes(name)) {
return obj
// every method can called like contract.methods[methodName](...args).
// add a methodName key to methodsObj allowing it to be called that way.
// it only needs to be assigned once
if (!seenMethods.includes(name)) {
const method = contractObj.methods[name]
methodsObj[name] = (...args) =>
constant
? modernCall(method, name, args)
: modernSend(method, name, args)
seenMethods.push(name)
}
seenMethods.push(name)
// add a key to methods allowing the current method to be called
// like contract.methods[`${methodName}(${...args})`](...args)
let overloadedMethodKey
if (inputs.length > 0) {
overloadedMethodKey = `${name}(${getOverloadedMethodKeys(inputs)})`
} else {
overloadedMethodKey = `${name}()`
}
const method = contractObj.methods[name]
const overloadedMethodKeys = methodsKeys.filter(
methodKey => methodKey.split('(')[0] === name && methodKey !== name
)
obj[name] = (...args) =>
const overloadedMethod = contractObj.methods[overloadedMethodKey]
methodsObj[overloadedMethodKey] = (...args) =>
constant
? modernCall(method, name, args)
: modernSend(method, name, args)
? modernCall(overloadedMethod, name, args)
: modernSend(overloadedMethod, name, args)
if (overloadedMethodKeys.length > 0) {
overloadedMethodKeys.forEach(key => {
const method = contractObj.methods[key]
obj[key] = (...args) =>
constant
? modernCall(method, name, args)
: modernSend(method, name, args)
})
}
return obj
return methodsObj
}, {})

@@ -467,31 +469,3 @@ }

await checkUserEnvironment()
const {
mobileDevice,
validBrowser,
currentProvider,
web3Wallet,
accessToAccounts,
walletLoggedIn,
walletEnabled,
accountAddress,
accountBalance,
minimumBalance,
userCurrentNetworkId,
correctNetwork
} = state
resolve({
mobileDevice,
validBrowser,
currentProvider,
web3Wallet,
accessToAccounts,
walletLoggedIn,
walletEnabled,
accountAddress,
accountBalance,
minimumBalance,
userCurrentNetworkId,
correctNetwork
})
resolve(filteredState())
})

@@ -498,0 +472,0 @@ }

@@ -20,2 +20,76 @@ import { state } from '~/js/helpers/state'

// Update UI styles based on the current style.notificationsPosition value
export function updateNotificationsPosition() {
const { notificationsPosition } = state.config.style
if (!notificationsPosition) return
positionElement(state.iframe)
// Position notificationsContainer and reorder it's elements
const notificationsContainer = state.iframeDocument.getElementById(
'blocknative-notifications'
)
if (notificationsContainer) {
const brand = notificationsContainer.querySelector(
'#bn-transaction-branding'
)
const scroll = notificationsContainer.querySelector(
'.bn-notifications-scroll'
)
if (notificationsPosition.includes('top')) {
notificationsContainer.insertBefore(brand, scroll)
} else {
notificationsContainer.insertBefore(scroll, brand)
}
positionElement(notificationsContainer)
}
// Update existing status-icon positions
const statusIcons = [
...state.iframeDocument.getElementsByClassName('bn-status-icon')
]
statusIcons.forEach(icon => {
notificationsPosition.includes('Left')
? icon.classList.add('bn-float-right')
: icon.classList.remove('bn-float-right')
})
// Update existing progress tooltip positions
const progressTooltips = [
...state.iframeDocument.getElementsByClassName('progress-tooltip')
]
progressTooltips.forEach(tooltip => {
notificationsPosition.includes('Left')
? tooltip.classList.add('bn-left')
: tooltip.classList.remove('bn-left')
})
// Update brand position
const brand = state.iframeDocument.getElementById('bn-transaction-branding')
if (brand) {
notificationsPosition.includes('Left')
? (brand.style.float = 'initial')
: (brand.style.float = 'right')
}
// Update existing notifications borders
const notifications = [
...state.iframeDocument.getElementsByClassName('bn-notification')
]
notifications.forEach(n => {
notificationsPosition.includes('Left')
? n.classList.add('bn-right-border')
: n.classList.remove('bn-right-border')
})
// Update notifications-scroll position
const scrolls = [
...state.iframeDocument.getElementsByClassName('bn-notifications-scroll')
]
scrolls.forEach(s => {
notificationsPosition === 'topRight'
? (s.style.float = 'right')
: delete s.style.float
})
}
export function createElementString(type, className, innerHTML) {

@@ -409,3 +483,3 @@ return `

setTimeout(() => {
if (parent.contains(element)) {
if (parent && parent.contains(element)) {
parent.removeChild(element)

@@ -449,6 +523,8 @@ if (parent !== state.iframeDocument.body) {

const scrollContainer = getByQuery('.bn-notifications-scroll')
setTimeout(
() => setHeight(scrollContainer, 'initial', 'auto'),
timeouts.changeUI
)
if (scrollContainer) {
setTimeout(
() => setHeight(scrollContainer, 'initial', 'auto'),
timeouts.changeUI
)
}
}

@@ -489,2 +565,4 @@

const scrollContainer = getByQuery('.bn-notifications-scroll')
// if no notifications to manipulate return
if (!scrollContainer) return
const maxHeight = window.innerHeight

@@ -498,2 +576,3 @@ const brandingHeight = getById('bn-transaction-branding').clientHeight + 26

setHeight(scrollContainer, 'scroll', maxHeight - brandingHeight)
scrollContainer.scrollTop = maxHeight * 4
} else {

@@ -500,0 +579,0 @@ setHeight(scrollContainer, 'initial', 'auto')

@@ -87,2 +87,7 @@ import { state } from '~/js/helpers/state'

txCancel: notificationsUI
},
userInitiatedNotify: {
success: notificationsUI,
pending: notificationsUI,
error: notificationsUI
}

@@ -164,3 +169,5 @@ }

inlineCustomMsgs,
eventCode
eventCode,
categoryCode,
customTimeout
}) {

@@ -181,3 +188,4 @@ // treat txConfirmedClient as txConfirm

eventCode === 'txStall' ||
eventCode === 'txSpeedUp'
eventCode === 'txSpeedUp' ||
eventCode === 'pending'

@@ -281,7 +289,10 @@ const showTime =

if (type === 'complete') {
const notificationShouldTimeout =
(type === 'complete' && categoryCode !== 'userInitiatedNotify') ||
customTimeout
if (notificationShouldTimeout) {
setTimeout(() => {
removeNotification(notification)
setTimeout(setNotificationsHeight, timeouts.changeUI)
}, timeouts.autoRemoveNotification)
}, customTimeout || timeouts.autoRemoveNotification)
}

@@ -288,0 +299,0 @@ }

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

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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