Skip to content

Commit

Permalink
Merge pull request #1 from Irys-xyz/feat/bundles-v1
Browse files Browse the repository at this point in the history
feat: change id encoding from base64url to base58, update package.json
  • Loading branch information
JesseTheRobot authored Sep 4, 2024
2 parents b35f492 + 850274c commit eb3eea7
Show file tree
Hide file tree
Showing 14 changed files with 43 additions and 41 deletions.
15 changes: 6 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
# ANS-104 Bundles

**If you want to use Bundlr Network head over to [this repo](https://github.com/Bundlr-Network/js-client)**
# Irys bundles
**If you want to use the Irys Network, head over to [our SDK](https://github.com/Irys-xyz/js-sdk)**

A low level library for creating, editing, reading and verifying bundles.

See [ANS-104](https://github.com/ArweaveTeam/arweave-standards/blob/master/ans/ANS-104.md) for more details.

## Installing the library

Using npm:

`npm install arbundles`
`npm install @irys/bundles`

Using yarn:

`yarn add arbundles`
`yarn add @irys/bundles`

## Creating bundles

```ts
import { bundleAndSignData, createData } from "arbundles";
import { bundleAndSignData, createData, EthereumSigner } from "@irys/bundles";

const dataItems = [createData("some data"), createData("some other data")];

const signer = new ArweaveSigner(jwk);
const signer = new EthereumSigner("privateKey")

const bundle = await bundleAndSignData(dataItems, signer);
```
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "arbundles",
"version": "0.11.1",
"description": "Arweave bundling library",
"author": "Josh Benaron <joshbenaron@gmail.com>",
"name": "@irys/bundles",
"version": "0.0.1",
"description": "Transaction bundling library",
"author": "Irys maintainers <hello@irys.xyz>",
"license": "Apache-2.0",
"repository": "https://github.com/Bundlr-Network/arbundles",
"repository": "https://github.com/Irys-xyz/bundles",
"main": "build/node/cjs/index.js",
"module": "build/node/esm/index.js",
"browser": "build/web/esm/webIndex.js",
Expand Down
7 changes: 4 additions & 3 deletions src/Bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { BundleInterface } from "./BundleInterface";
import type { JWKInterface } from "./interface-jwk";
import { createHash } from "crypto";
import type { CreateTransactionInterface, Transaction } from "$/utils";
import base58 from "bs58";

const HEADER_START = 32;

Expand Down Expand Up @@ -56,7 +57,7 @@ export class Bundle implements BundleInterface {
if (bundleId.length === 0) {
throw new Error("Invalid bundle, id specified in headers doesn't exist");
}
ids.push(base64url.encode(bundleId));
ids.push(base58.encode(bundleId));
}

return ids;
Expand All @@ -68,7 +69,7 @@ export class Bundle implements BundleInterface {
}

const start = 64 + 64 * index;
return base64url.encode(this.binary.subarray(start, start + 32));
return base58.encode(this.binary.subarray(start, start + 32));
}

public async toTransaction(
Expand All @@ -85,7 +86,7 @@ export class Bundle implements BundleInterface {
public async verify(): Promise<boolean> {
for (const item of this.items) {
const valid = await item.isValid();
const expected = base64url(createHash("sha256").update(item.rawSignature).digest());
const expected = base58.encode(createHash("sha256").update(item.rawSignature).digest());
if (!(valid && item.id === expected)) {
return false;
}
Expand Down
7 changes: 4 additions & 3 deletions src/DataItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import { SIG_CONFIG, SignatureConfig } from "./constants";
import { getCryptoDriver } from "$/utils";
import { deserializeTags } from "./tags";
import { createHash } from "crypto";
import type { Base64URLString } from "./types";
import type { Base58String, Base64URLString } from "./types";
import base58 from "bs58";

export const MIN_BINARY_SIZE = 80;
export const MAX_TAG_BYTES = 4096;
Expand Down Expand Up @@ -39,8 +40,8 @@ export class DataItem implements BundleItem {
return DataItem.verify(this.binary);
}

get id(): Base64URLString {
return base64url.encode(this.rawId);
get id(): Base58String {
return base58.encode(this.rawId);
}

set id(id: string) {
Expand Down
3 changes: 2 additions & 1 deletion src/__tests__/dataItem.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ describe("DataItem", () => {
});
describe("given we want to get the id", () => {
it("should return the id", async () => {
expect(dataItem.id).toBe("mM5C3u9R1AJp1UL1MUvvLHRo1AGtXYUWi_q0wBCPdfc");
// expect(dataItem.id).toBe("mM5C3u9R1AJp1UL1MUvvLHRo1AGtXYUWi_q0wBCPdfc");
expect(dataItem.id).toBe("BHVPXzXznQ8hqa76NcarF9B8LPgSyvzSebTfBBardGcW");
});
});
describe("given we want to get the owner", () => {
Expand Down
2 changes: 0 additions & 2 deletions src/__tests__/filePolygon.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ describe("Polygon signing tests", function () {
await d.sign(signer);
expect(await d.isValid()).toBe(true);

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
expect((await d.rawOwner()).toString("hex")).toEqual(signer.pk);
expect(await d.signatureType()).toEqual(3);
expect(await d.target()).toEqual("OXcT1sVRSA5eGwt2k6Yuz8-3e3g9WJi5uSE99CWqsBs");
Expand Down
4 changes: 2 additions & 2 deletions src/ar-data-bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ export async function bundleAndSignData(dataItems: DataItem[], signer: Signer):
const binaries = await Promise.all(
dataItems.map(async (d, index) => {
// Sign DataItem
const id = d.isSigned() ? d.rawId : await sign(d, signer);
const rawId = d.isSigned() ? d.rawId : await sign(d, signer);
// Create header array
const header = new Uint8Array(64);
// Set offset
header.set(longTo32ByteArray(d.getRaw().byteLength), 0);
// Set id
header.set(id, 32);
header.set(rawId, 32);
// Add header to array of headers
headers.set(header, 64 * index);
// Convert to array for flattening
Expand Down
10 changes: 5 additions & 5 deletions src/file/FileBundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import MultiStream from "multistream";
// import { createTransactionAsync } from 'arweave-stream';
import type { JWKInterface } from "../interface-jwk";
import { promisify } from "util";
import base64url from "base64url";
import { pipeline } from "stream/promises";

import type { CreateTransactionInterface, Transaction } from "$/utils";
import { resolve } from "path";
import base58 from "bs58";
// import { Readable } from 'stream';
// import { createTransactionAsync } from 'arweave-stream';
// import { pipeline } from 'stream/promises';
Expand Down Expand Up @@ -131,7 +131,7 @@ export class FileBundle implements BundleInterface {
for (let i = 32; i < 32 + 64 * (await this.length()); i += 64) {
yield {
offset: byteArrayToLong(await read(handle.fd, Buffer.allocUnsafe(32), 0, 32, i).then((r) => r.buffer)),
id: await read(handle.fd, Buffer.allocUnsafe(32), 0, 32, i + 32).then((r) => base64url.encode(r.buffer)),
id: await read(handle.fd, Buffer.allocUnsafe(32), 0, 32, i + 32).then((r) => base58.encode(r.buffer)),
};
}
await handle.close();
Expand All @@ -140,15 +140,15 @@ export class FileBundle implements BundleInterface {
private async *itemsGenerator(): AsyncGenerator<FileDataItem> {
let counter = 0;
for await (const { id } of this.getHeaders()) {
yield new FileDataItem(this.txs[counter], base64url.toBuffer(id));
yield new FileDataItem(this.txs[counter], base58.decode(id));
counter++;
}
}

private async getById(txId: string): Promise<FileDataItem> {
let counter = 0;
for await (const { id } of this.getHeaders()) {
if (id === txId) return new FileDataItem(this.txs[counter], base64url.toBuffer(id));
if (id === txId) return new FileDataItem(this.txs[counter], base58.decode(id));
counter++;
}
throw new Error("Can't find by id");
Expand All @@ -159,7 +159,7 @@ export class FileBundle implements BundleInterface {

for await (const { id } of this.getHeaders()) {
if (count === index) {
return new FileDataItem(this.txs[count], base64url.toBuffer(id));
return new FileDataItem(this.txs[count], base58.decode(id));
}
count++;
}
Expand Down
7 changes: 4 additions & 3 deletions src/file/FileDataItem.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import axios from "axios";
import { SIG_CONFIG } from "../constants";
import { promisify } from "util";
import { deserializeTags } from "../tags";
import type { Base64URLString } from "../types";
import type { Base58String, Base64URLString } from "../types";
import base58 from "bs58";

const read = promisify(FSRead);
const write = promisify(FSWrite);
Expand All @@ -39,9 +40,9 @@ export class FileDataItem implements BundleItem {

private _id?: Buffer;

get id(): string {
get id(): Base58String {
if (!this._id) throw new Error("FileDataItem - ID is undefined");
return base64url.encode(this._id);
return base58.encode(this._id);
}

get rawId(): Buffer {
Expand Down
3 changes: 2 additions & 1 deletion src/file/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { streamSigner } from "../stream/index";
import type { Readable } from "stream";
import type { Tag } from "../tags";
import { deserializeTags } from "../tags";
import base58 from "bs58";

type File = string | FileHandle;
const read = promisify(FSRead);
Expand Down Expand Up @@ -87,7 +88,7 @@ export async function getHeaderAt(file: File, index: number): Promise<DataItemHe
await fd.close();
return {
offset: byteArrayToLong(headerBuffer.subarray(0, 32)),
id: base64url.encode(headerBuffer.subarray(32, 64)),
id: base58.encode(headerBuffer.subarray(32, 64)),
};
}

Expand Down
5 changes: 3 additions & 2 deletions src/stream/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { deepHash } from "../deepHash";
import type { Signer } from "../signing/index";
import { deserializeTags } from "../tags";
import { createHash } from "crypto";
import base58 from "bs58";

export async function processStream(stream: Readable): Promise<Record<string, any>[]> {
const reader = getReader(stream);
Expand All @@ -22,7 +23,7 @@ export async function processStream(stream: Readable): Promise<Record<string, an
bytes = await readBytes(reader, bytes, headersLength);
const headers: [number, string][] = new Array(itemCount);
for (let i = 0; i < headersLength; i += 64) {
headers[i / 64] = [byteArrayToLong(bytes.subarray(i, i + 32)), base64url(Buffer.from(bytes.subarray(i + 32, i + 64)))];
headers[i / 64] = [byteArrayToLong(bytes.subarray(i, i + 32)), base58.encode(Buffer.from(bytes.subarray(i + 32, i + 64)))];
}

bytes = bytes.subarray(headersLength);
Expand Down Expand Up @@ -125,7 +126,7 @@ export async function processStream(stream: Readable): Promise<Record<string, an
transform.end();

// Check id
if (id !== base64url(createHash("sha256").update(signature).digest())) throw new Error("ID doesn't match signature");
if (id !== base58.encode(createHash("sha256").update(signature).digest())) throw new Error("ID doesn't match signature");

const Signer = indexToType[signatureType];

Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export type Base64URLString = string;
export type Base58String = string;
8 changes: 4 additions & 4 deletions webIndex.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as arbundlesSrc from "./src";
import * as bundlesSrc from "./src";
import * as stream from "./src/stream";
const expObj = { ...arbundlesSrc, stream };
globalThis.arbundles ??= expObj;
const expObj = { ...bundlesSrc, stream };
globalThis.bundles ??= expObj;
export * from "./src/index";
export * from "./src/stream";
export default expObj;
export const arbundles = expObj;
export const bundles = expObj;
2 changes: 1 addition & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,6 @@ module.exports = {
filename: "bundle.js",
path: path.resolve(__dirname, "./build/web/"),
libraryTarget: "umd",
library: "Arbundles",
library: "bundles",
},
};

0 comments on commit eb3eea7

Please sign in to comment.