From 41874f4c675b031b98f60508336cde7a9eef2c21 Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:36:13 +0100 Subject: [PATCH 01/16] =?UTF-8?q?implemented=20the=20index=20barrel=20expo?= =?UTF-8?q?rts=20=E2=80=94=20ensure=20every=20public=20symbol=20is=20expor?= =?UTF-8?q?ted=20from=20src/index.ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 758ad95..40d7d43 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,6 +18,10 @@ // Client // --------------------------------------------------------------------------- export { VeriTixClient } from './client'; +export { VeriTixClientExtended } from './client-extended'; +export { createSafeToJSON, createSafeInspect } from './client-security'; +export { VeriTixSDK } from './namespace'; +export { createFromFreighter } from './modules/freighter-factory'; // NOTE: WatchOptions was previously exported from './client' (deprecated). // The canonical export is from './types/index' below. // @deprecated importing WatchOptions from './client' — use './types/index' directly. @@ -96,4 +100,4 @@ export { buildContractCall, simulateTransaction, submitTransaction, -} from './utils/transaction'; +} from './utils/transaction'; \ No newline at end of file From 0cdf08d47cf23bf51b217041a3355a1b1b17fc5b Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:36:19 +0100 Subject: [PATCH 02/16] =?UTF-8?q?implemented=20the=20index=20barrel=20expo?= =?UTF-8?q?rts=20=E2=80=94=20ensure=20every=20public=20symbol=20is=20expor?= =?UTF-8?q?ted=20from=20src/index.ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.ts b/src/index.ts index 40d7d43..7518810 100644 --- a/src/index.ts +++ b/src/index.ts @@ -35,6 +35,7 @@ export type { ContractMetadata, EscrowRecord, TicketEscrowParams, + BatchSettlementResult, SplitRecord, SplitRecipient, DisputeRecord, From 14911a5e3ab138a7dad7f62ce661b3b872bb3d58 Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:36:29 +0100 Subject: [PATCH 03/16] =?UTF-8?q?implemented=20the=20index=20barrel=20expo?= =?UTF-8?q?rts=20=E2=80=94=20ensure=20every=20public=20symbol=20is=20expor?= =?UTF-8?q?ted=20from=20src/index.ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/index.ts b/src/index.ts index 7518810..598d38a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -57,6 +57,13 @@ export { SplitterModule } from './modules/splitter'; export { RecurringModule } from './modules/recurring'; export { AdminModule } from './modules/admin'; export { BatchModule } from './modules/batch'; +export { EventsService } from './modules/events-service'; +export { EventDashboard } from './modules/events-dashboard'; +export { EventGalleryService } from './modules/event-gallery.service'; +export { RevenueAnalyticsModule } from './modules/analytics/revenue-analytics.service'; +export { TicketAnalyticsModule } from './modules/analytics/ticket-analytics.service'; +export { CollaboratorModule } from './modules/collaborator/collaborator.service'; +export { TicketPurchaseModule } from './modules/ticket/ticket-purchase.service'; // Module param types export type { MintParams, BurnParams, TransferParams, ApproveParams } from './modules/token'; From 5a148c11b3c18cbd12d4ee5492896835e86cf657 Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:36:52 +0100 Subject: [PATCH 04/16] =?UTF-8?q?implemented=20the=20index=20barrel=20expo?= =?UTF-8?q?rts=20=E2=80=94=20ensure=20every=20public=20symbol=20is=20expor?= =?UTF-8?q?ted=20from=20src/index.ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/index.ts b/src/index.ts index 598d38a..2085a73 100644 --- a/src/index.ts +++ b/src/index.ts @@ -72,6 +72,17 @@ export type { OpenDisputeParams, ResolveDisputeParams } from './modules/dispute' export type { CreateSplitParams } from './modules/splitter'; export type { SetupRecurringParams } from './modules/recurring'; export type { BatchMintEntry, BatchTransferEntry } from './modules/batch'; +// New module types +export type { Event, EventFilter } from './modules/events-service'; +export type { DashboardMetrics } from './modules/events-dashboard'; +export type { RevenuePeriod, TicketSale } from './modules/analytics/revenue-analytics.service'; +export type { TicketPeriod, ExportFormat, TicketOrder } from './modules/analytics/ticket-analytics.service'; +export type { Collaborator, CollaboratorUpdate } from './modules/collaborator/collaborator.service'; +export type { BillingDetails, AddressDetails, PurchaseRequest, Receipt } from './modules/ticket/ticket-purchase.service'; + +// Module constants +export { TRANSACTION_CHARGE_RATE } from './modules/analytics/revenue-analytics.service'; +export { MAX_COLLABORATORS_PER_EVENT } from './modules/collaborator/collaborator.service'; // --------------------------------------------------------------------------- // Errors From 244010c674e96b09f4ad428f0d956025936d9549 Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:37:42 +0100 Subject: [PATCH 05/16] =?UTF-8?q?implemented=20the=20index=20barrel=20expo?= =?UTF-8?q?rts=20=E2=80=94=20ensure=20every=20public=20symbol=20is=20expor?= =?UTF-8?q?ted=20from=20src/index.ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/index.ts b/src/index.ts index 2085a73..5344560 100644 --- a/src/index.ts +++ b/src/index.ts @@ -106,6 +106,30 @@ export { assertValidAddress, } from './utils/network'; +// --------------------------------------------------------------------------- +// ScVal conversion helpers +// --------------------------------------------------------------------------- +export { + addressToScVal, + bigintToScVal, + boolToScVal, + stringToScVal, + scValToString, + scValToBigint, + scValToBoolean, + scValToNumber, +} from './utils/scval'; + +// --------------------------------------------------------------------------- +// XDR struct parsers +// --------------------------------------------------------------------------- +export { + parseEscrowRecord, + parseSplitRecord, + parseDisputeRecord, + parseRecurringRecord, +} from './utils/parsers'; + // --------------------------------------------------------------------------- // Format helpers // --------------------------------------------------------------------------- From 61c8ed0c2ce5f7b2637b802355b7a540a83d858b Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:37:56 +0100 Subject: [PATCH 06/16] =?UTF-8?q?implemented=20the=20index=20barrel=20expo?= =?UTF-8?q?rts=20=E2=80=94=20ensure=20every=20public=20symbol=20is=20expor?= =?UTF-8?q?ted=20from=20src/index.ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/freighter-factory.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/freighter-factory.ts b/src/modules/freighter-factory.ts index abd7757..0d23e20 100644 --- a/src/modules/freighter-factory.ts +++ b/src/modules/freighter-factory.ts @@ -1,4 +1,6 @@ // Factory for creating VeriTixClient from Freighter wallet +import { VeriTixClient } from '../client'; + export async function createFromFreighter(network: string = 'testnet') { try { const freighter = (window as any).freighter; @@ -15,4 +17,4 @@ export async function createFromFreighter(network: string = 'testnet') { console.error('Failed to connect to Freighter:', error); throw error; } -} +} \ No newline at end of file From c57d7866c77d0a19f9daefbacb4be34329b27d60 Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:38:20 +0100 Subject: [PATCH 07/16] =?UTF-8?q?implemented=20the=20index=20barrel=20expo?= =?UTF-8?q?rts=20=E2=80=94=20ensure=20every=20public=20symbol=20is=20expor?= =?UTF-8?q?ted=20from=20src/index.ts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client.ts b/src/client.ts index ac2c2fc..00fae86 100644 --- a/src/client.ts +++ b/src/client.ts @@ -91,7 +91,7 @@ export class VeriTixClient extends EventEmitter { public readonly batch: BatchModule; private server!: SorobanRpc.Server; - private readonly keypair: Keypair | undefined; + protected readonly keypair: Keypair | undefined; private connected = false; /** Cache for getCurrentLedger — { sequence, fetchedAt } */ @@ -603,4 +603,4 @@ export class VeriTixClient extends EventEmitter { }, }); } -} +} \ No newline at end of file From 562b3b54eaa4dcaee397e4b2aede54e8d147bb17 Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:39:47 +0100 Subject: [PATCH 08/16] =?UTF-8?q?implemented=20the=20enforce=20consistent?= =?UTF-8?q?=20error=20throwing=20pattern=20=E2=80=94=20every=20module=20mu?= =?UTF-8?q?st=20throw=20VeriTixError=20not=20raw=20Error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/ticket/ticket-purchase.service.ts | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/modules/ticket/ticket-purchase.service.ts b/src/modules/ticket/ticket-purchase.service.ts index bd387ba..9a1a58a 100644 --- a/src/modules/ticket/ticket-purchase.service.ts +++ b/src/modules/ticket/ticket-purchase.service.ts @@ -1,3 +1,5 @@ +import { VeriTixError, VeriTixErrorCode } from '../../utils/errors'; + /** Billing contact captured at checkout. */ export interface BillingDetails { fullName: string; @@ -38,12 +40,15 @@ export class TicketPurchaseModule { /** Confirms a purchase against remaining availability and stores a receipt. */ public purchase(orderId: string, request: PurchaseRequest, available: number): Receipt { if (!Number.isInteger(request.quantity) || request.quantity < 1) { - throw new Error('Ticket quantity must be a positive integer.'); + throw new VeriTixError( + VeriTixErrorCode.InvalidAmount, + 'Ticket quantity must be a positive integer.' + ); } if (request.quantity > available) { - throw new Error( - `Only ${available} ticket(s) remain for event ${request.eventId}; ` + - `${request.quantity} requested.`, + throw new VeriTixError( + VeriTixErrorCode.InsufficientBalance, + `Only ${available} ticket(s) remain for event ${request.eventId}; ${request.quantity} requested.` ); } const receipt: Receipt = { @@ -60,4 +65,4 @@ export class TicketPurchaseModule { public getReceipt(orderId: string): Receipt | undefined { return this.receipts.get(orderId); } -} +} \ No newline at end of file From 289018522d13aab749ed3f9143ba8897c20eade9 Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:41:04 +0100 Subject: [PATCH 09/16] =?UTF-8?q?implemented=20the=20enforce=20consistent?= =?UTF-8?q?=20error=20throwing=20pattern=20=E2=80=94=20every=20module=20mu?= =?UTF-8?q?st=20throw=20VeriTixError=20not=20raw=20Error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../collaborator/collaborator.service.ts | 20 +++++++++++++------ src/modules/freighter-factory.ts | 6 +++++- src/modules/splitter.ts | 7 +++++-- src/utils/errors.ts | 16 ++++++++++++++- 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/modules/collaborator/collaborator.service.ts b/src/modules/collaborator/collaborator.service.ts index 25d6c94..d6d6262 100644 --- a/src/modules/collaborator/collaborator.service.ts +++ b/src/modules/collaborator/collaborator.service.ts @@ -1,3 +1,5 @@ +import { VeriTixError, VeriTixErrorCode } from '../../utils/errors'; + /** A person collaborating on an event. */ export interface Collaborator { id: string; @@ -19,12 +21,15 @@ export class CollaboratorModule { public add(collaborator: Collaborator): Collaborator { if (this.collaborators.has(collaborator.id)) { - throw new Error(`Collaborator ${collaborator.id} already exists.`); + throw new VeriTixError( + VeriTixErrorCode.CollaboratorAlreadyExists, + `Collaborator ${collaborator.id} already exists.` + ); } if (this.listByEvent(collaborator.eventId).length >= MAX_COLLABORATORS_PER_EVENT) { - throw new Error( - `Event ${collaborator.eventId} already has the maximum of ` + - `${MAX_COLLABORATORS_PER_EVENT} collaborators.`, + throw new VeriTixError( + VeriTixErrorCode.MaxCollaboratorsReached, + `Event ${collaborator.eventId} already has the maximum of ${MAX_COLLABORATORS_PER_EVENT} collaborators.` ); } this.collaborators.set(collaborator.id, collaborator); @@ -46,7 +51,10 @@ export class CollaboratorModule { public update(id: string, changes: CollaboratorUpdate): Collaborator { const existing = this.collaborators.get(id); if (!existing) { - throw new Error(`Collaborator ${id} not found.`); + throw new VeriTixError( + VeriTixErrorCode.CollaboratorNotFound, + `Collaborator ${id} not found.` + ); } const updated: Collaborator = { ...existing, ...changes }; this.collaborators.set(id, updated); @@ -56,4 +64,4 @@ export class CollaboratorModule { public remove(id: string): boolean { return this.collaborators.delete(id); } -} +} \ No newline at end of file diff --git a/src/modules/freighter-factory.ts b/src/modules/freighter-factory.ts index 0d23e20..f380567 100644 --- a/src/modules/freighter-factory.ts +++ b/src/modules/freighter-factory.ts @@ -1,11 +1,15 @@ // Factory for creating VeriTixClient from Freighter wallet import { VeriTixClient } from '../client'; +import { VeriTixError, VeriTixErrorCode } from '../utils/errors'; export async function createFromFreighter(network: string = 'testnet') { try { const freighter = (window as any).freighter; if (!freighter) { - throw new Error('Freighter wallet not found'); + throw new VeriTixError( + VeriTixErrorCode.FreighterNotFound, + 'Freighter wallet not found' + ); } const publicKey = await freighter.getPublicKey(); return new VeriTixClient({ diff --git a/src/modules/splitter.ts b/src/modules/splitter.ts index 5ece0ec..cd78f94 100644 --- a/src/modules/splitter.ts +++ b/src/modules/splitter.ts @@ -53,7 +53,10 @@ export class SplitterModule { // TODO: implement void this.config; void this.server; - throw new Error('SplitterModule.getSplit: not implemented'); + throw new VeriTixError( + VeriTixErrorCode.NotImplemented, + 'SplitterModule.getSplit: not implemented' + ); } /** @@ -415,4 +418,4 @@ export class SplitterModule { return { distributed, failed }; } -} +} \ No newline at end of file diff --git a/src/utils/errors.ts b/src/utils/errors.ts index f108cec..e7c3eb0 100644 --- a/src/utils/errors.ts +++ b/src/utils/errors.ts @@ -96,6 +96,20 @@ export enum VeriTixErrorCode { WatchTimeout = 'WATCH_TIMEOUT', /** Transaction was rejected by the network */ TransactionFailed = 'TRANSACTION_FAILED', + /** Feature or method is not yet implemented */ + NotImplemented = 'NOT_IMPLEMENTED', + /** Collaborator not found */ + CollaboratorNotFound = 'COLLABORATOR_NOT_FOUND', + /** Collaborator already exists */ + CollaboratorAlreadyExists = 'COLLABORATOR_ALREADY_EXISTS', + /** Maximum number of collaborators reached for event */ + MaxCollaboratorsReached = 'MAX_COLLABORATORS_REACHED', + /** Freighter wallet not found in browser */ + FreighterNotFound = 'FREIGHTER_NOT_FOUND', + /** Client not connected - call connect() first */ + ClientNotConnected = 'CLIENT_NOT_CONNECTED', + /** Invalid input parameter */ + InvalidInput = 'INVALID_INPUT', } // --------------------------------------------------------------------------- @@ -276,4 +290,4 @@ function buildMessage(code: VeriTixErrorCode, rawStr: string): string { [VeriTixErrorCode.TransactionFailed]: 'Transaction was rejected by the Stellar network.', }; return messages[code]; -} +} \ No newline at end of file From bc3516aa0c87f457536299a8f9f3957a08028eae Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:41:26 +0100 Subject: [PATCH 10/16] =?UTF-8?q?implemented=20the=20enforce=20consistent?= =?UTF-8?q?=20error=20throwing=20pattern=20=E2=80=94=20every=20module=20mu?= =?UTF-8?q?st=20throw=20VeriTixError=20not=20raw=20Error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/splitter.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/modules/splitter.ts b/src/modules/splitter.ts index cd78f94..18a63bf 100644 --- a/src/modules/splitter.ts +++ b/src/modules/splitter.ts @@ -235,7 +235,10 @@ export class SplitterModule { // TODO: build & submit contract call void simulateTransaction; void submitTransaction; - throw new Error('SplitterModule.createSplit: not implemented'); + throw new VeriTixError( + VeriTixErrorCode.NotImplemented, + 'SplitterModule.createSplit: not implemented' + ); } /** @@ -384,7 +387,12 @@ export class SplitterModule { * ``` */ async distribute(_id: bigint): Promise { - throw new Error('SplitterModule.distribute: not implemented'); + void this.server; + void _id; + throw new VeriTixError( + VeriTixErrorCode.NotImplemented, + 'SplitterModule.distribute: not implemented' + ); } /** From f1ec6f58e6b5e874333bf5a83e9ae7cbdaf8b493 Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:42:00 +0100 Subject: [PATCH 11/16] =?UTF-8?q?implemented=20the=20enforce=20consistent?= =?UTF-8?q?=20error=20throwing=20pattern=20=E2=80=94=20every=20module=20mu?= =?UTF-8?q?st=20throw=20VeriTixError=20not=20raw=20Error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/modules/user.ts | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/src/modules/user.ts b/src/modules/user.ts index 7a4d1d2..5f1c649 100644 --- a/src/modules/user.ts +++ b/src/modules/user.ts @@ -8,6 +8,7 @@ */ import { SorobanRpc, Keypair } from '@stellar/stellar-sdk'; +import { VeriTixError, VeriTixErrorCode } from '../utils/errors'; import type { NetworkConfig, TransactionResult } from '../types/index'; /** @@ -49,7 +50,10 @@ export class AdminModule { void this.config; void this.server; void this.keypair; - throw new Error('AdminModule.setAdmin: not implemented'); + throw new VeriTixError( + VeriTixErrorCode.NotImplemented, + 'AdminModule.setAdmin: not implemented' + ); } // ------------------------------------------------------------------------- @@ -66,7 +70,11 @@ export class AdminModule { */ async freeze(_address: string): Promise { // TODO: implement - throw new Error('AdminModule.freeze: not implemented'); + void _address; + throw new VeriTixError( + VeriTixErrorCode.NotImplemented, + 'AdminModule.freeze: not implemented' + ); } /** @@ -78,7 +86,11 @@ export class AdminModule { */ async unfreeze(_address: string): Promise { // TODO: implement - throw new Error('AdminModule.unfreeze: not implemented'); + void _address; + throw new VeriTixError( + VeriTixErrorCode.NotImplemented, + 'AdminModule.unfreeze: not implemented' + ); } // ------------------------------------------------------------------------- @@ -96,7 +108,12 @@ export class AdminModule { */ async clawback(_from: string, _amount: bigint): Promise { // TODO: implement - throw new Error('AdminModule.clawback: not implemented'); + void _from; + void _amount; + throw new VeriTixError( + VeriTixErrorCode.NotImplemented, + 'AdminModule.clawback: not implemented' + ); } // ------------------------------------------------------------------------- @@ -112,7 +129,10 @@ export class AdminModule { */ async pause(): Promise { // TODO: implement - throw new Error('AdminModule.pause: not implemented'); + throw new VeriTixError( + VeriTixErrorCode.NotImplemented, + 'AdminModule.pause: not implemented' + ); } /** @@ -123,6 +143,9 @@ export class AdminModule { */ async unpause(): Promise { // TODO: implement - throw new Error('AdminModule.unpause: not implemented'); + throw new VeriTixError( + VeriTixErrorCode.NotImplemented, + 'AdminModule.unpause: not implemented' + ); } -} +} \ No newline at end of file From 30a08b7fa9f0a025d7b3e7868267e1a4a62bb36d Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:42:41 +0100 Subject: [PATCH 12/16] =?UTF-8?q?implemented=20the=20enforce=20consistent?= =?UTF-8?q?=20error=20throwing=20pattern=20=E2=80=94=20every=20module=20mu?= =?UTF-8?q?st=20throw=20VeriTixError=20not=20raw=20Error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client.ts | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/client.ts b/src/client.ts index 00fae86..05c34ab 100644 --- a/src/client.ts +++ b/src/client.ts @@ -394,7 +394,10 @@ export class VeriTixClient extends EventEmitter { */ async simulate(method: string, args: xdr.ScVal[]): Promise { if (!this.connected) { - throw new Error('VeriTixClient: call connect() before simulate()'); + throw new VeriTixError( + VeriTixErrorCode.ClientNotConnected, + 'VeriTixClient: call connect() before simulate()' + ); } try { @@ -448,7 +451,10 @@ export class VeriTixClient extends EventEmitter { */ async getCurrentLedger(): Promise { if (!this.connected || !this.server) { - throw new Error('VeriTixClient: call connect() before using module methods'); + throw new VeriTixError( + VeriTixErrorCode.ClientNotConnected, + 'VeriTixClient: call connect() before using module methods' + ); } const now = Date.now(); if ( @@ -473,7 +479,10 @@ export class VeriTixClient extends EventEmitter { */ async watchTransaction(hash: string, options?: WatchOptions): Promise { if (!this.connected || !this.server) { - throw new Error('VeriTixClient: call connect() before using module methods'); + throw new VeriTixError( + VeriTixErrorCode.ClientNotConnected, + 'VeriTixClient: call connect() before using module methods' + ); } const intervalMs = options?.intervalMs ?? 2_000; const timeoutMs = options?.timeoutMs ?? 60_000; @@ -518,7 +527,10 @@ export class VeriTixClient extends EventEmitter { */ async getContractMetadata(): Promise { if (!this.connected || !this.server) { - throw new Error('VeriTixClient: call connect() before using module methods'); + throw new VeriTixError( + VeriTixErrorCode.ClientNotConnected, + 'VeriTixClient: call connect() before using module methods' + ); } const [name, symbol, decimal, totalSupply] = await Promise.all([ this.token.name(), @@ -595,8 +607,9 @@ export class VeriTixClient extends EventEmitter { return new Proxy({} as SorobanRpc.Server, { get: (_target, prop) => { if (!this.connected || !this.server) { - throw new Error( - `VeriTixClient: call connect() before using module methods (attempted access to server.${String(prop)})`, + throw new VeriTixError( + VeriTixErrorCode.ClientNotConnected, + `VeriTixClient: call connect() before using module methods (attempted access to server.${String(prop)})` ); } return (this.server as unknown as Record)[prop]; From 33a933f5c4a738825f42fcab9278c7182c96f561 Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:47:25 +0100 Subject: [PATCH 13/16] =?UTF-8?q?implemented=20the=20enforce=20consistent?= =?UTF-8?q?=20error=20throwing=20pattern=20=E2=80=94=20every=20module=20mu?= =?UTF-8?q?st=20throw=20VeriTixError=20not=20raw=20Error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/parsers.ts | 3 ++- src/utils/scval.ts | 29 +++++++++++++++++------------ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/utils/parsers.ts b/src/utils/parsers.ts index eec0d8f..a2055c0 100644 --- a/src/utils/parsers.ts +++ b/src/utils/parsers.ts @@ -7,6 +7,7 @@ * matching the field names used in the VeriTix Soroban contract structs. */ import { xdr, scValToNative } from '@stellar/stellar-sdk'; +import { VeriTixError, VeriTixErrorCode } from './errors'; import type { EscrowRecord, SplitRecord, @@ -219,4 +220,4 @@ function parseDisputeStatus(raw: string): DisputeStatus { ); } return status; -} +} \ No newline at end of file diff --git a/src/utils/scval.ts b/src/utils/scval.ts index b83736e..d60fb6d 100644 --- a/src/utils/scval.ts +++ b/src/utils/scval.ts @@ -11,6 +11,7 @@ import { scValToNative, xdr, } from '@stellar/stellar-sdk'; +import { VeriTixError, VeriTixErrorCode } from './errors'; // --------------------------------------------------------------------------- // TypeScript → ScVal @@ -63,8 +64,9 @@ export function stringToScVal(value: string): xdr.ScVal { export function scValToString(val: xdr.ScVal): string { const native = scValToNative(val); if (typeof native !== 'string') { - throw new Error( - `Expected ScVal of type String or Symbol, got switch: ${val.switch().name}`, + throw new VeriTixError( + VeriTixErrorCode.InvalidInput, + `Expected ScVal of type String or Symbol, got switch: ${val.switch().name}` ); } return native; @@ -74,27 +76,29 @@ export function scValToString(val: xdr.ScVal): string { * Extracts a `bigint` from an `ScVal` of any integer type * (`i64`, `u64`, `i128`, `u128`, `i256`, `u256`). * - * @throws {Error} if the native value is not a `bigint` or `number`. + * @throws {VeriTixError} if the native value is not a `bigint` or `number`. */ export function scValToBigint(val: xdr.ScVal): bigint { const native = scValToNative(val); if (typeof native === 'bigint') return native; if (typeof native === 'number') return BigInt(native); - throw new Error( - `Expected ScVal to be a numeric type, got switch: ${val.switch().name}`, + throw new VeriTixError( + VeriTixErrorCode.InvalidInput, + `Expected ScVal to be a numeric type, got switch: ${val.switch().name}` ); } /** * Extracts a `boolean` from an `ScVal` of type `Bool`. * - * @throws {Error} if the `ScVal` is not a boolean type. + * @throws {VeriTixError} if the `ScVal` is not a boolean type. */ export function scValToBoolean(val: xdr.ScVal): boolean { const native = scValToNative(val); if (typeof native !== 'boolean') { - throw new Error( - `Expected ScVal of type Bool, got switch: ${val.switch().name}`, + throw new VeriTixError( + VeriTixErrorCode.InvalidInput, + `Expected ScVal of type Bool, got switch: ${val.switch().name}` ); } return native; @@ -106,13 +110,14 @@ export function scValToBoolean(val: xdr.ScVal): boolean { * > **Warning:** values exceeding `Number.MAX_SAFE_INTEGER` will lose * > precision. For large amounts, prefer {@link scValToBigint}. * - * @throws {Error} if the native value is not numeric. + * @throws {VeriTixError} if the native value is not numeric. */ export function scValToNumber(val: xdr.ScVal): number { const native = scValToNative(val); if (typeof native === 'number') return native; if (typeof native === 'bigint') return Number(native); - throw new Error( - `Expected ScVal to be a numeric type, got switch: ${val.switch().name}`, + throw new VeriTixError( + VeriTixErrorCode.InvalidInput, + `Expected ScVal to be a numeric type, got switch: ${val.switch().name}` ); -} +} \ No newline at end of file From c8541f27a90360d53b552f0e6d3020dfa03821a6 Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:47:37 +0100 Subject: [PATCH 14/16] =?UTF-8?q?implemented=20the=20enforce=20consistent?= =?UTF-8?q?=20error=20throwing=20pattern=20=E2=80=94=20every=20module=20mu?= =?UTF-8?q?st=20throw=20VeriTixError=20not=20raw=20Error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/parsers.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/utils/parsers.ts b/src/utils/parsers.ts index a2055c0..1ed01f3 100644 --- a/src/utils/parsers.ts +++ b/src/utils/parsers.ts @@ -35,8 +35,9 @@ import { */ function scMapToRecord(val: xdr.ScVal): Map { if (val.switch() !== xdr.ScValType.scvMap()) { - throw new Error( - `Expected ScvMap, got ScVal type: ${val.switch().name}`, + throw new VeriTixError( + VeriTixErrorCode.InvalidInput, + `Expected ScvMap, got ScVal type: ${val.switch().name}` ); } const map = new Map(); @@ -51,11 +52,15 @@ function scMapToRecord(val: xdr.ScVal): Map { * Retrieves a required field from an `ScvMap` record. * * @throws {Error} if the field is absent. + * @internal */ function getField(map: Map, field: string): xdr.ScVal { const val = map.get(field); if (val === undefined) { - throw new Error(`Missing required field "${field}" in ScvMap`); + throw new VeriTixError( + VeriTixErrorCode.InvalidInput, + `Missing required field "${field}" in ScvMap` + ); } return val; } From c54ada7e8caccc589e9739541e228a1c795a6944 Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:47:48 +0100 Subject: [PATCH 15/16] =?UTF-8?q?implemented=20the=20enforce=20consistent?= =?UTF-8?q?=20error=20throwing=20pattern=20=E2=80=94=20every=20module=20mu?= =?UTF-8?q?st=20throw=20VeriTixError=20not=20raw=20Error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/parsers.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/utils/parsers.ts b/src/utils/parsers.ts index 1ed01f3..0acb60d 100644 --- a/src/utils/parsers.ts +++ b/src/utils/parsers.ts @@ -116,7 +116,10 @@ export function parseSplitRecord(val: xdr.ScVal): SplitRecord { const recipientsVal = getField(map, 'recipients'); if (recipientsVal.switch() !== xdr.ScValType.scvVec()) { - throw new Error('Field "recipients" must be an ScvVec'); + throw new VeriTixError( + VeriTixErrorCode.InvalidInput, + 'Field "recipients" must be an ScvVec' + ); } const recipients: SplitRecipient[] = (recipientsVal.vec() ?? []).map((item) => { From c23734ec916c6238ce078af9df4069b40ba34421 Mon Sep 17 00:00:00 2001 From: nafiuishaaq Date: Fri, 28 Aug 2026 14:47:56 +0100 Subject: [PATCH 16/16] =?UTF-8?q?implemented=20the=20enforce=20consistent?= =?UTF-8?q?=20error=20throwing=20pattern=20=E2=80=94=20every=20module=20mu?= =?UTF-8?q?st=20throw=20VeriTixError=20not=20raw=20Error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/parsers.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/utils/parsers.ts b/src/utils/parsers.ts index 0acb60d..2f28d59 100644 --- a/src/utils/parsers.ts +++ b/src/utils/parsers.ts @@ -223,8 +223,9 @@ const DISPUTE_STATUS_MAP: Record = { function parseDisputeStatus(raw: string): DisputeStatus { const status = DISPUTE_STATUS_MAP[raw]; if (!status) { - throw new Error( - `Unknown DisputeStatus value: "${raw}". Expected one of: ${Object.keys(DISPUTE_STATUS_MAP).join(', ')}`, + throw new VeriTixError( + VeriTixErrorCode.InvalidInput, + `Unknown DisputeStatus value: "${raw}". Expected one of: ${Object.keys(DISPUTE_STATUS_MAP).join(', ')}` ); } return status;