@orangecheck/legal 0.1.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/LICENSE +21 -0
- package/README.md +95 -0
- package/dist/index.d.mts +86 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.js +1980 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1961 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +62 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 OrangeCheck (OCHK)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# @orangecheck/legal
|
|
2
|
+
|
|
3
|
+
Family-internal legal-document engine for the `.ochk.io` sub-sites. **Not for
|
|
4
|
+
third-party integration.**
|
|
5
|
+
|
|
6
|
+
It composes **Terms of Service** and **Privacy Policy** pages from one shared
|
|
7
|
+
clause library plus per-profile content, so the whole family stays in sync
|
|
8
|
+
from a single source of truth — while the commercial products keep the
|
|
9
|
+
variants they genuinely need.
|
|
10
|
+
|
|
11
|
+
## Why this exists
|
|
12
|
+
|
|
13
|
+
The ecosystem outgrew "one Terms page on ochk.io". The non-custodial protocol
|
|
14
|
+
sites, a consumer product that pays users in sats, a paid encrypted vault, and
|
|
15
|
+
an enterprise B2B product cannot share one legal document. This package keeps
|
|
16
|
+
the boilerplate shared and the divergence explicit.
|
|
17
|
+
|
|
18
|
+
## Profiles
|
|
19
|
+
|
|
20
|
+
| Profile | Sites |
|
|
21
|
+
|------------|-------------------------------------------------------------------|
|
|
22
|
+
| `protocol` | ochk.io + the six verb sites + docs + analytics (one shared doc) |
|
|
23
|
+
| `me` | me.ochk.io — consumer identity that pays users in sats |
|
|
24
|
+
| `vault` | vault.ochk.io — paid end-to-end-encrypted secrets vault |
|
|
25
|
+
| `fleet` | fleet.ochk.io — enterprise managed agent infrastructure |
|
|
26
|
+
|
|
27
|
+
The nine `protocol` sites do **not** host their own pages — their footers link
|
|
28
|
+
to ochk.io. Only the three commercial products self-host.
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
// src/pages/terms.tsx on a self-hosting site
|
|
34
|
+
import { buildDoc, LegalDocument } from '@orangecheck/legal';
|
|
35
|
+
import { Seo } from '@/components/layout/Seo';
|
|
36
|
+
|
|
37
|
+
const doc = buildDoc('me', 'terms'); // pure + synchronous
|
|
38
|
+
|
|
39
|
+
export default function TermsPage() {
|
|
40
|
+
return (
|
|
41
|
+
<>
|
|
42
|
+
<Seo title={doc.metaTitle} description={doc.metaDescription} canonical="/terms" />
|
|
43
|
+
<div className="container py-12">
|
|
44
|
+
<LegalDocument doc={doc} />
|
|
45
|
+
</div>
|
|
46
|
+
</>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Tailwind 4 must scan the package so its utility classes emit. In `globals.css`:
|
|
52
|
+
|
|
53
|
+
```css
|
|
54
|
+
@source '../../node_modules/@orangecheck/legal';
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Footer links resolve through one helper:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { legalHref } from '@orangecheck/legal';
|
|
61
|
+
legalHref('me', 'terms'); // → '/terms'
|
|
62
|
+
legalHref('stamp', 'terms'); // → 'https://ochk.io/terms'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Security pages stay bespoke per product but share the disclosure block:
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
import { SecurityDisclosure } from '@orangecheck/legal';
|
|
69
|
+
<SecurityDisclosure securityContact="security@ochk.io" />
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Authoring
|
|
73
|
+
|
|
74
|
+
- Shared clauses live in `src/content/clauses.ts`.
|
|
75
|
+
- Each profile composes them in `src/content/<profile>.ts`.
|
|
76
|
+
- Strings use `[[TOKEN]]` placeholders (`ENTITY`, `PRODUCT`, `HOST`, `CONTACT`,
|
|
77
|
+
`SECURITY_CONTACT`, `GOVERNING_LAW`, `ARBITRATION_SEAT`) resolved by
|
|
78
|
+
`buildDoc`.
|
|
79
|
+
- A `stub` block renders a visible **"pending · counsel review"** notice — used
|
|
80
|
+
for money, custody, refund, SLA, and regulated-activity sections that must be
|
|
81
|
+
finalized by counsel before the commercial products reach general
|
|
82
|
+
availability.
|
|
83
|
+
|
|
84
|
+
### Entity of record
|
|
85
|
+
|
|
86
|
+
No formal legal entity is registered yet. `LEGAL_ENTITY` in `src/constants.ts`
|
|
87
|
+
is the single swap point — set it (and `LEGAL_ENTITY_LONG`) when the entity is
|
|
88
|
+
formed, rebuild, and publish; every document family-wide updates.
|
|
89
|
+
|
|
90
|
+
## Build
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
npm install
|
|
94
|
+
npm run build
|
|
95
|
+
```
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type LegalProfile = 'protocol' | 'me' | 'vault' | 'fleet';
|
|
4
|
+
type DocKind = 'terms' | 'privacy';
|
|
5
|
+
type BulletItem = string | {
|
|
6
|
+
k: string;
|
|
7
|
+
v: string;
|
|
8
|
+
};
|
|
9
|
+
type Block = {
|
|
10
|
+
kind: 'para';
|
|
11
|
+
text: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'subhead';
|
|
14
|
+
text: string;
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'bullets';
|
|
17
|
+
items: BulletItem[];
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'callout';
|
|
20
|
+
text: string;
|
|
21
|
+
emphatic?: boolean;
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'stub';
|
|
24
|
+
text: string;
|
|
25
|
+
};
|
|
26
|
+
interface Section {
|
|
27
|
+
id: string;
|
|
28
|
+
num?: string;
|
|
29
|
+
heading: string;
|
|
30
|
+
hint?: string;
|
|
31
|
+
blocks: Block[];
|
|
32
|
+
}
|
|
33
|
+
interface DocSpec {
|
|
34
|
+
kind: DocKind;
|
|
35
|
+
eyebrow: string;
|
|
36
|
+
title: string;
|
|
37
|
+
description: string;
|
|
38
|
+
metaTitle: string;
|
|
39
|
+
metaDescription: string;
|
|
40
|
+
effective: string;
|
|
41
|
+
updated: string;
|
|
42
|
+
preamble?: Block[];
|
|
43
|
+
sections: Section[];
|
|
44
|
+
summary?: string;
|
|
45
|
+
}
|
|
46
|
+
interface LegalDoc extends DocSpec {
|
|
47
|
+
site: string;
|
|
48
|
+
profile: LegalProfile;
|
|
49
|
+
}
|
|
50
|
+
interface SiteContext {
|
|
51
|
+
slug: string;
|
|
52
|
+
profile: LegalProfile;
|
|
53
|
+
host: string;
|
|
54
|
+
product: string;
|
|
55
|
+
productShort: string;
|
|
56
|
+
contact: string;
|
|
57
|
+
securityContact: string;
|
|
58
|
+
selfHosted: boolean;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
declare function buildDoc(siteSlug: string, kind: DocKind): LegalDoc;
|
|
62
|
+
|
|
63
|
+
interface LegalDocumentProps {
|
|
64
|
+
doc: LegalDoc;
|
|
65
|
+
}
|
|
66
|
+
declare function LegalDocument({ doc }: LegalDocumentProps): react_jsx_runtime.JSX.Element;
|
|
67
|
+
|
|
68
|
+
interface SecurityDisclosureProps {
|
|
69
|
+
securityContact?: string;
|
|
70
|
+
heading?: string | null;
|
|
71
|
+
}
|
|
72
|
+
declare function SecurityDisclosure({ securityContact, heading, }: SecurityDisclosureProps): react_jsx_runtime.JSX.Element;
|
|
73
|
+
|
|
74
|
+
declare const LEGAL_SITES: Record<string, SiteContext>;
|
|
75
|
+
declare const PROTOCOL_LINKED_SITES: readonly ["attest", "lock", "vote", "stamp", "agent", "pledge", "docs", "analytics"];
|
|
76
|
+
declare function getSiteContext(slug: string): SiteContext;
|
|
77
|
+
declare function legalHref(siteSlug: string, kind: 'terms' | 'privacy' | 'security'): string;
|
|
78
|
+
|
|
79
|
+
declare const LEGAL_ENTITY = "OrangeCheck";
|
|
80
|
+
declare const LEGAL_ENTITY_LONG = "OrangeCheck (OCHK), an unincorporated project";
|
|
81
|
+
declare const ENTITY_PENDING = true;
|
|
82
|
+
declare const CONTACT_GENERAL = "hello@ochk.io";
|
|
83
|
+
declare const CONTACT_SECURITY = "security@ochk.io";
|
|
84
|
+
declare const CONTACT_PRIVACY = "hello@ochk.io";
|
|
85
|
+
|
|
86
|
+
export { type Block, type BulletItem, CONTACT_GENERAL, CONTACT_PRIVACY, CONTACT_SECURITY, type DocKind, type DocSpec, ENTITY_PENDING, LEGAL_ENTITY, LEGAL_ENTITY_LONG, LEGAL_SITES, type LegalDoc, LegalDocument, type LegalDocumentProps, type LegalProfile, PROTOCOL_LINKED_SITES, type Section, SecurityDisclosure, type SecurityDisclosureProps, type SiteContext, buildDoc, getSiteContext, legalHref };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
type LegalProfile = 'protocol' | 'me' | 'vault' | 'fleet';
|
|
4
|
+
type DocKind = 'terms' | 'privacy';
|
|
5
|
+
type BulletItem = string | {
|
|
6
|
+
k: string;
|
|
7
|
+
v: string;
|
|
8
|
+
};
|
|
9
|
+
type Block = {
|
|
10
|
+
kind: 'para';
|
|
11
|
+
text: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'subhead';
|
|
14
|
+
text: string;
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'bullets';
|
|
17
|
+
items: BulletItem[];
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'callout';
|
|
20
|
+
text: string;
|
|
21
|
+
emphatic?: boolean;
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'stub';
|
|
24
|
+
text: string;
|
|
25
|
+
};
|
|
26
|
+
interface Section {
|
|
27
|
+
id: string;
|
|
28
|
+
num?: string;
|
|
29
|
+
heading: string;
|
|
30
|
+
hint?: string;
|
|
31
|
+
blocks: Block[];
|
|
32
|
+
}
|
|
33
|
+
interface DocSpec {
|
|
34
|
+
kind: DocKind;
|
|
35
|
+
eyebrow: string;
|
|
36
|
+
title: string;
|
|
37
|
+
description: string;
|
|
38
|
+
metaTitle: string;
|
|
39
|
+
metaDescription: string;
|
|
40
|
+
effective: string;
|
|
41
|
+
updated: string;
|
|
42
|
+
preamble?: Block[];
|
|
43
|
+
sections: Section[];
|
|
44
|
+
summary?: string;
|
|
45
|
+
}
|
|
46
|
+
interface LegalDoc extends DocSpec {
|
|
47
|
+
site: string;
|
|
48
|
+
profile: LegalProfile;
|
|
49
|
+
}
|
|
50
|
+
interface SiteContext {
|
|
51
|
+
slug: string;
|
|
52
|
+
profile: LegalProfile;
|
|
53
|
+
host: string;
|
|
54
|
+
product: string;
|
|
55
|
+
productShort: string;
|
|
56
|
+
contact: string;
|
|
57
|
+
securityContact: string;
|
|
58
|
+
selfHosted: boolean;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
declare function buildDoc(siteSlug: string, kind: DocKind): LegalDoc;
|
|
62
|
+
|
|
63
|
+
interface LegalDocumentProps {
|
|
64
|
+
doc: LegalDoc;
|
|
65
|
+
}
|
|
66
|
+
declare function LegalDocument({ doc }: LegalDocumentProps): react_jsx_runtime.JSX.Element;
|
|
67
|
+
|
|
68
|
+
interface SecurityDisclosureProps {
|
|
69
|
+
securityContact?: string;
|
|
70
|
+
heading?: string | null;
|
|
71
|
+
}
|
|
72
|
+
declare function SecurityDisclosure({ securityContact, heading, }: SecurityDisclosureProps): react_jsx_runtime.JSX.Element;
|
|
73
|
+
|
|
74
|
+
declare const LEGAL_SITES: Record<string, SiteContext>;
|
|
75
|
+
declare const PROTOCOL_LINKED_SITES: readonly ["attest", "lock", "vote", "stamp", "agent", "pledge", "docs", "analytics"];
|
|
76
|
+
declare function getSiteContext(slug: string): SiteContext;
|
|
77
|
+
declare function legalHref(siteSlug: string, kind: 'terms' | 'privacy' | 'security'): string;
|
|
78
|
+
|
|
79
|
+
declare const LEGAL_ENTITY = "OrangeCheck";
|
|
80
|
+
declare const LEGAL_ENTITY_LONG = "OrangeCheck (OCHK), an unincorporated project";
|
|
81
|
+
declare const ENTITY_PENDING = true;
|
|
82
|
+
declare const CONTACT_GENERAL = "hello@ochk.io";
|
|
83
|
+
declare const CONTACT_SECURITY = "security@ochk.io";
|
|
84
|
+
declare const CONTACT_PRIVACY = "hello@ochk.io";
|
|
85
|
+
|
|
86
|
+
export { type Block, type BulletItem, CONTACT_GENERAL, CONTACT_PRIVACY, CONTACT_SECURITY, type DocKind, type DocSpec, ENTITY_PENDING, LEGAL_ENTITY, LEGAL_ENTITY_LONG, LEGAL_SITES, type LegalDoc, LegalDocument, type LegalDocumentProps, type LegalProfile, PROTOCOL_LINKED_SITES, type Section, SecurityDisclosure, type SecurityDisclosureProps, type SiteContext, buildDoc, getSiteContext, legalHref };
|