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

gridplus-sdk

Package Overview
Dependencies
Maintainers
1
Versions
182
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

gridplus-sdk - npm Package Compare versions

Comparing version 0.7.8 to 0.7.9

7

package.json
{
"name": "gridplus-sdk",
"version": "0.7.8",
"version": "0.7.9",
"description": "SDK to interact with GridPlus Lattice1 device",

@@ -15,2 +15,3 @@ "scripts": {

"test-eth": "mocha --timeout 180000 -R spec test/testEth.js --recursive --exit",
"test-eth-msg": "mocha --timeout 180000 -R spec test/testEthMsg.js --recursive --exit",
"test-btc": "mocha --timeout 180000 -R spec test/testBtc.js --recursive --exit",

@@ -31,4 +32,7 @@ "test-wallet-jobs": "mocha --timeout 300000 -R spec test/testWalletJobs.js --recursive --exit"

"buffer": "^5.6.0",
"cbor": "^7.0.3",
"crc-32": "^1.2.0",
"elliptic": "6.5.4",
"ethers": "^5.0.31",
"ethers-eip712": "^0.2.0",
"js-sha3": "^0.8.0",

@@ -53,3 +57,2 @@ "rlp-browser": "^1.0.1",

"ethereumjs-tx": "^2.1.2",
"ethers": "^5.0.31",
"it-each": "^0.4.0",

@@ -56,0 +59,0 @@ "lodash": "^4.17.20",

@@ -163,7 +163,8 @@ const bitwise = require('bitwise');

const { startPath, n, skipCache=true } = opts;
if (startPath === undefined || n === undefined || startPath.length !== 5) {
if (startPath === undefined || n === undefined)
return cb('Please provide `startPath` and `n` options');
} else if (n > MAX_ADDR) {
if (startPath.length < 2 || startPath.length > 5)
return cb('Path must include between 2 and 5 indices');
if (n > MAX_ADDR)
return cb(`You may only request ${MAX_ADDR} addresses at once.`);
}

@@ -174,3 +175,10 @@ if ((skipCache === false && false === isValidAssetPath(startPath)) ||

const payload = Buffer.alloc(1 + 32 + startPath.length * 4);
const fwConstants = getFwVersionConst(this.fwVersion);
let sz = 32 + 20 + 1; // walletUID + 5 u32 indices + count/flag
if (fwConstants.varAddrPathSzAllowed) {
sz += 1; // pathDepth
} else if (startPath.length !== 5) {
return cb('Your Lattice firmware only supports derivation paths with 5 indices. Please upgrade.')
}
const payload = Buffer.alloc(sz);
let off = 0;

@@ -183,4 +191,9 @@

// Build the start path (5x u32 indices)
for (let i = 0; i < startPath.length; i++) {
payload.writeUInt32BE(startPath[i], off);
if (fwConstants.varAddrPathSzAllowed) {
payload.writeUInt8(startPath.length, off);
off += 1;
}
for (let i = 0; i < 5; i++) {
if (i <= startPath.length)
payload.writeUInt32BE(startPath[i], off);
off += 4;

@@ -192,3 +205,2 @@ }

let val;
const fwConstants = getFwVersionConst(this.fwVersion);
if (true === fwConstants.addrFlagsAllowed) {

@@ -501,2 +513,3 @@ const flag = skipCache === true ? bitwise.nibble.read(SKIP_CACHE_FLAG) : bitwise.nibble.read(0);

.catch((err) => {
console.log('request err', err)
const isTimeout = err.code === 'ECONNABORTED' && err.errno === 'ETIME';

@@ -503,0 +516,0 @@ if (isTimeout)

@@ -117,3 +117,59 @@ // Consistent with Lattice's IV

const ethMsgProtocol = {
SIGN_PERSONAL: 0,
SIGN_PERSONAL: {
str: 'signPersonal',
enumIdx: 0, // Enum index of this protocol in Lattice firmware
},
TYPED_DATA: {
str: 'typedData',
enumIdx: 1,
rawDataMaxLen: 1629, // Max size of raw data payload in bytes
typeCodes: { // Enum indices of data types in Lattice firmware
'bytes1': 1,
'bytes2': 2,
'bytes3': 3,
'bytes4': 4,
'bytes5': 5,
'bytes6': 6,
'bytes7': 7,
'bytes8': 8,
'bytes9': 9,
'bytes10': 10,
'bytes11': 11,
'bytes12': 12,
'bytes13': 13,
'bytes14': 14,
'bytes15': 15,
'bytes16': 16,
'bytes17': 17,
'bytes18': 18,
'bytes19': 19,
'bytes20': 20,
'bytes21': 21,
'bytes22': 22,
'bytes23': 23,
'bytes24': 24,
'bytes25': 25,
'bytes26': 27,
'bytes27': 28,
'bytes28': 29,
'bytes29': 30,
'bytes30': 31,
'bytes31': 32,
'bytes32': 33,
'uint8': 34,
'uint16': 35,
'uint32': 36,
'uint64': 37,
'uint256': 38,
// 'int8': 39, // We do not support signed typed right now
// 'int16': 40,
// 'int32': 41,
// 'int64': 42,
// 'int256': 43,
'bool': 44,
'address': 45,
'bytes': 47,
'string': 48,
}
},
}

@@ -204,3 +260,2 @@

const c = {
reqMaxDataSz: 1152,
extraDataFrameSz: 0,

@@ -216,11 +271,19 @@ extraDataMaxFrames: 0,

}
if (v.length === 0 || !gte(v, [0, 10, 0])) {
// Legacy versions (<0.10.0)
c.ethMaxDataSz = c.reqMaxDataSz - 128;
c.ethMaxMsgSz = c.ethMaxDataSz;
c.ethMaxGasPrice = 500000000000; // 500 gwei
c.addrFlagsAllowed = false;
return c;
}
if (gte(v, [0, 10, 4])) {
// Very old legacy versions do not give a version number
const legacy = (v.length === 0);
// V0.10.5 added the ability to use flexible address path sizes, which
// changes the `getAddress` API. It also added support for EIP712
if (!legacy && gte(v, [0, 10, 5])) {
c.varAddrPathSzAllowed = true;
c.eip712Supported = true;
}
// V0.10.4 introduced the ability to send signing requests over multiple
// data frames (i.e. in multiple requests)
if (!legacy && gte(v, [0, 10, 4])) {
c.extraDataFrameSz = 1500; // 1500 bytes per frame of extraData allowed
c.extraDataMaxFrames = 1; // 1 frame of extraData allowed
}
// Various size constants have changed on the firmware side over time and
// are captured here
if (!legacy && gte(v, [0, 10, 4])) {
// >=0.10.3

@@ -232,5 +295,3 @@ c.reqMaxDataSz = 1678;

c.addrFlagsAllowed = true;
c.extraDataFrameSz = 1500; // 1500 bytes per frame of extraData allowed
c.extraDataMaxFrames = 1; // 1 frame of extraData allowed
} else {
} else if (!legacy && gte(v, [0, 10, 0])) {
// >=0.10.0

@@ -242,2 +303,9 @@ c.reqMaxDataSz = 1678;

c.addrFlagsAllowed = true;
} else {
// Legacy or <0.10.0
c.reqMaxDataSz = 1152;
c.ethMaxDataSz = c.reqMaxDataSz - 128;
c.ethMaxMsgSz = c.ethMaxDataSz;
c.ethMaxGasPrice = 500000000000; // 500 gwei
c.addrFlagsAllowed = false;
}

@@ -244,0 +312,0 @@ return c;

// Utils for Ethereum transactions. This is effecitvely a shim of ethereumjs-util, which
// does not have browser (or, by proxy, React-Native) support.
const BN = require('bignumber.js');
const Buffer = require('buffer/').Buffer
const Buffer = require('buffer/').Buffer;
const cbor = require('cbor');
const constants = require('./constants');
const ethers = require('ethers');
const eip712 = require('ethers-eip712');
const keccak256 = require('js-sha3').keccak256;

@@ -13,2 +16,4 @@ const rlp = require('rlp-browser');

throw new Error('You must provide `payload`, `signerPath`, and `protocol` arguments in the messsage request');
if (input.signerPath.length > 5 || input.signerPath.length < 2)
throw new Error('Please provide a signer path with 2-5 indices');
const req = {

@@ -20,67 +25,15 @@ schema: constants.signingSchema.ETH_MSG,

}
const { ethMaxMsgSz, extraDataFrameSz, extraDataMaxFrames } = input.fwConstants;
const MAX_BASE_MSG_SZ = ethMaxMsgSz;
const EXTRA_DATA_ALLOWED = extraDataFrameSz > 0 && extraDataMaxFrames > 0;
if (input.protocol === 'signPersonal') {
const L = ((input.signerPath.length + 1) * 4) + MAX_BASE_MSG_SZ + 4;
let off = 0;
req.payload = Buffer.alloc(L);
req.payload.writeUInt8(constants.ethMsgProtocol.SIGN_PERSONAL, 0); off += 1;
req.payload.writeUInt32LE(input.signerPath.length, off); off += 4;
for (let i = 0; i < input.signerPath.length; i++) {
req.payload.writeUInt32LE(input.signerPath[i], off); off += 4;
try {
switch (input.protocol) {
case 'signPersonal':
return buildPersonalSignRequest(req, input)
case 'eip712':
if (!input.fwConstants.eip712Supported)
throw new Error('EIP712 is not supported by your Lattice firmware version. Please upgrade.')
return buildEIP712Request(req, input)
default:
throw new Error('Unsupported protocol');
}
// Write the payload buffer. The payload can come in either as a buffer or as a string
let payload = input.payload;
// Determine if this is a hex string
let displayHex = false;
if (typeof input.payload === 'string') {
if (input.payload.slice(0, 2) === '0x') {
payload = ensureHexBuffer(input.payload)
displayHex = true === isHexStr(input.payload.slice(2));
} else {
if (false === latticeCanDisplayStr(input.payload))
throw new Error('Currently, the Lattice can only display ASCII strings.');
payload = Buffer.from(input.payload)
}
} else if (typeof input.displayHex === 'boolean') {
// If this is a buffer and the user has specified whether or not this
// is a hex buffer with the optional argument, write that
displayHex = input.displayHex
} else {
// Otherwise, determine if this buffer is an ASCII string. If it is, set `displayHex` accordingly.
// NOTE: THIS MEANS THAT NON-ASCII STRINGS WILL DISPLAY AS HEX SINCE WE CANNOT KNOW IF THE REQUESTER
// EXPECTED NON-ASCII CHARACTERS TO DISPLAY IN A STRING
// TODO: Develop a more elegant solution for this
if (!input.payload.toString)
throw new Error('Unsupported input data type');
displayHex = false === isASCIIStr(input.payload.toString())
}
// Flow data into extraData requests, which will follow-up transaction requests, if supported/applicable
const extraDataPayloads = [];
if (payload.length > MAX_BASE_MSG_SZ) {
// Determine sizes and run through sanity checks
const maxSzAllowed = MAX_BASE_MSG_SZ + (extraDataMaxFrames * extraDataFrameSz);
if (!EXTRA_DATA_ALLOWED)
throw new Error(`Your message is ${payload.length} bytes, but can only be a maximum of ${MAX_BASE_MSG_SZ}`);
else if (EXTRA_DATA_ALLOWED && payload.length > maxSzAllowed)
throw new Error(`Your message is ${payload.length} bytes, but can only be a maximum of ${maxSzAllowed}`);
// Split overflow data into extraData frames
const frames = splitFrames(payload.slice(MAX_BASE_MSG_SZ), extraDataFrameSz);
frames.forEach((frame) => {
const szLE = Buffer.alloc(4);
szLE.writeUInt32LE(frame.length);
extraDataPayloads.push(Buffer.concat([szLE, frame]));
})
}
// Write the payload and metadata into our buffer
req.extraDataPayloads = extraDataPayloads
req.msg = payload;
req.payload.writeUInt8(displayHex, off); off += 1;
req.payload.writeUInt16LE(payload.length, off); off += 2;
payload.copy(req.payload, off);
return req;
} else {
throw new Error('Unsupported protocol');
} catch (err) {
return { err: err.toString() }
}

@@ -99,3 +52,7 @@ }

// may be configurable in future versions
return addRecoveryParam(Buffer.concat([prefix, msg]), sig, signer, 1, false)
const hash = Buffer.from(keccak256(Buffer.concat([prefix, msg])), 'hex')
return addRecoveryParam(hash, sig, signer, 1, false)
} else if (input.protocol === 'eip712') {
const digest = eip712.TypedDataUtils.encodeDigest(req.input.payload)
return addRecoveryParam(digest, sig, signer)
} else {

@@ -110,5 +67,7 @@ throw new Error('Unsupported protocol');

const { signerPath, eip155=null, fwConstants } = data;
const { ethMaxDataSz, extraDataFrameSz, extraDataMaxFrames } = fwConstants;
const { extraDataFrameSz, extraDataMaxFrames } = fwConstants;
const EXTRA_DATA_ALLOWED = extraDataFrameSz > 0 && extraDataMaxFrames > 0;
const MAX_BASE_DATA_SZ = ethMaxDataSz;
const MAX_BASE_DATA_SZ = fwConstants.ethMaxDataSz;
const VAR_PATH_SZ = fwConstants.varAddrPathSzAllowed;
// Sanity checks:

@@ -123,4 +82,4 @@ // There are a handful of named chains we allow the user to reference (`chainIds`)

// Sanity check on signePath
if (!signerPath || signerPath.length !== 5)
throw new Error('Please provider full signer path (`signerPath`)')
if (!signerPath)
throw new Error('`signerPath` not provided');

@@ -193,10 +152,7 @@ // Determine if we should use EIP155 given the chainID.

// 2. BIP44 Path
// 2. Signer Path
//------------------
// First write the number of indices in this path (will probably always be 5, but
// we want to keep this extensible)
txReqPayload.writeUInt32LE(signerPath.length, off); off += 4;
for (let i = 0; i < signerPath.length; i++) {
txReqPayload.writeUInt32LE(signerPath[i], off); off += 4;
}
const signerPathBuf = buildSignerPathBuf(signerPath, VAR_PATH_SZ);
signerPathBuf.copy(txReqPayload, off);
off += signerPathBuf.length;

@@ -258,3 +214,3 @@ // 3. ETH TX request data

rawTx,
payload: txReqPayload,
payload: txReqPayload.slice(0, off),
extraDataPayloads,

@@ -286,3 +242,4 @@ schema: constants.signingSchema.ETH_TRANSFER, // We will use eth transfer for all ETH txs for v1

const rlpEncoded = rlp.encode(tx.rawTx);
const newSig = addRecoveryParam(rlpEncoded, sig, address, tx.chainId, useEIP155);
const hash = Buffer.from(keccak256(rlpEncoded), 'hex')
const newSig = addRecoveryParam(hash, sig, address, tx.chainId, useEIP155);
// Use the signature to generate a new raw transaction payload

@@ -299,6 +256,6 @@ const newRawTx = tx.rawTx.slice(0, 6);

// Attach a recovery parameter to a signature by brute-forcing ECRecover
function addRecoveryParam(payload, sig, address, chainId, useEIP155) {
function addRecoveryParam(hashBuf, sig, address, chainId, useEIP155) {
try {
// Rebuild the keccak256 hash here so we can `ecrecover`
const hash = new Uint8Array(Buffer.from(keccak256(payload), 'hex'));
const hash = new Uint8Array(hashBuf);
let v = 0;

@@ -330,3 +287,2 @@ // Fix signature componenet lengths to 32 bytes each

}
exports.addRecoveryParam = addRecoveryParam;

@@ -457,11 +413,165 @@ // Convert an RLP-serialized transaction (plus signature) into a transaction hash

function ensureHexBuffer(x) {
if (x === null || x === 0) return Buffer.alloc(0);
else if (Buffer.isBuffer(x)) return x;
if (typeof x === 'number') x = `${new BN(x).toString(16)}`;
else if (typeof x === 'string' && x.slice(0, 2) === '0x') x = x.slice(2);
if (x.length % 2 > 0) x = `0${x}`;
return Buffer.from(x, 'hex');
try {
// For null values, return a 0-sized buffer
if (x === null || x === 0) return Buffer.alloc(0);
// Otherwise try to get this converted to a hex string
if (typeof x === 'number') {
x = `${new BN(x).toString(16)}`;
} else if (typeof x === 'string' && x.slice(0, 2) === '0x') {
x = x.slice(2);
} else {
x = x.toString('hex')
}
if (x.length % 2 > 0) x = `0${x}`;
if (x === '00')
return Buffer.alloc(0);
return Buffer.from(x, 'hex');
} catch (err) {
throw new Error(`Cannot convert ${x.toString()} to hex buffer (${err.toString()})`);
}
}
exports.ensureHexBuffer = ensureHexBuffer;
function buildPersonalSignRequest(req, input) {
const MAX_BASE_MSG_SZ = input.fwConstants.ethMaxMsgSz;
const VAR_PATH_SZ = input.fwConstants.varAddrPathSzAllowed;
const L = (24) + MAX_BASE_MSG_SZ + 4;
let off = 0;
req.payload = Buffer.alloc(L);
req.payload.writeUInt8(constants.ethMsgProtocol.SIGN_PERSONAL, 0); off += 1;
// Write the signer path into the buffer
const signerPathBuf = buildSignerPathBuf(input.signerPath, VAR_PATH_SZ);
signerPathBuf.copy(req.payload, off);
off += signerPathBuf.length;
// Write the payload buffer. The payload can come in either as a buffer or as a string
let payload = input.payload;
// Determine if this is a hex string
let displayHex = false;
if (typeof input.payload === 'string') {
if (input.payload.slice(0, 2) === '0x') {
payload = ensureHexBuffer(input.payload)
displayHex = true === isHexStr(input.payload.slice(2));
} else {
if (false === latticeCanDisplayStr(input.payload))
throw new Error('Currently, the Lattice can only display ASCII strings.');
payload = Buffer.from(input.payload)
}
} else if (typeof input.displayHex === 'boolean') {
// If this is a buffer and the user has specified whether or not this
// is a hex buffer with the optional argument, write that
displayHex = input.displayHex
} else {
// Otherwise, determine if this buffer is an ASCII string. If it is, set `displayHex` accordingly.
// NOTE: THIS MEANS THAT NON-ASCII STRINGS WILL DISPLAY AS HEX SINCE WE CANNOT KNOW IF THE REQUESTER
// EXPECTED NON-ASCII CHARACTERS TO DISPLAY IN A STRING
// TODO: Develop a more elegant solution for this
if (!input.payload.toString)
throw new Error('Unsupported input data type');
displayHex = false === isASCIIStr(input.payload.toString())
}
// Flow data into extraData requests, which will follow-up transaction requests, if supported/applicable
const extraDataPayloads = getExtraData(payload, input);
// Write the payload and metadata into our buffer
req.extraDataPayloads = extraDataPayloads
req.msg = payload;
req.payload.writeUInt8(displayHex, off); off += 1;
req.payload.writeUInt16LE(payload.length, off); off += 2;
payload.copy(req.payload, off);
return req;
}
function buildEIP712Request(req, input) {
try {
const MAX_BASE_MSG_SZ = input.fwConstants.ethMaxMsgSz;
const VAR_PATH_SZ = input.fwConstants.varAddrPathSzAllowed;
const TYPED_DATA = constants.ethMsgProtocol.TYPED_DATA;
const L = (24) + MAX_BASE_MSG_SZ + 4;
let off = 0;
req.payload = Buffer.alloc(L);
req.payload.writeUInt8(TYPED_DATA.enumIdx, 0); off += 1;
// Write the signer path
const signerPathBuf = buildSignerPathBuf(input.signerPath, VAR_PATH_SZ);
signerPathBuf.copy(req.payload, off);
off += signerPathBuf.length;
// Parse/clean the EIP712 payload, serialize with CBOR, and write to the payload
const data = JSON.parse(JSON.stringify(input.payload));
if (!data.primaryType || !data.types[data.primaryType])
throw new Error('primaryType must be specified and the type must be included.')
if (!data.message || !data.domain)
throw new Error('message and domain must be specified.')
if (0 > Object.keys(data.types).indexOf('EIP712Domain'))
throw new Error('EIP712Domain type must be defined.')
// Parse the payload to ensure we have valid EIP712 data types and that
// they are encoded such that Lattice firmware can parse them.
// We need two different encodings:
// 1. Use `ethers` BigNumber when building the request to be validated by ethers-eip712.
// Make sure we use a copy of the data to avoid mutation problems
input.payload.message = parseEIP712Msg( JSON.parse(JSON.stringify(data.message)),
JSON.parse(JSON.stringify(data.primaryType)),
JSON.parse(JSON.stringify(data.types)),
true);
input.payload.domain = parseEIP712Msg( JSON.parse(JSON.stringify(data.domain)),
'EIP712Domain',
JSON.parse(JSON.stringify(data.types)),
true);
// 2. Use `bignumber.js` for the request going to the Lattice, since it's the required
// BigNumber lib for `cbor`, which we use to encode the request data to the Lattice.
data.domain = parseEIP712Msg(data.domain, 'EIP712Domain', data.types, false);
data.message = parseEIP712Msg(data.message, data.primaryType, data.types, false);
// Now build the message to be sent to the Lattice
const payload = Buffer.from(cbor.encode(data));
const extraDataPayloads = getExtraData(payload, input);
req.extraDataPayloads = extraDataPayloads;
req.payload.writeUInt16LE(payload.length, off); off += 2;
payload.copy(req.payload, off); off += payload.length;
// Slice out the part of the buffer that we didn't use.
req.payload = req.payload.slice(0, off);
return req;
} catch (err) {
return { err: `Failed to build EIP712 request: ${err.message}` };
}
}
function buildSignerPathBuf(signerPath, varAddrPathSzAllowed) {
const buf = Buffer.alloc(24);
let off = 0;
if (varAddrPathSzAllowed && signerPath.length > 5)
throw new Error('Signer path must be <=5 indices.');
if (!varAddrPathSzAllowed && signerPath.length !== 5)
throw new Error('Your Lattice firmware only supports 5-index derivation paths. Please upgrade.');
buf.writeUInt32LE(signerPath.length, off); off += 4;
for (let i = 0; i < 5; i++) {
if (i < signerPath.length)
buf.writeUInt32LE(signerPath[i], off);
else
buf.writeUInt32LE(0, off);
off += 4;
}
return buf;
}
function getExtraData(payload, input) {
const { ethMaxMsgSz, extraDataFrameSz, extraDataMaxFrames } = input.fwConstants;
const MAX_BASE_MSG_SZ = ethMaxMsgSz;
const EXTRA_DATA_ALLOWED = extraDataFrameSz > 0 && extraDataMaxFrames > 0;
const extraDataPayloads = [];
if (payload.length > MAX_BASE_MSG_SZ) {
// Determine sizes and run through sanity checks
const maxSzAllowed = MAX_BASE_MSG_SZ + (extraDataMaxFrames * extraDataFrameSz);
if (!EXTRA_DATA_ALLOWED)
throw new Error(`Your message is ${payload.length} bytes, but can only be a maximum of ${MAX_BASE_MSG_SZ}`);
else if (EXTRA_DATA_ALLOWED && payload.length > maxSzAllowed)
throw new Error(`Your message is ${payload.length} bytes, but can only be a maximum of ${maxSzAllowed}`);
// Split overflow data into extraData frames
const frames = splitFrames(payload.slice(MAX_BASE_MSG_SZ), extraDataFrameSz);
frames.forEach((frame) => {
const szLE = Buffer.alloc(4);
szLE.writeUInt32LE(frame.length);
extraDataPayloads.push(Buffer.concat([szLE, frame]));
})
}
return extraDataPayloads;
}
function splitFrames(data, frameSz) {

@@ -476,2 +586,60 @@ const frames = []

return frames;
}
function parseEIP712Msg(msg, typeName, types, isEthers=false) {
try {
const type = types[typeName];
type.forEach((item) => {
const isCustomType = Object.keys(types).indexOf(item.type) > -1;
if (true === isCustomType) {
msg[item.name] = parseEIP712Msg(msg[item.name], item.type, types, isEthers)
} else {
msg[item.name] = parseEIP712Item(msg[item.name], item.type, isEthers)
}
})
} catch (err) {
throw new Error(err.message);
}
return msg;
}
function parseEIP712Item(data, type, isEthers=false) {
if (type === 'bytes') {
// Variable sized bytes need to be buffer type
data = ensureHexBuffer(data);
if (data.length === 0)
throw new Error('"bytes" type must contain at least one byte in value');
} else if (type.slice(0, 5) === 'bytes') {
// Fixed sizes bytes need to be buffer type. We also add some sanity checks.
const nBytes = parseInt(type.slice(5));
data = ensureHexBuffer(data);
if (data.length !== nBytes)
throw new Error(`Expected ${type} type, but got ${data.length} bytes`);
} else if (type === 'address') {
// Address must be a 20 byte buffer
data = ensureHexBuffer(data);
if (data.length !== 20)
throw new Error(`Address type must be 20 bytes, but got ${data.length} bytes`);
// Ethers wants addresses as hex strings
if (isEthers === true) {
data = `0x${data.toString('hex')}`
}
} else if (type === 'uint8' || type === 'uint16' || type === 'uint32' || type === 'uint64') {
data = parseInt(ensureHexBuffer(data).toString('hex'), 16)
} else if (type === 'uint256') {
// Uint256s should be encoded as bignums.
if (isEthers === true) {
// `ethers` uses their own BigNumber lib
data = ethers.BigNumber.from(`0x${ensureHexBuffer(data).toString('hex')}`)
} else {
// `bignumber.js` is needed for `cbor` encoding, which gets sent to the Lattice and plays
// nicely with its firmware cbor lib.
data = new BN(ensureHexBuffer(data).toString('hex'), 16)
}
} else if (type === 'bool') {
// Booleans need to be cast to a u8
data = data === true ? 1 : 0;
}
// Other types don't need to be modified
return data;
}
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