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

jupiter-fs

Package Overview
Dependencies
Maintainers
2
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

jupiter-fs - npm Package Compare versions

Comparing version 0.0.11 to 0.1.0

Changelog.md

2

dist/JupiterFs.d.ts

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

export default function JupiterFs({ server, address, passphrase, encryptSecret, feeNQT, }: any): any;
export default function JupiterFs({ server, address, passphrase, encryptSecret, feeNQT, minimumFndrAccountBalance, minimumUserAccountBalance }: any): any;

@@ -30,5 +30,13 @@ "use strict";

const jupiter_node_sdk_1 = __importStar(require("jupiter-node-sdk"));
function JupiterFs({ server, address, passphrase, encryptSecret, feeNQT, }) {
const jupServer = server || 'https://jpr.gojupiter.tech';
const zlib_1 = __importDefault(require("zlib"));
function JupiterFs({ server, address, passphrase, encryptSecret, feeNQT, minimumFndrAccountBalance, minimumUserAccountBalance }) {
// const jupServer = server || 'https://fs.jup.io'
const jupServer = server || '';
feeNQT = feeNQT || 400;
// Quantity to found the binary client when doesnt have enought founds
minimumFndrAccountBalance = minimumFndrAccountBalance || 1000000;
minimumUserAccountBalance = minimumUserAccountBalance || 2000000;
// Chunk size to split the file to upload
// Max lengh in Jupiter is 43008 bytes per encrypted message
const CHUNK_SIZE_PATTERN = /.{1,40000}/g;
return {

@@ -43,2 +51,4 @@ key: `jupiter-fs`,

feeNQT,
minimumFndrAccountBalance,
minimumUserAccountBalance
}),

@@ -58,2 +68,4 @@ binaryClient: null,

feeNQT,
minimumFndrAccountBalance: this.binaryClient.minimumFndrAccountBalance,
minimumUserAccountBalance: this.binaryClient.minimumUserAccountBalance
};

@@ -79,14 +91,30 @@ }

