Skip to content
This repository has been archived by the owner on Sep 4, 2024. It is now read-only.

Commit

Permalink
Merge pull request #78 from Bundlr-Network/feat/provenance
Browse files Browse the repository at this point in the history
Feat/provenance
  • Loading branch information
JesseTheRobot authored Oct 3, 2023
2 parents 4c90af5 + 09290bd commit 536b0b3
Show file tree
Hide file tree
Showing 14 changed files with 185 additions and 348 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@
"@ethersproject/signing-key": "^5.7.0",
"@ethersproject/transactions": "^5.7.0",
"@ethersproject/wallet": "^5.7.0",
"@irys/arweave": "^0.0.2",
"@noble/ed25519": "^1.6.1",
"arweave": "=1.11.8",
"base64url": "^3.0.1",
"bs58": "^4.0.1",
"keccak": "^3.0.2",
Expand All @@ -151,4 +151,4 @@
"multistream": "^4.1.0",
"tmp-promise": "^3.0.2"
}
}
}
2 changes: 1 addition & 1 deletion src/Bundle.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import base64url from "base64url";
import { byteArrayToLong } from "./utils";
import DataItem from "./DataItem";
import type Arweave from "arweave";
import type Arweave from "@irys/arweave";
import type { BundleInterface } from "./BundleInterface";
import type { JWKInterface } from "./interface-jwk";
import { createHash } from "crypto";
Expand Down
2 changes: 1 addition & 1 deletion src/BundleInterface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { BundleItem } from "./BundleItem";
import type Arweave from "arweave";
import type Arweave from "@irys/arweave";
import type { JWKInterface } from "./interface-jwk";
import type { CreateTransactionInterface, Transaction } from "$/utils";

Expand Down
40 changes: 33 additions & 7 deletions src/__tests__/fileBundle.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ import Bundle from "../file/FileBundle";
import { EthereumSigner } from "../../index";
import { bundleAndSignData } from "../file";
import base64url from "base64url";
import type Transactions from "arweave/node/transactions";
import type Arweave from "arweave/node/common";
import type Transactions from "@irys/arweave/common/transactions";
import type Arweave from "@irys/arweave";
import type { JWKInterface } from "../";
import Transaction from "arweave/node/lib/transaction";
import Transaction from "@irys/arweave/common/lib/transaction";
import path from "path";
import type { PathLike } from "fs";
import fs from "fs";
import { tmpName } from "tmp-promise";
import { randomBytes } from "crypto";
import { unlink, writeFile } from "fs/promises";

