@fairmint/open-captable-protocol-daml-js 0.2.138 → 0.2.140
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 +3 -257
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,259 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
# open-captable-protocol-daml
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
DAML implementation of the Open Cap Format (OCF) standard on Canton Network.
|
|
4
4
|
|
|
5
|
-
-
|
|
6
|
-
- **Docs folder**: `docs/README.md` (optional; keep minimal)
|
|
7
|
-
|
|
8
|
-
This repository contains multiple DAML packages (e.g., `OpenCapTable-v32`,
|
|
9
|
-
`OpenCapTableReports-v01`, `OpenCapTableProofOfOwnership-v01`, `Shared`, `CantonPayments`). This
|
|
10
|
-
document defines coding guidelines that apply to all packages.
|
|
11
|
-
|
|
12
|
-
For package-specific details about each implementation, see the README.md file in the respective
|
|
13
|
-
package directory (e.g., `open-captable-protocol-daml/OpenCapTable-v32/README.md`).
|
|
14
|
-
|
|
15
|
-
### Global exceptions
|
|
16
|
-
|
|
17
|
-
- We use DAML `Time` instead of schema `Date` (schema excludes time) as a workaround for a
|
|
18
|
-
JavaScript parsing issue.
|
|
19
|
-
|
|
20
|
-
### Implementation guidance
|
|
21
|
-
|
|
22
|
-
- **Non-empty Text values**:
|
|
23
|
-
- Never allow empty `Text` strings. For `Optional Text`, if provided (`Some t`), ensure `t /= ""`.
|
|
24
|
-
- For arrays of `Text`, validate each element is non-empty.
|
|
25
|
-
- **Arrays are non-optional**: Do not omit array fields. When there are no items, emit an empty
|
|
26
|
-
array (`[]`) instead of leaving the field out.
|
|
27
|
-
- **Avoid trivial type aliases**: Do not create semantic aliases for native types (e.g.,
|
|
28
|
-
`type OcfMd5 = Text`). Prefer native types with validators. Example:
|
|
29
|
-
|
|
30
|
-
```daml
|
|
31
|
-
-- MD5
|
|
32
|
-
-- OCF: https://raw.githubusercontent.com/Open-Cap-Table-Coalition/Open-Cap-Format-OCF/main/schema/types/Md5.schema.json
|
|
33
|
-
validateOcfMd5 : Text -> Bool
|
|
34
|
-
validateOcfMd5 md5 =
|
|
35
|
-
let n = Text.length md5 in
|
|
36
|
-
n == 32 && CryptoText.isHex md5
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
- **Shared types and organization**:
|
|
40
|
-
- Define any type used by more than one template in `Types.daml` (with its validator) and import
|
|
41
|
-
where needed.
|
|
42
|
-
- Keep template files focused; if a type is only used by a single template, define it in that
|
|
43
|
-
template file.
|
|
44
|
-
- Do not import a template module solely to access a type; move that type to `Types.daml` instead.
|
|
45
|
-
- Within each record, maintain field ordering for readability:
|
|
46
|
-
1. `id` first
|
|
47
|
-
2. Required scalar fields (alphabetical)
|
|
48
|
-
3. Arrays (alphabetical)
|
|
49
|
-
4. Optional fields (alphabetical)
|
|
50
|
-
- This ordering applies to all types/records (not only top-level transaction objects). If a record
|
|
51
|
-
does not have an `id`, skip step 1 and still follow required → arrays → optional with
|
|
52
|
-
alphabetical ordering within each group.
|
|
53
|
-
- Required refers to types which are not `Optional` or an array. Keep the groups strict and
|
|
54
|
-
correct.
|
|
55
|
-
- Use short section headers and separators to denote these groups exactly as:
|
|
56
|
-
- `-- Required fields (alphabetical)`
|
|
57
|
-
- `-- ---------------------------------`
|
|
58
|
-
- `-- Arrays (alphabetical)`
|
|
59
|
-
- `-- ---------------------------------`
|
|
60
|
-
- `-- Optional fields (alphabetical)`
|
|
61
|
-
- `-- ---------------------------------`
|
|
62
|
-
- **Declaration order in template files**: Place declarations in this order within each template
|
|
63
|
-
file: 1) `template` block first, 2) top-level `data` (the main object record), 3) subtype `data`
|
|
64
|
-
(helper or nested records specific to the template). Keep the two data definitions adjacent.
|
|
65
|
-
- **Validator placement**: Define the validator immediately after the corresponding `data` type it
|
|
66
|
-
validates, in the same file. Example:
|
|
67
|
-
|
|
68
|
-
```daml
|
|
69
|
-
data OcfThing = OcfThing with field: Text deriving (Eq, Show)
|
|
70
|
-
|
|
71
|
-
validateOcfThing : OcfThing -> Bool
|
|
72
|
-
validateOcfThing t = t.field /= ""
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
- **Test helpers**: Place test helpers only in the `Test` package, never in main packages.
|
|
76
|
-
|
|
77
|
-
- **Choice ordering in templates**: When there is no clear logical lifecycle ordering, sort choice
|
|
78
|
-
declarations alphabetically by choice name. As a convention, place create-style choices before
|
|
79
|
-
archive-style choices (e.g., put `ArchiveByIssuer` last).
|
|
80
|
-
|
|
81
|
-
### Package-specific guidance
|
|
82
|
-
|
|
83
|
-
Each package may include additional constraints and domain guidance. Refer to:
|
|
84
|
-
|
|
85
|
-
- `open-captable-protocol-daml/OpenCapTable-v32/README.md` for Open Cap Table specifics (e.g.,
|
|
86
|
-
Issuer management patterns).
|
|
87
|
-
- Other package READMEs as applicable.
|
|
88
|
-
|
|
89
|
-
## Adding Support for New Packages
|
|
90
|
-
|
|
91
|
-
When adding a new DAML package to this repository (e.g., `NewPackage-v01`), follow these steps to
|
|
92
|
-
ensure full integration with the build, deployment, and publishing pipeline:
|
|
93
|
-
|
|
94
|
-
### 1. Create the Package Directory
|
|
95
|
-
|
|
96
|
-
Create a new directory at the root level with your package name and version (e.g.,
|
|
97
|
-
`NewPackage-v01/`).
|
|
98
|
-
|
|
99
|
-
### 2. Set Up Package Structure
|
|
100
|
-
|
|
101
|
-
- Create `daml.yaml` with proper configuration
|
|
102
|
-
- Add your DAML modules under `daml/` directory
|
|
103
|
-
- Create a package-specific `README.md` documenting the package purpose and usage
|
|
104
|
-
|
|
105
|
-
### 3. Update Build Scripts
|
|
106
|
-
|
|
107
|
-
Update the following files to include your new package:
|
|
108
|
-
|
|
109
|
-
#### `package.json`
|
|
110
|
-
|
|
111
|
-
- **codegen script**: Add codegen step for your package in the `codegen` script
|
|
112
|
-
```
|
|
113
|
-
cd NewPackage-v01 && daml codegen js && cd ..
|
|
114
|
-
```
|
|
115
|
-
- **upload-dar script**: Add new script for uploading DAR files
|
|
116
|
-
```json
|
|
117
|
-
"upload-dar:newpackage": "npm run build && ts-node scripts/upload-dar-newpackage.ts --network devnet && ts-node scripts/upload-dar-newpackage.ts --network mainnet"
|
|
118
|
-
```
|
|
119
|
-
- **create-factory script**: Add new script for creating factory contracts
|
|
120
|
-
```json
|
|
121
|
-
"create-factory:newpackage": "npm run codegen && ts-node scripts/create-newpackage-factory.ts --network devnet && ts-node scripts/create-newpackage-factory.ts --network mainnet"
|
|
122
|
-
```
|
|
123
|
-
- **upload-and-create script**: Add combined script
|
|
124
|
-
```json
|
|
125
|
-
"upload-and-create:newpackage": "npm run upload-dar:newpackage && npm run create-factory:newpackage"
|
|
126
|
-
```
|
|
127
|
-
- **exports**: Add export for factory contract ID JSON
|
|
128
|
-
```json
|
|
129
|
-
"./newpackage-factory-contract-id.json": {
|
|
130
|
-
"types": "./generated/newpackage-factory-contract-id.json.d.ts",
|
|
131
|
-
"default": "./generated/newpackage-factory-contract-id.json"
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
- **files**: Add generated files to the npm package
|
|
135
|
-
```json
|
|
136
|
-
"generated/newpackage-factory-contract-id.json",
|
|
137
|
-
"generated/newpackage-factory-contract-id.json.d.ts"
|
|
138
|
-
```
|
|
139
|
-
- **typesVersions**: Add type definitions for JSON imports
|
|
140
|
-
```json
|
|
141
|
-
"newpackage-factory-contract-id.json": [
|
|
142
|
-
"generated/newpackage-factory-contract-id.json.d.ts"
|
|
143
|
-
]
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
#### `scripts/bundle-dependencies.ts`
|
|
147
|
-
|
|
148
|
-
Add your package directory to the `PACKAGE_DIRS` array:
|
|
149
|
-
|
|
150
|
-
```typescript
|
|
151
|
-
const PACKAGE_DIRS = [
|
|
152
|
-
path.join(__dirname, '../generated/js/OpenCapTable-v32-0.0.1'),
|
|
153
|
-
path.join(__dirname, '../generated/js/OpenCapTableReports-v01-0.0.2'),
|
|
154
|
-
path.join(__dirname, '../generated/js/NewPackage-v01-0.0.1'),
|
|
155
|
-
];
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
#### `scripts/create-package-index.ts`
|
|
159
|
-
|
|
160
|
-
Add your package directory to the `packageDirs` array:
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
|
-
const packageDirs = [
|
|
164
|
-
path.join(__dirname, '..', 'generated', 'js', 'OpenCapTable-v32-0.0.1'),
|
|
165
|
-
path.join(__dirname, '..', 'generated', 'js', 'OpenCapTableReports-v01-0.0.2'),
|
|
166
|
-
path.join(__dirname, '..', 'generated', 'js', 'NewPackage-v01-0.0.1'),
|
|
167
|
-
];
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
#### `scripts/create-root-index.ts`
|
|
171
|
-
|
|
172
|
-
1. Add constants for your package directories:
|
|
173
|
-
|
|
174
|
-
```typescript
|
|
175
|
-
const NEWPACKAGE_DIR = path.join(ROOT_DIR, 'generated', 'js', 'NewPackage-v01-0.0.1');
|
|
176
|
-
const NEWPACKAGE_LIB = path.join(NEWPACKAGE_DIR, 'lib');
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
2. Copy your package namespace in `buildCombinedLib()`:
|
|
180
|
-
|
|
181
|
-
```typescript
|
|
182
|
-
copyDir(
|
|
183
|
-
path.join(NEWPACKAGE_LIB, 'Fairmint', 'NewPackage'),
|
|
184
|
-
path.join(destFairmint, 'NewPackage')
|
|
185
|
-
);
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
3. Update Fairmint index files to export your namespace:
|
|
189
|
-
|
|
190
|
-
```typescript
|
|
191
|
-
// In index.js:
|
|
192
|
-
var NewPackage = require('./NewPackage');
|
|
193
|
-
exports.NewPackage = NewPackage;
|
|
194
|
-
|
|
195
|
-
// In index.d.ts:
|
|
196
|
-
export * as NewPackage from './NewPackage';
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
4. Add JSON type definition in `ensureJsonDts()`:
|
|
200
|
-
```typescript
|
|
201
|
-
ensureJson(
|
|
202
|
-
path.join(ROOT_DIR, 'generated', 'newpackage-factory-contract-id.json'),
|
|
203
|
-
path.join(ROOT_DIR, 'generated', 'newpackage-factory-contract-id.json.d.ts'),
|
|
204
|
-
`declare const data: {\n devnet: {\n newpackageFactoryContractId: string;\n templateId: string;\n };\n mainnet: {\n newpackageFactoryContractId: string;\n templateId: string;\n };\n};\nexport default data;\n`
|
|
205
|
-
);
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
### 4. Create Deployment Scripts
|
|
209
|
-
|
|
210
|
-
Create two new scripts in the `scripts/` directory:
|
|
211
|
-
|
|
212
|
-
#### `scripts/upload-dar-newpackage.ts`
|
|
213
|
-
|
|
214
|
-
Upload the DAR file to both devnet and mainnet. Use existing scripts as templates (e.g.,
|
|
215
|
-
`upload-dar-reports.ts`).
|
|
216
|
-
|
|
217
|
-
Key elements:
|
|
218
|
-
|
|
219
|
-
- Parse `--network` argument
|
|
220
|
-
- Upload to both `intellect` and `5n` providers
|
|
221
|
-
- Point to correct DAR file path: `NewPackage-v01/.daml/dist/NewPackage-v01-{version}.dar`
|
|
222
|
-
|
|
223
|
-
#### `scripts/create-newpackage-factory.ts`
|
|
224
|
-
|
|
225
|
-
Create factory contract on both networks. Use existing factory scripts as templates.
|
|
226
|
-
|
|
227
|
-
Key elements:
|
|
228
|
-
|
|
229
|
-
- Import generated DAML types from `../lib`
|
|
230
|
-
- Create factory contract with appropriate arguments
|
|
231
|
-
- Save contract ID to `generated/newpackage-factory-contract-id.json`
|
|
232
|
-
- Include proper error handling and network argument parsing
|
|
233
|
-
|
|
234
|
-
### 5. Test the Integration
|
|
235
|
-
|
|
236
|
-
1. Build DAML packages:
|
|
237
|
-
|
|
238
|
-
```bash
|
|
239
|
-
npm run build
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
2. Generate JavaScript bindings:
|
|
243
|
-
|
|
244
|
-
```bash
|
|
245
|
-
npm run codegen
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
3. Verify generated files exist in `lib/Fairmint/NewPackage/`
|
|
249
|
-
|
|
250
|
-
4. Test deployment scripts:
|
|
251
|
-
```bash
|
|
252
|
-
npm run upload-and-create:newpackage
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
### 6. Update Documentation
|
|
256
|
-
|
|
257
|
-
- Add package to the list in this README's introduction
|
|
258
|
-
- Create package-specific README with domain guidance
|
|
259
|
-
- Document any new contract templates and their usage
|
|
5
|
+
See the [wiki](https://github.com/fairmint/open-captable-protocol-daml/wiki) for full documentation.
|