await this.checkAndFundAccount(addy.address);
this.binaryClient = jupiter_node_sdk_1.default({ ...addy, server: jupServer, feeNQT });
this.binaryClient = jupiter_node_sdk_1.default({ ...addy,
server: jupServer,
feeNQT,
minimumFndrAccountBalance,
minimumUserAccountBalance });
return addy;
},
async checkAndFundAccount(targetAddress) {
// Get balance for binary client
const balanceJup = await this.client.getBalance(targetAddress);
if (!balanceJup ||
if (
// if binary client doesnt have money or is less than minimumFndrAccountBalance
// then send money to support file upload
!balanceJup ||
new bignumber_js_1.default(balanceJup).lt(new bignumber_js_1.default(this.client.nqtToJup(this.client.config.minimumFndrAccountBalance)).div(2))) {
// send money to the binary client to pay fees for transactions
await this.client.sendMoney(targetAddress);
}
},
/**
* Get the address for the binary account used to upload files
* @returns
*/
async getBinaryAddress() {
// Get all the transactions for the main jupiter account
const allTxns = await this.client.getAllTransactions();
// for each transaction, check if contains the jupiter-fs metaDataKey and
// decrypt the chuncked transactions
const binaryAccountInfo = (await Promise.all(allTxns.map(async (txn) => {

@@ -96,2 +124,3 @@ try {

let data = JSON.parse(await this.client.decrypt(decryptedMessage));
// tx with jupiter-fs-meta:true contains info related to the binary client
if (!data[this.metaDataKey])

@@ -133,8 +162,20 @@ return false;

},
/**
* Push a file into the Jupiter blockchain
* The file is splitted into chunks of CHUNK_SIZE_PATTERN
* and pushed by the binary client
* @param name
* @param data
* @param errorCallback
* @returns
*/
async writeFile(name, data, errorCallback) {
await this.getOrCreateBinaryAddress();
const chunks = data.toString('base64').match(/.{1,1000}/g);
// compress the binary data before to convert to base64
const encodedFileData = zlib_1.default.deflateSync(Buffer.from(data)).toString('base64');
const chunks = encodedFileData.match(CHUNK_SIZE_PATTERN);
assert_1.default(chunks, `we couldn't split the data into chunks`);
const dataTxns = await Promise.all(chunks.map(async (str) => {
const { transaction } = await exponentialBackoff(async () => {
// check if the binarclient have enought found for the transaction
await this.checkAndFundAccount(this.binaryClient.address);

@@ -170,19 +211,25 @@ return await this.binaryClient.storeRecord({

await this.getOrCreateBinaryAddress();
// search first in the unconfirmed transactions
let txns = await this.binaryClient.getAllUnconfirmedTransactions();
const files = await this.ls();
const targetFile = files.find((t) => (id && id === t.id) || t.fileName === name);
if (!targetFile) {
// if not found, search in the confirmed transactions
txns = await this.binaryClient.getAllConfirmedTransactions();
const files = await this.ls();
const targetFile = files.find((t) => (id && id === t.id) || t.fileName === name);
}
assert_1.default(targetFile, 'target file was not found');
// decrypt the transactions info with the list of txIds where is stored the file
const dataTxns = JSON.parse(await this.client.decrypt(targetFile.txns));
const readable = new stream_1.Readable();
/**
* Get the base64 chunks of the image
* @param readableStream
* @returns
*/
const getBase64Strings = async (readableStream) => {
const allBase64Strings = await Promise.all(dataTxns.map(async (txnId) => {
const { data } = await this.binaryClient.request('post', '/nxt', {
params: {
requestType: 'readMessage',
secretPhrase: encryptSecret || this.binaryClient.passphrase,
transaction: txnId,
},
});
if (data.errorCode > 0)
throw new Error(JSON.stringify(data));
const jsonWithData = await this.binaryClient.decrypt(data.decryptedMessage);
// Decrypt the message and parse the json chunk
const getBase64Chunk = async (decryptedMessage) => {
const jsonWithData = await this.binaryClient.decrypt(decryptedMessage);
const base64Chunk = JSON.parse(jsonWithData).data;

@@ -192,2 +239,22 @@ if (readableStream)

return base64Chunk;
};
// Get the transaction info for each txId of the file
const allBase64Strings = await Promise.all(dataTxns.map(async (txnId) => {
try {
const { data } = await this.binaryClient.request('post', '/nxt', {
params: {
requestType: 'readMessage',
secretPhrase: encryptSecret || this.binaryClient.passphrase,
transaction: txnId,
},
});
if (data.errorCode > 0) {
throw new Error(JSON.stringify(data));
}
// decrypt and decode the chunk
return await getBase64Chunk(data.decryptedMessage);
}
catch (err) {
throw new Error(`target file was not found ` + JSON.stringify(err));
}
}));

@@ -205,3 +272,3 @@ if (readableStream)

const base64Strings = await getBase64Strings();
return Buffer.from(base64Strings.join(''), 'base64');
return zlib_1.default.inflateSync(Buffer.from(base64Strings.join(''), 'base64'));
},

@@ -222,2 +289,13 @@ async getFileStream({ name, id }) {

exports.default = JupiterFs;
/**
* Function to create a exponential backoff
* if there is an error, it wait for some time and if the problems contine
* the time to wait is increased in a exponentional way
* @param promiseFunction
* @param failureFunction
* @param err
* @param totalAllowedBackoffTries
* @param backoffAttempt
* @returns
*/
async function exponentialBackoff(promiseFunction, failureFunction = () => { }, err = null, totalAllowedBackoffTries = 10, backoffAttempt = 1) {

@@ -224,0 +302,0 @@ const backoffSecondsToWait = 2 + Math.pow(backoffAttempt, 2);

@@ -9,2 +9,3 @@ "use strict";

const path_1 = __importDefault(require("path"));
const uuid_1 = require("uuid");
const JupiterFs_1 = __importDefault(require("./JupiterFs"));

@@ -17,9 +18,11 @@ /**

describe('JupiterFs', function () {
this.timeout(5000);
// const fs = JupiterFs({ server: 'http://localhost:7876' })
assert_1.default(process.env.JUPITER_ADDRESS, 'JUPITER_ADDRESS env variable is not set');
assert_1.default(process.env.JUPITER_PASSPHRASE, 'JUPITER_PASSPHRASE env variable is not set');
// const fs = JupiterFs({ server: 'http://localhost:6876' })
const jupFs = JupiterFs_1.default({
server: 'https://jpr4.gojupiter.tech',
address: '',
passphrase: '',
server: process.env.JUPITER_SERVER || 'http://104.131.166.136:6876/test',
address: process.env.JUPITER_ADDRESS,
passphrase: process.env.JUPITER_PASSPHRASE,
});
const testFilename = `${uuid_1.v1()}.js`;
describe('#newBinaryAddress()', function () {

@@ -34,10 +37,8 @@ it(`should get a new JUP address from a passphrase`, async () => {

const addy = await jupFs.getOrCreateBinaryAddress();
// console.log('ADDY', addy)
assert_1.default.strictEqual(typeof addy.address === 'string', true);
});
});
describe('#ls()', function () {
xdescribe('#ls()', function () {
it(`should fetch a list of files for a jupiter account`, async () => {
const files = await jupFs.ls();
// console.log('FILES', files)
assert_1.default.strictEqual(files instanceof Array, true);

@@ -47,7 +48,7 @@ });

describe('#writeFile()', function () {
this.timeout(10000);
it(`should write a file to a jupiter account without error`, async () => {
const fileData = await fs_1.default.promises.readFile(path_1.default.join(__dirname, 'JupiterFs.ts'), { encoding: null });
const res = await jupFs.writeFile('JupiterFs.ts', fileData, (err) => console.error(`Error writing file`, err));
assert_1.default.strictEqual(res.fileName, 'JupiterFs.ts');
const fileData = await fs_1.default.promises.readFile(path_1.default.join(__dirname, '../testFiles/medium.jpg'), { encoding: null });
console.log("filename " + testFilename);
const res = await jupFs.writeFile(testFilename, fileData, assert_1.default.fail);
assert_1.default.strictEqual(res.fileName, testFilename);
assert_1.default.strictEqual(res.txns.length > 0, true);

@@ -58,8 +59,10 @@ });

it(`should get the binary data for a file specified`, async () => {
const fileData = await jupFs.getFile({ name: `JupiterFs.ts` });
await fs_1.default.promises.writeFile(path_1.default.join(__dirname, 'JupiterFs.ts'), fileData);
console.log("filename " + testFilename);
const fileData = await jupFs.getFile({ name: testFilename });
const origFileData = await fs_1.default.promises.readFile(path_1.default.join(__dirname, '../testFiles/medium.jpg'), 'utf-8');
assert_1.default.strictEqual(fileData instanceof Buffer, true);
assert_1.default.strictEqual(fileData.length > 0, true);
assert_1.default.strictEqual(origFileData, fileData.toString('utf-8'));
});
});
});
{
"name": "jupiter-fs",
"version": "0.0.11",
"version": "0.1.0",
"description": "A small file system implementation for the Jupiter blockchain.",

@@ -8,3 +8,3 @@ "main": "./dist/JupiterFs.js",

"type": "git",
"url": "https://github.com/whatl3y/jupiter-fs"
"url": "https://github.com/jupiter-project/jupiter-fs"
},

@@ -27,3 +27,3 @@ "scripts": {

"dependencies": {
"jupiter-node-sdk": "^0.1.3",
"jupiter-node-sdk": "^0.2.1",
"uuid": "^8.3.2"

@@ -30,0 +30,0 @@ },

@@ -0,0 +0,0 @@ # jupiter-fs

@@ -13,4 +13,2 @@ import assert from 'assert'

describe('JupiterFs', function() {
this.timeout(10000)
assert(process.env.JUPITER_ADDRESS, 'JUPITER_ADDRESS env variable is not set')

@@ -22,5 +20,5 @@ assert(

// const fs = JupiterFs({ server: 'http://localhost:7876' })
// const fs = JupiterFs({ server: 'http://localhost:6876' })
const jupFs = JupiterFs({
server: process.env.JUPITER_SERVER || 'https://jpr4.gojupiter.tech',
server: process.env.JUPITER_SERVER || 'http://104.131.166.136:6876/test',
address: process.env.JUPITER_ADDRESS,

@@ -45,3 +43,3 @@ passphrase: process.env.JUPITER_PASSPHRASE,

describe('#ls()', function() {
xdescribe('#ls()', function() {
it(`should fetch a list of files for a jupiter account`, async () => {

@@ -56,5 +54,6 @@ const files = await jupFs.ls()

const fileData = await fs.promises.readFile(
path.join(__dirname, 'JupiterFs.ts'),
path.join(__dirname, '../testFiles/medium.jpg'),
{ encoding: null }
)
console.log("filename " + testFilename);
const res = await jupFs.writeFile(testFilename, fileData, assert.fail)

@@ -68,5 +67,6 @@ assert.strictEqual(res.fileName, testFilename)

it(`should get the binary data for a file specified`, async () => {
console.log("filename " + testFilename);
const fileData = await jupFs.getFile({ name: testFilename })
const origFileData = await fs.promises.readFile(
path.join(__dirname, 'JupiterFs.ts'),
path.join(__dirname, '../testFiles/medium.jpg'),
'utf-8'

@@ -73,0 +73,0 @@ )

@@ -6,2 +6,3 @@ import assert from 'assert'

import JupiterClient, { generatePassphrase } from 'jupiter-node-sdk'
import zlib from 'zlib'

@@ -14,6 +15,16 @@ export default function JupiterFs({

feeNQT,
minimumFndrAccountBalance,
minimumUserAccountBalance
}: any): any {
const jupServer = server || 'https://jpr.gojupiter.tech'
// const jupServer = server || 'https://fs.jup.io'
const jupServer = server || ''
feeNQT = feeNQT || 400
// Quantity to found the binary client when doesnt have enought founds
minimumFndrAccountBalance = minimumFndrAccountBalance || 1000000
minimumUserAccountBalance = minimumUserAccountBalance || 2000000
// Chunk size to split the file to upload
// Max lengh in Jupiter is 43008 bytes per encrypted message
const CHUNK_SIZE_PATTERN = /.{1,40000}/g;
return {

@@ -28,2 +39,4 @@ key: `jupiter-fs`,

feeNQT,
minimumFndrAccountBalance,
minimumUserAccountBalance
}),

@@ -44,2 +57,4 @@ binaryClient: null,

feeNQT,
minimumFndrAccountBalance: this.binaryClient.minimumFndrAccountBalance,
minimumUserAccountBalance: this.binaryClient.minimumUserAccountBalance
}

@@ -72,3 +87,7 @@ }

await this.checkAndFundAccount(addy.address)
this.binaryClient = JupiterClient({ ...addy, server: jupServer, feeNQT })
this.binaryClient = JupiterClient({ ...addy,
server: jupServer,
feeNQT,
minimumFndrAccountBalance,
minimumUserAccountBalance })
return addy

@@ -78,4 +97,7 @@ },

async checkAndFundAccount(targetAddress: string) {
// Get balance for binary client
const balanceJup = await this.client.getBalance(targetAddress)
if (
// if binary client doesnt have money or is less than minimumFndrAccountBalance
// then send money to support file upload
!balanceJup ||

@@ -88,2 +110,3 @@ new BigNumber(balanceJup).lt(

) {
// send money to the binary client to pay fees for transactions
await this.client.sendMoney(targetAddress)

@@ -93,4 +116,11 @@ }

/**
* Get the address for the binary account used to upload files
* @returns
*/
async getBinaryAddress() {
// Get all the transactions for the main jupiter account
const allTxns = await this.client.getAllTransactions()
// for each transaction, check if contains the jupiter-fs metaDataKey and
// decrypt the chuncked transactions
const binaryAccountInfo: any = (

@@ -104,4 +134,5 @@ await Promise.all(

let data = JSON.parse(await this.client.decrypt(decryptedMessage))
// tx with jupiter-fs-meta:true contains info related to the binary client
if (!data[this.metaDataKey]) return false
return { transaction: txn.transaction, ...data }

@@ -122,2 +153,3 @@ } catch (err) {

)
return Object.values(binaryAccountInfo).find((r: any) => !r.isDeleted)

@@ -156,2 +188,11 @@ },

/**
* Push a file into the Jupiter blockchain
* The file is splitted into chunks of CHUNK_SIZE_PATTERN
* and pushed by the binary client
* @param name
* @param data
* @param errorCallback
* @returns
*/
async writeFile(

@@ -162,4 +203,8 @@ name: string,

) {
await this.getOrCreateBinaryAddress()
const chunks = data.toString('base64').match(/.{1,1000}/g)
await this.getOrCreateBinaryAddress()
// compress the binary data before to convert to base64
const encodedFileData = zlib.deflateSync(Buffer.from(data)).toString('base64')
const chunks = encodedFileData.match(CHUNK_SIZE_PATTERN)
assert(chunks, `we couldn't split the data into chunks`)

@@ -170,2 +215,3 @@

const { transaction } = await exponentialBackoff(async () => {
// check if the binarclient have enought found for the transaction
await this.checkAndFundAccount(this.binaryClient.address)

@@ -209,3 +255,5 @@ return await this.binaryClient.storeRecord({

await this.getOrCreateBinaryAddress()
const unconfTxns = await this.binaryClient.getAllUnconfirmedTransactions()
// search first in the unconfirmed transactions
let txns = await this.binaryClient.getAllUnconfirmedTransactions()
const files = await this.ls()

@@ -215,9 +263,27 @@ const targetFile = files.find(

)
if (!targetFile){
// if not found, search in the confirmed transactions
txns = await this.binaryClient.getAllConfirmedTransactions()
const files = await this.ls()
const targetFile = files.find(
(t: any) => (id && id === t.id) || t.fileName === name
)
}
assert(targetFile, 'target file was not found')
// decrypt the transactions info with the list of txIds where is stored the file
const dataTxns = JSON.parse(await this.client.decrypt(targetFile.txns))
const readable = new Readable()
/**
* Get the base64 chunks of the image
* @param readableStream
* @returns
*/
const getBase64Strings = async (
readableStream?: Readable
): Promise<string[]> => {
// Decrypt the message and parse the json chunk
const getBase64Chunk = async (decryptedMessage: string) => {

@@ -231,2 +297,3 @@ const jsonWithData = await this.binaryClient.decrypt(decryptedMessage)

// Get the transaction info for each txId of the file
const allBase64Strings: string[] = await Promise.all(

@@ -242,14 +309,11 @@ dataTxns.map(async (txnId: string) => {

})
if (data.errorCode > 0) throw new Error(JSON.stringify(data))
if (data.errorCode > 0){
throw new Error(JSON.stringify(data))
}
// decrypt and decode the chunk
return await getBase64Chunk(data.decryptedMessage)
} catch (err) {
const txn = unconfTxns.find(
(txn: any) => txn.transaction === txnId
)
if (!txn) throw new Error(`target file was not found`)
const decryptedMessage = await this.binaryClient.decryptRecord(
txn.attachment.encryptedMessage
)
return await getBase64Chunk(decryptedMessage)
throw new Error(`target file was not found ` + JSON.stringify(err))
}

@@ -270,3 +334,3 @@ })

const base64Strings = await getBase64Strings()
return Buffer.from(base64Strings.join(''), 'base64')
return zlib.inflateSync(Buffer.from(base64Strings.join(''), 'base64'))
},

@@ -289,2 +353,13 @@

/**
* Function to create a exponential backoff
* if there is an error, it wait for some time and if the problems contine
* the time to wait is increased in a exponentional way
* @param promiseFunction
* @param failureFunction
* @param err
* @param totalAllowedBackoffTries
* @param backoffAttempt
* @returns
*/
async function exponentialBackoff(

@@ -291,0 +366,0 @@ promiseFunction: any,

@@ -0,0 +0,0 @@ {

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