export function randomNumber(min, max): number {
export function randomNumber(min: number, max: number): number {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
Expand Down Expand Up @@ -128,7 +128,7 @@ describe.each(testDataVariations)("given we have $description FileDataItems", ({
});
});

describe("and given we want to convert the bundle to a transaction", () => {
describe.skip("and given we want to convert the bundle to a transaction", () => {
let tx: any;
beforeEach(async () => {
tx = await bundle.toTransaction(
Expand Down Expand Up @@ -256,7 +256,7 @@ describe.each(testDataVariations)("given we have $description FileDataItems", ({
});
});

describe("and we signAndSubmit the bundle", () => {
describe.skip("and we signAndSubmit the bundle", () => {
const signAndSubmitTagVariations = [
{
description: "no",
Expand Down Expand Up @@ -287,7 +287,25 @@ describe.each(testDataVariations)("given we have $description FileDataItems", ({
getTransactionAnchor: jest.fn().mockReturnValue("testAnchor"),
getPrice: jest.fn().mockReturnValue(123),
} as any as Transactions,
} as any as Arweave;
stream: {
uploadTransactionAsync: jest.fn().mockReturnValue(async (s: any) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for await (const _ of s) {
true;
}
}),
createTransactionAsync: jest.fn().mockReturnValue(async (s: any) => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
for await (const _ of s) {
true;
}
return {
// eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/explicit-function-return-type
addTag: (_: any) => {},
};
}),
},
} as any as typeof Arweave;

const jwkInterfaceMock = {
k: "k",
Expand All @@ -297,6 +315,7 @@ describe.each(testDataVariations)("given we have $description FileDataItems", ({
} as any as JWKInterface;

beforeEach(async () => {
// @ts-expect-error types
tx = await bundle.signAndSubmit(arweaveMock, jwkInterfaceMock, tags);
});
it("should return a transaction", () => {
Expand All @@ -319,9 +338,16 @@ describe.each(testDataVariations)("given we have $description FileDataItems", ({
expect(tx.data_size).toBe((await bundle.getRaw()).length.toString());
});
it("should call the api", () => {
// @ts-expect-error types
expect(arweaveMock.api.post).toHaveBeenCalled();

// @ts-expect-error types
expect(arweaveMock.transactions.sign).toHaveBeenCalled();

// @ts-expect-error types
expect(arweaveMock.transactions.getTransactionAnchor).toHaveBeenCalled();

// @ts-expect-error types
expect(arweaveMock.transactions.getPrice).toHaveBeenCalled();
});
it("should set the correct tags", () => {
Expand Down
11 changes: 5 additions & 6 deletions src/file/FileBundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import FileDataItem from "./FileDataItem";
import type { PathLike } from "fs";
import { createReadStream, promises } from "fs";
import { byteArrayToLong } from "../utils";
import type Arweave from "arweave";
import type NodeArweave from "@irys/arweave/node";
import { read as FSRead } from "fs";
import MultiStream from "multistream";
// import { pipeline } from 'stream/promises';
Expand All @@ -13,7 +13,6 @@ import { promisify } from "util";
import base64url from "base64url";
import { pipeline } from "stream/promises";

import { createTransactionAsync, uploadTransactionAsync } from "arweave-stream-tx";
import type { CreateTransactionInterface, Transaction } from "$/utils";
import { resolve } from "path";
// import { Readable } from 'stream';
Expand Down Expand Up @@ -95,19 +94,19 @@ export class FileBundle implements BundleInterface {
return buff;
}

async toTransaction(attributes: Partial<Omit<CreateTransactionInterface, "data">>, arweave: Arweave, jwk: JWKInterface): Promise<Transaction> {
async toTransaction(attributes: Partial<Omit<CreateTransactionInterface, "data">>, arweave: NodeArweave, jwk: JWKInterface): Promise<Transaction> {
const streams = [createReadStream(this.headerFile), ...this.txs.map((t) => createReadStream(t))];

const stream = MultiStream.obj(streams);

const tx = await pipeline(stream, createTransactionAsync(attributes, arweave, jwk));
const tx = await pipeline(stream, arweave.stream.createTransactionAsync(attributes, jwk));
tx.addTag("Bundle-Format", "binary");
tx.addTag("Bundle-Version", "2.0.0");

return tx;
}

async signAndSubmit(arweave: Arweave, jwk: JWKInterface, tags: { name: string; value: string }[] = []): Promise<Transaction> {
async signAndSubmit(arweave: NodeArweave, jwk: JWKInterface, tags: { name: string; value: string }[] = []): Promise<Transaction> {
const tx = await this.toTransaction({}, arweave, jwk);
// tx.addTag("Bundle-Format", "binary");
// tx.addTag("Bundle-Version", "2.0.0");
Expand All @@ -122,7 +121,7 @@ export class FileBundle implements BundleInterface {
const stream2 = MultiStream.obj(streams2);

// eslint-disable-next-line @typescript-eslint/no-explicit-any
await pipeline(stream2, uploadTransactionAsync(tx, arweave, true) as any);
await pipeline(stream2, arweave.stream.uploadTransactionAsync(tx, true) as any);

return tx;
}
Expand Down
10 changes: 5 additions & 5 deletions src/nodeUtils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { createPublicKey } from "crypto";
import { default as nodeDriver } from "arweave/node/lib/crypto/node-driver";
import { default as nodeDriver } from "@irys/arweave/node/node-driver";
import type { JWKInterface } from "./interface-jwk";
// import CryptoInterface from "arweave/node/lib/crypto/crypto-interface";
export { stringToBuffer, concatBuffers } from "arweave/node/lib/utils";
export { default as Transaction } from "arweave/node/lib/transaction";
export { stringToBuffer, concatBuffers } from "@irys/arweave/common/lib/utils";
export { default as Transaction } from "@irys/arweave/common/lib/transaction";
export { deepHash } from "./deepHash";
// import type { Hash } from "crypto";
// export { default as Arweave } from "arweave/node";
// export const sha384 = (): Hash => createHash("sha384");
export type { CreateTransactionInterface } from "arweave/node/common";
export { default as Arweave } from "arweave/node";
export type { CreateTransactionInterface } from "@irys/arweave/common/arweave";
export { default as Arweave } from "@irys/arweave/node";

// hack as ESM won't unpack .default CJS imports, so we do so dynamically
// eslint-disable-next-line @typescript-eslint/dot-notation
Expand Down
2 changes: 1 addition & 1 deletion src/signing/chains/ArweaveSigner.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Rsa4096Pss from "../keys/Rsa4096Pss";
import type { JWKInterface } from "../../interface-jwk";
import { jwkTopem } from "arweave/node/lib/crypto/pem";
import { jwkTopem } from "@irys/arweave/common/lib/crypto/pem";
import base64url from "base64url";
import { getCryptoDriver } from "$/utils";

Expand Down
20 changes: 18 additions & 2 deletions src/signing/chains/InjectedTypedEthereumSigner.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
import { SignatureConfig, SIG_CONFIG } from "../../constants";
import { verifyTypedData } from "@ethersproject/wallet";
import InjectedEthereumSigner from "./injectedEthereumSigner";
import { domain, types } from "./TypedEthereumSigner";
import type { TypedDataDomain, TypedDataField } from "@ethersproject/abstract-signer";
import type { Signer } from "../index";

export default class InjectedTypedEthereumSigner extends InjectedEthereumSigner {
export interface InjectedTypedEthereumSignerMinimalSigner {
getAddress: () => Promise<string>;
_signTypedData(domain: TypedDataDomain, types: Record<string, TypedDataField[]>, value: Record<string, any>): Promise<string>;
}

export interface InjectedTypedEthereumSignerMinimalProvider {
getSigner(): InjectedTypedEthereumSignerMinimalSigner;
}

export class InjectedTypedEthereumSigner implements Signer {
readonly ownerLength: number = SIG_CONFIG[SignatureConfig.TYPEDETHEREUM].pubLength;
readonly signatureLength: number = SIG_CONFIG[SignatureConfig.TYPEDETHEREUM].sigLength;
readonly signatureType: SignatureConfig = SignatureConfig.TYPEDETHEREUM;
private address: string;
protected signer: InjectedTypedEthereumSignerMinimalSigner;
public publicKey: Buffer;

constructor(provider: InjectedTypedEthereumSignerMinimalProvider) {
this.signer = provider.getSigner();
}
async ready(): Promise<void> {
this.address = (await this.signer.getAddress()).toString().toLowerCase();
this.publicKey = Buffer.from(this.address); // pk *is* address
Expand All @@ -29,3 +44,4 @@ export default class InjectedTypedEthereumSigner extends InjectedEthereumSigner
return address.toLowerCase() === addr.toLowerCase();
}
}
export default InjectedTypedEthereumSigner;
12 changes: 7 additions & 5 deletions src/signing/chains/arconnectSigner.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import type { Signer } from "..";
import { SignatureConfig, SIG_CONFIG } from "../../constants";
import Arweave from "arweave";
import type Arweave from "@irys/arweave";
import base64url from "base64url";
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import type * as _ from "arconnect";
import { getCryptoDriver } from "$/utils";

export default class InjectedArweaveSigner implements Signer {
private signer: Window["arweaveWallet"];
public publicKey: Buffer;
readonly ownerLength: number = SIG_CONFIG[SignatureConfig.ARWEAVE].pubLength;
readonly signatureLength: number = SIG_CONFIG[SignatureConfig.ARWEAVE].sigLength;
readonly signatureType: SignatureConfig = SignatureConfig.ARWEAVE;

constructor(windowArweaveWallet: Window["arweaveWallet"]) {
protected arweave: Arweave;
constructor(windowArweaveWallet: Window["arweaveWallet"], arweave: Arweave) {
this.signer = windowArweaveWallet;
this.arweave = arweave;
}

async setPublicKey(): Promise<void> {
Expand All @@ -32,11 +34,11 @@ export default class InjectedArweaveSigner implements Signer {
};

const signature = await this.signer.signature(message, algorithm);
const buf = new Uint8Array(Object.values(signature));
const buf = new Uint8Array(Object.values(signature).map((v) => +v));
return buf;
}

static async verify(pk: string, message: Uint8Array, signature: Uint8Array): Promise<boolean> {
return await Arweave.crypto.verify(pk, message, signature);
return await getCryptoDriver().verify(pk, message, signature);
}
}
4 changes: 2 additions & 2 deletions src/signing/chains/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export { default as ArweaveSigner } from "./ArweaveSigner";
export { default as InjectedSolanaSigner } from "./injectedSolanaSigner";
export { default as InjectedEthereumSigner } from "./injectedEthereumSigner";
export * from "./injectedEthereumSigner";
export { default as SolanaSigner } from "./SolanaSigner";
export { default as PolygonSigner } from "./PolygonSigner";
export { default as NearSigner } from "./NearSigner";
Expand All @@ -12,5 +12,5 @@ export { default as AptosSigner } from "./AptosSigner";
export { default as InjectedAptosSigner } from "./InjectedAptosSigner";
export { default as MultiSignatureAptosSigner } from "./multiSignatureAptos";
export { default as TypedEthereumSigner } from "./TypedEthereumSigner";
export { default as InjectedTypedEthereumSigner } from "./InjectedTypedEthereumSigner";
export * from "./InjectedTypedEthereumSigner";
export { default as ArconnectSigner } from "./arconnectSigner";
16 changes: 12 additions & 4 deletions src/signing/chains/injectedEthereumSigner.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
import type { Web3Provider, JsonRpcSigner } from "@ethersproject/providers";
import { hashMessage } from "@ethersproject/hash";
import { recoverPublicKey } from "@ethersproject/signing-key";
import type { Signer } from "../index";
import { SignatureConfig, SIG_CONFIG } from "../../constants";
import type { Bytes } from "@ethersproject/bytes";
import { arrayify } from "@ethersproject/bytes";
import { computeAddress } from "@ethersproject/transactions";
import { verifyMessage } from "@ethersproject/wallet";
export interface InjectedEthereumSignerMinimalSigner {
signMessage(message: string | Bytes): Promise<string>;
}
export interface InjectedEthereumSignerMinimalProvider {
getSigner(): InjectedEthereumSignerMinimalSigner;
}

export default class InjectedEthereumSigner implements Signer {
protected signer: JsonRpcSigner;
export class InjectedEthereumSigner implements Signer {
// protected signer: JsonRpcSigner;
protected signer: InjectedEthereumSignerMinimalSigner;
public publicKey: Buffer;
readonly ownerLength: number = SIG_CONFIG[SignatureConfig.ETHEREUM].pubLength;
readonly signatureLength: number = SIG_CONFIG[SignatureConfig.ETHEREUM].sigLength;
readonly signatureType: SignatureConfig = SignatureConfig.ETHEREUM;

constructor(provider: Web3Provider) {
constructor(provider: InjectedEthereumSignerMinimalProvider) {
this.signer = provider.getSigner();
}

Expand All @@ -39,3 +46,4 @@ export default class InjectedEthereumSigner implements Signer {
return verifyMessage(message, signature) === address;
}
}
export default InjectedEthereumSigner;
2 changes: 1 addition & 1 deletion src/signing/keys/__tests__/rsa4096.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Rsa4096Pss from "../Rsa4096Pss";
import { jwkTopem } from "arweave/node/lib/crypto/pem";
import { jwkTopem } from "@irys/arweave/common/lib/crypto/pem";
import testKey from "../../../__tests__/test_key0.json";

const privateKey = jwkTopem(testKey);
Expand Down
10 changes: 5 additions & 5 deletions src/webUtils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { JWKInterface } from "./interface-jwk";
export type { default as Transaction } from "arweave/web/lib/transaction";
export type { CreateTransactionInterface } from "arweave/web/common";
import webDriver from "arweave/web/lib/crypto/webcrypto-driver";
export { stringToBuffer, concatBuffers } from "arweave/web/lib/utils";
export type { default as Transaction } from "@irys/arweave/common/lib/transaction";
export type { CreateTransactionInterface } from "@irys/arweave/common/arweave";
import webDriver from "@irys/arweave/web/webcrypto-driver";
export { stringToBuffer, concatBuffers } from "@irys/arweave/common/lib/utils";
export { deepHash } from "./deepHash";
export { default as Arweave } from "arweave/web";
export { Arweave } from "@irys/arweave/web/arweave";
// import { sha384 as SHA384 } from "sha";
// export { default as Arweave } from "arweave/web";
// import type { Hash } from "crypto";
Expand Down
Loading

0 comments on commit 536b0b3

Please sign in to comment.