@forgedevv/shared 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,210 @@
1
+ import type { GatingResponse, Lamports, OwnerTransactionSummary, Quote, Session } from './api.js';
2
+ import type { LaunchpadStatus, PaymentKind } from './db.js';
3
+ import type { FailedStage, JobStatus, JobType } from './jobs.js';
4
+ import type { LaunchpadSpec, LaunchpadSpecDraft, SpecValidation } from './spec.js';
5
+ /** `enabled: false` before the $FORGE launch (then `ok: true`). Amounts are raw token units. */
6
+ export type Gating = GatingResponse;
7
+ export interface Flags {
8
+ signupsPaused: boolean;
9
+ }
10
+ export interface Job {
11
+ id: string;
12
+ launchpadId: string;
13
+ type: JobType;
14
+ status: JobStatus;
15
+ attempts: number;
16
+ failedStage: FailedStage | null;
17
+ error: string | null;
18
+ previewUrl: string | null;
19
+ createdAt: string;
20
+ updatedAt: string;
21
+ refund?: {
22
+ lamports: Lamports;
23
+ signature: string;
24
+ } | null;
25
+ }
26
+ export interface JobEvent {
27
+ id: number;
28
+ jobId: string;
29
+ message: string;
30
+ createdAt: string;
31
+ }
32
+ export interface LaunchpadSummary {
33
+ id: string;
34
+ name: string;
35
+ slug: string;
36
+ /**
37
+ * Where the live site is: `https://<site_host>` when the builder recorded its exact host
38
+ * (`launchpads.site_host`), else `https://<slug>.<CLIENTS_DOMAIN>`. Null unless the launchpad is
39
+ * live or sleeping (or when neither is known).
40
+ */
41
+ siteUrl: string | null;
42
+ status: LaunchpadStatus;
43
+ coin: {
44
+ name: string;
45
+ symbol: string;
46
+ mint: string | null;
47
+ imageUrl: string;
48
+ };
49
+ coinsCount: number;
50
+ claimablePartnerFeesLamports: Lamports;
51
+ includedModificationsLeft: number;
52
+ activeJobId: string | null;
53
+ /** Status of `activeJobId` (null without one). Absent from older servers. */
54
+ activeJobStatus?: JobStatus | null;
55
+ /**
56
+ * A draft whose creation was refunded, with nothing in progress: `retryLaunchpad` can start it
57
+ * again with the same blueprint. The server re-checks everything (payments, refunds, kill
58
+ * switches, access) when asked. Absent from older servers: then treated as false.
59
+ */
60
+ canStartAgain?: boolean;
61
+ /**
62
+ * A draft whose creation jobs were all refunded but that cannot be started again yet, and why
63
+ * (null otherwise, and whenever a job is open: its tracker explains). The same rules as the
64
+ * route, so "start again" is never offered and then refused. Absent from older servers.
65
+ */
66
+ startAgainBlocked?: StartAgainBlockedReason | null;
67
+ }
68
+ /**
69
+ * Why "start again" is not available for a refunded draft:
70
+ * - `refund_pending`: money of an earlier attempt is still owed back (refund not recorded, or a
71
+ * payment anomaly waiting for its manual refund);
72
+ * - `payment_pending`: a payment for an earlier attempt may still land or be confirmed;
73
+ * - `needs_support`: the team has to look at it first (on-chain setup recorded, or the limit of
74
+ * refunded creations reached);
75
+ * - `invalid_spec`: the stored blueprint no longer passes the checks (design it again).
76
+ */
77
+ export declare const START_AGAIN_BLOCKED_REASONS: readonly ["refund_pending", "payment_pending", "needs_support", "invalid_spec"];
78
+ export type StartAgainBlockedReason = (typeof START_AGAIN_BLOCKED_REASONS)[number];
79
+ export interface LaunchpadDetail extends LaunchpadSummary {
80
+ /** Complete spec. */
81
+ spec: LaunchpadSpecDraft;
82
+ onchain: {
83
+ launchpadConfig: string | null;
84
+ launchpadCoinConfig: string | null;
85
+ launchpadCoinMint: string | null;
86
+ };
87
+ versions: {
88
+ jobId: string;
89
+ createdAt: string;
90
+ request: string | null;
91
+ previewUrl: string | null;
92
+ }[];
93
+ jobs: Job[];
94
+ }
95
+ export type TxPhase = 'idle' | 'awaiting_signature' | 'sending' | 'confirmed' | 'rejected' | 'error';
96
+ export interface TxResult {
97
+ phase: TxPhase;
98
+ signature?: string;
99
+ error?: string;
100
+ }
101
+ export declare const CLIENT_ERROR_CODES: readonly ["RATE_LIMITED", "UNAUTHORIZED", "GATING_REQUIRED", "SIGNUPS_PAUSED", "QUOTE_EXPIRED", "WRONG_WALLET", "BETA_NOT_INVITED", "NETWORK"];
102
+ export type ClientErrorCode = (typeof CLIENT_ERROR_CODES)[number];
103
+ /** Rejection of client functions; `message` is readable by the end user. */
104
+ export declare class ClientError extends Error {
105
+ readonly code: ClientErrorCode;
106
+ constructor(code: ClientErrorCode, message: string);
107
+ }
108
+ export declare function isClientError(value: unknown): value is ClientError;
109
+ export interface UseSessionResult {
110
+ session: Session | null;
111
+ connect(): Promise<void>;
112
+ disconnect(): Promise<void>;
113
+ status: 'idle' | 'signing' | 'error';
114
+ }
115
+ export interface UseGatingResult {
116
+ gating: Gating | null;
117
+ loading: boolean;
118
+ recheck(): Promise<void>;
119
+ }
120
+ export interface UiChatMessage {
121
+ role: 'user' | 'assistant';
122
+ content: string;
123
+ }
124
+ export interface UseChatOptions {
125
+ conversationId?: string;
126
+ launchpadId?: string;
127
+ }
128
+ export interface UseChatResult {
129
+ messages: UiChatMessage[];
130
+ send(text: string): void;
131
+ streaming: boolean;
132
+ spec: LaunchpadSpecDraft;
133
+ validation: SpecValidation;
134
+ rateLimited: boolean;
135
+ conversationId: string | null;
136
+ }
137
+ export interface UseJobResult {
138
+ job: Job | null;
139
+ events: JobEvent[];
140
+ loading: boolean;
141
+ }
142
+ export interface UseLaunchpadsResult {
143
+ launchpads: LaunchpadSummary[];
144
+ loading: boolean;
145
+ refresh(): void;
146
+ }
147
+ export interface UseLaunchpadResult {
148
+ launchpad: LaunchpadDetail | null;
149
+ loading: boolean;
150
+ }
151
+ /** Options of `formatSol` (not detailed in CONTRACT.md). */
152
+ export interface FormatSolOptions {
153
+ /** Maximum number of fraction digits. */
154
+ maxFractionDigits?: number;
155
+ /** Append the " SOL" unit. */
156
+ withUnit?: boolean;
157
+ }
158
+ export type OnTxPhase = (phase: TxPhase) => void;
159
+ /** One `data:` line of the `POST /api/chat` event stream (INTERFACES §6). */
160
+ export type ChatStreamEvent = {
161
+ type: 'conversation';
162
+ conversationId: string;
163
+ } | {
164
+ type: 'text';
165
+ delta: string;
166
+ } | {
167
+ type: 'spec';
168
+ spec: LaunchpadSpecDraft;
169
+ validation: SpecValidation;
170
+ } | {
171
+ type: 'error';
172
+ code: ClientErrorCode;
173
+ message: string;
174
+ } | {
175
+ type: 'done';
176
+ };
177
+ /** Every function and hook exported by `apps/web/src/client/` (and by its mocks). */
178
+ export interface WebClient {
179
+ useSession(): UseSessionResult;
180
+ useFlags(): Flags;
181
+ useGating(): UseGatingResult;
182
+ useChat(opts: UseChatOptions): UseChatResult;
183
+ confirmSpec(conversationId: string, spec: LaunchpadSpec): Promise<{
184
+ launchpadId: string;
185
+ jobId: string;
186
+ }>;
187
+ requestModification(launchpadId: string, conversationId: string, request: string): Promise<{
188
+ jobId: string;
189
+ }>;
190
+ getQuote(jobId: string, kind: PaymentKind): Promise<Quote>;
191
+ payQuote(quote: Quote, onPhase: OnTxPhase): Promise<TxResult>;
192
+ useJob(jobId: string): UseJobResult;
193
+ approvePreview(jobId: string): Promise<void>;
194
+ getOwnerTransactionSummary(jobId: string): Promise<OwnerTransactionSummary>;
195
+ signOwnerTransaction(jobId: string, onPhase: OnTxPhase): Promise<TxResult>;
196
+ useLaunchpads(): UseLaunchpadsResult;
197
+ useLaunchpad(id: string): UseLaunchpadResult;
198
+ claimPartnerFees(launchpadId: string, onPhase: OnTxPhase): Promise<TxResult>;
199
+ reactivateLaunchpad(launchpadId: string): Promise<void>;
200
+ /** "Start again" on a refunded draft: the new (or still unpaid) creation job, to pay next. */
201
+ retryLaunchpad(launchpadId: string): Promise<{
202
+ jobId: string;
203
+ }>;
204
+ formatSol(lamports: Lamports, opts?: FormatSolOptions): string;
205
+ formatUsd(n: number): string;
206
+ shortAddress(a: string): string;
207
+ explorerTxUrl(sig: string): string;
208
+ }
209
+ /** Client-facing labels of job statuses. For `failed`, show details according to `failedStage`. */
210
+ export declare const JOB_STATUS_LABELS: Record<JobStatus, string>;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Why "start again" is not available for a refunded draft:
3
+ * - `refund_pending`: money of an earlier attempt is still owed back (refund not recorded, or a
4
+ * payment anomaly waiting for its manual refund);
5
+ * - `payment_pending`: a payment for an earlier attempt may still land or be confirmed;
6
+ * - `needs_support`: the team has to look at it first (on-chain setup recorded, or the limit of
7
+ * refunded creations reached);
8
+ * - `invalid_spec`: the stored blueprint no longer passes the checks (design it again).
9
+ */
10
+ export const START_AGAIN_BLOCKED_REASONS = [
11
+ 'refund_pending',
12
+ 'payment_pending',
13
+ 'needs_support',
14
+ 'invalid_spec',
15
+ ];
16
+ export const CLIENT_ERROR_CODES = [
17
+ 'RATE_LIMITED',
18
+ 'UNAUTHORIZED',
19
+ 'GATING_REQUIRED',
20
+ 'SIGNUPS_PAUSED',
21
+ 'QUOTE_EXPIRED',
22
+ 'WRONG_WALLET',
23
+ 'BETA_NOT_INVITED',
24
+ 'NETWORK',
25
+ ];
26
+ /** Rejection of client functions; `message` is readable by the end user. */
27
+ export class ClientError extends Error {
28
+ code;
29
+ constructor(code, message) {
30
+ super(message);
31
+ this.name = 'ClientError';
32
+ this.code = code;
33
+ }
34
+ }
35
+ export function isClientError(value) {
36
+ return value instanceof ClientError;
37
+ }
38
+ /** Client-facing labels of job statuses. For `failed`, show details according to `failedStage`. */
39
+ export const JOB_STATUS_LABELS = {
40
+ spec_ready: 'Awaiting payment',
41
+ paid: 'Payment received',
42
+ building: 'Building',
43
+ preview_ready: 'Preview ready',
44
+ approved: 'Approved',
45
+ onchain_setup: 'Connecting to Meteora',
46
+ awaiting_owner_signature: 'Your turn to sign the launch',
47
+ owner_signed: 'Launch signed',
48
+ deploying: 'Going live',
49
+ live: 'Live',
50
+ failed: 'Problem',
51
+ refunded: 'Refunded',
52
+ };
package/package.json CHANGED
@@ -1,6 +1,41 @@
1
1
  {
2
2
  "name": "@forgedevv/shared",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.2.0",
4
+ "description": "Shared contracts (constants, zod schemas, types) between all FORGE apps. Published on npm as @forgedevv/shared.",
5
+ "license": "UNLICENSED",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/Forgedevv/Forge.git",
9
+ "directory": "packages/shared"
10
+ },
11
+ "homepage": "https://github.com/Forgedevv/Forge/tree/main/packages/shared#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/Forgedevv/Forge/issues"
14
+ },
15
+ "engines": {
16
+ "node": ">=20"
17
+ },
18
+ "type": "module",
19
+ "sideEffects": false,
20
+ "main": "./dist/index.js",
21
+ "types": "./dist/index.d.ts",
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js"
26
+ },
27
+ "./package.json": "./package.json"
28
+ },
29
+ "files": [
30
+ "dist/**/*.js",
31
+ "dist/**/*.d.ts",
32
+ "!dist/**/*.test.*"
33
+ ],
34
+ "publishConfig": {
35
+ "access": "public",
36
+ "registry": "https://registry.npmjs.org/"
37
+ },
38
+ "dependencies": {
39
+ "zod": "4.6.5"
40
+ }
6
41
  }
package/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Temporary Holding Version
2
-
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.