Skip to content

Commit 454b7ea

Browse files
committed
feat: add global config var for w3id
1 parent 57b44bc commit 454b7ea

File tree

5 files changed

+103
-85
lines changed

5 files changed

+103
-85
lines changed

infrastructure/w3id/src/index.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,18 @@ export class W3IDBuilder {
2424
private entropy?: string;
2525
private namespace?: string;
2626
private nextKeyHash?: string;
27+
private global?: boolean = false;
2728

2829
public withEntropy(str: string): W3IDBuilder {
2930
this.entropy = str;
3031
return this;
3132
}
3233

34+
public withGlobal(isGlobal: boolean): W3IDBuilder {
35+
this.global = isGlobal;
36+
return this;
37+
}
38+
3339
public withNamespace(uuid: string): W3IDBuilder {
3440
this.namespace = uuid;
3541
return this;
@@ -55,7 +61,9 @@ export class W3IDBuilder {
5561
public async build(): Promise<W3ID> {
5662
this.entropy = this.entropy ?? generateRandomAlphaNum();
5763
this.namespace = this.namespace ?? uuidv4();
58-
const id = generateUuid(this.entropy, this.namespace);
64+
const id = this.global
65+
? "@"
66+
: "" + generateUuid(this.entropy, this.namespace);
5967
if (!this.signer) {
6068
return new W3ID(id);
6169
} else {

infrastructure/w3id/tests/logs/log.test.ts

Lines changed: 4 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,10 @@
1-
import { StorageSpec } from "../../src/logs/storage/storage-spec.ts";
2-
import {
3-
LogEvent,
4-
Signer,
5-
VerifierCallback,
6-
} from "../../src/logs/log.types.ts";
1+
import { LogEvent } from "../../src/logs/log.types.ts";
72
import { IDLogManager } from "../../src/logs/log-manager";
83
import { generateUuid } from "../../src/utils/uuid";
94
import { describe, expect, test, expectTypeOf } from "vitest";
105
import { hash } from "../../src/utils/hash";
116
import nacl from "tweetnacl";
12-
import {
13-
uint8ArrayToHex,
14-
stringToUint8Array,
15-
hexToUint8Array,
16-
} from "../../src/utils/codec";
17-
import { base58btc } from "multiformats/bases/base58";
7+
import { uint8ArrayToHex } from "../../src/utils/codec";
188
import falso from "@ngneat/falso";
199
import {
2010
BadNextKeySpecifiedError,
@@ -23,44 +13,9 @@ import {
2313
MalformedHashChainError,
2414
MalformedIndexChainError,
2515
} from "../../src/errors/errors.ts";
16+
import { InMemoryStorage } from "../utils/store.ts";
17+
import { createSigner, verifierCallback } from "../utils/crypto.ts";
2618

27-
export class InMemoryStorage<T extends LogEvent, K extends LogEvent>
28-
implements StorageSpec<T, K>
29-
{
30-
private data: K[] = [];
31-
32-
public static build<T extends LogEvent, K extends LogEvent>(): StorageSpec<
33-
T,
34-
K
35-
> {
36-
return new InMemoryStorage<T, K>();
37-
}
38-
39-
public async create(body: T): Promise<K> {
40-
const entry = body as unknown as K;
41-
this.data.push(entry);
42-
return entry;
43-
}
44-
45-
public async findOne(options: Partial<K>): Promise<K> {
46-
const result = this.data.find((item) =>
47-
Object.entries(options).every(
48-
([key, value]) => item[key as keyof K] === value,
49-
),
50-
);
51-
52-
if (!result) throw new Error("Not found");
53-
return result;
54-
}
55-
56-
public async findMany(options: Partial<K>): Promise<K[]> {
57-
return this.data.filter((item) =>
58-
Object.entries(options).every(
59-
([key, value]) => item[key as keyof K] === value,
60-
),
61-
);
62-
}
63-
}
6419
const keyPair = nacl.sign.keyPair();
6520
let currNextKey = nacl.sign.keyPair();
6621

@@ -69,36 +24,6 @@ const signer = createSigner(keyPair);
6924
const logManager = new IDLogManager(InMemoryStorage.build(), signer);
7025
const w3id = `@${generateUuid("asdfa")}`;
7126

72-
export const verifierCallback: VerifierCallback = async (
73-
message: string,
74-
signature: string,
75-
pubKey: string,
76-
) => {
77-
const signatureBuffer = base58btc.decode(signature);
78-
const messageBuffer = stringToUint8Array(message);
79-
const publicKey = hexToUint8Array(pubKey);
80-
const isValid = nacl.sign.detached.verify(
81-
messageBuffer,
82-
signatureBuffer,
83-
publicKey,
84-
);
85-
86-
return isValid;
87-
};
88-
89-
export function createSigner(keyPair: nacl.SignKeyPair): Signer {
90-
const publicKey = uint8ArrayToHex(keyPair.publicKey);
91-
const signer: Signer = {
92-
pubKey: publicKey,
93-
sign: (str: string) => {
94-
const buffer = stringToUint8Array(str);
95-
const signature = nacl.sign.detached(buffer, keyPair.secretKey);
96-
return base58btc.encode(signature);
97-
},
98-
};
99-
return signer;
100-
}
101-
10227
describe("LogManager", async () => {
10328
test("GenesisEvent: [Throw at Bad Options]", async () => {
10429
const nextKeyHash = await hash(uint8ArrayToHex(currNextKey.publicKey));
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { base58btc } from "multiformats/bases/base58";
2+
import { Signer, VerifierCallback } from "../../src/logs/log.types";
3+
import {
4+
hexToUint8Array,
5+
stringToUint8Array,
6+
uint8ArrayToHex,
7+
} from "../../src/utils/codec";
8+
import nacl from "tweetnacl";
9+
10+
export const verifierCallback: VerifierCallback = async (
11+
message: string,
12+
signature: string,
13+
pubKey: string,
14+
) => {
15+
const signatureBuffer = base58btc.decode(signature);
16+
const messageBuffer = stringToUint8Array(message);
17+
const publicKey = hexToUint8Array(pubKey);
18+
const isValid = nacl.sign.detached.verify(
19+
messageBuffer,
20+
signatureBuffer,
21+
publicKey,
22+
);
23+
24+
return isValid;
25+
};
26+
27+
export function createSigner(keyPair: nacl.SignKeyPair): Signer {
28+
const publicKey = uint8ArrayToHex(keyPair.publicKey);
29+
const signer: Signer = {
30+
pubKey: publicKey,
31+
sign: (str: string) => {
32+
const buffer = stringToUint8Array(str);
33+
const signature = nacl.sign.detached(buffer, keyPair.secretKey);
34+
return base58btc.encode(signature);
35+
},
36+
};
37+
return signer;
38+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { LogEvent } from "../../src/logs/log.types";
2+
import { StorageSpec } from "../../src/logs/storage/storage-spec.ts";
3+
4+
export class InMemoryStorage<T extends LogEvent, K extends LogEvent>
5+
implements StorageSpec<T, K>
6+
{
7+
private data: K[] = [];
8+
9+
public static build<T extends LogEvent, K extends LogEvent>(): StorageSpec<
10+
T,
11+
K
12+
> {
13+
return new InMemoryStorage<T, K>();
14+
}
15+
16+
public async create(body: T): Promise<K> {
17+
const entry = body as unknown as K;
18+
this.data.push(entry);
19+
return entry;
20+
}
21+
22+
public async findOne(options: Partial<K>): Promise<K> {
23+
const result = this.data.find((item) =>
24+
Object.entries(options).every(
25+
([key, value]) => item[key as keyof K] === value,
26+
),
27+
);
28+
29+
if (!result) throw new Error("Not found");
30+
return result;
31+
}
32+
33+
public async findMany(options: Partial<K>): Promise<K[]> {
34+
return this.data.filter((item) =>
35+
Object.entries(options).every(
36+
([key, value]) => item[key as keyof K] === value,
37+
),
38+
);
39+
}
40+
}

infrastructure/w3id/tests/w3id.test.ts

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@ import { W3ID, W3IDBuilder } from "../src";
22
import { describe, test, expect } from "vitest";
33
import falso from "@ngneat/falso";
44
import nacl from "tweetnacl";
5-
import {
6-
createSigner,
7-
InMemoryStorage,
8-
verifierCallback,
9-
} from "./logs/log.test";
5+
import { createSigner, verifierCallback } from "./utils/crypto";
6+
import { InMemoryStorage } from "./utils/store";
107
import { IDLogManager } from "../src/logs/log-manager";
118
import { hash } from "../src/utils/hash";
129
import { uint8ArrayToHex } from "../src/utils/codec";
@@ -21,6 +18,16 @@ describe("W3IDBuilder", () => {
2118
expect(id.logs).toBeUndefined();
2219
});
2320

21+
test("ID Generation: Global ID begins with `@`", async () => {
22+
const id = await new W3IDBuilder().withGlobal(true).build();
23+
expect(id.id.startsWith("@")).toBe(true);
24+
});
25+
26+
test("ID Generation: Local ID begins doesn't begin with `@`", async () => {
27+
const id = await new W3IDBuilder().build();
28+
expect(id.id.startsWith("@")).toBe(false);
29+
});
30+
2431
test("ID Generation: UUID is Deterministic", async () => {
2532
const namespace = falso.randUuid();
2633
const entropy = falso.randText();

0 commit comments

Comments
 (0)