Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@iota/bundle

Package Overview
Dependencies
Maintainers
5
Versions
41
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@iota/bundle - npm Package Compare versions

Comparing version 1.0.0-beta.5 to 1.0.0-beta.722117ce

.nyc_output/b8387aacf01ccb5653aed6d848f86d30.json

155

out/bundle/src/index.js
"use strict";
/** @module bundle */
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
exports.__esModule = true;
var bundle_1 = require("./bundle");
exports.createBundle = bundle_1.createBundle;
exports.addEntry = bundle_1.addEntry;
exports.addTrytes = bundle_1.addTrytes;
exports.finalizeBundle = bundle_1.finalizeBundle;
var converter_1 = require("@iota/converter");
var kerl_1 = require("@iota/kerl");
var pad_1 = require("@iota/pad");
var signing_1 = require("@iota/signing");
require("../../typed-array");
var t = new Int8Array(1).slice();
var NULL_HASH_TRYTES = '9'.repeat(81);
var NULL_TAG_TRYTES = '9'.repeat(27);
var NULL_NONCE_TRYTES = '9'.repeat(27);
var NULL_SIGNATURE_MESSAGE_FRAGMENT_TRYTES = '9'.repeat(2187);
var getEntryWithDefaults = function (entry) { return ({
length: entry.length || 1,
address: entry.address || NULL_HASH_TRYTES,
value: entry.value || 0,
tag: entry.tag || NULL_TAG_TRYTES,
timestamp: entry.timestamp || Math.floor(Date.now() / 1000),
signatureMessageFragments: entry.signatureMessageFragments
? entry.signatureMessageFragments.map(pad_1.padTrytes(2187))
: Array(entry.length || 1).fill(NULL_SIGNATURE_MESSAGE_FRAGMENT_TRYTES)
}); };
/**
* Creates a bunlde with given transaction entries.
*
* @method createBundle
*
* @param {BundleEntry[]} entries - Entries of signle or multiple transactions with the same address
*
* @return {Transaction[]} List of transactions in the bundle
*/
exports.createBundle = function (entries) {
if (entries === void 0) { entries = []; }
return entries.reduce(function (bundle, entry) { return exports.addEntry(bundle, entry); }, []);
};
/**
* Creates a bunlde with given transaction entries
*
* @method addEntry
*
* @param {Transaction[]} transactions - List of transactions currently in the bundle
*
* @param {object} entry - Entry of single or multiple transactions with the same address
* @param {number} [entry.length=1] - Entry length, which indicates how many transactions in the bundle will occupy
* @param {string} [entry.address] - Address, defaults to all-9s
* @param {number} [entry.value = 0] - Value to transfer in _IOTAs_
* @param {string[]} [entry.signatureMessageFragments] - Array of signature message fragments trytes, defaults to all-9s
* @param {number} [entry.timestamp] - Transaction timestamp, defaults to `Math.floor(Date.now() / 1000)`
* @param {string} [entry.tag] - Optional Tag, defaults to null tag (all-9s)
*
* @return {Transaction[]} Bundle
*/
exports.addEntry = function (transactions, entry) {
var entryWithDefaults = getEntryWithDefaults(entry);
var length = entryWithDefaults.length, address = entryWithDefaults.address, value = entryWithDefaults.value, timestamp = entryWithDefaults.timestamp, signatureMessageFragments = entryWithDefaults.signatureMessageFragments;
var lastIndex = transactions.length - 1 + length;
var tag = pad_1.padTag(entryWithDefaults.tag);
var obsoleteTag = tag;
return transactions.map(function (transaction) { return (__assign({}, transaction, { lastIndex: lastIndex })); }).concat(Array(length)
.fill(null)
.map(function (_, i) { return ({
address: address,
value: i === 0 ? value : 0,
tag: tag,
obsoleteTag: obsoleteTag,
currentIndex: transactions.length + i,
lastIndex: lastIndex,
timestamp: timestamp,
signatureMessageFragment: signatureMessageFragments[i],
trunkTransaction: NULL_HASH_TRYTES,
branchTransaction: NULL_HASH_TRYTES,
attachmentTimestamp: 0,
attachmentTimestampLowerBound: 0,
attachmentTimestampUpperBound: 0,
bundle: NULL_HASH_TRYTES,
nonce: NULL_NONCE_TRYTES,
hash: NULL_HASH_TRYTES
}); }));
};
/**
* Adds a list of trytes in the bundle starting at offset
*
* @method addTrytes
*
* @param {Transaction[]} transactions - Transactions in the bundle
*
* @param {Trytes[]} fragments - Message signature fragments to add
*
* @param {number} [offset=0] - Optional offset to start appending signature message fragments
*
* @return {Transaction[]} Transactions of finalized bundle
*/
exports.addTrytes = function (transactions, fragments, offset) {
if (offset === void 0) { offset = 0; }
return transactions.map(function (transaction, i) {
return i >= offset && i < offset + fragments.length
? __assign({}, transaction, { signatureMessageFragment: pad_1.padTrytes(27 * 81)(fragments[i - offset] || '') }) : transaction;
});
};
/**
* Finalizes the bundle by calculating the bundle hash
*
* @method finalizeBundle
*
* @param {Transaction[]} transactions - Transactions in the bundle
*
* @return {Transaction[]} Transactions of finalized bundle
*/
exports.finalizeBundle = function (transactions) {
var valueTrits = transactions.map(function (tx) { return converter_1.trits(tx.value); }).map(pad_1.padTrits(81));
var timestampTrits = transactions.map(function (tx) { return converter_1.trits(tx.timestamp); }).map(pad_1.padTrits(27));
var currentIndexTrits = transactions.map(function (tx) { return converter_1.trits(tx.currentIndex); }).map(pad_1.padTrits(27));
var lastIndexTrits = pad_1.padTrits(27)(converter_1.trits(transactions[0].lastIndex));
var obsoleteTagTrits = transactions.map(function (tx) { return converter_1.trits(tx.obsoleteTag); }).map(pad_1.padTrits(81));
var bundleHash;
var validBundle = false;
while (!validBundle) {
var kerl = new kerl_1["default"]();
kerl.initialize();
for (var i = 0; i < transactions.length; i++) {
var essence = converter_1.trits(transactions[i].address +
converter_1.trytes(valueTrits[i]) +
converter_1.trytes(obsoleteTagTrits[i]) +
converter_1.trytes(timestampTrits[i]) +
converter_1.trytes(currentIndexTrits[i]) +
converter_1.trytes(lastIndexTrits));
kerl.absorb(essence, 0, essence.length);
}
var bundleHashTrits = new Int8Array(kerl_1["default"].HASH_LENGTH);
kerl.squeeze(bundleHashTrits, 0, kerl_1["default"].HASH_LENGTH);
bundleHash = converter_1.trytes(bundleHashTrits);
if (signing_1.normalizedBundleHash(bundleHash).indexOf(13) !== -1) {
// Insecure bundle, increment obsoleteTag and recompute bundle hash
obsoleteTagTrits[0] = signing_1.add(obsoleteTagTrits[0], new Int8Array(1).fill(1));
}
else {
validBundle = true;
}
}
return transactions.map(function (transaction, i) { return (__assign({}, transaction, {
// overwrite obsoleteTag in first entry
obsoleteTag: i === 0 ? converter_1.trytes(obsoleteTagTrits[0]) : transaction.obsoleteTag, bundle: bundleHash })); });
};
//# sourceMappingURL=index.js.map

