@ottochain/sdk 2.4.0 → 2.6.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/dist/cjs/apps/compute/index.js +33 -0
- package/dist/cjs/apps/compute/state-machines/compute-rule110.js +164 -0
- package/dist/cjs/apps/compute/state-machines/index.js +9 -0
- package/dist/cjs/apps/contracts/index.js +1 -1
- package/dist/cjs/apps/contracts/state-machines/contract-agreement.js +126 -148
- package/dist/cjs/apps/contracts/state-machines/contract-escrow.js +153 -174
- package/dist/cjs/apps/contracts/state-machines/contract-universal.js +46 -58
- package/dist/cjs/apps/corporate/state-machines/corp-board.js +415 -481
- package/dist/cjs/apps/corporate/state-machines/corp-entity.js +368 -440
- package/dist/cjs/apps/corporate/state-machines/corp-securities.js +532 -647
- package/dist/cjs/apps/corporate/state-machines/corp-shareholders.js +499 -603
- package/dist/cjs/apps/governance/index.js +7 -7
- package/dist/cjs/apps/governance/state-machines/dao-multisig.js +170 -209
- package/dist/cjs/apps/governance/state-machines/dao-reputation.js +161 -214
- package/dist/cjs/apps/governance/state-machines/dao-single.js +92 -92
- package/dist/cjs/apps/governance/state-machines/dao-token.js +169 -223
- package/dist/cjs/apps/governance/state-machines/governance-simple.js +185 -217
- package/dist/cjs/apps/governance/state-machines/governance-universal.js +64 -64
- package/dist/cjs/apps/identity/constants.js +16 -24
- package/dist/cjs/apps/identity/index.js +1 -1
- package/dist/cjs/apps/identity/state-machines/identity-agent.js +124 -158
- package/dist/cjs/apps/identity/state-machines/identity-oracle.js +151 -169
- package/dist/cjs/apps/identity/state-machines/identity-registry.js +89 -115
- package/dist/cjs/apps/identity/state-machines/identity-universal.js +51 -57
- package/dist/cjs/apps/index.js +4 -1
- package/dist/cjs/apps/lending/assets.js +41 -17
- package/dist/cjs/apps/lending/credit-scoring.js +4 -4
- package/dist/cjs/apps/lending/eligibility.js +9 -25
- package/dist/cjs/apps/lending/index.js +1 -1
- package/dist/cjs/apps/lending/state-machines/lending-zk-loan.js +177 -156
- package/dist/cjs/apps/markets/index.js +1 -1
- package/dist/cjs/apps/markets/state-machines/market-auction.js +115 -134
- package/dist/cjs/apps/markets/state-machines/market-crowdfund.js +122 -137
- package/dist/cjs/apps/markets/state-machines/market-group-buy.js +158 -177
- package/dist/cjs/apps/markets/state-machines/market-prediction.js +193 -227
- package/dist/cjs/apps/markets/state-machines/market-universal.js +65 -80
- package/dist/cjs/apps/oracles/index.js +1 -1
- package/dist/cjs/apps/privacy/index.js +67 -0
- package/dist/cjs/apps/privacy/state-machines/index.js +17 -0
- package/dist/cjs/apps/privacy/state-machines/mixer-ddhRing.js +286 -0
- package/dist/cjs/apps/privacy/state-machines/note-pool.js +476 -0
- package/dist/cjs/apps/staked-pool/assets.js +103 -0
- package/dist/cjs/apps/staked-pool/base.js +498 -0
- package/dist/cjs/apps/staked-pool/consumer.js +55 -0
- package/dist/cjs/apps/staked-pool/index.js +83 -0
- package/dist/cjs/apps/staked-pool/state-machines/index.js +12 -0
- package/dist/cjs/apps/staked-pool/state-machines/staked-pool-base.js +49 -0
- package/dist/cjs/apps/staked-pool/state-machines/staked-pool-oracle.js +131 -0
- package/dist/cjs/generated/google/protobuf/struct.js +1 -1
- package/dist/cjs/generated/google/protobuf/timestamp.js +1 -1
- package/dist/cjs/generated/ottochain/apps/contracts/v1/contract.js +1 -1
- package/dist/cjs/generated/ottochain/apps/corporate/v1/corporate.js +1 -1
- package/dist/cjs/generated/ottochain/apps/governance/v1/governance.js +1 -1
- package/dist/cjs/generated/ottochain/apps/identity/v1/attestation.js +1 -1
- package/dist/cjs/generated/ottochain/apps/identity/v1/identity.js +1 -1
- package/dist/cjs/generated/ottochain/apps/markets/v1/market.js +1 -1
- package/dist/cjs/generated/ottochain/v1/common.js +1 -1
- package/dist/cjs/generated/ottochain/v1/fiber.js +40 -2
- package/dist/cjs/generated/ottochain/v1/messages.js +1 -1
- package/dist/cjs/generated/ottochain/v1/records.js +1 -1
- package/dist/cjs/index.js +21 -3
- package/dist/cjs/ottochain/genesis-manifest.js +6 -0
- package/dist/cjs/ottochain/metagraph-client.js +63 -11
- package/dist/cjs/ottochain/snapshot.js +2 -4
- package/dist/cjs/ottochain/transaction.js +10 -0
- package/dist/cjs/privacy/sealed-bid.js +85 -82
- package/dist/cjs/privacy/shield-app.js +32 -32
- package/dist/cjs/schema/effects.js +145 -1
- package/dist/cjs/schema/fiber-app.js +139 -5
- package/dist/cjs/schema/guard-lint.js +3 -12
- package/dist/cjs/schema/guards.js +38 -38
- package/dist/cjs/templates/asset-policy.js +190 -0
- package/dist/cjs/templates/index.js +86 -0
- package/dist/cjs/templates/machine.js +130 -0
- package/dist/cjs/templates/migration.js +39 -0
- package/dist/cjs/templates/state-shape.js +38 -0
- package/dist/cjs/validation.js +1 -3
- package/dist/esm/apps/compute/index.js +29 -0
- package/dist/esm/apps/compute/state-machines/compute-rule110.js +161 -0
- package/dist/esm/apps/compute/state-machines/index.js +5 -0
- package/dist/esm/apps/contracts/index.js +4 -4
- package/dist/esm/apps/contracts/state-machines/contract-agreement.js +128 -150
- package/dist/esm/apps/contracts/state-machines/contract-escrow.js +155 -176
- package/dist/esm/apps/contracts/state-machines/contract-universal.js +47 -59
- package/dist/esm/apps/corporate/index.js +2 -2
- package/dist/esm/apps/corporate/state-machines/corp-board.js +418 -484
- package/dist/esm/apps/corporate/state-machines/corp-entity.js +371 -443
- package/dist/esm/apps/corporate/state-machines/corp-securities.js +535 -650
- package/dist/esm/apps/corporate/state-machines/corp-shareholders.js +502 -606
- package/dist/esm/apps/governance/index.js +10 -10
- package/dist/esm/apps/governance/state-machines/dao-multisig.js +172 -211
- package/dist/esm/apps/governance/state-machines/dao-reputation.js +163 -216
- package/dist/esm/apps/governance/state-machines/dao-single.js +94 -94
- package/dist/esm/apps/governance/state-machines/dao-token.js +171 -225
- package/dist/esm/apps/governance/state-machines/governance-simple.js +187 -219
- package/dist/esm/apps/governance/state-machines/governance-universal.js +65 -65
- package/dist/esm/apps/identity/constants.js +18 -26
- package/dist/esm/apps/identity/index.js +8 -8
- package/dist/esm/apps/identity/state-machines/identity-agent.js +125 -159
- package/dist/esm/apps/identity/state-machines/identity-oracle.js +153 -171
- package/dist/esm/apps/identity/state-machines/identity-registry.js +91 -117
- package/dist/esm/apps/identity/state-machines/identity-universal.js +52 -58
- package/dist/esm/apps/index.js +9 -6
- package/dist/esm/apps/lending/assets.js +41 -17
- package/dist/esm/apps/lending/credit-scoring.js +6 -6
- package/dist/esm/apps/lending/eligibility.js +10 -26
- package/dist/esm/apps/lending/index.js +5 -5
- package/dist/esm/apps/lending/state-machines/lending-zk-loan.js +178 -157
- package/dist/esm/apps/markets/index.js +5 -5
- package/dist/esm/apps/markets/state-machines/market-auction.js +117 -136
- package/dist/esm/apps/markets/state-machines/market-crowdfund.js +124 -139
- package/dist/esm/apps/markets/state-machines/market-group-buy.js +160 -179
- package/dist/esm/apps/markets/state-machines/market-prediction.js +195 -229
- package/dist/esm/apps/markets/state-machines/market-universal.js +66 -81
- package/dist/esm/apps/oracles/index.js +3 -3
- package/dist/esm/apps/privacy/index.js +56 -0
- package/dist/esm/apps/privacy/state-machines/index.js +6 -0
- package/dist/esm/apps/privacy/state-machines/mixer-ddhRing.js +282 -0
- package/dist/esm/apps/privacy/state-machines/note-pool.js +470 -0
- package/dist/esm/apps/staked-pool/assets.js +91 -0
- package/dist/esm/apps/staked-pool/base.js +493 -0
- package/dist/esm/apps/staked-pool/consumer.js +49 -0
- package/dist/esm/apps/staked-pool/index.js +60 -0
- package/dist/esm/apps/staked-pool/state-machines/index.js +6 -0
- package/dist/esm/apps/staked-pool/state-machines/staked-pool-base.js +46 -0
- package/dist/esm/apps/staked-pool/state-machines/staked-pool-oracle.js +127 -0
- package/dist/esm/generated/google/protobuf/struct.js +1 -1
- package/dist/esm/generated/google/protobuf/timestamp.js +1 -1
- package/dist/esm/generated/ottochain/apps/contracts/v1/contract.js +1 -1
- package/dist/esm/generated/ottochain/apps/corporate/v1/corporate.js +1 -1
- package/dist/esm/generated/ottochain/apps/governance/v1/governance.js +1 -1
- package/dist/esm/generated/ottochain/apps/identity/v1/attestation.js +1 -1
- package/dist/esm/generated/ottochain/apps/identity/v1/identity.js +1 -1
- package/dist/esm/generated/ottochain/apps/markets/v1/market.js +1 -1
- package/dist/esm/generated/ottochain/v1/common.js +1 -1
- package/dist/esm/generated/ottochain/v1/fiber.js +40 -2
- package/dist/esm/generated/ottochain/v1/messages.js +1 -1
- package/dist/esm/generated/ottochain/v1/records.js +1 -1
- package/dist/esm/index.js +10 -4
- package/dist/esm/ottochain/genesis-manifest.js +6 -0
- package/dist/esm/ottochain/metagraph-client.js +63 -11
- package/dist/esm/ottochain/snapshot.js +2 -4
- package/dist/esm/ottochain/transaction.js +8 -0
- package/dist/esm/privacy/index.js +2 -2
- package/dist/esm/privacy/sealed-bid.js +87 -84
- package/dist/esm/privacy/shield-app.js +33 -33
- package/dist/esm/schema/effects.js +137 -0
- package/dist/esm/schema/fiber-app.js +134 -5
- package/dist/esm/schema/guard-lint.js +3 -12
- package/dist/esm/schema/guards.js +36 -37
- package/dist/esm/templates/asset-policy.js +182 -0
- package/dist/esm/templates/index.js +41 -0
- package/dist/esm/templates/machine.js +125 -0
- package/dist/esm/templates/migration.js +34 -0
- package/dist/esm/templates/state-shape.js +34 -0
- package/dist/esm/validation.js +1 -3
- package/dist/esm/zk/index.js +4 -4
- package/dist/types/apps/compute/index.d.ts +176 -0
- package/dist/types/apps/compute/state-machines/compute-rule110.d.ts +157 -0
- package/dist/types/apps/compute/state-machines/index.d.ts +5 -0
- package/dist/types/apps/contracts/index.d.ts +14 -14
- package/dist/types/apps/contracts/state-machines/contract-agreement.d.ts +3 -3
- package/dist/types/apps/contracts/state-machines/contract-escrow.d.ts +3 -3
- package/dist/types/apps/contracts/state-machines/contract-universal.d.ts +4 -4
- package/dist/types/apps/corporate/index.d.ts +162 -162
- package/dist/types/apps/corporate/state-machines/corp-board.d.ts +88 -88
- package/dist/types/apps/corporate/state-machines/corp-entity.d.ts +14 -14
- package/dist/types/apps/corporate/state-machines/corp-securities.d.ts +18 -18
- package/dist/types/apps/corporate/state-machines/corp-shareholders.d.ts +43 -43
- package/dist/types/apps/governance/index.d.ts +81 -81
- package/dist/types/apps/governance/state-machines/dao-multisig.d.ts +16 -16
- package/dist/types/apps/governance/state-machines/dao-reputation.d.ts +22 -22
- package/dist/types/apps/governance/state-machines/dao-token.d.ts +21 -21
- package/dist/types/apps/governance/state-machines/governance-simple.d.ts +11 -11
- package/dist/types/apps/governance/state-machines/governance-universal.d.ts +4 -4
- package/dist/types/apps/identity/constants.d.ts +2 -2
- package/dist/types/apps/identity/index.d.ts +70 -70
- package/dist/types/apps/identity/state-machines/identity-agent.d.ts +23 -23
- package/dist/types/apps/identity/state-machines/identity-oracle.d.ts +11 -11
- package/dist/types/apps/identity/state-machines/identity-registry.d.ts +27 -27
- package/dist/types/apps/identity/state-machines/identity-universal.d.ts +4 -4
- package/dist/types/apps/index.d.ts +9 -6
- package/dist/types/apps/lending/assets.d.ts +2 -2
- package/dist/types/apps/lending/credit-scoring.d.ts +5 -5
- package/dist/types/apps/lending/eligibility.d.ts +2 -2
- package/dist/types/apps/lending/index.d.ts +20 -12
- package/dist/types/apps/lending/state-machines/lending-zk-loan.d.ts +15 -7
- package/dist/types/apps/markets/index.d.ts +76 -76
- package/dist/types/apps/markets/state-machines/market-auction.d.ts +12 -12
- package/dist/types/apps/markets/state-machines/market-crowdfund.d.ts +19 -19
- package/dist/types/apps/markets/state-machines/market-group-buy.d.ts +18 -18
- package/dist/types/apps/markets/state-machines/market-prediction.d.ts +15 -15
- package/dist/types/apps/markets/state-machines/market-universal.d.ts +7 -7
- package/dist/types/apps/oracles/index.d.ts +1 -1
- package/dist/types/apps/privacy/index.d.ts +328 -0
- package/dist/types/apps/privacy/state-machines/index.d.ts +6 -0
- package/dist/types/apps/privacy/state-machines/mixer-ddhRing.d.ts +337 -0
- package/dist/types/apps/privacy/state-machines/note-pool.d.ts +196 -0
- package/dist/types/apps/staked-pool/assets.d.ts +53 -0
- package/dist/types/apps/staked-pool/base.d.ts +80 -0
- package/dist/types/apps/staked-pool/consumer.d.ts +29 -0
- package/dist/types/apps/staked-pool/index.d.ts +51 -0
- package/dist/types/apps/staked-pool/state-machines/index.d.ts +6 -0
- package/dist/types/apps/staked-pool/state-machines/staked-pool-base.d.ts +8 -0
- package/dist/types/apps/staked-pool/state-machines/staked-pool-oracle.d.ts +34 -0
- package/dist/types/generated/openapi.d.ts +13 -0
- package/dist/types/generated/ottochain/v1/fiber.d.ts +7 -0
- package/dist/types/index.d.ts +3 -3
- package/dist/types/openapi.d.ts +4 -2
- package/dist/types/ottochain/genesis-manifest.d.ts +6 -0
- package/dist/types/ottochain/index.d.ts +1 -1
- package/dist/types/ottochain/metagraph-client.d.ts +69 -15
- package/dist/types/ottochain/transaction.d.ts +9 -1
- package/dist/types/ottochain/types.d.ts +1 -1
- package/dist/types/privacy/index.d.ts +2 -2
- package/dist/types/privacy/sealed-bid.d.ts +9 -9
- package/dist/types/privacy/shield-app.d.ts +1 -1
- package/dist/types/schema/effects.d.ts +132 -0
- package/dist/types/schema/fiber-app.d.ts +281 -0
- package/dist/types/schema/guards.d.ts +12 -0
- package/dist/types/templates/asset-policy.d.ts +119 -0
- package/dist/types/templates/index.d.ts +26 -0
- package/dist/types/templates/machine.d.ts +139 -0
- package/dist/types/templates/migration.d.ts +34 -0
- package/dist/types/templates/state-shape.d.ts +30 -0
- package/dist/types/zk/index.d.ts +4 -4
- package/package.json +31 -13
|
@@ -105,6 +105,269 @@ export interface Transition<TState extends string = string, TEvent extends strin
|
|
|
105
105
|
dependencies?: readonly (string | DependencySpec)[];
|
|
106
106
|
emits?: readonly (string | EmitSpec)[];
|
|
107
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* `allowedEffects` element — the 5 `EffectKind` families, UPPERCASE on the wire
|
|
110
|
+
* (`enumeratum` `Uppercase` mixin). Chain: `EffectKind` in `FiberPolicy.scala`.
|
|
111
|
+
*/
|
|
112
|
+
export type EffectKind = 'TRIGGER' | 'SPAWN' | 'EMIT' | 'TRANSFER' | 'DEPENDENCY';
|
|
113
|
+
/**
|
|
114
|
+
* `spawnOwnerPolicy` — UPPERCASE (`enumeratum` `Uppercase`). Chain: `SpawnOwnerPolicy`
|
|
115
|
+
* (`Explicit` / `SubsetOfParent` / `InheritParent` ⇒ `"EXPLICIT"` / `"SUBSETOFPARENT"`
|
|
116
|
+
* / `"INHERITPARENT"`).
|
|
117
|
+
*/
|
|
118
|
+
export type SpawnOwnerPolicy = 'EXPLICIT' | 'SUBSETOFPARENT' | 'INHERITPARENT';
|
|
119
|
+
/**
|
|
120
|
+
* `dependencyPolicy.mode` — UPPERCASE (`enumeratum` `Uppercase`). Chain: `DependencyMode`
|
|
121
|
+
* (`Open` / `Allowlist` / `Frozen`). REQUIRED on the wire (Scala defaults it to `Open`,
|
|
122
|
+
* but the `customizableEncoder` always encodes the value).
|
|
123
|
+
*/
|
|
124
|
+
export type DependencyMode = 'OPEN' | 'ALLOWLIST' | 'FROZEN';
|
|
125
|
+
/**
|
|
126
|
+
* `transferPolicy` — recipient allowlist for `_transferAsset`. Chain: `TransferPolicy`
|
|
127
|
+
* (`Option[Set[UUID]]` fibers, `Option[Set[Address]]` wallets). Each field is OPTIONAL;
|
|
128
|
+
* an absent field ⇒ that recipient class is unconstrained (and is `dropNulls`-stripped).
|
|
129
|
+
*/
|
|
130
|
+
export interface TransferPolicy {
|
|
131
|
+
/** Fiber UUIDs permitted to receive a transfer. */
|
|
132
|
+
allowedRecipientFibers?: readonly string[];
|
|
133
|
+
/** DAG wallet addresses permitted to receive a transfer. */
|
|
134
|
+
allowedRecipientWallets?: readonly string[];
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* `dependencyPolicy` — dynamic-dependency posture. Chain: `DependencyPolicy`
|
|
138
|
+
* (`mode: DependencyMode`, `allowed: Option[Set[UUID]]`). `mode` is REQUIRED; `allowed`
|
|
139
|
+
* is meaningful only when `mode === 'ALLOWLIST'` and is `dropNulls`-stripped otherwise.
|
|
140
|
+
*/
|
|
141
|
+
export interface DependencyPolicy {
|
|
142
|
+
/** Posture: `OPEN` (any target) / `ALLOWLIST` (only `allowed`) / `FROZEN` (no new). */
|
|
143
|
+
mode: DependencyMode;
|
|
144
|
+
/** Fiber UUIDs permitted as dependency targets (meaningful only under `ALLOWLIST`). */
|
|
145
|
+
allowed?: readonly string[];
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* `migrationAuthority` — who may authorize a `Governed` migration. Chain:
|
|
149
|
+
* `MigrationAuthority`, a DISJOINT-FIELD discriminated union (no tag key): the `Signers`
|
|
150
|
+
* arm carries `addresses`, the `Role` arm carries `registryFiberId` + `roleField`. The
|
|
151
|
+
* presence of disjoint fields is the discriminator (same as the chain decoder's `.or`).
|
|
152
|
+
*/
|
|
153
|
+
export type MigrationAuthority = {
|
|
154
|
+
/** VERIFIED signer DAG addresses permitted to authorize the migration (`Signers`). */
|
|
155
|
+
addresses: readonly string[];
|
|
156
|
+
} | {
|
|
157
|
+
/** Registry fiber UUID whose role-map is consulted (`Role`). */
|
|
158
|
+
registryFiberId: string;
|
|
159
|
+
/** Field/key in that fiber's state holding the `{<address>: true}` role map (`Role`). */
|
|
160
|
+
roleField: string;
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* `upgradePolicy` — the upgrade-path constitution. Chain: `UpgradePolicy`. The three
|
|
164
|
+
* bare variants encode as LOWERCASE tag STRINGS (`"immutable"` / `"appendOnly"` /
|
|
165
|
+
* `"arbitrary"`); the `Governed` arm encodes as the object `{ authority: <MigrationAuthority> }`.
|
|
166
|
+
*
|
|
167
|
+
* NOTE: this lowercase `"immutable"` is the upgradePolicy DIAL VALUE — distinct from the
|
|
168
|
+
* policy-level variant tag `"Immutable"` (capital-I), a different construct added in a
|
|
169
|
+
* later change.
|
|
170
|
+
*/
|
|
171
|
+
export type UpgradePolicy = 'immutable' | 'appendOnly' | 'arbitrary' | {
|
|
172
|
+
/** Authority that may consent to a `Governed` migration. */
|
|
173
|
+
authority: MigrationAuthority;
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* `transitionPolicy` — WHO may drive a transition on this fiber. Chain: `TransitionPolicy`
|
|
177
|
+
* (chain PR #194), a bare tag STRING with three ranked levels:
|
|
178
|
+
*
|
|
179
|
+
* - `"Open"` — anyone may drive a transition; the transition's `guard` is the only gate.
|
|
180
|
+
* This is the chain DEFAULT when the dial is ABSENT, so omitting it is byte-identical
|
|
181
|
+
* to the legacy (pre-#194) behaviour.
|
|
182
|
+
* - `"OwnersOrParticipants"` — only the fiber's owners or its declared participants.
|
|
183
|
+
* - `"Owners"` — only the fiber's owners.
|
|
184
|
+
*
|
|
185
|
+
* Absent ⇒ `"Open"` (chain `transitionPolicy: Option[TransitionPolicy] = None`,
|
|
186
|
+
* `dropNulls`-stripped). The chain joins this to the tighten-only upgrade lattice, so an
|
|
187
|
+
* upgrade may only RAISE the level (`Open < OwnersOrParticipants < Owners`); LOOSENING it
|
|
188
|
+
* (including dropping the dial on a fiber that had it set) is rejected as `CombineRejected`.
|
|
189
|
+
*/
|
|
190
|
+
export type TransitionPolicy = 'Open' | 'OwnersOrParticipants' | 'Owners';
|
|
191
|
+
/**
|
|
192
|
+
* `compatibleWith` — the inclusive-min / exclusive-max SemVer bridge window a migration
|
|
193
|
+
* may target. Chain: `VersionRange` (`min: Option[SemVer]`, `max: Option[SemVer]`). Each
|
|
194
|
+
* bound is a SemVer STRING (`"1.2.3"`); an absent bound is unconstrained on that side and
|
|
195
|
+
* is `dropNulls`-stripped.
|
|
196
|
+
*/
|
|
197
|
+
export interface VersionRange {
|
|
198
|
+
/** Inclusive lower bound, e.g. `"1.0.0"` (absent ⇒ unconstrained below). */
|
|
199
|
+
min?: string;
|
|
200
|
+
/** Exclusive upper bound, e.g. `"2.0.0"` (absent ⇒ unconstrained above). */
|
|
201
|
+
max?: string;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* `FiberPolicy` — the constitution a definition declares for the fibers it spawns.
|
|
205
|
+
*
|
|
206
|
+
* This MIRRORS the chain ADT `FiberPolicy = Unconstrained | Immutable | Constrained(<dials>)`
|
|
207
|
+
* (chain branch `feat/fiber-policy-adt`). The representation here is chosen for
|
|
208
|
+
* BYTE-FOR-BYTE wire parity with the chain, because a `StateMachineDefinition` is
|
|
209
|
+
* signed verbatim by the SDK (`batchSign(dropNulls(...))`) and re-encoded + verified
|
|
210
|
+
* by the chain. The rule is:
|
|
211
|
+
*
|
|
212
|
+
* - **`Unconstrained`** ⇒ there is **NO `policy` key** on the wire definition at all.
|
|
213
|
+
* In the SDK this is the DEFAULT and is represented by simply OMITTING `policy`
|
|
214
|
+
* (i.e. `policy === undefined`).
|
|
215
|
+
* - **`Immutable`** ⇒ the definition is permanently locked; `policy` is the bare JSON
|
|
216
|
+
* STRING `"Immutable"` (EXACT casing, capital-I) — NOT an object. Semantically this is
|
|
217
|
+
* the upgradePolicy DIAL set to its LOWERCASE `"immutable"` value with no other dial
|
|
218
|
+
* set, and the chain collapses that exact `Constrained` into the `Immutable` variant.
|
|
219
|
+
* See {@link immutable} and the canonical collapse in {@link projectFiberPolicy}.
|
|
220
|
+
* - **`Constrained(dials)`** ⇒ `policy` is a bare object of ONLY the dials that are
|
|
221
|
+
* SET. Unset dials are absent (the chain `dropNulls`-strips them; so does the SDK
|
|
222
|
+
* at sign time). A `Constrained` with no dials set is wire-indistinguishable from
|
|
223
|
+
* `Unconstrained`, so `toProtoDefinition` collapses it back to "no policy key".
|
|
224
|
+
*
|
|
225
|
+
* All 15 dials are optional. Provide any subset.
|
|
226
|
+
*/
|
|
227
|
+
export interface FiberPolicyDials {
|
|
228
|
+
/** Whether the fiber may reproduce itself (spawn instances of its own definition). Wire: boolean. */
|
|
229
|
+
selfReproducing?: boolean;
|
|
230
|
+
/**
|
|
231
|
+
* Allow-list of effect families this fiber's transitions may produce, as a SET of the 5
|
|
232
|
+
* UPPERCASE {@link EffectKind} tokens (`"TRIGGER" | "SPAWN" | "EMIT" | "TRANSFER" |
|
|
233
|
+
* "DEPENDENCY"`). Order is not significant; duplicates are collapsed by the chain's `Set`.
|
|
234
|
+
* Chain: `allowedEffects: Option[Set[EffectKind]]`.
|
|
235
|
+
*/
|
|
236
|
+
allowedEffects?: readonly EffectKind[];
|
|
237
|
+
/**
|
|
238
|
+
* Who/what may own fibers this one spawns — an UPPERCASE {@link SpawnOwnerPolicy} token
|
|
239
|
+
* (`"EXPLICIT" | "SUBSETOFPARENT" | "INHERITPARENT"`). Chain: `spawnOwnerPolicy: Option[SpawnOwnerPolicy]`.
|
|
240
|
+
*/
|
|
241
|
+
spawnOwnerPolicy?: SpawnOwnerPolicy;
|
|
242
|
+
/** Maximum spawn-generation depth (descendant chain length). Wire: number. */
|
|
243
|
+
maxGenerations?: number;
|
|
244
|
+
/** Maximum number of children a single transition may spawn. Wire: number. */
|
|
245
|
+
maxSpawnFanout?: number;
|
|
246
|
+
/** SET of caller fiber UUIDs permitted to drive transitions on this fiber. Wire: string[]. */
|
|
247
|
+
acceptedCallers?: readonly string[];
|
|
248
|
+
/** SET of state ids that are sealed (no transition may fire from them). Wire: string[]. */
|
|
249
|
+
sealedStates?: readonly string[];
|
|
250
|
+
/**
|
|
251
|
+
* WHO may drive a transition on this fiber — a {@link TransitionPolicy} bare tag
|
|
252
|
+
* (`"Open" | "OwnersOrParticipants" | "Owners"`). Absent ⇒ `"Open"` (guard-only, the
|
|
253
|
+
* chain default); set `"Owners"`/`"OwnersOrParticipants"` to gate transitions by identity
|
|
254
|
+
* in ADDITION to the guard. Chain: `transitionPolicy: Option[TransitionPolicy]` (chain PR #194).
|
|
255
|
+
*/
|
|
256
|
+
transitionPolicy?: TransitionPolicy;
|
|
257
|
+
/**
|
|
258
|
+
* Recipient allowlist for `_transferAsset` — the {@link TransferPolicy} object
|
|
259
|
+
* `{ allowedRecipientFibers?: uuid[], allowedRecipientWallets?: DAG-address[] }`.
|
|
260
|
+
* Chain: `transferPolicy: Option[TransferPolicy]`.
|
|
261
|
+
*/
|
|
262
|
+
transferPolicy?: TransferPolicy;
|
|
263
|
+
/**
|
|
264
|
+
* Dynamic-dependency policy — the {@link DependencyPolicy} object `{ mode, allowed? }`
|
|
265
|
+
* where `mode` is the REQUIRED UPPERCASE {@link DependencyMode}. Chain:
|
|
266
|
+
* `dependencyPolicy: Option[DependencyPolicy]`.
|
|
267
|
+
*/
|
|
268
|
+
dependencyPolicy?: DependencyPolicy;
|
|
269
|
+
/**
|
|
270
|
+
* In-place upgrade/migration posture — an {@link UpgradePolicy}: a LOWERCASE bare tag
|
|
271
|
+
* (`"immutable" | "appendOnly" | "arbitrary"`) OR the `Governed` object
|
|
272
|
+
* `{ authority: <MigrationAuthority> }`. Chain: `upgradePolicy: Option[UpgradePolicy]`.
|
|
273
|
+
*/
|
|
274
|
+
upgradePolicy?: UpgradePolicy;
|
|
275
|
+
/** Self-declared SemVer of this definition as a STRING `"major.minor.patch"` (e.g. `"1.2.3"`). Chain: `version: Option[SemVer]`. */
|
|
276
|
+
version?: string;
|
|
277
|
+
/**
|
|
278
|
+
* Migration bridge window — the {@link VersionRange} object `{ min?: semver, max?: semver }`
|
|
279
|
+
* naming the successor versions this definition declares it will migrate TO. Chain:
|
|
280
|
+
* `compatibleWith: Option[VersionRange]`.
|
|
281
|
+
*/
|
|
282
|
+
compatibleWith?: VersionRange;
|
|
283
|
+
/** SET of (ERC-165-style) interface identifiers this definition advertises. Wire: string[]. */
|
|
284
|
+
interfaces?: readonly string[];
|
|
285
|
+
/**
|
|
286
|
+
* Authority permitted to authorize a `Governed` migration — a {@link MigrationAuthority}:
|
|
287
|
+
* `{ addresses: DAG-address[] }` (Signers) OR `{ registryFiberId: uuid, roleField: string }`
|
|
288
|
+
* (Role), discriminated by disjoint fields. Chain: `migrationAuthority: Option[MigrationAuthority]`.
|
|
289
|
+
*/
|
|
290
|
+
migrationAuthority?: MigrationAuthority;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* The wire (and authoring) tag for the `Immutable` policy VARIANT: the bare JSON string
|
|
294
|
+
* `"Immutable"`. EXACT casing, capital-I — this is the POLICY-LEVEL variant name and is
|
|
295
|
+
* DISTINCT from the `upgradePolicy` dial VALUE `"immutable"` (lowercase). The chain emits
|
|
296
|
+
* exactly this capital-I string for `Immutable`, so the SDK must too, byte-for-byte.
|
|
297
|
+
*/
|
|
298
|
+
export declare const IMMUTABLE_POLICY: "Immutable";
|
|
299
|
+
export type ImmutablePolicy = typeof IMMUTABLE_POLICY;
|
|
300
|
+
/**
|
|
301
|
+
* Wire form of a `FiberPolicy`. Mirrors the chain ADT's non-`Unconstrained` arms:
|
|
302
|
+
*
|
|
303
|
+
* - a bare object of the SET dials — the `Constrained` arm. Unset dials are stripped at
|
|
304
|
+
* projection time (and again by `dropNulls` at sign time), so this object matches the
|
|
305
|
+
* chain's `dropNulls`-stripped `Constrained` encoding exactly; OR
|
|
306
|
+
* - the bare JSON string `"Immutable"` — the {@link ImmutablePolicy} arm.
|
|
307
|
+
*
|
|
308
|
+
* (`Unconstrained` has no wire representation: it is the absence of the `policy` key.)
|
|
309
|
+
*/
|
|
310
|
+
export type FiberPolicy = FiberPolicyDials | ImmutablePolicy;
|
|
311
|
+
/**
|
|
312
|
+
* The canonical UNCONSTRAINED policy: omission. Provided as a named export for
|
|
313
|
+
* readability at call sites — `policy: unconstrained()` documents intent, and projects
|
|
314
|
+
* to NO `policy` key (identical to leaving `policy` off entirely).
|
|
315
|
+
*/
|
|
316
|
+
export declare function unconstrained(): undefined;
|
|
317
|
+
/**
|
|
318
|
+
* The canonical IMMUTABLE policy: the definition is permanently locked. Projects to the
|
|
319
|
+
* bare JSON string `"Immutable"` ({@link IMMUTABLE_POLICY}), the chain's `Immutable`
|
|
320
|
+
* variant tag. Semantically equivalent to `constrained({ upgradePolicy: 'immutable' })`
|
|
321
|
+
* with no other dial set — which `constrained()`/`projectFiberPolicy()` collapse to the
|
|
322
|
+
* same string for wire parity (see {@link constrained}).
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```ts
|
|
326
|
+
* const def = defineFiberApp({ ...spec, policy: immutable() });
|
|
327
|
+
* ```
|
|
328
|
+
*/
|
|
329
|
+
export declare function immutable(): ImmutablePolicy;
|
|
330
|
+
/**
|
|
331
|
+
* Build a CONSTRAINED `FiberPolicy` from any subset of the 15 dials.
|
|
332
|
+
*
|
|
333
|
+
* Pass only the dials you want to set. Dials left `undefined`/`null` are dropped so the
|
|
334
|
+
* result is a clean, minimal object that serializes identically to the chain's
|
|
335
|
+
* `dropNulls`-stripped `Constrained`. If NO dial is effectively set, this returns
|
|
336
|
+
* `undefined` (an empty constraint == `Unconstrained`), which projects to no `policy`
|
|
337
|
+
* key — preserving wire parity.
|
|
338
|
+
*
|
|
339
|
+
* CANONICAL COLLAPSE: `constrained({ upgradePolicy: 'immutable' })` with NO other dial set
|
|
340
|
+
* collapses to the bare string `"Immutable"` ({@link IMMUTABLE_POLICY}), because the chain
|
|
341
|
+
* collapses that exact `Constrained` into the `Immutable` variant. NOTE the casing: the
|
|
342
|
+
* collapse triggers on the chain's LOWERCASE upgradePolicy dial value `"immutable"`, and
|
|
343
|
+
* the result is the capital-I policy-variant tag `"Immutable"`. Signing the dials object
|
|
344
|
+
* `{ "upgradePolicy": "immutable" }` instead would diverge the canonical (the chain
|
|
345
|
+
* re-encodes it as `"Immutable"`) and break the create signature. Adding ANY other dial
|
|
346
|
+
* keeps it a dials object.
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```ts
|
|
350
|
+
* const policy = constrained({
|
|
351
|
+
* selfReproducing: false,
|
|
352
|
+
* maxGenerations: 3,
|
|
353
|
+
* allowedEffects: ['EMIT', 'TRANSFER'],
|
|
354
|
+
* sealedStates: ['ARCHIVED'],
|
|
355
|
+
* });
|
|
356
|
+
* ```
|
|
357
|
+
*/
|
|
358
|
+
export declare function constrained(dials: FiberPolicyDials): FiberPolicy | undefined;
|
|
359
|
+
/**
|
|
360
|
+
* Project an authoring `policy` value onto the wire form. Returns one of:
|
|
361
|
+
* - `undefined` when the policy is (effectively) `Unconstrained` — i.e. omit the `policy`
|
|
362
|
+
* key entirely;
|
|
363
|
+
* - the bare string `"Immutable"` ({@link IMMUTABLE_POLICY}) for the `Immutable` variant
|
|
364
|
+
* (also the collapse of a lone LOWERCASE `upgradePolicy: 'immutable'`); or
|
|
365
|
+
* - the minimal `Constrained` dials object otherwise.
|
|
366
|
+
*
|
|
367
|
+
* Centralizes the omit-on-unconstrained AND the Immutable-collapse parity rules so every
|
|
368
|
+
* projection path (`toProtoDefinition`, the genesis manifest) stays consistent.
|
|
369
|
+
*/
|
|
370
|
+
export declare function projectFiberPolicy(policy: FiberPolicy | undefined): FiberPolicy | undefined;
|
|
108
371
|
export interface FiberAppMetadata {
|
|
109
372
|
name: string;
|
|
110
373
|
app: string;
|
|
@@ -125,6 +388,16 @@ export interface CrossReferences {
|
|
|
125
388
|
}
|
|
126
389
|
export interface FiberAppDefinition<TState extends string = string, TEvent extends string = string> {
|
|
127
390
|
metadata: FiberAppMetadata;
|
|
391
|
+
/**
|
|
392
|
+
* Fiber constitution. Mirrors the chain ADT `FiberPolicy = Unconstrained | Immutable |
|
|
393
|
+
* Constrained(<dials>)`. OMIT this field (the default) for `Unconstrained` — the projected
|
|
394
|
+
* wire definition then has NO `policy` key. Set it to `immutable()` to permanently lock the
|
|
395
|
+
* definition (projects to the bare string `"Immutable"`). Set it to a `constrained({...})`
|
|
396
|
+
* object to declare a subset of the 15 dials; unset dials are stripped so the wire form
|
|
397
|
+
* matches the chain's `dropNulls`-stripped `Constrained` byte-for-byte (and a lone
|
|
398
|
+
* `upgradePolicy: 'immutable'` collapses to `"Immutable"`).
|
|
399
|
+
*/
|
|
400
|
+
policy?: FiberPolicy;
|
|
128
401
|
/** Schema for fiber creation inputs (user-provided) */
|
|
129
402
|
createSchema?: {
|
|
130
403
|
required?: readonly string[];
|
|
@@ -195,6 +468,14 @@ export interface ProtoStateMachineDefinition {
|
|
|
195
468
|
dependencies: string[];
|
|
196
469
|
}>;
|
|
197
470
|
metadata?: Record<string, unknown>;
|
|
471
|
+
/**
|
|
472
|
+
* Fiber constitution. PRESENT for `Constrained` (a bare object of the SET dials) and for
|
|
473
|
+
* `Immutable` (the bare string `"Immutable"`); ABSENT for `Unconstrained`. This
|
|
474
|
+
* omit-on-unconstrained rule is the wire parity contract: the chain emits no `policy` key
|
|
475
|
+
* for `Unconstrained`, so neither may the SDK, or the signature breaks (HTTP 400). See
|
|
476
|
+
* {@link projectFiberPolicy}.
|
|
477
|
+
*/
|
|
478
|
+
policy?: FiberPolicy;
|
|
198
479
|
}
|
|
199
480
|
/**
|
|
200
481
|
* Extract proto-compatible StateMachineDefinition from a FiberAppDefinition.
|
|
@@ -131,4 +131,16 @@ export declare const signerHasRoleVia: (registryIdVar: string, roleField: string
|
|
|
131
131
|
* so a single gated transition is split into a bind step then this assert step. See
|
|
132
132
|
* docs/design/app-hardening-identity-integration.md §5–§6.
|
|
133
133
|
*/
|
|
134
|
+
/**
|
|
135
|
+
* EFFECT-KEY-BINDING dedup over an ARRAY of records: no existing element of the array at `arrayVar`
|
|
136
|
+
* (e.g. `"state.submissions"`, shaped `[ { addr, value }, … ]`) has its `field` (default `"addr"`)
|
|
137
|
+
* equal to the actor at `actorVar` (default `"event.agent"`). The array analog of the map-keyed
|
|
138
|
+
* `{"!":[has(...)]}` dedup — used where the collection is an append-only array of `{addr,…}` records
|
|
139
|
+
* (there is no `(array,string)` key check, but `none` over the array with a per-element `===` is total).
|
|
140
|
+
*
|
|
141
|
+
* The bare-element callback context inside `none` sees each record map directly, so `{get:[{var:""},field]}`
|
|
142
|
+
* is a valid `(map,string)` read. Pair with an `actorIsSigner`/`actorHasEntry` clause on the same
|
|
143
|
+
* `actorVar` (the dedup proves "not yet present", not "is the verified signer").
|
|
144
|
+
*/
|
|
145
|
+
export declare const actorNotInArray: (arrayVar: string, field?: string, actorVar?: string) => GuardRule;
|
|
134
146
|
export declare const depInState: (refVar: string, requiredState: string) => GuardRule;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Asset-policy preset builders (§1.1 of the SDK std-lib/templates handoff).
|
|
3
|
+
*
|
|
4
|
+
* Each builder is a PURE function that emits the exact {@link CreateAssetPolicy} wire body the chain
|
|
5
|
+
* re-derives — no `Date.now()`/`Math.random()`/`crypto.randomUUID()`; fixed inputs → fixed output. The
|
|
6
|
+
* on-chain policy `schemaHash` and `logicHash` are both `RegistryShape.AssetPolicy.computeDigest` over
|
|
7
|
+
* `behavior`/`supply`/`morphisms`/`stateShape` (no JSON-Logic body), so these presets are pure data.
|
|
8
|
+
*
|
|
9
|
+
* Hard invariants (CLAUDE.md rule #1 — the signed canonical is frozen):
|
|
10
|
+
* - `behavior` is ALWAYS summed from {@link TOKEN_BEHAVIOR_BITS} (T=16, S=8, C=4, E=2, G=1), never a
|
|
11
|
+
* magic literal int.
|
|
12
|
+
* - `morphisms` is REQUIRED on the wire (presence required, emptiness meaningful) — emit `{}` when empty,
|
|
13
|
+
* NEVER omit it.
|
|
14
|
+
* - `supply` is REQUIRED — emit `{}` when there is no supply authority, never omit it.
|
|
15
|
+
* - Absent optionals are OMITTED, never emitted as `null`/`undefined` (the chain signs over
|
|
16
|
+
* `JCS(dropNulls(payload))`).
|
|
17
|
+
*
|
|
18
|
+
* @see src/ottochain/types.ts — CreateAssetPolicy, SupplyPolicy, MorphismSpec, MorphismKind, TOKEN_BEHAVIOR_BITS
|
|
19
|
+
*/
|
|
20
|
+
import { TOKEN_BEHAVIOR_BITS, type CreateAssetPolicy, type JsonLogicExpression, type MorphismKind, type MorphismSpec, type SupplyPolicy } from '../ottochain/types.js';
|
|
21
|
+
/** A behavior-bit NAME (a key of {@link TOKEN_BEHAVIOR_BITS}) — the only legal way to spell `behavior`. */
|
|
22
|
+
export type BehaviorBitName = keyof typeof TOKEN_BEHAVIOR_BITS;
|
|
23
|
+
/** Sum behavior bits from their NAMES — never a magic literal int (CLAUDE.md #1). */
|
|
24
|
+
export declare function sumBehavior(bits: readonly BehaviorBitName[]): number;
|
|
25
|
+
/**
|
|
26
|
+
* Derive the default `stateShape.typeName`: strip a trailing `.asset` label, PascalCase the remainder
|
|
27
|
+
* (splitting on `.`/`-`/`_`/space), then append `State`.
|
|
28
|
+
* `rvd.asset` → `RvdState`, `goods.asset` → `GoodsState`, `capped.asset` → `CappedState`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function defaultStateTypeName(name: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Fungible currency. Behavior `T|S|C = 28` (transferable + splittable + combinable). Standard morphism
|
|
33
|
+
* set TRANSFER + FRACTIONALIZE + STAKE (`stakeable`, default true) + BURN (when `burnable`), all PUBLIC.
|
|
34
|
+
*
|
|
35
|
+
* Reproduces `riverdale-economy/rvd-policy.json` exactly via
|
|
36
|
+
* `fungiblePolicy({ name: 'rvd.asset', version: '1.0.0', mintable: true, burnable: true })`.
|
|
37
|
+
*/
|
|
38
|
+
export declare function fungiblePolicy(p: {
|
|
39
|
+
/** Registry name; conventionally ends `.asset`. */
|
|
40
|
+
name: string;
|
|
41
|
+
/** SemVer string. */
|
|
42
|
+
version: string;
|
|
43
|
+
/** `supply.decimals` — fractional precision; omit for whole-unit. */
|
|
44
|
+
decimals?: number;
|
|
45
|
+
/** `supply.maxSupply` — omit ⇒ uncapped. */
|
|
46
|
+
maxSupply?: number;
|
|
47
|
+
/** true ⇒ `supply.mintPolicy = {"==":[1,1]}` (open mint). */
|
|
48
|
+
mintable?: boolean;
|
|
49
|
+
/** true ⇒ `supply.burnPolicy = {"==":[1,1]}` AND a BURN morphism. */
|
|
50
|
+
burnable?: boolean;
|
|
51
|
+
/** JSON-Logic predicate that OVERRIDES `mintable`'s default mint guard (and enables minting). */
|
|
52
|
+
mintGuard?: JsonLogicExpression;
|
|
53
|
+
/** default true ⇒ a STAKE morphism. */
|
|
54
|
+
stakeable?: boolean;
|
|
55
|
+
/** `stateShape.typeName`; default `${PascalCase(name-without-.asset)}State`. */
|
|
56
|
+
stateTypeName?: string;
|
|
57
|
+
/** Off-chain links grab-bag; omitted when absent. */
|
|
58
|
+
metadata?: Record<string, string>;
|
|
59
|
+
}): CreateAssetPolicy;
|
|
60
|
+
/**
|
|
61
|
+
* Non-fungible token. Behavior `T = 16`, or `T|C = 20` with `combinable: true` (the riverdale
|
|
62
|
+
* `goods.asset`); `transferable: false` drops the T bit (a bound collectible). `morphisms` is `{}` by
|
|
63
|
+
* default (emitted explicitly, never omitted). Mintable by default ⇒ `supply.mintPolicy = {"==":[1,1]}`.
|
|
64
|
+
*
|
|
65
|
+
* Reproduces `riverdale-economy/goods-policy.json` exactly via
|
|
66
|
+
* `nftPolicy({ name: 'goods.asset', version: '1.0.0', combinable: true })`.
|
|
67
|
+
*/
|
|
68
|
+
export declare function nftPolicy(p: {
|
|
69
|
+
name: string;
|
|
70
|
+
version: string;
|
|
71
|
+
/** `T(16)` → `T|C(20)`. */
|
|
72
|
+
combinable?: boolean;
|
|
73
|
+
/** default true; false ⇒ drop the T bit (bound collectible: `0`, or `4` with `combinable`). */
|
|
74
|
+
transferable?: boolean;
|
|
75
|
+
/** default true ⇒ `supply.mintPolicy = {"==":[1,1]}`. */
|
|
76
|
+
mintable?: boolean;
|
|
77
|
+
/** JSON-Logic predicate that OVERRIDES the default mint guard. */
|
|
78
|
+
mintGuard?: JsonLogicExpression;
|
|
79
|
+
/** `supply.maxSupply` — omit ⇒ uncapped edition. */
|
|
80
|
+
maxSupply?: number;
|
|
81
|
+
/** `stateShape.typeName`; default `${PascalCase(name-without-.asset)}State`. */
|
|
82
|
+
stateTypeName?: string;
|
|
83
|
+
metadata?: Record<string, string>;
|
|
84
|
+
}): CreateAssetPolicy;
|
|
85
|
+
/**
|
|
86
|
+
* Soulbound token: non-transferable, governable only (`G = 1`; `+E = 3` when `expirable`). No TRANSFER
|
|
87
|
+
* morphism (`morphisms: {}`); minting is closed after issue (empty `supply`).
|
|
88
|
+
*/
|
|
89
|
+
export declare function soulboundPolicy(p: {
|
|
90
|
+
name: string;
|
|
91
|
+
version: string;
|
|
92
|
+
/** `+E(2)` ⇒ behavior `3`. */
|
|
93
|
+
expirable?: boolean;
|
|
94
|
+
/** `stateShape.typeName`; default `${PascalCase(name-without-.asset)}State`. */
|
|
95
|
+
stateTypeName?: string;
|
|
96
|
+
metadata?: Record<string, string>;
|
|
97
|
+
}): CreateAssetPolicy;
|
|
98
|
+
/**
|
|
99
|
+
* Escape hatch: declare `behavior` by NAME (summed from {@link TOKEN_BEHAVIOR_BITS}, never a magic int)
|
|
100
|
+
* and pass `supply` + `morphisms` through raw. Use when no preset fits.
|
|
101
|
+
*
|
|
102
|
+
* Reproduces `riverdale-economy/capped-policy.json` exactly via
|
|
103
|
+
* `customPolicy({ name: 'capped.asset', version: '1.0.0',
|
|
104
|
+
* behavior: ['transferable', 'splittable', 'combinable'],
|
|
105
|
+
* supply: { maxSupply: 100, mintPolicy: { '==': [1, 1] } }, morphisms: {} })`.
|
|
106
|
+
*/
|
|
107
|
+
export declare function customPolicy(p: {
|
|
108
|
+
name: string;
|
|
109
|
+
version: string;
|
|
110
|
+
/** Behavior-bit NAMES summed to the int (e.g. `['transferable','combinable']` ⇒ 20). Never a literal. */
|
|
111
|
+
behavior: readonly BehaviorBitName[];
|
|
112
|
+
/** Raw supply authority, passed through verbatim. */
|
|
113
|
+
supply: SupplyPolicy;
|
|
114
|
+
/** Raw morphism map, passed through verbatim (emit `{}` when empty, never omit). */
|
|
115
|
+
morphisms: Partial<Record<MorphismKind, MorphismSpec>>;
|
|
116
|
+
/** `stateShape.typeName`; default `${PascalCase(name-without-.asset)}State`. */
|
|
117
|
+
stateTypeName?: string;
|
|
118
|
+
metadata?: Record<string, string>;
|
|
119
|
+
}): CreateAssetPolicy;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@ottochain/sdk/templates` — the fiber & asset authoring template catalog.
|
|
3
|
+
*
|
|
4
|
+
* Typed builders that emit the EXACT canonical wire shapes app authors otherwise hand-roll as raw
|
|
5
|
+
* JSON-Logic (asset policies, versioned machines, effect directives, migrations, seeded state). Every
|
|
6
|
+
* builder is additive and pure — it returns the same wire shape the chain re-derives, so a template
|
|
7
|
+
* output signs to byte-identical `JCS(dropNulls(payload))` (CLAUDE.md rule #1). Hand-rolled JSON keeps
|
|
8
|
+
* working; these just make the recurring shapes typed, named, and mistake-resistant.
|
|
9
|
+
*
|
|
10
|
+
* Origin: the fiber-ergonomics program (ottochain `docs/proposals/fiber-ergonomics/`), Phase A — the
|
|
11
|
+
* `riverdale-economy` e2e is the migration proof (each preset reproduces its checked-in golden JSON).
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* import {
|
|
15
|
+
* fungiblePolicy, machine, transition, effect, guard,
|
|
16
|
+
* transferAsset, triggers, spawn, seedState, seedFields,
|
|
17
|
+
* } from '@ottochain/sdk/templates';
|
|
18
|
+
*/
|
|
19
|
+
export * from './asset-policy.js';
|
|
20
|
+
export * from './machine.js';
|
|
21
|
+
export * from './migration.js';
|
|
22
|
+
export * from './state-shape.js';
|
|
23
|
+
export * from '../schema/effects.js';
|
|
24
|
+
export * as guard from '../schema/guards.js';
|
|
25
|
+
export { defineFiberApp, toProtoDefinition, constrained, unconstrained, immutable, projectFiberPolicy, } from '../schema/fiber-app.js';
|
|
26
|
+
export type { FiberAppDefinition, Transition, ProtoStateMachineDefinition, FiberPolicy, FiberPolicyDials, } from '../schema/fiber-app.js';
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Versioned-machine skeleton + `transition()` / `effect()` composition (handoff §1.2).
|
|
3
|
+
*
|
|
4
|
+
* Two moves:
|
|
5
|
+
* 1. `transition()` / `effect()` build the wire `Transition` + its flat effect map from typed
|
|
6
|
+
* fragments instead of a hand-rolled JSON blob.
|
|
7
|
+
* 2. `machine()` is a versioned-package SKELETON that OWNS exactly ONE canonical wire definition
|
|
8
|
+
* (`toProtoDefinition(app)`, computed once) and hands the SAME object to BOTH `publishVersion()`
|
|
9
|
+
* and `create()`. That is the verified-binding invariant (F9): because publish and create cannot
|
|
10
|
+
* drift, the chain's `definition.computeDigest` equals the registered `logicHash` and the bind
|
|
11
|
+
* admits the fiber. The skeleton REUSES `toProtoDefinition` (the one canonicalization path) — it
|
|
12
|
+
* never re-derives the wire shape.
|
|
13
|
+
*
|
|
14
|
+
* Guardrail (CLAUDE.md #1): every builder here is a pure function emitting the exact wire shape the
|
|
15
|
+
* chain re-derives. Absent optionals (`metadata`/`participants`/`parentFiberId`/`migration`) are
|
|
16
|
+
* OMITTED, never `null`; required-no-default fields (`strict` on publish, `dependencies: []` per
|
|
17
|
+
* transition) are ALWAYS present.
|
|
18
|
+
*/
|
|
19
|
+
import { type Transition, type JsonLogicRule, type DependencySpec, type FiberAppDefinition, type ProtoStateMachineDefinition } from '../schema/fiber-app.js';
|
|
20
|
+
import type { MachineShape, PublishMachineVersion, CreateStateMachine, UpgradeFiber, SemVer, JsonLogicValue, JsonLogicExpression } from '../ottochain/types.js';
|
|
21
|
+
/** Authoring shape for {@link transition} — `on` is the event name (mapped to the wire `eventName`). */
|
|
22
|
+
export interface TransitionSpec<TState extends string = string, TEvent extends string = string> {
|
|
23
|
+
from: TState;
|
|
24
|
+
to: TState;
|
|
25
|
+
/** Event that fires this transition. Mapped to the wire key `eventName`. */
|
|
26
|
+
on: TEvent;
|
|
27
|
+
/** JSON-Logic predicate; defaults to the always-true `{ "==": [1, 1] }` when omitted. */
|
|
28
|
+
guard?: JsonLogicRule;
|
|
29
|
+
/** The flat effect map (build it with {@link effect}). Passed through verbatim. */
|
|
30
|
+
effect?: JsonLogicRule;
|
|
31
|
+
/**
|
|
32
|
+
* Dependencies for this transition. Defaults to `[]` (ALWAYS present — the chain
|
|
33
|
+
* `Transition.dependencies: Set[UUID]` has no default; omitting it diverges the canonical).
|
|
34
|
+
* `toProtoDefinition` later drops any non-string {@link DependencySpec} authoring entries.
|
|
35
|
+
*/
|
|
36
|
+
dependencies?: readonly (string | DependencySpec)[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Build a wire {@link Transition} from a typed spec.
|
|
40
|
+
*
|
|
41
|
+
* - `on` → `eventName` (the wire key);
|
|
42
|
+
* - `guard` defaults to `{ "==": [1, 1] }`;
|
|
43
|
+
* - `dependencies` defaults to `[]` and is ALWAYS present;
|
|
44
|
+
* - `effect` is passed through (build it with {@link effect}).
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```ts
|
|
48
|
+
* transition({
|
|
49
|
+
* from: 'debt_current', to: 'debt_current', on: 'buy',
|
|
50
|
+
* effect: effect(
|
|
51
|
+
* { status: 'debt_current', purchaseCount: { '+': [{ var: 'state.purchaseCount' }, 1] } },
|
|
52
|
+
* triggers([...]), transferAsset([...]),
|
|
53
|
+
* ),
|
|
54
|
+
* });
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export declare function transition<TState extends string = string, TEvent extends string = string>(t: TransitionSpec<TState, TEvent>): Transition<TState, TEvent>;
|
|
58
|
+
/**
|
|
59
|
+
* Compose an effect into ONE FLAT map: the state-update fields PLUS any `_`-directive fragments,
|
|
60
|
+
* all in a single object (`Object.assign({}, stateUpdate, ...directives)`).
|
|
61
|
+
*
|
|
62
|
+
* Riverdale effects are flat maps that mix `_`-reserved directives (`_triggers`, `_transferAsset`,
|
|
63
|
+
* `_spawn`, …) with plain state-update fields — they are NOT `merge`-wrapped. Each directive fragment
|
|
64
|
+
* is a `Record` (e.g. the output of `transferAsset(...)` / `triggers(...)`), spread in here. Later
|
|
65
|
+
* fragments override earlier keys (`Object.assign` semantics).
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* effect(
|
|
70
|
+
* { status: 'debt_current', purchaseCount: { '+': [{ var: 'state.purchaseCount' }, 1] } },
|
|
71
|
+
* { _triggers: [...] },
|
|
72
|
+
* transferAsset([{ assetId: { var: 'event.payAssetId' }, recipient: toFiber({ var: 'event.retailerId' }) }]),
|
|
73
|
+
* );
|
|
74
|
+
* // => { status, purchaseCount, _triggers, _transferAsset }
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export declare function effect(stateUpdate: Record<string, unknown>, ...directives: Record<string, unknown>[]): Record<string, unknown>;
|
|
78
|
+
/** The machine package spec: identity (`name`@`version`) + the one canonical `app` + its schema shape. */
|
|
79
|
+
export interface MachineSpec<TState extends string = string, TEvent extends string = string> {
|
|
80
|
+
/** Full registry name `labels.tld` (e.g. `"consumer.package"`). */
|
|
81
|
+
name: string;
|
|
82
|
+
/** SemVer string (e.g. `"1.0.0"`). */
|
|
83
|
+
version: SemVer;
|
|
84
|
+
/** The typed fiber app; projected ONCE to the canonical wire definition via `toProtoDefinition`. */
|
|
85
|
+
app: FiberAppDefinition<TState, TEvent>;
|
|
86
|
+
/** The advisory proto projection the chain stores for discovery (carried onto `PublishMachineVersion.machineShape`). */
|
|
87
|
+
schemaShape: MachineShape;
|
|
88
|
+
}
|
|
89
|
+
/** Options for {@link Machine.publishVersion}. */
|
|
90
|
+
export interface PublishVersionOptions {
|
|
91
|
+
/** Opt-in runtime conformance gate (#33). Defaults to `false` (REQUIRED on the wire — never omitted). */
|
|
92
|
+
strict?: boolean;
|
|
93
|
+
/** Optional off-chain links grab-bag; OMITTED when absent (never `null`). */
|
|
94
|
+
metadata?: Record<string, string>;
|
|
95
|
+
/**
|
|
96
|
+
* Base64 of the proto FileDescriptorSet. REQUIRED on the wire `PublishMachineVersion` (the chain
|
|
97
|
+
* base64-validates + hashes it, then drops the bytes), so it is ALWAYS present; defaults to the empty
|
|
98
|
+
* string `''` (valid empty base64) when the skeleton has no descriptor set bound. The verified binding
|
|
99
|
+
* hangs on `definition.computeDigest`, NOT on this field.
|
|
100
|
+
*/
|
|
101
|
+
schemaB64?: string;
|
|
102
|
+
}
|
|
103
|
+
/** Options for {@link Machine.create}. */
|
|
104
|
+
export interface CreateOptions {
|
|
105
|
+
fiberId: string;
|
|
106
|
+
/** Seeded fiber state (e.g. from `seedState(...)`); pre-seed accumulators so no field reads `null`. */
|
|
107
|
+
initialData: JsonLogicValue;
|
|
108
|
+
/** Optional DAG addresses authorized to sign transitions; OMITTED when absent (never `null`). */
|
|
109
|
+
participants?: string[];
|
|
110
|
+
/** Optional parent fiber UUID; OMITTED when absent (never `null`). */
|
|
111
|
+
parentFiberId?: string;
|
|
112
|
+
}
|
|
113
|
+
/** Options for {@link Machine.upgradeFrom}. */
|
|
114
|
+
export interface UpgradeOptions {
|
|
115
|
+
fiberId: string;
|
|
116
|
+
targetSequenceNumber: number;
|
|
117
|
+
/** Optional JSON-Logic migration transform of the prior state; OMITTED when absent (never `null`). */
|
|
118
|
+
migration?: JsonLogicExpression;
|
|
119
|
+
}
|
|
120
|
+
/** The versioned-machine skeleton returned by {@link machine}. */
|
|
121
|
+
export interface Machine {
|
|
122
|
+
/** The ONE canonical wire definition (`toProtoDefinition(app)`), shared by publish + create. */
|
|
123
|
+
wireDefinition(): ProtoStateMachineDefinition;
|
|
124
|
+
/** The `PublishMachineVersion` body — its `definition` is the SAME object as `wireDefinition()`. */
|
|
125
|
+
publishVersion(o?: PublishVersionOptions): PublishMachineVersion;
|
|
126
|
+
/** The `CreateStateMachine` body — references `name@version` via `schemaRef` + the SAME `definition`. */
|
|
127
|
+
create(o: CreateOptions): CreateStateMachine;
|
|
128
|
+
/** The `UpgradeFiber` body — re-pins to `name@version` with the SAME `newDefinition`. */
|
|
129
|
+
upgradeFrom(o: UpgradeOptions): UpgradeFiber;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Build a versioned-machine skeleton that binds publish + create to ONE canonical definition.
|
|
133
|
+
*
|
|
134
|
+
* The definition is projected ONCE here (`toProtoDefinition(spec.app)`) and the SAME reference is handed
|
|
135
|
+
* to `wireDefinition()`, `publishVersion().definition`, `create().definition`, and
|
|
136
|
+
* `upgradeFrom().newDefinition` — so they cannot drift and the chain's verified binding admits the fiber
|
|
137
|
+
* (F9). REUSES `toProtoDefinition` (the single canonicalization path); never re-derives the wire shape.
|
|
138
|
+
*/
|
|
139
|
+
export declare function machine<TState extends string = string, TEvent extends string = string>(spec: MachineSpec<TState, TEvent>): Machine;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration builders — the `UpgradeFiber.migration` JSON-Logic transform applied on a version upgrade.
|
|
3
|
+
*
|
|
4
|
+
* THE FOOT-GUN (F9): a migration's evaluation root is the BARE prior state, not `state.x`.
|
|
5
|
+
* The chain evaluates the migration expression against `sm.stateData` directly
|
|
6
|
+
* (`MeteredEvaluator.eval(expr, sm.stateData, Migration)`, FiberEngine.scala:300), so:
|
|
7
|
+
* - `{ var: '' }` => the WHOLE prior state object
|
|
8
|
+
* - `{ var: 'loyaltyPoints' }` => the top-level `loyaltyPoints` field
|
|
9
|
+
* This is UNLIKE an effect, where the root is the transition context and you read `{ var: 'state.x' }`.
|
|
10
|
+
* Writing `state.loyaltyPoints` in a migration silently reads `undefined`. These helpers hide that
|
|
11
|
+
* asymmetry by pinning the bare-state root for you.
|
|
12
|
+
*
|
|
13
|
+
* `migration` is `Option` on `UpgradeFiber` — when there is no transform, OMIT the key (never send `null`).
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Seed / overwrite top-level state fields on a version upgrade.
|
|
17
|
+
* Emits `{ merge: [{ var: '' }, fields] }` — merges `fields` onto the bare prior state, so existing
|
|
18
|
+
* fields are preserved and the named fields are added or overwritten.
|
|
19
|
+
*
|
|
20
|
+
* The `{ var: '' }` root is the BARE prior state (NOT `state.x` like an effect) — that asymmetry is
|
|
21
|
+
* exactly the F9 foot-gun this helper hides.
|
|
22
|
+
*
|
|
23
|
+
* @example seedFields({ loyaltyPoints: 0 }) // => { merge: [{ var: '' }, { loyaltyPoints: 0 }] }
|
|
24
|
+
*/
|
|
25
|
+
export declare const seedFields: (fields: Record<string, unknown>) => unknown;
|
|
26
|
+
/**
|
|
27
|
+
* General migration transform with the bare-state root made explicit. `build` receives `{ var: '' }`
|
|
28
|
+
* (the whole prior state) and returns the migration JSON-Logic.
|
|
29
|
+
*
|
|
30
|
+
* @example migration((s) => ({ merge: [s, { x: 1 }] })) // => { merge: [{ var: '' }, { x: 1 }] }
|
|
31
|
+
*/
|
|
32
|
+
export declare const migration: (build: (priorState: {
|
|
33
|
+
var: "";
|
|
34
|
+
}) => unknown) => unknown;
|