@strimz/shared-types 0.1.0 → 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.
- package/README.md +66 -36
- package/dist/agents.cjs.map +1 -1
- package/dist/agents.d.cts +1 -1
- package/dist/agents.d.ts +1 -1
- package/dist/agents.js.map +1 -1
- package/dist/api-keys.cjs +8 -3
- package/dist/api-keys.cjs.map +1 -1
- package/dist/api-keys.d.cts +15 -16
- package/dist/api-keys.d.ts +15 -16
- package/dist/api-keys.js +8 -3
- package/dist/api-keys.js.map +1 -1
- package/dist/common.cjs.map +1 -1
- package/dist/common.d.cts +2 -2
- package/dist/common.d.ts +2 -2
- package/dist/common.js.map +1 -1
- package/dist/compliance.cjs.map +1 -1
- package/dist/compliance.d.cts +1 -1
- package/dist/compliance.d.ts +1 -1
- package/dist/compliance.js.map +1 -1
- package/dist/customers.cjs.map +1 -1
- package/dist/customers.d.cts +1 -1
- package/dist/customers.d.ts +1 -1
- package/dist/customers.js.map +1 -1
- package/dist/events.cjs +24 -6
- package/dist/events.cjs.map +1 -1
- package/dist/events.d.cts +12 -12
- package/dist/events.d.ts +12 -12
- package/dist/events.js +24 -6
- package/dist/events.js.map +1 -1
- package/dist/index.cjs +188 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +302 -17
- package/dist/index.d.ts +302 -17
- package/dist/index.js +167 -12
- package/dist/index.js.map +1 -1
- package/dist/invoices.cjs.map +1 -1
- package/dist/invoices.d.cts +1 -1
- package/dist/invoices.d.ts +1 -1
- package/dist/invoices.js.map +1 -1
- package/dist/merchants.cjs +59 -1
- package/dist/merchants.cjs.map +1 -1
- package/dist/merchants.d.cts +171 -1
- package/dist/merchants.d.ts +171 -1
- package/dist/merchants.js +55 -2
- package/dist/merchants.js.map +1 -1
- package/dist/payment-sessions.cjs +6 -2
- package/dist/payment-sessions.cjs.map +1 -1
- package/dist/payment-sessions.d.cts +20 -4
- package/dist/payment-sessions.d.ts +20 -4
- package/dist/payment-sessions.js +6 -3
- package/dist/payment-sessions.js.map +1 -1
- package/dist/refunds.cjs +12 -0
- package/dist/refunds.cjs.map +1 -1
- package/dist/refunds.d.cts +135 -2
- package/dist/refunds.d.ts +135 -2
- package/dist/refunds.js +11 -1
- package/dist/refunds.js.map +1 -1
- package/dist/storefronts.cjs +16 -2
- package/dist/storefronts.cjs.map +1 -1
- package/dist/storefronts.d.cts +38 -2
- package/dist/storefronts.d.ts +38 -2
- package/dist/storefronts.js +15 -3
- package/dist/storefronts.js.map +1 -1
- package/dist/subscriptions.cjs +2 -2
- package/dist/subscriptions.cjs.map +1 -1
- package/dist/subscriptions.d.cts +3 -3
- package/dist/subscriptions.d.ts +3 -3
- package/dist/subscriptions.js +2 -2
- package/dist/subscriptions.js.map +1 -1
- package/dist/transactions.cjs.map +1 -1
- package/dist/transactions.d.cts +2 -2
- package/dist/transactions.d.ts +2 -2
- package/dist/transactions.js.map +1 -1
- package/dist/webhooks.cjs +7 -1
- package/dist/webhooks.cjs.map +1 -1
- package/dist/webhooks.d.cts +63 -4
- package/dist/webhooks.d.ts +63 -4
- package/dist/webhooks.js +7 -2
- package/dist/webhooks.js.map +1 -1
- package/package.json +2 -2
- package/src/agents.ts +1 -1
- package/src/api-keys.ts +9 -5
- package/src/common.ts +2 -2
- package/src/compliance.ts +1 -1
- package/src/contact.ts +26 -0
- package/src/customers.ts +1 -1
- package/src/index.ts +2 -0
- package/src/invoices.ts +1 -1
- package/src/merchants.ts +84 -0
- package/src/notifications.ts +88 -0
- package/src/payment-sessions.ts +25 -3
- package/src/refunds.ts +20 -1
- package/src/storefronts.ts +25 -1
- package/src/subscriptions.ts +3 -3
- package/src/tokens.ts +7 -7
- package/src/transactions.ts +2 -2
- package/src/webhooks.ts +15 -3
package/src/api-keys.ts
CHANGED
|
@@ -12,9 +12,8 @@ export const apiKeyKindSchema = z.enum(['secret', 'publishable'])
|
|
|
12
12
|
export type ApiKeyKind = z.infer<typeof apiKeyKindSchema>
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Underscore-separated
|
|
16
|
-
*
|
|
17
|
-
* same form so there is no boundary translation.
|
|
15
|
+
* Underscore-separated. The wire format and any database representation
|
|
16
|
+
* use the same form so there is no boundary translation.
|
|
18
17
|
*/
|
|
19
18
|
export const apiKeyScopeSchema = z.enum([
|
|
20
19
|
'sessions_read',
|
|
@@ -32,11 +31,16 @@ export const apiKeyScopeSchema = z.enum([
|
|
|
32
31
|
'storefronts_write',
|
|
33
32
|
'agents_read',
|
|
34
33
|
'agents_write',
|
|
35
|
-
// Meta-tx relayer
|
|
34
|
+
// Meta-tx relayer. Submitting payer-signed EIP-3009 / EIP-2612
|
|
36
35
|
// authorizations on the merchant's behalf. Granted to keys used by
|
|
37
36
|
// hosted checkout and merchants embedding the SDK.
|
|
38
37
|
'relay_read',
|
|
39
38
|
'relay_write',
|
|
39
|
+
// Self-service key management from an API key holder. Rarely used
|
|
40
|
+
// day-to-day; needed for partner onboarding flows that mint scoped
|
|
41
|
+
// keys per sub-tenant.
|
|
42
|
+
'api_keys_read',
|
|
43
|
+
'api_keys_write',
|
|
40
44
|
])
|
|
41
45
|
export type ApiKeyScope = z.infer<typeof apiKeyScopeSchema>
|
|
42
46
|
|
|
@@ -67,7 +71,7 @@ export type CreateApiKeyInput = z.infer<typeof createApiKeyInputSchema>
|
|
|
67
71
|
|
|
68
72
|
export const createApiKeyOutputSchema = z.object({
|
|
69
73
|
apiKey: apiKeySchema,
|
|
70
|
-
/** Full plaintext key
|
|
74
|
+
/** Full plaintext key. Shown exactly once. */
|
|
71
75
|
secret: z.string(),
|
|
72
76
|
})
|
|
73
77
|
export type CreateApiKeyOutput = z.infer<typeof createApiKeyOutputSchema>
|
package/src/common.ts
CHANGED
|
@@ -89,7 +89,7 @@ export const metadataSchema = z
|
|
|
89
89
|
export const modeSchema = z.enum(['test', 'live'])
|
|
90
90
|
export type Mode = z.infer<typeof modeSchema>
|
|
91
91
|
|
|
92
|
-
/** Payment token enum
|
|
92
|
+
/** Payment token enum. */
|
|
93
93
|
export const paymentCurrencySchema = z.enum(['USDC', 'EURC'])
|
|
94
94
|
export type PaymentCurrency = z.infer<typeof paymentCurrencySchema>
|
|
95
95
|
|
|
@@ -97,7 +97,7 @@ export type PaymentCurrency = z.infer<typeof paymentCurrencySchema>
|
|
|
97
97
|
export const tokenSymbolSchema = z.enum(['USDC', 'EURC', 'USYC'])
|
|
98
98
|
export type TokenSymbol = z.infer<typeof tokenSymbolSchema>
|
|
99
99
|
|
|
100
|
-
/** Merchant tier enum
|
|
100
|
+
/** Merchant tier enum. */
|
|
101
101
|
export const merchantTierSchema = z.enum(['free', 'growth', 'business', 'enterprise'])
|
|
102
102
|
export type MerchantTier = z.infer<typeof merchantTierSchema>
|
|
103
103
|
|
package/src/compliance.ts
CHANGED
package/src/contact.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public marketing contact form. Not an authenticated API resource —
|
|
3
|
+
* routed straight to a support inbox by the contact module in
|
|
4
|
+
* `apps/api`. Kept shape-compatible with what the marketing form on
|
|
5
|
+
* the Strimz landing page already validates client-side.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { z } from 'zod'
|
|
9
|
+
import { emailSchema } from './common.js'
|
|
10
|
+
|
|
11
|
+
export const contactTopicSchema = z.enum(['sales', 'support', 'partnership', 'security', 'other'])
|
|
12
|
+
export type ContactTopic = z.infer<typeof contactTopicSchema>
|
|
13
|
+
|
|
14
|
+
export const contactRequestInputSchema = z.object({
|
|
15
|
+
name: z.string().min(2).max(120),
|
|
16
|
+
email: emailSchema,
|
|
17
|
+
company: z.string().min(1).max(120).optional(),
|
|
18
|
+
topic: contactTopicSchema,
|
|
19
|
+
message: z.string().min(20).max(4000),
|
|
20
|
+
})
|
|
21
|
+
export type ContactRequestInput = z.infer<typeof contactRequestInputSchema>
|
|
22
|
+
|
|
23
|
+
export const contactRequestOutputSchema = z.object({
|
|
24
|
+
ok: z.literal(true),
|
|
25
|
+
})
|
|
26
|
+
export type ContactRequestOutput = z.infer<typeof contactRequestOutputSchema>
|
package/src/customers.ts
CHANGED
package/src/index.ts
CHANGED
package/src/invoices.ts
CHANGED
package/src/merchants.ts
CHANGED
|
@@ -30,6 +30,8 @@ export const merchantSchema = z.object({
|
|
|
30
30
|
tier: merchantTierSchema,
|
|
31
31
|
status: merchantStatusSchema,
|
|
32
32
|
payoutAddress: evmAddressSchema.nullable(),
|
|
33
|
+
walletAddress: evmAddressSchema.nullable(),
|
|
34
|
+
onboardingCompleted: z.boolean(),
|
|
33
35
|
defaultCurrency: z.enum(['USDC', 'EURC']),
|
|
34
36
|
countryCode: z.string().length(2).nullable(),
|
|
35
37
|
websiteUrl: z.string().url().nullable(),
|
|
@@ -52,6 +54,23 @@ export const createMerchantInputSchema = z.object({
|
|
|
52
54
|
})
|
|
53
55
|
export type CreateMerchantInput = z.infer<typeof createMerchantInputSchema>
|
|
54
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Merchant email opt-outs, persisted at `Merchant.metadata.emailPrefs`.
|
|
59
|
+
* Both default to true. Welcome, refunds, and admin broadcasts always send.
|
|
60
|
+
*/
|
|
61
|
+
export const merchantEmailPrefsSchema = z.object({
|
|
62
|
+
/** "You received X USDC" one-off payment notifications. */
|
|
63
|
+
paymentReceived: z.boolean(),
|
|
64
|
+
/** "You were paid X for subscription Y" per-charge notifications. */
|
|
65
|
+
subscriptionCharged: z.boolean(),
|
|
66
|
+
})
|
|
67
|
+
export type MerchantEmailPrefs = z.infer<typeof merchantEmailPrefsSchema>
|
|
68
|
+
|
|
69
|
+
export const DEFAULT_MERCHANT_EMAIL_PREFS: MerchantEmailPrefs = {
|
|
70
|
+
paymentReceived: true,
|
|
71
|
+
subscriptionCharged: true,
|
|
72
|
+
}
|
|
73
|
+
|
|
55
74
|
export const updateMerchantInputSchema = z
|
|
56
75
|
.object({
|
|
57
76
|
businessName: z.string().min(2).max(120),
|
|
@@ -61,6 +80,7 @@ export const updateMerchantInputSchema = z
|
|
|
61
80
|
logoUrl: z.string().url().nullable(),
|
|
62
81
|
countryCode: z.string().length(2).nullable(),
|
|
63
82
|
metadata: metadataSchema,
|
|
83
|
+
emailPrefs: merchantEmailPrefsSchema.partial(),
|
|
64
84
|
})
|
|
65
85
|
.partial()
|
|
66
86
|
export type UpdateMerchantInput = z.infer<typeof updateMerchantInputSchema>
|
|
@@ -70,6 +90,70 @@ export const changeTierInputSchema = z.object({
|
|
|
70
90
|
})
|
|
71
91
|
export type ChangeTierInput = z.infer<typeof changeTierInputSchema>
|
|
72
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Self-attested onboarding form the dashboard collects after a
|
|
95
|
+
* merchant first logs in via Privy. On success the API stamps
|
|
96
|
+
* `onboardingCompleted: true` on the row, and the dashboard exits
|
|
97
|
+
* the wizard. Shared here so the API's DTO and the web client's
|
|
98
|
+
* hook can enforce the same shape.
|
|
99
|
+
*/
|
|
100
|
+
export const onboardMerchantInputSchema = z.object({
|
|
101
|
+
businessName: z.string().min(2).max(120),
|
|
102
|
+
businessSector: z.string().min(2).max(80),
|
|
103
|
+
countryCode: z
|
|
104
|
+
.string()
|
|
105
|
+
.length(2)
|
|
106
|
+
.regex(/^[A-Z]{2}$/, 'must be a 2-letter ISO country code'),
|
|
107
|
+
websiteUrl: z.string().url().optional(),
|
|
108
|
+
logoUrl: z.string().url().optional(),
|
|
109
|
+
phone: z.string().min(6).max(20).optional(),
|
|
110
|
+
payoutAddress: evmAddressSchema,
|
|
111
|
+
defaultCurrency: z.enum(['USDC', 'EURC']).optional(),
|
|
112
|
+
})
|
|
113
|
+
export type OnboardMerchantInput = z.infer<typeof onboardMerchantInputSchema>
|
|
114
|
+
|
|
115
|
+
export const merchantPublicBrandSchema = z.object({
|
|
116
|
+
id: idSchema,
|
|
117
|
+
businessName: z.string().min(2).max(120),
|
|
118
|
+
logoUrl: z.string().url().nullable(),
|
|
119
|
+
walletAddress: evmAddressSchema.nullable(),
|
|
120
|
+
})
|
|
121
|
+
export type MerchantPublicBrand = z.infer<typeof merchantPublicBrandSchema>
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* On-chain balance view for the withdraw page. Strimz is
|
|
125
|
+
* non-custodial: payments settle directly into the merchant's
|
|
126
|
+
* `payoutAddress`, and "withdrawal" means the merchant transferring
|
|
127
|
+
* out with their own wallet. This shape reports current on-chain
|
|
128
|
+
* state so the dashboard renders live balances + decides whether to
|
|
129
|
+
* offer the signing UI.
|
|
130
|
+
*/
|
|
131
|
+
export const merchantBalanceSchema = z.object({
|
|
132
|
+
/** Payout wallet, checksummed; null when the merchant hasn't set one. */
|
|
133
|
+
payoutAddress: evmAddressSchema.nullable(),
|
|
134
|
+
/** Privy embedded wallet, checksummed if resolvable. */
|
|
135
|
+
walletAddress: evmAddressSchema.nullable(),
|
|
136
|
+
/**
|
|
137
|
+
* True when `payoutAddress === walletAddress`, i.e. the merchant
|
|
138
|
+
* can sign a transfer from the dashboard via Privy. False for
|
|
139
|
+
* merchants using an external wallet as payout — the UI falls back
|
|
140
|
+
* to "copy the address, transfer with your wallet."
|
|
141
|
+
*/
|
|
142
|
+
canSignFromDashboard: z.boolean(),
|
|
143
|
+
balances: z.array(
|
|
144
|
+
z.object({
|
|
145
|
+
currency: z.enum(['USDC', 'EURC']),
|
|
146
|
+
contractAddress: evmAddressSchema,
|
|
147
|
+
/** Base-6 integer as string. */
|
|
148
|
+
raw: z.string(),
|
|
149
|
+
/** Human-formatted, e.g. `1234.56`. */
|
|
150
|
+
formatted: z.string(),
|
|
151
|
+
decimals: z.number().int().min(0).max(30),
|
|
152
|
+
}),
|
|
153
|
+
),
|
|
154
|
+
})
|
|
155
|
+
export type MerchantBalanceView = z.infer<typeof merchantBalanceSchema>
|
|
156
|
+
|
|
73
157
|
// ---------- Team members ----------
|
|
74
158
|
|
|
75
159
|
export const merchantMemberSchema = z.object({
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard notifications. Derived server-side from recent activity
|
|
3
|
+
* (confirmed payment sessions, new subscribers, processed refunds).
|
|
4
|
+
* Read state is tracked on the merchant record via
|
|
5
|
+
* `notificationsLastReadAt` — `event.createdAt <= that timestamp` is
|
|
6
|
+
* "read", anything newer is "unread". No dedicated notifications
|
|
7
|
+
* table because the source rows already exist; a separate table would
|
|
8
|
+
* just be a denormalised copy.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { z } from 'zod'
|
|
12
|
+
import { idSchema, isoTimestampSchema } from './common.js'
|
|
13
|
+
|
|
14
|
+
export const notificationKindSchema = z.enum([
|
|
15
|
+
'payment_received',
|
|
16
|
+
'subscription_started',
|
|
17
|
+
'refund_processed',
|
|
18
|
+
/** Message an admin broadcast to this merchant (or all merchants). */
|
|
19
|
+
'admin_broadcast',
|
|
20
|
+
])
|
|
21
|
+
export type NotificationKind = z.infer<typeof notificationKindSchema>
|
|
22
|
+
|
|
23
|
+
// ---------- Admin broadcasts ----------
|
|
24
|
+
|
|
25
|
+
export const broadcastAudienceSchema = z.enum(['all', 'merchant'])
|
|
26
|
+
export type BroadcastAudience = z.infer<typeof broadcastAudienceSchema>
|
|
27
|
+
|
|
28
|
+
export const createBroadcastInputSchema = z
|
|
29
|
+
.object({
|
|
30
|
+
title: z.string().min(4).max(160),
|
|
31
|
+
body: z.string().min(4).max(4000),
|
|
32
|
+
audience: broadcastAudienceSchema.default('all'),
|
|
33
|
+
/** Required when `audience === 'merchant'`; ignored otherwise. */
|
|
34
|
+
merchantId: z.string().optional(),
|
|
35
|
+
})
|
|
36
|
+
.refine((v) => v.audience !== 'merchant' || !!v.merchantId, {
|
|
37
|
+
message: 'merchantId is required when audience is merchant',
|
|
38
|
+
path: ['merchantId'],
|
|
39
|
+
})
|
|
40
|
+
export type CreateBroadcastInput = z.infer<typeof createBroadcastInputSchema>
|
|
41
|
+
|
|
42
|
+
export const broadcastSchema = z.object({
|
|
43
|
+
id: idSchema,
|
|
44
|
+
title: z.string(),
|
|
45
|
+
body: z.string(),
|
|
46
|
+
audience: broadcastAudienceSchema,
|
|
47
|
+
merchantId: idSchema.nullable(),
|
|
48
|
+
merchantEmail: z.string().nullable(),
|
|
49
|
+
senderId: idSchema,
|
|
50
|
+
senderEmail: z.string(),
|
|
51
|
+
emailedAt: isoTimestampSchema.nullable(),
|
|
52
|
+
createdAt: isoTimestampSchema,
|
|
53
|
+
})
|
|
54
|
+
export type Broadcast = z.infer<typeof broadcastSchema>
|
|
55
|
+
|
|
56
|
+
export const broadcastListResponseSchema = z.object({
|
|
57
|
+
data: z.array(broadcastSchema),
|
|
58
|
+
})
|
|
59
|
+
export type BroadcastListResponse = z.infer<typeof broadcastListResponseSchema>
|
|
60
|
+
|
|
61
|
+
export const notificationSchema = z.object({
|
|
62
|
+
/** Deterministic client id — `{kind}:{sourceId}`. Safe for React keys. */
|
|
63
|
+
id: z.string().min(1),
|
|
64
|
+
kind: notificationKindSchema,
|
|
65
|
+
title: z.string().min(1),
|
|
66
|
+
detail: z.string(),
|
|
67
|
+
/** Dashboard route the tray links to. */
|
|
68
|
+
href: z.string().min(1),
|
|
69
|
+
/** ISO timestamp of the source event; drives sort + read comparison. */
|
|
70
|
+
createdAt: isoTimestampSchema,
|
|
71
|
+
/** Server-derived from the merchant's `notificationsLastReadAt`. */
|
|
72
|
+
read: z.boolean(),
|
|
73
|
+
/** Optional foreign key back to the source row (for deep-linking). */
|
|
74
|
+
sourceId: idSchema.optional(),
|
|
75
|
+
})
|
|
76
|
+
export type NotificationView = z.infer<typeof notificationSchema>
|
|
77
|
+
|
|
78
|
+
export const notificationListResponseSchema = z.object({
|
|
79
|
+
data: z.array(notificationSchema),
|
|
80
|
+
unreadCount: z.number().int().min(0),
|
|
81
|
+
lastReadAt: isoTimestampSchema.nullable(),
|
|
82
|
+
})
|
|
83
|
+
export type NotificationListResponse = z.infer<typeof notificationListResponseSchema>
|
|
84
|
+
|
|
85
|
+
export const markNotificationsReadResponseSchema = z.object({
|
|
86
|
+
lastReadAt: isoTimestampSchema,
|
|
87
|
+
})
|
|
88
|
+
export type MarkNotificationsReadResponse = z.infer<typeof markNotificationsReadResponseSchema>
|
package/src/payment-sessions.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Payment session
|
|
2
|
+
* Payment session. A one-shot checkout intent.
|
|
3
3
|
*
|
|
4
4
|
* State machine:
|
|
5
5
|
* created → awaiting_payment → submitted → confirmed
|
|
@@ -31,6 +31,28 @@ export const paymentSessionStatusSchema = z.enum([
|
|
|
31
31
|
])
|
|
32
32
|
export type PaymentSessionStatus = z.infer<typeof paymentSessionStatusSchema>
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Merchant-supplied callback URL. The hosted checkout dispatches with
|
|
36
|
+
* `window.location.href = redirectUrl` on completion / cancellation,
|
|
37
|
+
* so we MUST reject anything other than `http://` and `https://`.
|
|
38
|
+
*
|
|
39
|
+
* Why this is a real risk: Zod's `.url()` validates RFC syntax, which
|
|
40
|
+
* accepts `javascript:`, `data:`, `vbscript:`, `file:`, blob:`, etc.
|
|
41
|
+
* A compromised merchant integration or an XSS upstream could ship a
|
|
42
|
+
* session whose redirect URL executes script (or exfiltrates session
|
|
43
|
+
* tokens) on every payer's browser. The damage is per-payer, but the
|
|
44
|
+
* blast radius is "every checkout the merchant runs."
|
|
45
|
+
*
|
|
46
|
+
* Mailto / tel and other handler protocols are also rejected — there
|
|
47
|
+
* is no legitimate flow on a payment checkout that would benefit.
|
|
48
|
+
*/
|
|
49
|
+
export const callbackUrlSchema = z
|
|
50
|
+
.string()
|
|
51
|
+
.url()
|
|
52
|
+
.refine((v) => v.startsWith('https://') || v.startsWith('http://'), {
|
|
53
|
+
message: 'must be an http:// or https:// URL',
|
|
54
|
+
})
|
|
55
|
+
|
|
34
56
|
export const paymentSessionSchema = z.object({
|
|
35
57
|
id: idSchema,
|
|
36
58
|
merchantId: idSchema,
|
|
@@ -63,8 +85,8 @@ export const paymentSessionSchema = z.object({
|
|
|
63
85
|
description: z.string().max(500).nullable(),
|
|
64
86
|
payerWalletAddress: evmAddressSchema.nullable(),
|
|
65
87
|
payerEmail: z.string().email().nullable(),
|
|
66
|
-
successUrl:
|
|
67
|
-
cancelUrl:
|
|
88
|
+
successUrl: callbackUrlSchema.nullable(),
|
|
89
|
+
cancelUrl: callbackUrlSchema.nullable(),
|
|
68
90
|
sourceChain: z
|
|
69
91
|
.enum(['arc', 'ethereum', 'base', 'polygon', 'arbitrum', 'optimism', 'avalanche', 'solana'])
|
|
70
92
|
.nullable(),
|
package/src/refunds.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Refund
|
|
2
|
+
* Refund. A merchant-initiated return of funds to a payer.
|
|
3
3
|
*
|
|
4
4
|
* Refunds are executed off-chain (from the merchant's wallet to the payer's
|
|
5
5
|
* wallet). Strimz records the intent, validates constraints, and reconciles
|
|
@@ -66,3 +66,22 @@ export const submitRefundSignatureInputSchema = z.object({
|
|
|
66
66
|
refundTxHash: evmTxHashSchema,
|
|
67
67
|
})
|
|
68
68
|
export type SubmitRefundSignatureInput = z.infer<typeof submitRefundSignatureInputSchema>
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Response envelope for `POST /v1/refunds`. The API returns the newly
|
|
72
|
+
* created refund plus the concrete ERC-20 transfer the merchant now
|
|
73
|
+
* has to sign from their payout wallet.
|
|
74
|
+
*/
|
|
75
|
+
export const refundSigningInstructionsSchema = z.object({
|
|
76
|
+
token: evmAddressSchema,
|
|
77
|
+
to: evmAddressSchema,
|
|
78
|
+
amount: tokenAmountSchema,
|
|
79
|
+
note: z.string(),
|
|
80
|
+
})
|
|
81
|
+
export type RefundSigningInstructions = z.infer<typeof refundSigningInstructionsSchema>
|
|
82
|
+
|
|
83
|
+
export const refundCreateOutputSchema = z.object({
|
|
84
|
+
refund: refundSchema,
|
|
85
|
+
signingInstructions: refundSigningInstructionsSchema,
|
|
86
|
+
})
|
|
87
|
+
export type RefundCreateOutput = z.infer<typeof refundCreateOutputSchema>
|
package/src/storefronts.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Storefronts
|
|
2
|
+
* Storefronts. Hosted product catalog with checkout baked in.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { z } from 'zod'
|
|
@@ -87,3 +87,27 @@ export const createStorefrontProductInputSchema = storefrontProductSchema
|
|
|
87
87
|
imageUrl: httpsUrlSchema.optional(),
|
|
88
88
|
})
|
|
89
89
|
export type CreateStorefrontProductInput = z.infer<typeof createStorefrontProductInputSchema>
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Payload for the public `/store/:slug/products/:id/checkout` endpoint.
|
|
93
|
+
* Optional customer email flows through into the payment session so
|
|
94
|
+
* the receipt lands in the buyer's inbox after the tx confirms.
|
|
95
|
+
* `returnPath` is used to synthesise the success + cancel URLs when
|
|
96
|
+
* the merchant hasn't wired their own.
|
|
97
|
+
*/
|
|
98
|
+
export const storefrontCheckoutInputSchema = z.object({
|
|
99
|
+
customerEmail: z.string().email().optional(),
|
|
100
|
+
returnPath: z.string().max(200).optional(),
|
|
101
|
+
})
|
|
102
|
+
export type StorefrontCheckoutInput = z.infer<typeof storefrontCheckoutInputSchema>
|
|
103
|
+
|
|
104
|
+
/** Response shape from the public product-checkout endpoint. */
|
|
105
|
+
export const storefrontCheckoutResponseSchema = z.object({
|
|
106
|
+
/** Fully-qualified checkout URL — payer redirects here to sign. */
|
|
107
|
+
checkoutUrl: z.string().url(),
|
|
108
|
+
/** Payment-session id (one-time) or plan id (subscription). */
|
|
109
|
+
ref: idSchema,
|
|
110
|
+
/** Which downstream checkout the URL points at. */
|
|
111
|
+
kind: z.enum(['payment_session', 'subscription_plan']),
|
|
112
|
+
})
|
|
113
|
+
export type StorefrontCheckoutResponse = z.infer<typeof storefrontCheckoutResponseSchema>
|
package/src/subscriptions.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Subscriptions
|
|
2
|
+
* Subscriptions: plans, active subscriptions, and individual charges.
|
|
3
3
|
*
|
|
4
4
|
* Design notes:
|
|
5
5
|
* - A SubscriptionPlan is the template a merchant defines.
|
|
@@ -39,7 +39,7 @@ export const subscriptionPlanSchema = z.object({
|
|
|
39
39
|
/**
|
|
40
40
|
* On-chain StrimzRegistry merchant id (uint96) as a decimal string.
|
|
41
41
|
* See `paymentSessionSchema.chainMerchantId`. Null when the merchant
|
|
42
|
-
* hasn't been registered on-chain yet
|
|
42
|
+
* hasn't been registered on-chain yet. The hosted enrolment page
|
|
43
43
|
* refuses to take signatures in that state.
|
|
44
44
|
*/
|
|
45
45
|
chainMerchantId: z
|
|
@@ -47,7 +47,7 @@ export const subscriptionPlanSchema = z.object({
|
|
|
47
47
|
.regex(/^[0-9]+$/u, 'must be a non-negative decimal integer string')
|
|
48
48
|
.nullable(),
|
|
49
49
|
/**
|
|
50
|
-
* ERC-20 token contract address resolved from `currency
|
|
50
|
+
* ERC-20 token contract address resolved from `currency`. This is the
|
|
51
51
|
* EIP-2612 `verifyingContract` the wallet signs over.
|
|
52
52
|
*/
|
|
53
53
|
tokenAddress: evmAddressSchema.nullable(),
|
package/src/tokens.ts
CHANGED
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Read by the SDK's BrowserClient to (1) pick the right meta-tx path
|
|
5
5
|
* for a given token and (2) build the EIP-712 typed-data domain. The
|
|
6
|
-
* shape is
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* shape is derived from on-chain reads. Name and version come from the
|
|
7
|
+
* token's ERC-5267 `eip712Domain()` (falling back to a default), and
|
|
8
|
+
* capabilities come from Strimz's TokenWhitelist contract.
|
|
9
9
|
*
|
|
10
10
|
* `capabilities.permit2612` means the token implements EIP-2612 (the
|
|
11
11
|
* gasless allowance + subscription enrolment path).
|
|
12
12
|
* `capabilities.transferAuth3009` means the token implements EIP-3009
|
|
13
13
|
* (the gasless one-shot payment path).
|
|
14
14
|
*
|
|
15
|
-
* Tokens may have one capability or both
|
|
15
|
+
* Tokens may have one capability or both. USDC and EURC on Arc
|
|
16
16
|
* advertise both.
|
|
17
17
|
*/
|
|
18
18
|
|
|
@@ -34,8 +34,8 @@ export const tokenMetadataSchema = z.object({
|
|
|
34
34
|
symbol: z.string(),
|
|
35
35
|
/**
|
|
36
36
|
* EIP-712 domain version. Read from ERC-5267 `eip712Domain()` when
|
|
37
|
-
* available; otherwise defaults to "1". Used by typed-data builders
|
|
38
|
-
*
|
|
37
|
+
* available; otherwise defaults to "1". Used by typed-data builders.
|
|
38
|
+
* A domain mismatch produces a different digest, so the contract's
|
|
39
39
|
* ecrecover would recover a different address.
|
|
40
40
|
*/
|
|
41
41
|
version: z.string(),
|
|
@@ -46,7 +46,7 @@ export type TokenMetadata = z.infer<typeof tokenMetadataSchema>
|
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* Owner-specific permit nonce. The EIP-2612 standard tracks a per-
|
|
49
|
-
* owner monotonic counter
|
|
49
|
+
* owner monotonic counter, and every successful permit consumes one,
|
|
50
50
|
* so signers must read the current value immediately before signing.
|
|
51
51
|
*
|
|
52
52
|
* Returned as a decimal string to avoid JS number truncation on the
|
package/src/transactions.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Transaction
|
|
2
|
+
* Transaction. The record of a confirmed on-chain payment.
|
|
3
3
|
*
|
|
4
4
|
* Every transaction corresponds to either a paid PaymentSession, a
|
|
5
|
-
* SubscriptionCharge, or a Refund.
|
|
5
|
+
* SubscriptionCharge, or a Refund. Records are derived from the
|
|
6
6
|
* `PaymentExecuted`, `SubscriptionCharged`, and `RefundRecorded` events.
|
|
7
7
|
*/
|
|
8
8
|
|
package/src/webhooks.ts
CHANGED
|
@@ -12,8 +12,8 @@ import { httpsUrlSchema, idSchema, isoTimestampSchema, modeSchema } from './comm
|
|
|
12
12
|
// ---------- Event name ----------
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Every webhook event name in the system. Listed
|
|
16
|
-
*
|
|
15
|
+
* Every webhook event name in the system. Listed inline so Zod can
|
|
16
|
+
* produce a concrete string union.
|
|
17
17
|
*/
|
|
18
18
|
export const webhookEventNameSchema = z.enum([
|
|
19
19
|
'payment.created',
|
|
@@ -71,7 +71,7 @@ export type CreateWebhookEndpointInput = z.infer<typeof createWebhookEndpointInp
|
|
|
71
71
|
|
|
72
72
|
export const createWebhookEndpointOutputSchema = z.object({
|
|
73
73
|
endpoint: webhookEndpointSchema,
|
|
74
|
-
/** Full signing secret
|
|
74
|
+
/** Full signing secret. Shown exactly once. */
|
|
75
75
|
signingSecret: z.string(),
|
|
76
76
|
})
|
|
77
77
|
export type CreateWebhookEndpointOutput = z.infer<typeof createWebhookEndpointOutputSchema>
|
|
@@ -103,6 +103,18 @@ export const webhookDeliverySchema = z.object({
|
|
|
103
103
|
})
|
|
104
104
|
export type WebhookDelivery = z.infer<typeof webhookDeliverySchema>
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Detail projection returned by GET /v1/webhook-deliveries/:id.
|
|
108
|
+
* Carries the payload envelope, response body, and the deliveryId
|
|
109
|
+
* header the receiver saw. Kept separate so list responses stay slim.
|
|
110
|
+
*/
|
|
111
|
+
export const webhookDeliveryDetailSchema = webhookDeliverySchema.extend({
|
|
112
|
+
deliveryId: z.string(),
|
|
113
|
+
responseBody: z.string().nullable(),
|
|
114
|
+
requestPayload: z.record(z.string(), z.unknown()),
|
|
115
|
+
})
|
|
116
|
+
export type WebhookDeliveryDetail = z.infer<typeof webhookDeliveryDetailSchema>
|
|
117
|
+
|
|
106
118
|
export const replayDeliveryInputSchema = z.object({
|
|
107
119
|
id: idSchema,
|
|
108
120
|
})
|