@loafmarkets/shared-types 1.0.1
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.
- package/README.md +91 -0
- package/dist/index.d.ts +255 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +90 -0
- package/dist/index.js.map +1 -0
- package/package.json +37 -0
- package/proto/trading.proto +172 -0
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# Shared Types
|
|
2
|
+
|
|
3
|
+
Shared contracts (TypeScript interfaces + protobuf schemas) used by the Loaf Markets backend, frontend, and matching engine.
|
|
4
|
+
|
|
5
|
+
## Repository layout
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Shared-Types/
|
|
9
|
+
├── proto/ # trading.proto (matching engine contracts)
|
|
10
|
+
├── src/
|
|
11
|
+
│ └── index.ts # TypeScript schemas and interfaces shared across services
|
|
12
|
+
├── dist/ # Build output (generated via `pnpm run build`)
|
|
13
|
+
├── package.json # npm package settings
|
|
14
|
+
└── tsconfig.json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Getting started
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Install dependencies
|
|
21
|
+
pnpm install
|
|
22
|
+
|
|
23
|
+
# Build once to emit dist/
|
|
24
|
+
pnpm run build
|
|
25
|
+
|
|
26
|
+
# Run type-check only
|
|
27
|
+
pnpm exec tsc --noEmit
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Consuming the package
|
|
31
|
+
|
|
32
|
+
In any Loaf service repo:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pnpm add @loafmarkets/shared-types@<version>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Then import types from TypeScript:
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import type { OrderApiRequestBody, propertySchema } from '@loafmarkets/shared-types';
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
To use the protobuf definition (for gRPC or codegen):
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
node_modules/@loafmarkets/shared-types/proto/trading.proto
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Making changes
|
|
51
|
+
|
|
52
|
+
1. **Modify contracts** in `src/index.ts` (TypeScript) or `proto/trading.proto`.
|
|
53
|
+
2. **Run tests/build** locally:
|
|
54
|
+
```bash
|
|
55
|
+
pnpm run build
|
|
56
|
+
```
|
|
57
|
+
3. **Update version** in `package.json` following semver (e.g., bump patch for backward-compatible additions).
|
|
58
|
+
4. **Document changes** in the commit message or a CHANGELOG entry if you maintain one.
|
|
59
|
+
|
|
60
|
+
## Release process
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# Ensure working tree is clean
|
|
64
|
+
git status
|
|
65
|
+
|
|
66
|
+
# Build artifacts
|
|
67
|
+
pnpm run build
|
|
68
|
+
|
|
69
|
+
# Commit and push
|
|
70
|
+
git commit -am "feat: add XYZ contract"
|
|
71
|
+
git push origin main
|
|
72
|
+
|
|
73
|
+
# Tag the release (match package.json version)
|
|
74
|
+
git tag v<version>
|
|
75
|
+
git push origin v<version>
|
|
76
|
+
|
|
77
|
+
# Publish to registry
|
|
78
|
+
pnpm publish --tag latest
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Once published, update each consumer repository:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pnpm add @loafmarkets/shared-types@<version>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Notes
|
|
88
|
+
|
|
89
|
+
- `dist/` and `node_modules/` should never be committed; they are generated during install/publish.
|
|
90
|
+
- The `prepare` script ensures `pnpm install` (even from Git) builds `dist/`, so consumers always have compiled output.
|
|
91
|
+
- Use Renovate/Dependabot to automate dependency bump PRs in downstream repos.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const MARKET_ORDER_PRICE = 0;
|
|
3
|
+
export declare const ORDER_QUANTITY_MAX_DECIMALS: 8;
|
|
4
|
+
export declare const ORDER_PRICE_MAX_DECIMALS: 2;
|
|
5
|
+
export type OrderSide = 'BUY' | 'SELL';
|
|
6
|
+
export type OrderType = 'MARKET' | 'LIMIT';
|
|
7
|
+
export type OrderStatus = 'PENDING' | 'OPEN' | 'PARTIALLY_FILLED' | 'FILLED' | 'CANCELLED' | 'REJECTED' | 'EXPIRED';
|
|
8
|
+
export type TimeInForce = 'GTC' | 'IOC' | 'FOK' | 'GTD';
|
|
9
|
+
export declare const orderBodySchema: z.ZodObject<{
|
|
10
|
+
propertyId: z.ZodNumber;
|
|
11
|
+
price: z.ZodNumber;
|
|
12
|
+
quantity: z.ZodNumber;
|
|
13
|
+
side: z.ZodEnum<{
|
|
14
|
+
BUY: "BUY";
|
|
15
|
+
SELL: "SELL";
|
|
16
|
+
}>;
|
|
17
|
+
type: z.ZodDefault<z.ZodEnum<{
|
|
18
|
+
MARKET: "MARKET";
|
|
19
|
+
LIMIT: "LIMIT";
|
|
20
|
+
}>>;
|
|
21
|
+
timeInForce: z.ZodDefault<z.ZodEnum<{
|
|
22
|
+
GTC: "GTC";
|
|
23
|
+
IOC: "IOC";
|
|
24
|
+
FOK: "FOK";
|
|
25
|
+
GTD: "GTD";
|
|
26
|
+
}>>;
|
|
27
|
+
expiresAt: z.ZodOptional<z.ZodString>;
|
|
28
|
+
nonce: z.ZodString;
|
|
29
|
+
walletAddress: z.ZodString;
|
|
30
|
+
signature: z.ZodString;
|
|
31
|
+
}, z.core.$strip>;
|
|
32
|
+
export type OrderApiRequestBody = z.infer<typeof orderBodySchema>;
|
|
33
|
+
export declare const sessionSignerOrderBodySchema: z.ZodObject<{
|
|
34
|
+
propertyId: z.ZodNumber;
|
|
35
|
+
price: z.ZodNumber;
|
|
36
|
+
quantity: z.ZodNumber;
|
|
37
|
+
side: z.ZodEnum<{
|
|
38
|
+
BUY: "BUY";
|
|
39
|
+
SELL: "SELL";
|
|
40
|
+
}>;
|
|
41
|
+
type: z.ZodDefault<z.ZodEnum<{
|
|
42
|
+
MARKET: "MARKET";
|
|
43
|
+
LIMIT: "LIMIT";
|
|
44
|
+
}>>;
|
|
45
|
+
timeInForce: z.ZodDefault<z.ZodEnum<{
|
|
46
|
+
GTC: "GTC";
|
|
47
|
+
IOC: "IOC";
|
|
48
|
+
FOK: "FOK";
|
|
49
|
+
GTD: "GTD";
|
|
50
|
+
}>>;
|
|
51
|
+
expiresAt: z.ZodOptional<z.ZodString>;
|
|
52
|
+
nonce: z.ZodString;
|
|
53
|
+
walletAddress: z.ZodString;
|
|
54
|
+
tokenName: z.ZodString;
|
|
55
|
+
}, z.core.$strip>;
|
|
56
|
+
export type SessionSignerOrderRequestBody = z.infer<typeof sessionSignerOrderBodySchema>;
|
|
57
|
+
export interface SessionSignerInfo {
|
|
58
|
+
quorumId: string;
|
|
59
|
+
policyId: string | undefined;
|
|
60
|
+
enabled: boolean;
|
|
61
|
+
}
|
|
62
|
+
export interface SessionSignerStatus {
|
|
63
|
+
enabled: boolean;
|
|
64
|
+
reason?: string;
|
|
65
|
+
}
|
|
66
|
+
export interface OrderApiResponse {
|
|
67
|
+
success: boolean;
|
|
68
|
+
orderId: number;
|
|
69
|
+
errorMessage?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface OrderNonceResponse {
|
|
72
|
+
nonce: string;
|
|
73
|
+
expiresAt: string;
|
|
74
|
+
}
|
|
75
|
+
export declare const cancelOrderBodySchema: z.ZodObject<{
|
|
76
|
+
orderId: z.ZodNumber;
|
|
77
|
+
}, z.core.$strip>;
|
|
78
|
+
export type CancelOrderRequestBody = z.infer<typeof cancelOrderBodySchema>;
|
|
79
|
+
export interface CancelOrderResponse {
|
|
80
|
+
success: boolean;
|
|
81
|
+
orderId: number;
|
|
82
|
+
errorMessage?: string;
|
|
83
|
+
}
|
|
84
|
+
export interface OrderHistoryItem {
|
|
85
|
+
readonly id: number;
|
|
86
|
+
readonly propertyId: number;
|
|
87
|
+
readonly side: OrderSide;
|
|
88
|
+
readonly type: OrderType;
|
|
89
|
+
readonly timeInForce: TimeInForce;
|
|
90
|
+
readonly quantity: number;
|
|
91
|
+
readonly limitPrice: number | null;
|
|
92
|
+
readonly status: OrderStatus;
|
|
93
|
+
readonly filledQuantity: number;
|
|
94
|
+
readonly averageFillPrice: number | null;
|
|
95
|
+
readonly rejectionReason: string | null;
|
|
96
|
+
readonly expiresAt: string | null;
|
|
97
|
+
readonly filledAt: string | null;
|
|
98
|
+
readonly cancelledAt: string | null;
|
|
99
|
+
readonly createdAt: string;
|
|
100
|
+
}
|
|
101
|
+
export interface OrderPositionMetrics {
|
|
102
|
+
readonly propertyId: number;
|
|
103
|
+
readonly netPosition: number;
|
|
104
|
+
readonly averageEntryPrice: number | null;
|
|
105
|
+
readonly realizedPnl: number;
|
|
106
|
+
readonly unrealizedPnl: number;
|
|
107
|
+
readonly totalPnl: number;
|
|
108
|
+
}
|
|
109
|
+
export interface TradeHistoryItem {
|
|
110
|
+
readonly tradeId: number;
|
|
111
|
+
readonly propertyId: number;
|
|
112
|
+
readonly side: OrderSide;
|
|
113
|
+
readonly quantity: number;
|
|
114
|
+
readonly price: number;
|
|
115
|
+
readonly fee: number;
|
|
116
|
+
readonly executedAt: string;
|
|
117
|
+
}
|
|
118
|
+
export interface PortfolioBalance {
|
|
119
|
+
readonly assetType: string;
|
|
120
|
+
readonly available: number;
|
|
121
|
+
readonly frozen: number;
|
|
122
|
+
readonly total: number;
|
|
123
|
+
}
|
|
124
|
+
export interface OrderHistoryResponse {
|
|
125
|
+
readonly orders: readonly OrderHistoryItem[];
|
|
126
|
+
readonly total: number;
|
|
127
|
+
readonly page: number;
|
|
128
|
+
readonly pageSize: number;
|
|
129
|
+
}
|
|
130
|
+
export interface TradeHistoryResponse {
|
|
131
|
+
readonly trades: readonly TradeHistoryItem[];
|
|
132
|
+
readonly total: number;
|
|
133
|
+
readonly page: number;
|
|
134
|
+
readonly pageSize: number;
|
|
135
|
+
}
|
|
136
|
+
export interface PortfolioResponse {
|
|
137
|
+
readonly orderHistory: readonly OrderHistoryItem[];
|
|
138
|
+
readonly tradeHistory: readonly TradeHistoryItem[];
|
|
139
|
+
readonly metrics: readonly OrderPositionMetrics[];
|
|
140
|
+
readonly balances: readonly PortfolioBalance[];
|
|
141
|
+
}
|
|
142
|
+
export interface PriceLevel {
|
|
143
|
+
price: number;
|
|
144
|
+
quantity: number;
|
|
145
|
+
}
|
|
146
|
+
export interface OrderBook {
|
|
147
|
+
property_id: number;
|
|
148
|
+
bids: PriceLevel[];
|
|
149
|
+
asks: PriceLevel[];
|
|
150
|
+
}
|
|
151
|
+
export interface UserProfileResponse {
|
|
152
|
+
readonly userId: string;
|
|
153
|
+
readonly user_type: 'INVESTOR' | 'HOMEOWNER' | 'ADMIN' | 'MARKET_MAKER';
|
|
154
|
+
readonly kycVerified: boolean;
|
|
155
|
+
}
|
|
156
|
+
export declare const propertySchema: z.ZodObject<{
|
|
157
|
+
id: z.ZodNumber;
|
|
158
|
+
tokenName: z.ZodString;
|
|
159
|
+
address: z.ZodString;
|
|
160
|
+
price: z.ZodNumber;
|
|
161
|
+
imageUrl: z.ZodString;
|
|
162
|
+
}, z.core.$strip>;
|
|
163
|
+
export declare const propertyListSchema: z.ZodArray<z.ZodObject<{
|
|
164
|
+
id: z.ZodNumber;
|
|
165
|
+
tokenName: z.ZodString;
|
|
166
|
+
address: z.ZodString;
|
|
167
|
+
price: z.ZodNumber;
|
|
168
|
+
imageUrl: z.ZodString;
|
|
169
|
+
}, z.core.$strip>>;
|
|
170
|
+
export type Property = z.infer<typeof propertySchema>;
|
|
171
|
+
export interface Candle {
|
|
172
|
+
readonly time: number;
|
|
173
|
+
readonly open: number;
|
|
174
|
+
readonly high: number;
|
|
175
|
+
readonly low: number;
|
|
176
|
+
readonly close: number;
|
|
177
|
+
readonly volume?: number;
|
|
178
|
+
}
|
|
179
|
+
export interface PropertyResponse {
|
|
180
|
+
readonly property: Property;
|
|
181
|
+
readonly orderBook: OrderBook | null;
|
|
182
|
+
readonly candlesticks: readonly Candle[];
|
|
183
|
+
}
|
|
184
|
+
interface BaseWebSocketMessage {
|
|
185
|
+
timestamp: string;
|
|
186
|
+
}
|
|
187
|
+
export interface ConnectionMessage extends BaseWebSocketMessage {
|
|
188
|
+
type: 'connection';
|
|
189
|
+
message: string;
|
|
190
|
+
}
|
|
191
|
+
export interface EchoMessage extends BaseWebSocketMessage {
|
|
192
|
+
type: 'echo';
|
|
193
|
+
data: unknown;
|
|
194
|
+
}
|
|
195
|
+
export interface TestMessage extends BaseWebSocketMessage {
|
|
196
|
+
type: 'test';
|
|
197
|
+
message: string;
|
|
198
|
+
}
|
|
199
|
+
export interface ErrorMessage extends BaseWebSocketMessage {
|
|
200
|
+
type: 'error';
|
|
201
|
+
message: string;
|
|
202
|
+
code?: string;
|
|
203
|
+
}
|
|
204
|
+
export interface OrderbookUpdateMessage extends BaseWebSocketMessage {
|
|
205
|
+
type: 'orderbook_update';
|
|
206
|
+
propertyId: number;
|
|
207
|
+
bids: PriceLevel[];
|
|
208
|
+
asks: PriceLevel[];
|
|
209
|
+
}
|
|
210
|
+
export interface OrderStatusMessage extends BaseWebSocketMessage {
|
|
211
|
+
type: 'order_status';
|
|
212
|
+
orderId: number;
|
|
213
|
+
status: OrderStatus;
|
|
214
|
+
}
|
|
215
|
+
export interface MarketDataMessage extends BaseWebSocketMessage {
|
|
216
|
+
type: 'market_data';
|
|
217
|
+
propertyId: number;
|
|
218
|
+
lastPrice: number;
|
|
219
|
+
volume24h: number;
|
|
220
|
+
priceChange24h: number;
|
|
221
|
+
}
|
|
222
|
+
export interface CandleUpdateMessage extends BaseWebSocketMessage {
|
|
223
|
+
type: 'candle_update';
|
|
224
|
+
propertyId: number;
|
|
225
|
+
candle: Candle;
|
|
226
|
+
}
|
|
227
|
+
export interface SubscribeMessage extends BaseWebSocketMessage {
|
|
228
|
+
type: 'subscribe';
|
|
229
|
+
channels: string[];
|
|
230
|
+
}
|
|
231
|
+
export interface UnsubscribeMessage extends BaseWebSocketMessage {
|
|
232
|
+
type: 'unsubscribe';
|
|
233
|
+
channels: string[];
|
|
234
|
+
}
|
|
235
|
+
export interface SubscriptionConfirmMessage extends BaseWebSocketMessage {
|
|
236
|
+
type: 'subscription_confirmed';
|
|
237
|
+
channels: string[];
|
|
238
|
+
}
|
|
239
|
+
export interface PortfolioUpdateMessage extends BaseWebSocketMessage {
|
|
240
|
+
type: 'portfolio_update';
|
|
241
|
+
userId: number;
|
|
242
|
+
totalValue: number;
|
|
243
|
+
totalPnL: number;
|
|
244
|
+
pnLPercentage: number;
|
|
245
|
+
holdings: Array<{
|
|
246
|
+
propertyId: number;
|
|
247
|
+
quantity: number;
|
|
248
|
+
avgPrice: number;
|
|
249
|
+
currentPrice: number;
|
|
250
|
+
pnL: number;
|
|
251
|
+
}>;
|
|
252
|
+
}
|
|
253
|
+
export type WebSocketMessage = ConnectionMessage | EchoMessage | TestMessage | ErrorMessage | OrderbookUpdateMessage | OrderStatusMessage | MarketDataMessage | CandleUpdateMessage | PortfolioUpdateMessage | SubscribeMessage | UnsubscribeMessage | SubscriptionConfirmMessage;
|
|
254
|
+
export {};
|
|
255
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// -----------------------------------------------------------------------------
|
|
3
|
+
// Orders & Trading
|
|
4
|
+
// -----------------------------------------------------------------------------
|
|
5
|
+
export const MARKET_ORDER_PRICE = 0;
|
|
6
|
+
export const ORDER_QUANTITY_MAX_DECIMALS = 8;
|
|
7
|
+
export const ORDER_PRICE_MAX_DECIMALS = 2;
|
|
8
|
+
const orderSideEnum = z.enum(['BUY', 'SELL']);
|
|
9
|
+
const orderTypeEnum = z.enum(['MARKET', 'LIMIT']);
|
|
10
|
+
const timeInForceEnum = z.enum(['GTC', 'IOC', 'FOK', 'GTD']);
|
|
11
|
+
const DECIMAL_SEPARATOR = '.';
|
|
12
|
+
function hasExcessDecimals(value, maxDecimals) {
|
|
13
|
+
const [, fractional = ''] = value.toString().split(DECIMAL_SEPARATOR);
|
|
14
|
+
return fractional.length > maxDecimals;
|
|
15
|
+
}
|
|
16
|
+
const baseOrderSchema = z
|
|
17
|
+
.object({
|
|
18
|
+
propertyId: z.number().int().positive(),
|
|
19
|
+
price: z.number().nonnegative(),
|
|
20
|
+
quantity: z.number().positive(),
|
|
21
|
+
side: orderSideEnum,
|
|
22
|
+
type: orderTypeEnum.default('MARKET'),
|
|
23
|
+
timeInForce: timeInForceEnum.default('GTC'),
|
|
24
|
+
expiresAt: z.string().optional(),
|
|
25
|
+
nonce: z.string(),
|
|
26
|
+
walletAddress: z.string(),
|
|
27
|
+
})
|
|
28
|
+
.superRefine((data, ctx) => {
|
|
29
|
+
// LIMIT orders must have a positive price
|
|
30
|
+
if (data.type === 'LIMIT' && (typeof data.price !== 'number' || data.price <= 0)) {
|
|
31
|
+
ctx.addIssue({
|
|
32
|
+
code: 'custom',
|
|
33
|
+
message: 'Limit orders require a positive price',
|
|
34
|
+
path: ['price'],
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
// MARKET orders must have price = MARKET_ORDER_PRICE
|
|
38
|
+
if (data.type === 'MARKET' && data.price !== MARKET_ORDER_PRICE) {
|
|
39
|
+
ctx.addIssue({
|
|
40
|
+
code: 'custom',
|
|
41
|
+
message: `Market orders must have price = ${MARKET_ORDER_PRICE}`,
|
|
42
|
+
path: ['price'],
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
// GTD requires expiresAt
|
|
46
|
+
if (data.timeInForce === 'GTD' && !data.expiresAt) {
|
|
47
|
+
ctx.addIssue({
|
|
48
|
+
code: 'custom',
|
|
49
|
+
message: 'GTD orders require an expiration timestamp',
|
|
50
|
+
path: ['expiresAt'],
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
if (hasExcessDecimals(data.quantity, ORDER_QUANTITY_MAX_DECIMALS)) {
|
|
54
|
+
ctx.addIssue({
|
|
55
|
+
code: 'custom',
|
|
56
|
+
message: `Quantity must have at most ${ORDER_QUANTITY_MAX_DECIMALS} decimal places`,
|
|
57
|
+
path: ['quantity'],
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (data.type === 'LIMIT' && hasExcessDecimals(data.price, ORDER_PRICE_MAX_DECIMALS)) {
|
|
61
|
+
ctx.addIssue({
|
|
62
|
+
code: 'custom',
|
|
63
|
+
message: `Limit price must have at most ${ORDER_PRICE_MAX_DECIMALS} decimal places`,
|
|
64
|
+
path: ['price'],
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
// Schema for orders signed client-side (signature provided in request)
|
|
69
|
+
export const orderBodySchema = baseOrderSchema.safeExtend({
|
|
70
|
+
signature: z.string(),
|
|
71
|
+
});
|
|
72
|
+
// Schema for orders signed server-side via session signer
|
|
73
|
+
export const sessionSignerOrderBodySchema = baseOrderSchema.safeExtend({
|
|
74
|
+
tokenName: z.string(),
|
|
75
|
+
});
|
|
76
|
+
export const cancelOrderBodySchema = z.object({
|
|
77
|
+
orderId: z.number().int().positive(),
|
|
78
|
+
});
|
|
79
|
+
// -----------------------------------------------------------------------------
|
|
80
|
+
// Properties
|
|
81
|
+
// -----------------------------------------------------------------------------
|
|
82
|
+
export const propertySchema = z.object({
|
|
83
|
+
id: z.number().int(),
|
|
84
|
+
tokenName: z.string(),
|
|
85
|
+
address: z.string(),
|
|
86
|
+
price: z.number(),
|
|
87
|
+
imageUrl: z.string(),
|
|
88
|
+
});
|
|
89
|
+
export const propertyListSchema = z.array(propertySchema);
|
|
90
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@loafmarkets/shared-types",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Shared contracts for Loaf Markets frontend, backend, and matching engine.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"private": false,
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./proto/trading.proto": "./proto/trading.proto"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"proto"
|
|
19
|
+
],
|
|
20
|
+
"keywords": [],
|
|
21
|
+
"author": "Cohen",
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"zod": "^4.2.1"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^25.0.3",
|
|
27
|
+
"rimraf": "^6.1.2",
|
|
28
|
+
"typescript": "^5.9.3"
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsc -p tsconfig.json",
|
|
35
|
+
"clean": "rimraf dist"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package loaf.trading;
|
|
4
|
+
|
|
5
|
+
// Order message
|
|
6
|
+
message Order {
|
|
7
|
+
uint64 order_id = 1;
|
|
8
|
+
uint32 user_id = 2;
|
|
9
|
+
uint32 property_id = 3;
|
|
10
|
+
uint64 price = 4;
|
|
11
|
+
uint32 quantity = 5;
|
|
12
|
+
OrderSide side = 6;
|
|
13
|
+
OrderType type = 7;
|
|
14
|
+
TimeInForce time_in_force = 8;
|
|
15
|
+
string expires_at = 9;
|
|
16
|
+
string signature = 10;
|
|
17
|
+
string wallet_address = 11;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
enum OrderSide {
|
|
21
|
+
BUY = 0;
|
|
22
|
+
SELL = 1;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
enum OrderType {
|
|
26
|
+
MARKET = 0;
|
|
27
|
+
LIMIT = 1;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
enum TimeInForce {
|
|
31
|
+
GTC = 0;
|
|
32
|
+
IOC = 1;
|
|
33
|
+
FOK = 2;
|
|
34
|
+
GTD = 3;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// enum OrderStatus {
|
|
38
|
+
// PENDING = 0;
|
|
39
|
+
// PARTIALLY_FILLED = 1;
|
|
40
|
+
// FILLED = 2;
|
|
41
|
+
// CANCELLED = 3;
|
|
42
|
+
// REJECTED = 4;
|
|
43
|
+
// }
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
// Trade execution
|
|
47
|
+
message TradeExecution {
|
|
48
|
+
uint64 trade_id = 1;
|
|
49
|
+
uint64 buy_order_id = 2;
|
|
50
|
+
uint64 sell_order_id = 3;
|
|
51
|
+
uint32 property_id = 4;
|
|
52
|
+
string property_token_address = 5;
|
|
53
|
+
double price = 6;
|
|
54
|
+
double quantity = 7;
|
|
55
|
+
double fee_amount = 8;
|
|
56
|
+
string buyer_wallet = 9;
|
|
57
|
+
string seller_wallet = 10;
|
|
58
|
+
OrderSide side = 11;
|
|
59
|
+
int64 timestamp = 12;
|
|
60
|
+
int64 deadline = 13;
|
|
61
|
+
string buyer_signature = 14;
|
|
62
|
+
string seller_signature = 15;
|
|
63
|
+
string cpp_signature = 16;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Order book
|
|
67
|
+
message PriceLevel {
|
|
68
|
+
double price = 1;
|
|
69
|
+
double quantity = 2;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
message OrderBookSnapshot {
|
|
73
|
+
uint32 property_id = 1;
|
|
74
|
+
repeated PriceLevel bids = 2;
|
|
75
|
+
repeated PriceLevel asks = 3;
|
|
76
|
+
repeated uint64 cancelled_order_ids = 4;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Quote book
|
|
80
|
+
message QuoteLevel {
|
|
81
|
+
OrderSide side = 1;
|
|
82
|
+
OrderType type = 2;
|
|
83
|
+
uint64 price = 3;
|
|
84
|
+
uint32 quantity = 4;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
message QuoteBook {
|
|
88
|
+
uint32 property_id = 1;
|
|
89
|
+
repeated QuoteLevel bids = 2;
|
|
90
|
+
repeated QuoteLevel asks = 3;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
// --------------------------------------------------------------
|
|
95
|
+
// Service 1: OrderService (for Node.js Backend)
|
|
96
|
+
// --------------------------------------------------------------
|
|
97
|
+
|
|
98
|
+
service OrderService {
|
|
99
|
+
rpc SubmitOrder(SubmitOrderRequest) returns (SubmitOrderResponse);
|
|
100
|
+
rpc CancelOrder(CancelOrderRequest) returns (CancelOrderResponse);
|
|
101
|
+
rpc GetOrderStatus(GetOrderStatusRequest) returns (Order);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
message SubmitOrderRequest {
|
|
105
|
+
uint32 user_id = 1;
|
|
106
|
+
uint32 property_id = 2;
|
|
107
|
+
uint64 price = 3;
|
|
108
|
+
uint32 quantity = 4;
|
|
109
|
+
OrderSide side = 5;
|
|
110
|
+
OrderType type = 6;
|
|
111
|
+
TimeInForce time_in_force = 7;
|
|
112
|
+
string expires_at = 8;
|
|
113
|
+
uint64 order_id = 9;
|
|
114
|
+
string signature = 10;
|
|
115
|
+
string wallet_address = 11;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
message SubmitOrderResponse {
|
|
119
|
+
bool success = 1;
|
|
120
|
+
uint64 order_id = 2;
|
|
121
|
+
string error_message = 3;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
message GetOrderStatusRequest {
|
|
125
|
+
// string order_id = 1;
|
|
126
|
+
// string user_id = 2;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
message CancelOrderRequest {
|
|
130
|
+
uint64 order_id = 1;
|
|
131
|
+
uint32 property_id = 2;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
message CancelOrderResponse {
|
|
135
|
+
bool success = 1;
|
|
136
|
+
uint64 order_id = 2;
|
|
137
|
+
string error_message = 3;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// --------------------------------------------------------------
|
|
141
|
+
// Service 2: TradingService (for Market Maker)
|
|
142
|
+
// --------------------------------------------------------------
|
|
143
|
+
|
|
144
|
+
// service TradingService {
|
|
145
|
+
// rpc StreamTradingData(stream MarketMakerMessage) returns (stream EngineMessage);
|
|
146
|
+
// }
|
|
147
|
+
|
|
148
|
+
// message MarketMakerMessage {
|
|
149
|
+
// oneof message {
|
|
150
|
+
// MarketMakerRegistration registration = 1;
|
|
151
|
+
// Quote quote = 2;
|
|
152
|
+
// TradeAck trade_ack = 3;
|
|
153
|
+
// }
|
|
154
|
+
// }
|
|
155
|
+
|
|
156
|
+
// message EngineMessage {
|
|
157
|
+
// oneof message {
|
|
158
|
+
// Order order = 1;
|
|
159
|
+
// TradeExecution trade_execution = 2;
|
|
160
|
+
// }
|
|
161
|
+
// }
|
|
162
|
+
|
|
163
|
+
// message MarketMakerRegistration {
|
|
164
|
+
// string market_maker_id = 1;
|
|
165
|
+
// repeated string property_ids = 2;
|
|
166
|
+
// }
|
|
167
|
+
|
|
168
|
+
// message TradeAck {
|
|
169
|
+
// string trade_id = 1;
|
|
170
|
+
// bool acknowledged = 2;
|
|
171
|
+
// string error_message = 3;
|
|
172
|
+
// }
|