10

out/bundle/test/bundle.test.js

@@ -12,3 +12,3 @@ "use strict";

var ava_1 = require("ava");
var bundle_1 = require("../src/bundle");
var src_1 = require("../src");
var NULL_HASH = '9'.repeat(81);

@@ -75,3 +75,3 @@ var NULL_NONCE = '9'.repeat(27);

ava_1["default"]('createBundle() returns correct transactions.', function (t) {
t.deepEqual(bundle_1.createBundle([
t.deepEqual(src_1.createBundle([
{

@@ -94,3 +94,3 @@ length: 2,

ava_1["default"]('addEntry() adds new entry and returns correct transactions.', function (t) {
t.deepEqual(bundle_1.addEntry(bundle.slice(0, 2), {
t.deepEqual(src_1.addEntry(bundle.slice(0, 2), {
length: 1,

@@ -104,3 +104,3 @@ address: addresses[1],

ava_1["default"]('addTrytes() adds trytes and returns correct transactions.', function (t) {
t.deepEqual(bundle_1.addTrytes(bundle, ['TRYTES', 'TRYTES', 'TRYTES']), bundle.map(function (transaction) { return (__assign({}, transaction, { signatureMessageFragment: 'TRYTES' + '9'.repeat(81 * 27 - 6) })); }), 'addEntry should add trytes and return correct transactions.');
t.deepEqual(src_1.addTrytes(bundle, ['TRYTES', 'TRYTES', 'TRYTES']), bundle.map(function (transaction) { return (__assign({}, transaction, { signatureMessageFragment: 'TRYTES' + '9'.repeat(81 * 27 - 6) })); }), 'addEntry should add trytes and return correct transactions.');
});

@@ -111,4 +111,4 @@ ava_1["default"]('finalizeBundle() adds correct bundle hash.', function (t) {

var expected = bundle.map(function (transaction, i) { return (__assign({}, transaction, { obsoleteTag: i === 0 ? incrObsoleteTag : transaction.obsoleteTag, bundle: bundleHash })); });
t.deepEqual(bundle_1.finalizeBundle(bundle), expected, 'finalizeBundle() should add correct bundle hash.');
t.deepEqual(src_1.finalizeBundle(bundle), expected, 'finalizeBundle() should add correct bundle hash.');
});
//# sourceMappingURL=bundle.test.js.map
{
"name": "@iota/bundle",
"version": "1.0.0-beta.5",
"version": "1.0.0-beta.722117ce",
"description": "Utilities for generating and signing bundles",

@@ -67,7 +67,7 @@ "main": "./out/bundle/src/index.js",

"dependencies": {
"@iota/converter": "^1.0.0-beta.5",
"@iota/kerl": "^1.0.0-beta.5",
"@iota/pad": "^1.0.0-beta.5",
"@iota/signing": "^1.0.0-beta.5"
"@iota/converter": "^1.0.0-beta.722117ce",
"@iota/kerl": "^1.0.0-beta.722117ce",
"@iota/pad": "^1.0.0-beta.722117ce",
"@iota/signing": "^1.0.0-beta.722117ce"
}
}

@@ -1,1 +0,176 @@

export { BundleEntry, createBundle, addEntry, addTrytes, finalizeBundle } from './bundle'
/** @module bundle */
import { trits, trytes } from '@iota/converter'
import Kerl from '@iota/kerl'
import { padTag, padTrits, padTrytes } from '@iota/pad'
import { add, normalizedBundleHash } from '@iota/signing'
import '../../typed-array'
import { Bundle, Hash, Transaction, Trytes } from '../../types'
const t = new Int8Array(1).slice()
const NULL_HASH_TRYTES = '9'.repeat(81)
const NULL_TAG_TRYTES = '9'.repeat(27)
const NULL_NONCE_TRYTES = '9'.repeat(27)
const NULL_SIGNATURE_MESSAGE_FRAGMENT_TRYTES = '9'.repeat(2187)
export interface BundleEntry {
readonly length: number
readonly address: Hash
readonly value: number
readonly tag: string
readonly timestamp: number
readonly signatureMessageFragments: ReadonlyArray<Trytes>
}
const getEntryWithDefaults = (entry: Partial<BundleEntry>): BundleEntry => ({
length: entry.length || 1,
address: entry.address || NULL_HASH_TRYTES,
value: entry.value || 0,
tag: entry.tag || NULL_TAG_TRYTES,
timestamp: entry.timestamp || Math.floor(Date.now() / 1000),
signatureMessageFragments: entry.signatureMessageFragments
? entry.signatureMessageFragments.map(padTrytes(2187))
: Array(entry.length || 1).fill(NULL_SIGNATURE_MESSAGE_FRAGMENT_TRYTES),
})
/**
* Creates a bunlde with given transaction entries.
*
* @method createBundle
*
* @param {BundleEntry[]} entries - Entries of signle or multiple transactions with the same address
*
* @return {Transaction[]} List of transactions in the bundle
*/
export const createBundle = (entries: ReadonlyArray<Partial<BundleEntry>> = []): Bundle =>
entries.reduce((bundle: Bundle, entry) => addEntry(bundle, entry), [])
/**
* Creates a bunlde with given transaction entries
*
* @method addEntry
*
* @param {Transaction[]} transactions - List of transactions currently in the bundle
*
* @param {object} entry - Entry of single or multiple transactions with the same address
* @param {number} [entry.length=1] - Entry length, which indicates how many transactions in the bundle will occupy
* @param {string} [entry.address] - Address, defaults to all-9s
* @param {number} [entry.value = 0] - Value to transfer in _IOTAs_
* @param {string[]} [entry.signatureMessageFragments] - Array of signature message fragments trytes, defaults to all-9s
* @param {number} [entry.timestamp] - Transaction timestamp, defaults to `Math.floor(Date.now() / 1000)`
* @param {string} [entry.tag] - Optional Tag, defaults to null tag (all-9s)
*
* @return {Transaction[]} Bundle
*/
export const addEntry = (transactions: Bundle, entry: Partial<BundleEntry>): Bundle => {
const entryWithDefaults = getEntryWithDefaults(entry)
const { length, address, value, timestamp, signatureMessageFragments } = entryWithDefaults
const lastIndex = transactions.length - 1 + length
const tag = padTag(entryWithDefaults.tag)
const obsoleteTag = tag
return transactions.map(transaction => ({ ...transaction, lastIndex })).concat(
Array(length)
.fill(null)
.map((_, i) => ({
address,
value: i === 0 ? value : 0,
tag,
obsoleteTag,
currentIndex: transactions.length + i,
lastIndex,
timestamp,
signatureMessageFragment: signatureMessageFragments[i],
trunkTransaction: NULL_HASH_TRYTES,
branchTransaction: NULL_HASH_TRYTES,
attachmentTimestamp: 0,
attachmentTimestampLowerBound: 0,
attachmentTimestampUpperBound: 0,
bundle: NULL_HASH_TRYTES,
nonce: NULL_NONCE_TRYTES,
hash: NULL_HASH_TRYTES,
}))
)
}
/**
* Adds a list of trytes in the bundle starting at offset
*
* @method addTrytes
*
* @param {Transaction[]} transactions - Transactions in the bundle
*
* @param {Trytes[]} fragments - Message signature fragments to add
*
* @param {number} [offset=0] - Optional offset to start appending signature message fragments
*
* @return {Transaction[]} Transactions of finalized bundle
*/
export const addTrytes = (transactions: Bundle, fragments: ReadonlyArray<Trytes>, offset = 0): Bundle =>
transactions.map(
(transaction, i) =>
i >= offset && i < offset + fragments.length
? {
...transaction,
signatureMessageFragment: padTrytes(27 * 81)(fragments[i - offset] || ''),
}
: transaction
)
/**
* Finalizes the bundle by calculating the bundle hash
*
* @method finalizeBundle
*
* @param {Transaction[]} transactions - Transactions in the bundle
*
* @return {Transaction[]} Transactions of finalized bundle
*/
export const finalizeBundle = (transactions: Bundle): Bundle => {
const valueTrits = transactions.map(tx => trits(tx.value)).map(padTrits(81))
const timestampTrits = transactions.map(tx => trits(tx.timestamp)).map(padTrits(27))
const currentIndexTrits = transactions.map(tx => trits(tx.currentIndex)).map(padTrits(27))
const lastIndexTrits = padTrits(27)(trits(transactions[0].lastIndex))
const obsoleteTagTrits = transactions.map(tx => trits(tx.obsoleteTag)).map(padTrits(81))
let bundleHash: Hash
let validBundle: boolean = false
while (!validBundle) {
const kerl = new Kerl()
kerl.initialize()
for (let i = 0; i < transactions.length; i++) {
const essence = trits(
transactions[i].address +
trytes(valueTrits[i]) +
trytes(obsoleteTagTrits[i]) +
trytes(timestampTrits[i]) +
trytes(currentIndexTrits[i]) +
trytes(lastIndexTrits)
)
kerl.absorb(essence, 0, essence.length)
}
const bundleHashTrits = new Int8Array(Kerl.HASH_LENGTH)
kerl.squeeze(bundleHashTrits, 0, Kerl.HASH_LENGTH)
bundleHash = trytes(bundleHashTrits)
if (normalizedBundleHash(bundleHash).indexOf(13) !== -1) {
// Insecure bundle, increment obsoleteTag and recompute bundle hash
obsoleteTagTrits[0] = add(obsoleteTagTrits[0], new Int8Array(1).fill(1))
} else {
validBundle = true
}
}
return transactions.map((transaction, i) => ({
...transaction,
// overwrite obsoleteTag in first entry
obsoleteTag: i === 0 ? trytes(obsoleteTagTrits[0]) : transaction.obsoleteTag,
bundle: bundleHash,
}))
}
import test from 'ava'
import { addEntry, addTrytes, createBundle, finalizeBundle } from '../src/bundle'
import { addEntry, addTrytes, createBundle, finalizeBundle } from '../src'

@@ -4,0 +4,0 @@ const NULL_HASH = '9'.repeat(81)

@@ -1,1 +0,62 @@

export { BundleEntry, createBundle, addEntry, addTrytes, finalizeBundle } from './bundle';
import '../../typed-array';
import { Hash, Transaction, Trytes } from '../../types';
export interface BundleEntry {
readonly length: number;
readonly address: Hash;
readonly value: number;
readonly tag: string;
readonly timestamp: number;
readonly signatureMessageFragments: ReadonlyArray<Trytes>;
}
/**
* Creates a bunlde with given transaction entries.
*
* @method createBundle
*
* @param {BundleEntry[]} entries - Entries of signle or multiple transactions with the same address
*
* @return {Transaction[]} List of transactions in the bundle
*/
export declare const createBundle: (entries?: ReadonlyArray<Partial<BundleEntry>>) => ReadonlyArray<Transaction>;
/**
* Creates a bunlde with given transaction entries
*
* @method addEntry
*
* @param {Transaction[]} transactions - List of transactions currently in the bundle
*
* @param {object} entry - Entry of single or multiple transactions with the same address
* @param {number} [entry.length=1] - Entry length, which indicates how many transactions in the bundle will occupy
* @param {string} [entry.address] - Address, defaults to all-9s
* @param {number} [entry.value = 0] - Value to transfer in _IOTAs_
* @param {string[]} [entry.signatureMessageFragments] - Array of signature message fragments trytes, defaults to all-9s
* @param {number} [entry.timestamp] - Transaction timestamp, defaults to `Math.floor(Date.now() / 1000)`
* @param {string} [entry.tag] - Optional Tag, defaults to null tag (all-9s)
*
* @return {Transaction[]} Bundle
*/
export declare const addEntry: (transactions: ReadonlyArray<Transaction>, entry: Partial<BundleEntry>) => ReadonlyArray<Transaction>;
/**
* Adds a list of trytes in the bundle starting at offset
*
* @method addTrytes
*
* @param {Transaction[]} transactions - Transactions in the bundle
*
* @param {Trytes[]} fragments - Message signature fragments to add
*
* @param {number} [offset=0] - Optional offset to start appending signature message fragments
*
* @return {Transaction[]} Transactions of finalized bundle
*/
export declare const addTrytes: (transactions: ReadonlyArray<Transaction>, fragments: ReadonlyArray<string>, offset?: number) => ReadonlyArray<Transaction>;
/**
* Finalizes the bundle by calculating the bundle hash
*
* @method finalizeBundle
*
* @param {Transaction[]} transactions - Transactions in the bundle
*
* @return {Transaction[]} Transactions of finalized bundle
*/
export declare const finalizeBundle: (transactions: ReadonlyArray<Transaction>) => ReadonlyArray<Transaction>;

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