diff --git a/anchor.ts b/anchor.ts index ea562e4..01ba501 100644 --- a/anchor.ts +++ b/anchor.ts @@ -2,7 +2,7 @@ import fs from 'fs'; import {Veritas, SLabel} from '@spacesprotocol/veritas'; import b4a from 'b4a'; import {EventRecord, CompactEvent, signableCompactEvent, TargetInfo} from './messages'; -import {log} from './utils'; +import {log, getProofFromTags} from './utils'; interface Anchor { root: string; @@ -98,9 +98,11 @@ export class AnchorStore { public assertAnchored(evt: CompactEvent, targetInfo: TargetInfo, prev?: EventRecord): EventRecord { if (!targetInfo.space) throw new Error('Not a space anchored') - if (evt.proof.length === 0) throw new Error('Proof needed') - - const proof = this.veritas.verifyProof(evt.proof); + + const proofBase64 = getProofFromTags(evt.tags); + if (proofBase64.length == 0) throw new Error('Proof is needed'); + const proofBuffer = b4a.from(proofBase64, 'base64'); + const proof = this.veritas.verifyProof(proofBuffer); const space = new SLabel(targetInfo.space); const utxo = proof.findSpace(space); if (!utxo) throw new Error('No space utxo found in proof'); diff --git a/index.ts b/index.ts index 585183c..6cdf722 100644 --- a/index.ts +++ b/index.ts @@ -25,6 +25,9 @@ interface NodeResposne { event: CompactEvent } +export { AnchorStore } from './anchor' + + export interface FabricOptions extends HyperDHTOptions { maxSize?: number; maxAge?: number; diff --git a/messages.ts b/messages.ts index 99af575..1c107aa 100644 --- a/messages.ts +++ b/messages.ts @@ -12,7 +12,6 @@ export interface CompactEvent { binary_content: boolean, content: Uint8Array, sig: Uint8Array, - proof: Uint8Array } export interface EventRecord { @@ -28,16 +27,14 @@ export interface TargetInfo { export function toCompactEvent(evt: NostrEvent, binary_content: boolean) : Uint8Array { if (!evt.sig) throw new Error('must be a signed event'); - return c.encode(compactEvent, { created_at: evt.created_at, kind: evt.kind, tags: evt.tags, binary_content: binary_content, - content: b4a.from(evt.content, binary_content ? 'base64' : 'utf-8'), + content: b4a.from(evt.content, binary_content ? 'base64' : 'utf-8'), sig: b4a.from(evt.sig, 'hex'), pubkey: b4a.from(evt.pubkey, 'hex'), - proof: evt.proof ? b4a.from(evt.proof, 'base64') : null, }); } @@ -60,11 +57,9 @@ export function toEvent(evt: CompactEvent) : NostrEvent { tags: evt.tags, content: b4a.toString(evt.content || new Uint8Array(), evt.binary_content ? 'base64' : 'utf-8'), sig: b4a.toString(evt.sig, 'hex'), - proof: evt.proof ? b4a.toString(evt.proof, 'base64') : undefined } } - export const compactEvent = { preencode (state: any, m: CompactEvent): void { c.uint.preencode(state, m.created_at) @@ -74,7 +69,6 @@ export const compactEvent = { c.bool.preencode(state, m.binary_content) c.buffer.preencode(state, m.content) c.fixed64.preencode(state, m.sig) - c.buffer.preencode(state, m.proof) }, encode (state: any, m: CompactEvent): void { c.uint.encode(state, m.created_at) @@ -84,7 +78,6 @@ export const compactEvent = { c.bool.encode(state, m.binary_content) c.buffer.encode(state, m.content) c.fixed64.encode(state, m.sig) - c.buffer.encode(state, m.proof) }, decode (state: any): CompactEvent { return { @@ -95,7 +88,6 @@ export const compactEvent = { binary_content: c.bool.decode(state), content: c.buffer.decode(state) || new Uint8Array, sig: c.fixed64.decode(state), - proof: c.buffer.decode(state) || new Uint8Array } } } diff --git a/package.json b/package.json index ec2602e..cabccdb 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,11 @@ "version": "0.0.7", "description": "", "main": "dist/index.js", + "exports": { + ".": "./dist/index.js", + "./anchor": "./dist/anchor.js" + }, + "types": "./dist/index.d.ts", "scripts": { "prepare": "npm run build", "build": "tsc", diff --git a/tsconfig.json b/tsconfig.json index 3eadf16..96b3862 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -56,8 +56,8 @@ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + "declarationMap": true, /* Create sourcemaps for d.ts files. */ // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ diff --git a/utils.ts b/utils.ts index 340ae4c..b870c88 100644 --- a/utils.ts +++ b/utils.ts @@ -13,7 +13,6 @@ export type NostrEvent = { pubkey: string content: string created_at: number - proof?: string } // from nostr-tools: @@ -73,6 +72,8 @@ export function computeSpaceTarget(space : string, kind : number, d : string = ' if (!space.startsWith('@')) throw new Error('space name must start with @') const key = Veritas.sha256(b4a.from(space, 'utf-8')); + + const targetString = nostrTarget(b4a.toString(key, 'hex'), kind, d); return Veritas.sha256(b4a.from(targetString, 'utf-8')); } @@ -84,15 +85,27 @@ export function computePubkeyTarget(pubkey: string | Uint8Array, kind : number, return Veritas.sha256(b4a.from(targetString, 'utf-8')); } +export function getProofFromTags(tags: string[][]): string { + for (const tag of tags) { + if (tag.length === 3 && tag[0] === 's') { + return tag[2]; + } + } + return ''; +} + + export function computeTarget(evt: CompactEvent) : TargetInfo { - const anchored = evt.proof.length !== 0; + const proof = getProofFromTags(evt.tags); + const anchored = proof.length !== 0; + if (isNaN(evt.kind)) throw new Error('Invalid event kind must be a number'); let space, d; for (const tag of evt.tags) { if (tag.length < 2) continue; - if (!space && anchored && tag[0] === 'space') { + if (!space && anchored && tag[0] === 's' && tag.length >= 2) { space = tag[1]; continue; }