
Security News
/Research
Wallet-Draining npm Package Impersonates Nodemailer to Hijack Crypto Transactions
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
gan-i3-356-bluetooth
Advanced tools
Library for connecting to and interacting with Bluetooth-enabled Rubik's cubes (GAN)
This library provides an interface for connecting to and interacting with Bluetooth-enabled Rubik's cubes, specifically the GAN 356 i3 3x3 Bluetooth Smart Cube. It allows you to track moves, monitor cube state, and receive gyroscope data. The package is fully minified for optimal performance and minimal size.
[!NOTE] Credit to CSTimer for the original code that this project is based on. It has been refactored and made more modular for easier use.
npm install gan-i3-356-bluetooth
import { BTCube } from 'gan-i3-356-bluetooth';
// Create a new BTCube instance
const btCube = new BTCube();
// Initialize the connection to the cube
btCube.init()
.then(() => console.log('Connected to cube'))
.catch(err => console.error('Failed to connect:', err));
// Set a callback for cube state changes
btCube.setCallback((state, moves, timestamps, deviceName) => {
console.log('Cube state:', state);
console.log('Moves:', moves);
console.log('Device:', deviceName);
});
// Disconnect from the cube when done
btCube.stop();
import { GanCube } from 'gan-i3-356-bluetooth';
// Create a new GanCube instance
const ganCube = new GanCube();
// The GanCube class is typically used through BTCube,
// but can be accessed directly for advanced usage
Simply run pnpm i
and pnpm dev
to start the example app (chrome does not like localhost having bluetooth permissions, so I dev with a HTTPS CloudFlare tunnel, using cloudflared tunnel --url http://localhost:3000
)
The library uses an object-oriented event system where each cube instance emits its own events. This replaces the previous window-based events with a more encapsulated approach.
import { BTCube } from 'gan-i3-356-bluetooth';
// Create a cube instance
const btCube = new BTCube();
// Listen for cube state changes
btCube.on('cubeStateChanged', (data) => {
const { facelet, move, corners, edges, timestamp } = data;
// facelet: String representation of the cube state (e.g., "UUUUUUUUURRRRRRRRRFFFFFFFFFDDDDDDDDDLLLLLLLLLBBBBBBBBB")
// move: The move that was just performed (e.g., "R'")
// corners: Array representing the corner pieces
// edges: Array representing the edge pieces
// timestamp: Time when the move was made
console.log('Cube state changed:', facelet);
console.log('Move performed:', move);
});
// Listen for gyroscope data
btCube.on('gyroData', (data) => {
const { x, y, z, timestamp } = data;
// x, y, z: Gyroscope readings for each axis
// timestamp: Time when the data was captured
console.log('Gyroscope data:', { x, y, z });
});
// Listen for move events
btCube.on('move', (data) => {
const { move, time } = data;
// move: The move that was performed (e.g., "R'")
// time: Time taken to perform the move
console.log('Move detected:', move, 'Time:', time);
});
// Listen for solved state
btCube.on('cubeSolved', () => {
console.log('Cube solved!');
// Trigger celebration or next steps
});
// Listen for unsolved state
btCube.on('unSolved', () => {
console.log('Cube is not solved');
});
// Remove event listeners when done
btCube.off('cubeStateChanged', yourListenerFunction);
// Or clear all listeners
btCube.clearAllListeners();
You can manually log the current state of the cube:
// Import the GanCube module if needed
import { btCube } from './code.js';
// Get the cube instance
const cube = btCube.getCube();
// Log the current state
const state = cube.logCubeState();
console.log(state);
To properly disconnect from the cube:
btCube.stop();
import React, { useEffect, useState, useRef } from 'react';
import { BTCube } from 'gan-i3-356-bluetooth';
function CubeApp() {
const btCubeRef = useRef(null);
const [btCube, setBtCube] = useState(null);
const [cubeState, setCubeState] = useState('');
const [lastMove, setLastMove] = useState('');
const [isSolved, setIsSolved] = useState(false);
// Initialize the cube instance
useEffect(() => {
if (!btCubeRef.current) {
btCubeRef.current = new BTCube();
setBtCube(btCubeRef.current);
}
return () => {
// Disconnect from cube when component unmounts
if (btCubeRef.current) {
btCubeRef.current.stop();
}
};
}, []);
// Set up event listeners
useEffect(() => {
if (!btCube) return;
// Listen for cube state changes
const handleStateChange = (data) => {
setCubeState(data.facelet);
if (data.move?.length <= 2) {
setLastMove(data.move);
}
};
// Listen for solved state
const handleSolved = () => {
setIsSolved(true);
};
// Listen for unsolved state
const handleUnsolved = () => {
setIsSolved(false);
};
// Register event listeners on the BTCube instance
btCube.on('cubeStateChanged', handleStateChange);
btCube.on('cubeSolved', handleSolved);
btCube.on('unSolved', handleUnsolved);
return () => {
// Remove event listeners when component unmounts
btCube.off('cubeStateChanged', handleStateChange);
btCube.off('cubeSolved', handleSolved);
btCube.off('unSolved', handleUnsolved);
};
}, [btCube]);
const connectCube = () => {
if (!btCube) return;
btCube.init()
.then(() => console.log('Connected to cube'))
.catch(err => console.error('Failed to connect:', err));
};
return (
<div>
<button onClick={connectCube}>Connect to Cube</button>
<div>Cube State: {cubeState}</div>
<div>Last Move: {lastMove}</div>
<div>Solved: {isSolved ? 'Yes' : 'No'}</div>
</div>
);
}
If you're maintaining this package, here's how to publish a new version:
pnpm run build:lib
npm publish
This project is licensed under the MIT License.
FAQs
Library for connecting to and interacting with Bluetooth-enabled Rubik's cubes (GAN)
The npm package gan-i3-356-bluetooth receives a total of 195 weekly downloads. As such, gan-i3-356-bluetooth popularity was classified as not popular.
We found that gan-i3-356-bluetooth demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
/Research
Malicious npm package impersonates Nodemailer and drains wallets by hijacking crypto transactions across multiple blockchains.
Security News
This episode explores the hard problem of reachability analysis, from static analysis limits to handling dynamic languages and massive dependency trees.
Security News
/Research
Malicious Nx npm versions stole secrets and wallet info using AI CLI tools; Socket’s AI scanner detected the supply chain attack and flagged the malware.