@fairmint/open-captable-protocol-daml-js 0.2.96 → 0.2.97
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 +63 -25
- package/package.json +56 -40
package/README.md
CHANGED
|
@@ -5,21 +5,27 @@
|
|
|
5
5
|
- **Start here**: `llms.txt`
|
|
6
6
|
- **Docs folder**: `docs/README.md` (optional; keep minimal)
|
|
7
7
|
|
|
8
|
-
This repository contains multiple DAML packages (e.g., `OpenCapTable-v26`,
|
|
8
|
+
This repository contains multiple DAML packages (e.g., `OpenCapTable-v26`,
|
|
9
|
+
`OpenCapTableReports-v01`, `OpenCapTableProofOfOwnership-v01`, `Shared`, `CantonPayments`). This
|
|
10
|
+
document defines coding guidelines that apply to all packages.
|
|
9
11
|
|
|
10
|
-
For package-specific details about each implementation, see the README.md file in the respective
|
|
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-v26/README.md`).
|
|
11
14
|
|
|
12
15
|
### Global exceptions
|
|
13
16
|
|
|
14
|
-
- We use DAML `Time` instead of schema `Date` (schema excludes time) as a workaround for a
|
|
17
|
+
- We use DAML `Time` instead of schema `Date` (schema excludes time) as a workaround for a
|
|
18
|
+
JavaScript parsing issue.
|
|
15
19
|
|
|
16
20
|
### Implementation guidance
|
|
17
|
-
|
|
21
|
+
|
|
18
22
|
- **Non-empty Text values**:
|
|
19
23
|
- Never allow empty `Text` strings. For `Optional Text`, if provided (`Some t`), ensure `t /= ""`.
|
|
20
24
|
- For arrays of `Text`, validate each element is non-empty.
|
|
21
|
-
- **Arrays are non-optional**: Do not omit array fields. When there are no items, emit an empty
|
|
22
|
-
|
|
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:
|
|
23
29
|
|
|
24
30
|
```daml
|
|
25
31
|
-- MD5
|
|
@@ -29,17 +35,23 @@ validateOcfMd5 md5 =
|
|
|
29
35
|
let n = Text.length md5 in
|
|
30
36
|
n == 32 && CryptoText.isHex md5
|
|
31
37
|
```
|
|
38
|
+
|
|
32
39
|
- **Shared types and organization**:
|
|
33
|
-
- Define any type used by more than one template in `Types.daml` (with its validator) and import
|
|
34
|
-
|
|
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.
|
|
35
44
|
- Do not import a template module solely to access a type; move that type to `Types.daml` instead.
|
|
36
45
|
- Within each record, maintain field ordering for readability:
|
|
37
|
-
1
|
|
38
|
-
2
|
|
39
|
-
3
|
|
40
|
-
4
|
|
41
|
-
- This ordering applies to all types/records (not only top-level transaction objects). If a record
|
|
42
|
-
|
|
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.
|
|
43
55
|
- Use short section headers and separators to denote these groups exactly as:
|
|
44
56
|
- `-- Required fields (alphabetical)`
|
|
45
57
|
- `-- ---------------------------------`
|
|
@@ -47,8 +59,11 @@ validateOcfMd5 md5 =
|
|
|
47
59
|
- `-- ---------------------------------`
|
|
48
60
|
- `-- Optional fields (alphabetical)`
|
|
49
61
|
- `-- ---------------------------------`
|
|
50
|
-
|
|
51
|
-
|
|
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:
|
|
52
67
|
|
|
53
68
|
```daml
|
|
54
69
|
data OcfThing = OcfThing with field: Text deriving (Eq, Show)
|
|
@@ -56,24 +71,30 @@ data OcfThing = OcfThing with field: Text deriving (Eq, Show)
|
|
|
56
71
|
validateOcfThing : OcfThing -> Bool
|
|
57
72
|
validateOcfThing t = t.field /= ""
|
|
58
73
|
```
|
|
74
|
+
|
|
59
75
|
- **Test helpers**: Place test helpers only in the `Test` package, never in main packages.
|
|
60
76
|
|
|
61
|
-
- **Choice ordering in templates**: When there is no clear logical lifecycle ordering, sort choice
|
|
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).
|
|
62
80
|
|
|
63
81
|
### Package-specific guidance
|
|
64
82
|
|
|
65
83
|
Each package may include additional constraints and domain guidance. Refer to:
|
|
66
84
|
|
|
67
|
-
- `open-captable-protocol-daml/OpenCapTable-v26/README.md` for Open Cap Table specifics (e.g.,
|
|
85
|
+
- `open-captable-protocol-daml/OpenCapTable-v26/README.md` for Open Cap Table specifics (e.g.,
|
|
86
|
+
Issuer management patterns).
|
|
68
87
|
- Other package READMEs as applicable.
|
|
69
88
|
|
|
70
89
|
## Adding Support for New Packages
|
|
71
90
|
|
|
72
|
-
When adding a new DAML package to this repository (e.g., `NewPackage-v01`), follow these steps to
|
|
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:
|
|
73
93
|
|
|
74
94
|
### 1. Create the Package Directory
|
|
75
95
|
|
|
76
|
-
Create a new directory at the root level with your package name and version (e.g.,
|
|
96
|
+
Create a new directory at the root level with your package name and version (e.g.,
|
|
97
|
+
`NewPackage-v01/`).
|
|
77
98
|
|
|
78
99
|
### 2. Set Up Package Structure
|
|
79
100
|
|
|
@@ -86,6 +107,7 @@ Create a new directory at the root level with your package name and version (e.g
|
|
|
86
107
|
Update the following files to include your new package:
|
|
87
108
|
|
|
88
109
|
#### `package.json`
|
|
110
|
+
|
|
89
111
|
- **codegen script**: Add codegen step for your package in the `codegen` script
|
|
90
112
|
```
|
|
91
113
|
cd NewPackage-v01 && daml codegen js && cd ..
|
|
@@ -122,7 +144,9 @@ Update the following files to include your new package:
|
|
|
122
144
|
```
|
|
123
145
|
|
|
124
146
|
#### `scripts/bundle-dependencies.ts`
|
|
147
|
+
|
|
125
148
|
Add your package directory to the `PACKAGE_DIRS` array:
|
|
149
|
+
|
|
126
150
|
```typescript
|
|
127
151
|
const PACKAGE_DIRS = [
|
|
128
152
|
path.join(__dirname, '../generated/js/OpenCapTable-v26-0.0.1'),
|
|
@@ -132,7 +156,9 @@ const PACKAGE_DIRS = [
|
|
|
132
156
|
```
|
|
133
157
|
|
|
134
158
|
#### `scripts/create-package-index.ts`
|
|
159
|
+
|
|
135
160
|
Add your package directory to the `packageDirs` array:
|
|
161
|
+
|
|
136
162
|
```typescript
|
|
137
163
|
const packageDirs = [
|
|
138
164
|
path.join(__dirname, '..', 'generated', 'js', 'OpenCapTable-v26-0.0.1'),
|
|
@@ -142,23 +168,30 @@ const packageDirs = [
|
|
|
142
168
|
```
|
|
143
169
|
|
|
144
170
|
#### `scripts/create-root-index.ts`
|
|
171
|
+
|
|
145
172
|
1. Add constants for your package directories:
|
|
173
|
+
|
|
146
174
|
```typescript
|
|
147
175
|
const NEWPACKAGE_DIR = path.join(ROOT_DIR, 'generated', 'js', 'NewPackage-v01-0.0.1');
|
|
148
176
|
const NEWPACKAGE_LIB = path.join(NEWPACKAGE_DIR, 'lib');
|
|
149
177
|
```
|
|
150
178
|
|
|
151
179
|
2. Copy your package namespace in `buildCombinedLib()`:
|
|
180
|
+
|
|
152
181
|
```typescript
|
|
153
|
-
copyDir(
|
|
182
|
+
copyDir(
|
|
183
|
+
path.join(NEWPACKAGE_LIB, 'Fairmint', 'NewPackage'),
|
|
184
|
+
path.join(destFairmint, 'NewPackage')
|
|
185
|
+
);
|
|
154
186
|
```
|
|
155
187
|
|
|
156
188
|
3. Update Fairmint index files to export your namespace:
|
|
189
|
+
|
|
157
190
|
```typescript
|
|
158
191
|
// In index.js:
|
|
159
192
|
var NewPackage = require('./NewPackage');
|
|
160
193
|
exports.NewPackage = NewPackage;
|
|
161
|
-
|
|
194
|
+
|
|
162
195
|
// In index.d.ts:
|
|
163
196
|
export * as NewPackage from './NewPackage';
|
|
164
197
|
```
|
|
@@ -177,17 +210,22 @@ const packageDirs = [
|
|
|
177
210
|
Create two new scripts in the `scripts/` directory:
|
|
178
211
|
|
|
179
212
|
#### `scripts/upload-dar-newpackage.ts`
|
|
180
|
-
|
|
213
|
+
|
|
214
|
+
Upload the DAR file to both devnet and mainnet. Use existing scripts as templates (e.g.,
|
|
215
|
+
`upload-dar-reports.ts`).
|
|
181
216
|
|
|
182
217
|
Key elements:
|
|
218
|
+
|
|
183
219
|
- Parse `--network` argument
|
|
184
220
|
- Upload to both `intellect` and `5n` providers
|
|
185
221
|
- Point to correct DAR file path: `NewPackage-v01/.daml/dist/NewPackage-v01-{version}.dar`
|
|
186
222
|
|
|
187
223
|
#### `scripts/create-newpackage-factory.ts`
|
|
224
|
+
|
|
188
225
|
Create factory contract on both networks. Use existing factory scripts as templates.
|
|
189
226
|
|
|
190
227
|
Key elements:
|
|
228
|
+
|
|
191
229
|
- Import generated DAML types from `../lib`
|
|
192
230
|
- Create factory contract with appropriate arguments
|
|
193
231
|
- Save contract ID to `generated/newpackage-factory-contract-id.json`
|
|
@@ -196,11 +234,13 @@ Key elements:
|
|
|
196
234
|
### 5. Test the Integration
|
|
197
235
|
|
|
198
236
|
1. Build DAML packages:
|
|
237
|
+
|
|
199
238
|
```bash
|
|
200
239
|
npm run build
|
|
201
240
|
```
|
|
202
241
|
|
|
203
242
|
2. Generate JavaScript bindings:
|
|
243
|
+
|
|
204
244
|
```bash
|
|
205
245
|
npm run codegen
|
|
206
246
|
```
|
|
@@ -217,5 +257,3 @@ Key elements:
|
|
|
217
257
|
- Add package to the list in this README's introduction
|
|
218
258
|
- Create package-specific README with domain guidance
|
|
219
259
|
- Document any new contract templates and their usage
|
|
220
|
-
|
|
221
|
-
|
package/package.json
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fairmint/open-captable-protocol-daml-js",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.97",
|
|
4
4
|
"description": "Open CapTable Protocol DAML smart contracts with generated JavaScript bindings.",
|
|
5
|
-
"
|
|
6
|
-
|
|
5
|
+
"keywords": [
|
|
6
|
+
"daml",
|
|
7
|
+
"opencaptable",
|
|
8
|
+
"blockchain",
|
|
9
|
+
"smart-contracts",
|
|
10
|
+
"fairmint"
|
|
11
|
+
],
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "git+https://github.com/fairmint/open-captable-protocol-daml.git"
|
|
15
|
+
},
|
|
16
|
+
"license": "UNLICENSED",
|
|
17
|
+
"author": "Fairmint",
|
|
7
18
|
"exports": {
|
|
8
19
|
".": {
|
|
9
20
|
"types": "./lib/index.d.ts",
|
|
@@ -27,6 +38,21 @@
|
|
|
27
38
|
"default": "./generated/paymentStreams-factory-contract-id.json"
|
|
28
39
|
}
|
|
29
40
|
},
|
|
41
|
+
"main": "lib/index.js",
|
|
42
|
+
"types": "lib/index.d.ts",
|
|
43
|
+
"typesVersions": {
|
|
44
|
+
"*": {
|
|
45
|
+
"ocp-factory-contract-id.json": [
|
|
46
|
+
"generated/ocp-factory-contract-id.json.d.ts"
|
|
47
|
+
],
|
|
48
|
+
"reports-factory-contract-id.json": [
|
|
49
|
+
"generated/reports-factory-contract-id.json.d.ts"
|
|
50
|
+
],
|
|
51
|
+
"paymentStreams-factory-contract-id.json": [
|
|
52
|
+
"generated/paymentStreams-factory-contract-id.json.d.ts"
|
|
53
|
+
]
|
|
54
|
+
}
|
|
55
|
+
},
|
|
30
56
|
"files": [
|
|
31
57
|
"lib/**",
|
|
32
58
|
"generated/ocp-factory-contract-id.json",
|
|
@@ -38,25 +64,30 @@
|
|
|
38
64
|
"OpenCapTable-v26/.daml/dist/OpenCapTable-v26-0.0.1.dar"
|
|
39
65
|
],
|
|
40
66
|
"scripts": {
|
|
67
|
+
"backup-dar": "tsx scripts/backup-dar.ts",
|
|
41
68
|
"build": "tsx scripts/codegen/generate-captable.ts && daml build --all",
|
|
42
69
|
"build:ts": "tsc",
|
|
43
70
|
"clean": "daml clean --all",
|
|
44
71
|
"codegen": "npm run build && cd OpenCapTable-v26 && daml codegen js && cd .. && cd Shared && daml codegen js && cd .. && cd OpenCapTableReports-v01 && daml codegen js && cd .. && cd CantonPayments && daml codegen js && cd .. && tsx scripts/bundle-dependencies.ts && tsx scripts/create-package-index.ts && tsx scripts/create-root-index.ts && tsx scripts/fix-splice-refs.ts && npm run build:ts",
|
|
45
|
-
"
|
|
46
|
-
"test:imports": "tsx scripts/test-imports.ts",
|
|
47
|
-
"backup-dar": "tsx scripts/backup-dar.ts",
|
|
48
|
-
"verify-dars": "tsx scripts/verify-dars.ts",
|
|
49
|
-
"upload-dar": "tsx scripts/upload-dar.ts",
|
|
72
|
+
"create-couponMinter": "tsx scripts/create-couponMinter.ts",
|
|
50
73
|
"create-factory:ocp": "npm run codegen && tsx scripts/create-ocp-factory.ts --network devnet && tsx scripts/create-ocp-factory.ts --network mainnet",
|
|
51
|
-
"create-factory:reports": "npm run codegen && tsx scripts/create-reports-factory.ts --network devnet && tsx scripts/create-reports-factory.ts --network mainnet",
|
|
52
74
|
"create-factory:paymentStreams": "npm run codegen && tsx scripts/create-paymentStreams-factory.ts --network devnet && tsx scripts/create-paymentStreams-factory.ts --network mainnet",
|
|
53
|
-
"create-
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
75
|
+
"create-factory:reports": "npm run codegen && tsx scripts/create-reports-factory.ts --network devnet && tsx scripts/create-reports-factory.ts --network mainnet",
|
|
76
|
+
"fix": "npm run lint:fix && npm run format:fix",
|
|
77
|
+
"format": "prettier --check .",
|
|
78
|
+
"format:fix": "prettier --write .",
|
|
79
|
+
"lint": "eslint .",
|
|
80
|
+
"lint:fix": "eslint . --fix",
|
|
57
81
|
"package:manifest": "npm run package:prep && npm pack --dry-run --json --ignore-scripts > /tmp/npm-pack.json 2>/dev/null && jq -r '.[0].files[].path' /tmp/npm-pack.json | sort | tsx scripts/collapse-manifest.ts > generated/npm-manifest.txt",
|
|
58
82
|
"package:prep": "npm run codegen && npm run update-version && tsx scripts/bundle-dependencies.ts && tsx scripts/create-package-index.ts && tsx scripts/create-root-index.ts && tsx scripts/fix-splice-refs.ts",
|
|
59
|
-
"
|
|
83
|
+
"package:publish": "npm run package:manifest && npm publish",
|
|
84
|
+
"prepare-release": "tsx scripts/prepare-release.ts",
|
|
85
|
+
"test": "cd Test && daml test --show-coverage --color --coverage-ignore-choice splice-amulet:.*",
|
|
86
|
+
"test:imports": "tsx scripts/test-imports.ts",
|
|
87
|
+
"update-version": "tsx scripts/update-generated-package.ts",
|
|
88
|
+
"upgrade-package": "tsx scripts/upgrade-package.ts",
|
|
89
|
+
"upload-dar": "tsx scripts/upload-dar.ts",
|
|
90
|
+
"verify-dars": "tsx scripts/verify-dars.ts"
|
|
60
91
|
},
|
|
61
92
|
"dependencies": {
|
|
62
93
|
"@daml/ledger": "2.10.3",
|
|
@@ -65,7 +96,18 @@
|
|
|
65
96
|
},
|
|
66
97
|
"devDependencies": {
|
|
67
98
|
"@types/node": "25.0.6",
|
|
99
|
+
"@typescript-eslint/eslint-plugin": "8.53.0",
|
|
100
|
+
"@typescript-eslint/parser": "8.53.0",
|
|
101
|
+
"eslint": "9.39.2",
|
|
102
|
+
"eslint-config-prettier": "10.1.8",
|
|
103
|
+
"eslint-import-resolver-typescript": "4.4.4",
|
|
104
|
+
"eslint-plugin-import": "2.32.0",
|
|
105
|
+
"eslint-plugin-unused-imports": "4.3.0",
|
|
68
106
|
"handlebars": "^4.7.8",
|
|
107
|
+
"prettier": "3.7.4",
|
|
108
|
+
"prettier-plugin-jsdoc": "1.8.0",
|
|
109
|
+
"prettier-plugin-organize-imports": "4.3.0",
|
|
110
|
+
"prettier-plugin-packagejson": "2.5.21",
|
|
69
111
|
"ts-node": "10.9.2",
|
|
70
112
|
"tsx": "4.21.0",
|
|
71
113
|
"typescript": "5.9.3",
|
|
@@ -75,33 +117,7 @@
|
|
|
75
117
|
"@daml/ledger": "2.10.3",
|
|
76
118
|
"@daml/types": "3.4.10"
|
|
77
119
|
},
|
|
78
|
-
"keywords": [
|
|
79
|
-
"daml",
|
|
80
|
-
"opencaptable",
|
|
81
|
-
"blockchain",
|
|
82
|
-
"smart-contracts",
|
|
83
|
-
"fairmint"
|
|
84
|
-
],
|
|
85
|
-
"author": "Fairmint",
|
|
86
|
-
"license": "UNLICENSED",
|
|
87
120
|
"publishConfig": {
|
|
88
121
|
"access": "public"
|
|
89
|
-
},
|
|
90
|
-
"repository": {
|
|
91
|
-
"type": "git",
|
|
92
|
-
"url": "git+https://github.com/fairmint/open-captable-protocol-daml.git"
|
|
93
|
-
},
|
|
94
|
-
"typesVersions": {
|
|
95
|
-
"*": {
|
|
96
|
-
"ocp-factory-contract-id.json": [
|
|
97
|
-
"generated/ocp-factory-contract-id.json.d.ts"
|
|
98
|
-
],
|
|
99
|
-
"reports-factory-contract-id.json": [
|
|
100
|
-
"generated/reports-factory-contract-id.json.d.ts"
|
|
101
|
-
],
|
|
102
|
-
"paymentStreams-factory-contract-id.json": [
|
|
103
|
-
"generated/paymentStreams-factory-contract-id.json.d.ts"
|
|
104
|
-
]
|
|
105
|
-
}
|
|
106
122
|
}
|
|
107
123
|
}
|